diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 79126fd658..7584eb8075 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,6 +29,12 @@ ] } }, + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + // https://github.com/devcontainers/features/issues/1466 + "moby": false + } + }, "forwardPorts": [3000, 9231, 9230, 2283], "portsAttributes": { "3000": { diff --git a/.devcontainer/server/container-compose-overrides.yml b/.devcontainer/server/container-compose-overrides.yml index 3be5cd8f3f..cc2b0c907b 100644 --- a/.devcontainer/server/container-compose-overrides.yml +++ b/.devcontainer/server/container-compose-overrides.yml @@ -21,6 +21,7 @@ services: - app-node_modules:/usr/src/app/node_modules - sveltekit:/usr/src/app/web/.svelte-kit - coverage:/usr/src/app/web/coverage + - ../plugins:/build/corePlugin immich-web: env_file: !reset [] immich-machine-learning: diff --git a/.github/.nvmrc b/.github/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/.github/.nvmrc +++ b/.github/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml index c214ba564e..9495d03bb9 100644 --- a/.github/workflows/build-mobile.yml +++ b/.github/workflows/build-mobile.yml @@ -96,7 +96,7 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: ref: ${{ inputs.ref || github.sha }} persist-credentials: false @@ -194,7 +194,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: ref: ${{ inputs.ref || github.sha }} persist-credentials: false diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml index 7d49d94791..a75770ec49 100644 --- a/.github/workflows/cache-cleanup.yml +++ b/.github/workflows/cache-cleanup.yml @@ -25,7 +25,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check out code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index fc2c9f6853..ef7300f7d4 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -35,7 +35,7 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -78,7 +78,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -105,7 +105,7 @@ jobs: - name: Generate docker image tags id: metadata - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: flavor: | latest=false diff --git a/.github/workflows/close-duplicates.yml b/.github/workflows/close-duplicates.yml index b3c79f81d8..24630bbb87 100644 --- a/.github/workflows/close-duplicates.yml +++ b/.github/workflows/close-duplicates.yml @@ -35,7 +35,7 @@ jobs: needs: [get_body, should_run] if: ${{ needs.should_run.outputs.should_run == 'true' }} container: - image: ghcr.io/immich-app/mdq:main@sha256:9c905a4ff69f00c4b2f98b40b6090ab3ab18d1a15ed1379733b8691aa1fcb271 + image: ghcr.io/immich-app/mdq:main@sha256:237cdae7783609c96f18037a513d38088713cf4a2e493a3aa136d0c45490749a outputs: checked: ${{ steps.get_checkbox.outputs.checked }} steps: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 34228843ad..dafc6eee3b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,14 +50,14 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -70,7 +70,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -83,6 +83,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 81b11c4aca..e27f1ebdf9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -132,7 +132,7 @@ jobs: suffixes: '-rocm' platforms: linux/amd64 runner-mapping: '{"linux/amd64": "mich"}' - uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@47a2ee86898ccff51592d6572391fb1abcd7f782 # multi-runner-build-workflow-v2.0.1 + uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0 permissions: contents: read actions: read @@ -155,7 +155,7 @@ jobs: name: Build and Push Server needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }} - uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@47a2ee86898ccff51592d6572391fb1abcd7f782 # multi-runner-build-workflow-v2.0.1 + uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0 permissions: contents: read actions: read diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index 823aa98fc8..24cb804e77 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -60,7 +60,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index 5d01646fef..3a0e918812 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -125,7 +125,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/docs-destroy.yml b/.github/workflows/docs-destroy.yml index 3ad3f3558e..643c35b1af 100644 --- a/.github/workflows/docs-destroy.yml +++ b/.github/workflows/docs-destroy.yml @@ -23,7 +23,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/fix-format.yml b/.github/workflows/fix-format.yml index f7f34b929c..d3db51348b 100644 --- a/.github/workflows/fix-format.yml +++ b/.github/workflows/fix-format.yml @@ -16,13 +16,13 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: 'Checkout' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: ref: ${{ github.event.pull_request.head.ref }} token: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/merge-translations.yml b/.github/workflows/merge-translations.yml index 32e1b1a138..92d2783441 100644 --- a/.github/workflows/merge-translations.yml +++ b/.github/workflows/merge-translations.yml @@ -31,7 +31,7 @@ jobs: - name: Generate a token id: generate_token if: ${{ inputs.skip != true }} - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 6e7ee8f608..e2543a53d0 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -49,20 +49,20 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: token: ${{ steps.generate-token.outputs.token }} persist-credentials: true ref: main - name: Install uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 - name: Setup pnpm uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 @@ -126,13 +126,13 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: token: ${{ steps.generate-token.outputs.token }} persist-credentials: false @@ -144,7 +144,7 @@ jobs: github-token: ${{ steps.generate-token.outputs.token }} - name: Create draft release - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 with: draft: true tag_name: ${{ env.IMMICH_VERSION }} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 524f6bc77c..204c0a853c 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -17,20 +17,20 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: token: ${{ steps.generate-token.outputs.token }} persist-credentials: true ref: main - name: Install uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 - name: Setup pnpm uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 @@ -159,7 +159,7 @@ jobs: - name: Create PR id: create-pr - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 with: token: ${{ steps.generate-token.outputs.token }} commit-message: 'chore: release ${{ steps.bump-type.outputs.next }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..1f6f7cf5cf --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,148 @@ +name: release.yml +on: + pull_request: + types: [closed] + paths: + - CHANGELOG.md + +jobs: + # Maybe double check PR source branch? + + merge_translations: + uses: ./.github/workflows/merge-translations.yml + permissions: + pull-requests: write + secrets: + PUSH_O_MATIC_APP_ID: ${{ secrets.PUSH_O_MATIC_APP_ID }} + PUSH_O_MATIC_APP_KEY: ${{ secrets.PUSH_O_MATIC_APP_KEY }} + WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} + + build_mobile: + uses: ./.github/workflows/build-mobile.yml + needs: merge_translations + permissions: + contents: read + secrets: + KEY_JKS: ${{ secrets.KEY_JKS }} + ALIAS: ${{ secrets.ALIAS }} + ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} + ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }} + # iOS secrets + APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} + APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} + APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} + IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }} + IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} + IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }} + IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}misc/release/notes.tmpl + IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }} + IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }} + IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }} + IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }} + FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }} + with: + ref: main + environment: production + + prepare_release: + runs-on: ubuntu-latest + needs: build_mobile + permissions: + actions: read # To download the app artifact + steps: + - name: Generate a token + id: generate-token + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 + with: + app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} + private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} + + - name: Checkout + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + with: + token: ${{ steps.generate-token.outputs.token }} + persist-credentials: false + ref: main + + - name: Extract changelog + id: changelog + run: | + CHANGELOG_PATH=$RUNNER_TEMP/changelog.md + sed -n '1,/^---$/p' CHANGELOG.md | head -n -1 > $CHANGELOG_PATH + echo "path=$CHANGELOG_PATH" >> $GITHUB_OUTPUT + VERSION=$(sed -n 's/^# //p' $CHANGELOG_PATH) + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Download APK + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + with: + name: release-apk-signed + github-token: ${{ steps.generate-token.outputs.token }} + + - name: Create draft release + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 + with: + tag_name: ${{ steps.version.outputs.result }} + token: ${{ steps.generate-token.outputs.token }} + body_path: ${{ steps.changelog.outputs.path }} + draft: true + files: | + docker/docker-compose.yml + docker/example.env + docker/hwaccel.ml.yml + docker/hwaccel.transcoding.yml + docker/prometheus.yml + *.apk + + - name: Rename Outline document + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + continue-on-error: true + env: + OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }} + VERSION: ${{ steps.changelog.outputs.version }} + with: + github-token: ${{ steps.generate-token.outputs.token }} + script: | + const outlineKey = process.env.OUTLINE_API_KEY; + const version = process.env.VERSION; + const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9'; + const baseUrl = 'https://outline.immich.cloud'; + + const listResponse = await fetch(`${baseUrl}/api/documents.list`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${outlineKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ parentDocumentId }) + }); + + if (!listResponse.ok) { + throw new Error(`Outline list failed: ${listResponse.statusText}`); + } + + const listData = await listResponse.json(); + const allDocuments = listData.data || []; + const document = allDocuments.find(doc => doc.title === 'next'); + + if (document) { + console.log(`Found document 'next', renaming to '${version}'...`); + + const updateResponse = await fetch(`${baseUrl}/api/documents.update`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${outlineKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + id: document.id, + title: version + }) + }); + + if (!updateResponse.ok) { + throw new Error(`Failed to rename document: ${updateResponse.statusText}`); + } + } else { + console.log('No document titled "next" found to rename'); + } diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index 12bdbc55bf..dc8cc34cb2 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -22,7 +22,7 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 99ee773af4..2b72ceb40a 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -55,7 +55,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44d7250f2f..f02114a39a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,7 +69,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -114,7 +114,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -161,7 +161,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -203,7 +203,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -247,7 +247,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -285,7 +285,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -333,7 +333,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -379,7 +379,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false submodules: 'recursive' @@ -418,7 +418,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false submodules: 'recursive' @@ -473,7 +473,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false submodules: 'recursive' @@ -500,8 +500,16 @@ jobs: run: docker compose build if: ${{ !cancelled() }} - name: Run e2e tests (web) + env: + CI: true run: npx playwright test if: ${{ !cancelled() }} + - name: Archive test results + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + if: success() || failure() + with: + name: e2e-web-test-results-${{ matrix.runner }} + path: e2e/playwright-report/ success-check-e2e: name: End-to-End Tests Success needs: [e2e-tests-server-cli, e2e-tests-web] @@ -526,7 +534,7 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -558,13 +566,13 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Install uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 + - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 # TODO: add caching when supported (https://github.com/actions/setup-python/pull/818) # with: # python-version: 3.11 @@ -602,7 +610,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -631,7 +639,7 @@ jobs: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -653,7 +661,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} @@ -715,7 +723,7 @@ jobs: private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/weblate-lock.yml b/.github/workflows/weblate-lock.yml index 1f0a7608d1..e37497b9bb 100644 --- a/.github/workflows/weblate-lock.yml +++ b/.github/workflows/weblate-lock.yml @@ -36,8 +36,7 @@ jobs: github-token: ${{ steps.token.outputs.token }} filters: | i18n: - - 'i18n/!(en)**\.json' - exclude-branches: 'chore/translations' + - modified: 'i18n/!(en)**\.json' skip-force-logic: 'true' enforce-lock: diff --git a/.vscode/settings.json b/.vscode/settings.json index b386502a11..54c018259b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -52,7 +52,7 @@ }, "cSpell.words": ["immich"], "editor.formatOnSave": true, - "eslint.validate": ["javascript", "svelte"], + "eslint.validate": ["javascript", "typescript", "svelte"], "explorer.fileNesting.enabled": true, "explorer.fileNesting.patterns": { "*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart", diff --git a/Makefile b/Makefile index fc99170676..2fc1c5d801 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,9 @@ dev-docs: e2e: @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans +e2e-dev: + @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans + e2e-update: @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans diff --git a/README.md b/README.md index b540408475..7e06d9de4b 100644 --- a/README.md +++ b/README.md @@ -118,16 +118,16 @@ Read more about translations [here](https://docs.immich.app/developer/translatio ## Star history - + - - - Star History Chart + + + Star History Chart ## Contributors - + diff --git a/cli/.nvmrc b/cli/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/cli/.nvmrc +++ b/cli/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/cli/Dockerfile b/cli/Dockerfile index 8c74fe12b1..d56190ee16 100644 --- a/cli/Dockerfile +++ b/cli/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22.16.0-alpine3.20@sha256:2289fb1fba0f4633b08ec47b94a89c7e20b829fc5679f9b7b298eaa2f1ed8b7e AS core +FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a7dea969802d7e0c2b25 AS core WORKDIR /usr/src/app COPY package* pnpm* .pnpmfile.cjs ./ diff --git a/cli/package.json b/cli/package.json index 6fed806003..b64354ee4a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@immich/cli", - "version": "2.2.101", + "version": "2.2.103", "description": "Command Line Interface (CLI) for Immich", "type": "module", "exports": "./dist/index.js", @@ -20,7 +20,7 @@ "@types/lodash-es": "^4.17.12", "@types/micromatch": "^4.0.9", "@types/mock-fs": "^4.13.1", - "@types/node": "^22.19.0", + "@types/node": "^24.10.1", "@vitest/coverage-v8": "^3.0.0", "byte-size": "^9.0.0", "cli-progress": "^3.12.0", @@ -28,7 +28,7 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", + "eslint-plugin-unicorn": "^62.0.0", "globals": "^16.0.0", "mock-fs": "^5.2.0", "prettier": "^3.2.5", @@ -69,6 +69,6 @@ "micromatch": "^4.0.8" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" } } diff --git a/cli/src/utils.spec.ts b/cli/src/utils.spec.ts index 5dd28a55e3..3924f9ecb9 100644 --- a/cli/src/utils.spec.ts +++ b/cli/src/utils.spec.ts @@ -299,7 +299,7 @@ describe('crawl', () => { .map(([file]) => file); // Compare file's content instead of path since a file can be represent in multiple ways. - expect(actual.map((path) => readContent(path)).sort()).toEqual(expected.sort()); + expect(actual.map((path) => readContent(path)).toSorted()).toEqual(expected.toSorted()); }); } }); diff --git a/cli/src/utils.ts b/cli/src/utils.ts index eae5164394..9ef20b3679 100644 --- a/cli/src/utils.ts +++ b/cli/src/utils.ts @@ -160,7 +160,7 @@ export const crawl = async (options: CrawlOptions): Promise => { ignore: [`**/${exclusionPattern}`], }); globbedFiles.push(...crawledFiles); - return globbedFiles.sort(); + return globbedFiles.toSorted(); }; export const sha1 = (filepath: string) => { diff --git a/cli/tsconfig.json b/cli/tsconfig.json index fcd01e01c0..d3a02a8257 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -9,7 +9,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, - "target": "es2022", + "target": "es2023", "sourceMap": true, "outDir": "./dist", "incremental": true, diff --git a/deployment/mise.toml b/deployment/mise.toml index f3d07ac31f..53b683a7d3 100644 --- a/deployment/mise.toml +++ b/deployment/mise.toml @@ -1,6 +1,6 @@ [tools] -terragrunt = "0.91.2" -opentofu = "1.10.6" +terragrunt = "0.93.10" +opentofu = "1.10.7" [tasks."tg:fmt"] run = "terragrunt hclfmt" diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index e2fb8fbc30..6fa1c51bdd 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -135,7 +135,7 @@ services: redis: container_name: immich_redis - image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa + image: docker.io/valkey/valkey:9@sha256:4503e204c900a00ad393bec83c8c7c4c76b0529cd629e23b34b52011aefd1d27 healthcheck: test: redis-cli ping || exit 1 diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index e01f4ead22..1aae886bc6 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -56,7 +56,7 @@ services: redis: container_name: immich_redis - image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa + image: docker.io/valkey/valkey:9@sha256:4503e204c900a00ad393bec83c8c7c4c76b0529cd629e23b34b52011aefd1d27 healthcheck: test: redis-cli ping || exit 1 restart: always @@ -95,7 +95,7 @@ services: command: ['./run.sh', '-disable-reporting'] ports: - 3000:3000 - image: grafana/grafana:12.2.1-ubuntu@sha256:797530c642f7b41ba7848c44cfda5e361ef1f3391a98bed1e5d448c472b6826a + image: grafana/grafana:12.3.0-ubuntu@sha256:cee936306135e1925ab21dffa16f8a411535d16ab086bef2309339a8e74d62df volumes: - grafana-data:/var/lib/grafana diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e4e0f964d3..51b6d3e860 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -49,7 +49,7 @@ services: redis: container_name: immich_redis - image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa + image: docker.io/valkey/valkey:9@sha256:4503e204c900a00ad393bec83c8c7c4c76b0529cd629e23b34b52011aefd1d27 healthcheck: test: redis-cli ping || exit 1 restart: always diff --git a/docs/.nvmrc b/docs/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/docs/.nvmrc +++ b/docs/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/docs/docs/FAQ.mdx b/docs/docs/FAQ.mdx index e3df672d35..9dcfcac48b 100644 --- a/docs/docs/FAQ.mdx +++ b/docs/docs/FAQ.mdx @@ -133,9 +133,9 @@ There are a few different scenarios that can lead to this situation. The solutio The job is only automatically run once per asset after upload. If metadata extraction originally failed, the jobs were cleared/canceled, etc., the job may not have run automatically the first time. -### How can I hide photos from the timeline? +### How can I hide a photo or video from the timeline? -You can _archive_ them. +You can _archive_ them. This will hide the asset from the main timeline and folder view, but it will still show up in searches. All archived assets can be found in the _Archive_ view ### How can I backup data from Immich? diff --git a/docs/docs/administration/backup-and-restore.md b/docs/docs/administration/backup-and-restore.md index fbb4cd8c23..2ca965624f 100644 --- a/docs/docs/administration/backup-and-restore.md +++ b/docs/docs/administration/backup-and-restore.md @@ -41,7 +41,7 @@ By default, Immich will keep the last 14 database dumps and create a new dump ev #### Trigger Dump -You are able to trigger a database dump in the [admin job status page](http://my.immich.app/admin/jobs-status). +You are able to trigger a database dump in the [admin job status page](http://my.immich.app/admin/queues). Visit the page, open the "Create job" modal from the top right, select "Create Database Dump" and click "Confirm". A job will run and trigger a dump, you can verify this worked correctly by checking the logs or the `backups/` folder. This dumps will count towards the last `X` dumps that will be kept based on your settings. diff --git a/docs/docs/administration/maintenance-mode.md b/docs/docs/administration/maintenance-mode.md new file mode 100644 index 0000000000..300c27ca40 --- /dev/null +++ b/docs/docs/administration/maintenance-mode.md @@ -0,0 +1,18 @@ +# Maintenance Mode + +Maintenance mode is used to perform administrative tasks such as restoring backups to Immich. + +You can enter maintenance mode by either: + +- Selecting "enable maintenance mode" in system settings in administration. +- Running the enable maintenance mode [administration command](./server-commands.md). + +## Logging in during maintenance + +Maintenance mode uses a separate login system which is handled automatically behind the scenes in most cases. Enabling maintenance mode in settings will automatically log you into maintenance mode when the server comes back up. + +If you find that you've been logged out, you can: + +- Open the logs for the Immich server and look for _"🚧 Immich is in maintenance mode, you can log in using the following URL:"_ +- Run the enable maintenance mode [administration command](./server-commands.md) again, this will give you a new URL to login with. +- Run the disable maintenance mode [administration command](./server-commands.md) then re-enter through system settings. diff --git a/docs/docs/administration/reverse-proxy.md b/docs/docs/administration/reverse-proxy.md index 5c9e47b010..f766f42719 100644 --- a/docs/docs/administration/reverse-proxy.md +++ b/docs/docs/administration/reverse-proxy.md @@ -21,6 +21,9 @@ server { # allow large file uploads client_max_body_size 50000M; + # disable buffering uploads to prevent OOM on reverse proxy server and make uploads twice as fast (no pause) + proxy_request_buffering off; + # Set headers proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/docs/docs/administration/server-commands.md b/docs/docs/administration/server-commands.md index 3838635c24..8c58baac17 100644 --- a/docs/docs/administration/server-commands.md +++ b/docs/docs/administration/server-commands.md @@ -2,17 +2,19 @@ The `immich-server` docker image comes preinstalled with an administrative CLI (`immich-admin`) that supports the following commands: -| Command | Description | -| ------------------------ | ------------------------------------------------------------- | -| `help` | Display help | -| `reset-admin-password` | Reset the password for the admin user | -| `disable-password-login` | Disable password login | -| `enable-password-login` | Enable password login | -| `enable-oauth-login` | Enable OAuth login | -| `disable-oauth-login` | Disable OAuth login | -| `list-users` | List Immich users | -| `version` | Print Immich version | -| `change-media-location` | Change database file paths to align with a new media location | +| Command | Description | +| -------------------------- | ------------------------------------------------------------- | +| `help` | Display help | +| `reset-admin-password` | Reset the password for the admin user | +| `disable-password-login` | Disable password login | +| `enable-password-login` | Enable password login | +| `disable-maintenance-mode` | Disable maintenance mode | +| `enable-maintenance-mode` | Enable maintenance mode | +| `enable-oauth-login` | Enable OAuth login | +| `disable-oauth-login` | Disable OAuth login | +| `list-users` | List Immich users | +| `version` | Print Immich version | +| `change-media-location` | Change database file paths to align with a new media location | ## How to run a command @@ -47,6 +49,23 @@ immich-admin enable-password-login Password login has been enabled. ``` +Disable Maintenance Mode + +``` +immich-admin disable-maintenace-mode +Maintenance mode has been disabled. +``` + +Enable Maintenance Mode + +``` +immich-admin enable-maintenance-mode +Maintenance mode has been enabled. + +Log in using the following URL: +https://my.immich.app/maintenance?token= +``` + Enable OAuth login ``` diff --git a/docs/docs/developer/devcontainers.md b/docs/docs/developer/devcontainers.md index 0a1946e6c1..f50ec62d8a 100644 --- a/docs/docs/developer/devcontainers.md +++ b/docs/docs/developer/devcontainers.md @@ -256,7 +256,7 @@ The Dev Container supports multiple ways to run tests: ```bash # Run tests for specific components -make test-server # Server unit tests +make test-server # Server unit tests make test-web # Web unit tests make test-e2e # End-to-end tests make test-cli # CLI tests @@ -268,12 +268,13 @@ make test-all # Runs tests for all components make test-medium-dev # End-to-end tests ``` -#### Using NPM Directly +#### Using PNPM Directly ```bash # Server tests cd /workspaces/immich/server -pnpm test # Run all tests +pnpm test # Run all tests +pnpm run test:medium # Medium tests (integration tests) pnpm run test:watch # Watch mode pnpm run test:cov # Coverage report @@ -293,21 +294,21 @@ pnpm run test:web # Run web UI tests ```bash # Linting make lint-server # Lint server code -make lint-web # Lint web code -make lint-all # Lint all components +make lint-web # Lint web code +make lint-all # Lint all components # Formatting make format-server # Format server code -make format-web # Format web code -make format-all # Format all code +make format-web # Format web code +make format-all # Format all code # Type checking make check-server # Type check server -make check-web # Type check web -make check-all # Check all components +make check-web # Type check web +make check-all # Check all components # Complete hygiene check -make hygiene-all # Runs lint, format, check, SQL sync, and audit +make hygiene-all # Run lint, format, check, SQL sync, and audit ``` ### Additional Make Commands @@ -315,21 +316,21 @@ make hygiene-all # Runs lint, format, check, SQL sync, and audit ```bash # Build commands make build-server # Build server -make build-web # Build web app -make build-all # Build everything +make build-web # Build web app +make build-all # Build everything # API generation -make open-api # Generate OpenAPI specs +make open-api # Generate OpenAPI specs make open-api-typescript # Generate TypeScript SDK -make open-api-dart # Generate Dart SDK +make open-api-dart # Generate Dart SDK # Database -make sql # Sync database schema +make sql # Sync database schema # Dependencies -make install-server # Install server dependencies -make install-web # Install web dependencies -make install-all # Install all dependencies +make install-server # Install server dependencies +make install-web # Install web dependencies +make install-all # Install all dependencies ``` ### Debugging diff --git a/docs/docs/developer/pr-checklist.md b/docs/docs/developer/pr-checklist.md index f855e854c4..e68567bc8f 100644 --- a/docs/docs/developer/pr-checklist.md +++ b/docs/docs/developer/pr-checklist.md @@ -14,15 +14,15 @@ When contributing code through a pull request, please check the following: - [ ] `pnpm run check:typescript` (check typescript) - [ ] `pnpm test` (unit tests) +:::tip AIO +Run all web checks with `pnpm run check:all` +::: + ## Documentation - [ ] `pnpm run format` (formatting via Prettier) - [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation. -:::tip AIO -Run all web checks with `pnpm run check:all` -::: - ## Server Checks - [ ] `pnpm run lint` (linting via ESLint) diff --git a/docs/docs/developer/setup.md b/docs/docs/developer/setup.md index f262743dcd..23c1862c19 100644 --- a/docs/docs/developer/setup.md +++ b/docs/docs/developer/setup.md @@ -48,7 +48,6 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3 **Notes:** - The "web" development container runs with uid 1000. If that uid does not have read/write permissions on the mounted volumes, you may encounter errors -- In case of rootless docker setup, you need to use root within the container, otherwise you will encounter read/write permission related errors, see comments in `docker/docker-compose.dev.yml`. #### Connect web to a remote backend diff --git a/docs/docs/developer/testing.md b/docs/docs/developer/testing.md index e1b96f9164..d7c9edcd31 100644 --- a/docs/docs/developer/testing.md +++ b/docs/docs/developer/testing.md @@ -18,6 +18,7 @@ make e2e Before you can run the tests, you need to run the following commands _once_: - `pnpm install` (in `e2e/`) +- `pnpm run build` (in `cli/`) - `make open-api` (in the project root `/`) Once the test environment is running, the e2e tests can be run via: diff --git a/docs/docs/features/searching.md b/docs/docs/features/searching.md index d7ebd1a468..e8985b0c92 100644 --- a/docs/docs/features/searching.md +++ b/docs/docs/features/searching.md @@ -1222,4 +1222,4 @@ Feel free to make a feature request if there's a model you want to use that we d [huggingface-clip]: https://huggingface.co/collections/immich-app/clip-654eaefb077425890874cd07 [huggingface-multilingual-clip]: https://huggingface.co/collections/immich-app/multilingual-clip-654eb08c2382f591eeb8c2a7 [smart-search-settings]: https://my.immich.app/admin/system-settings?isOpen=machine-learning+smart-search -[job-status-page]: https://my.immich.app/admin/jobs-status +[job-status-page]: https://my.immich.app/admin/queues diff --git a/docs/docs/guides/remote-machine-learning.md b/docs/docs/guides/remote-machine-learning.md index 0a8ddf2577..b677d83b0d 100644 --- a/docs/docs/guides/remote-machine-learning.md +++ b/docs/docs/guides/remote-machine-learning.md @@ -53,7 +53,7 @@ Version mismatches between both hosts may cause bugs and instability, so remembe Adding a new URL to the settings is recommended over replacing the existing URL. This is because it will allow machine learning tasks to be processed successfully when the remote server is down by falling back to the local machine learning container. If you do not want machine learning tasks to be processed locally when the remote server is not available, you can instead replace the existing URL and only provide the remote container's URL. If doing this, you can remove the `immich-machine-learning` section of the local `docker-compose.yml` file to save resources, as this service will never be used. -Do note that this will mean that Smart Search and Face Detection jobs will fail to be processed when the remote instance is not available. This in turn means that tasks dependent on these features—Duplicate Detection and Facial Recognition—will not run for affected assets. If this occurs, you must manually click the _Missing_ button next to Smart Search and Face Detection in the [Job Status](http://my.immich.app/admin/jobs-status) page for the jobs to be retried. +Do note that this will mean that Smart Search and Face Detection jobs will fail to be processed when the remote instance is not available. This in turn means that tasks dependent on these features—Duplicate Detection and Facial Recognition—will not run for affected assets. If this occurs, you must manually click the _Missing_ button next to Smart Search and Face Detection in the [Job Status](http://my.immich.app/admin/queues) page for the jobs to be retried. ## Load balancing diff --git a/docs/docs/install/environment-variables.md b/docs/docs/install/environment-variables.md index 55c226d507..76784b285a 100644 --- a/docs/docs/install/environment-variables.md +++ b/docs/docs/install/environment-variables.md @@ -62,10 +62,10 @@ Information on the current workers can be found [here](/administration/jobs-work ## Ports -| Variable | Description | Default | -| :------------ | :------------- | :----------------------------------------: | -| `IMMICH_HOST` | Listening host | `0.0.0.0` | -| `IMMICH_PORT` | Listening port | `2283` (server), `3003` (machine learning) | +| Variable | Description | Default | Containers | +| :------------ | :------------- | :----------------------------------------: | :----------------------- | +| `IMMICH_HOST` | Listening host | `0.0.0.0` | server, machine learning | +| `IMMICH_PORT` | Listening port | `2283` (server), `3003` (machine learning) | server, machine learning | ## Database @@ -80,7 +80,7 @@ Information on the current workers can be found [here](/administration/jobs-work | `DB_SSL_MODE` | Database SSL mode | | server | | `DB_VECTOR_EXTENSION`\*2 | Database vector extension (one of [`vectorchord`, `pgvector`, `pgvecto.rs`]) | | server | | `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server | -| `DB_STORAGE_TYPE` | Optimize concurrent IO on SSDs or sequential IO on HDDs ([`SSD`, `HDD`])\*3 | `SSD` | server | +| `DB_STORAGE_TYPE` | Optimize concurrent IO on SSDs or sequential IO on HDDs ([`SSD`, `HDD`])\*3 | `SSD` | database | \*1: The values of `DB_USERNAME`, `DB_PASSWORD`, and `DB_DATABASE_NAME` are passed to the Postgres container as the variables `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` in `docker-compose.yml`. @@ -93,7 +93,7 @@ Information on the current workers can be found [here](/administration/jobs-work All `DB_` variables must be provided to all Immich workers, including `api` and `microservices`. `DB_URL` must be in the format `postgresql://immichdbusername:immichdbpassword@postgreshost:postgresport/immichdatabasename`. -You can require SSL by adding `?sslmode=require` to the end of the `DB_URL` string, or require SSL and skip certificate verification by adding `?sslmode=require&sslmode=no-verify`. +You can require SSL by adding `?sslmode=require` to the end of the `DB_URL` string, or require SSL and skip certificate verification by adding `?sslmode=require&uselibpqcompat=true`. This allows both immich and `pg_dumpall` (the utility used for database backups) to [properly connect](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string#tcp-connections) to your database. When `DB_URL` is defined, the `DB_HOSTNAME`, `DB_PORT`, `DB_USERNAME`, `DB_PASSWORD` and `DB_DATABASE_NAME` database variables are ignored. diff --git a/docs/package.json b/docs/package.json index a7c958351c..b96059c523 100644 --- a/docs/package.json +++ b/docs/package.json @@ -57,6 +57,6 @@ "node": ">=20" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" } } diff --git a/docs/static/archived-versions.json b/docs/static/archived-versions.json index 6affb532c9..87dc3f3465 100644 --- a/docs/static/archived-versions.json +++ b/docs/static/archived-versions.json @@ -1,4 +1,12 @@ [ + { + "label": "v2.3.1", + "url": "https://docs.v2.3.1.archive.immich.app" + }, + { + "label": "v2.3.0", + "url": "https://docs.v2.3.0.archive.immich.app" + }, { "label": "v2.2.3", "url": "https://docs.v2.2.3.archive.immich.app" diff --git a/e2e/.gitignore b/e2e/.gitignore index bbc06c5549..00b1601f07 100644 --- a/e2e/.gitignore +++ b/e2e/.gitignore @@ -4,3 +4,4 @@ node_modules/ /blob-report/ /playwright/.cache/ /dist +.env diff --git a/e2e/.nvmrc b/e2e/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/e2e/.nvmrc +++ b/e2e/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/e2e/docker-compose.dev.yml b/e2e/docker-compose.dev.yml new file mode 100644 index 0000000000..cd1d3d4982 --- /dev/null +++ b/e2e/docker-compose.dev.yml @@ -0,0 +1,105 @@ +name: immich-e2e + +services: + immich-server: + container_name: immich-e2e-server + command: ['immich-dev'] + image: immich-server-dev:latest + build: + context: ../ + dockerfile: server/Dockerfile.dev + target: dev + environment: + - DB_HOSTNAME=database + - DB_USERNAME=postgres + - DB_PASSWORD=postgres + - DB_DATABASE_NAME=immich + - IMMICH_MACHINE_LEARNING_ENABLED=false + - IMMICH_TELEMETRY_INCLUDE=all + - IMMICH_ENV=testing + - IMMICH_PORT=2285 + - IMMICH_IGNORE_MOUNT_CHECK_ERRORS=true + volumes: + - ./test-assets:/test-assets + - ..:/usr/src/app + - ${UPLOAD_LOCATION}/photos:/data + - /etc/localtime:/etc/localtime:ro + - pnpm-store:/usr/src/app/.pnpm-store + - server-node_modules:/usr/src/app/server/node_modules + - web-node_modules:/usr/src/app/web/node_modules + - github-node_modules:/usr/src/app/.github/node_modules + - cli-node_modules:/usr/src/app/cli/node_modules + - docs-node_modules:/usr/src/app/docs/node_modules + - e2e-node_modules:/usr/src/app/e2e/node_modules + - sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules + - app-node_modules:/usr/src/app/node_modules + - sveltekit:/usr/src/app/web/.svelte-kit + - coverage:/usr/src/app/web/coverage + - ../plugins:/build/corePlugin + depends_on: + redis: + condition: service_started + database: + condition: service_healthy + + immich-web: + container_name: immich-e2e-web + image: immich-web-dev:latest + build: + context: ../ + dockerfile: server/Dockerfile.dev + target: dev + command: ['immich-web'] + ports: + - 2285:3000 + environment: + - IMMICH_SERVER_URL=http://immich-server:2285/ + volumes: + - ..:/usr/src/app + - pnpm-store:/usr/src/app/.pnpm-store + - server-node_modules:/usr/src/app/server/node_modules + - web-node_modules:/usr/src/app/web/node_modules + - github-node_modules:/usr/src/app/.github/node_modules + - cli-node_modules:/usr/src/app/cli/node_modules + - docs-node_modules:/usr/src/app/docs/node_modules + - e2e-node_modules:/usr/src/app/e2e/node_modules + - sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules + - app-node_modules:/usr/src/app/node_modules + - sveltekit:/usr/src/app/web/.svelte-kit + - coverage:/usr/src/app/web/coverage + restart: unless-stopped + + redis: + image: redis:6.2-alpine@sha256:37e002448575b32a599109664107e374c8709546905c372a34d64919043b9ceb + + database: + image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0@sha256:6f3e9d2c2177af16c2988ff71425d79d89ca630ec2f9c8db03209ab716542338 + command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: immich + ports: + - 5435:5432 + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres -d immich'] + interval: 1s + timeout: 5s + retries: 30 + start_period: 10s + +volumes: + model-cache: + prometheus-data: + grafana-data: + pnpm-store: + server-node_modules: + web-node_modules: + github-node_modules: + cli-node_modules: + docs-node_modules: + e2e-node_modules: + sdk-node_modules: + app-node_modules: + sveltekit: + coverage: diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml index 3d62c8a34a..867a367d54 100644 --- a/e2e/docker-compose.yml +++ b/e2e/docker-compose.yml @@ -7,6 +7,9 @@ services: build: context: ../ dockerfile: server/Dockerfile + cache_from: + - type=registry,ref=ghcr.io/immich-app/immich-server-build-cache:linux-amd64-cc099f297acd18c924b35ece3245215b53d106eb2518e3af6415931d055746cd-main + - type=registry,ref=ghcr.io/immich-app/immich-server-build-cache:linux-arm64-cc099f297acd18c924b35ece3245215b53d106eb2518e3af6415931d055746cd-main args: - BUILD_ID=1234567890 - BUILD_IMAGE=e2e diff --git a/e2e/package.json b/e2e/package.json index 84e1823e0c..7bf61ea232 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -1,6 +1,6 @@ { "name": "immich-e2e", - "version": "2.2.3", + "version": "2.3.1", "description": "", "main": "index.js", "type": "module", @@ -20,21 +20,23 @@ "license": "GNU Affero General Public License version 3", "devDependencies": { "@eslint/js": "^9.8.0", + "@faker-js/faker": "^10.1.0", "@immich/cli": "file:../cli", "@immich/sdk": "file:../open-api/typescript-sdk", "@playwright/test": "^1.44.1", "@socket.io/component-emitter": "^3.1.2", "@types/luxon": "^3.4.2", - "@types/node": "^22.19.0", + "@types/node": "^24.10.1", "@types/oidc-provider": "^9.0.0", "@types/pg": "^8.15.1", "@types/pngjs": "^6.0.4", "@types/supertest": "^6.0.2", + "dotenv": "^17.2.3", "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", - "exiftool-vendored": "^31.1.0", + "eslint-plugin-unicorn": "^62.0.0", + "exiftool-vendored": "^33.0.0", "globals": "^16.0.0", "jose": "^5.6.3", "luxon": "^3.4.4", @@ -43,7 +45,7 @@ "pngjs": "^7.0.0", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^4.0.0", - "sharp": "^0.34.4", + "sharp": "^0.34.5", "socket.io-client": "^4.7.4", "supertest": "^7.0.0", "typescript": "^5.3.3", @@ -52,6 +54,6 @@ "vitest": "^3.0.0" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" } } diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 2576a2c5c9..4ae542bacf 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -1,23 +1,50 @@ -import { defineConfig, devices } from '@playwright/test'; +import { defineConfig, devices, PlaywrightTestConfig } from '@playwright/test'; +import dotenv from 'dotenv'; +import { cpus } from 'node:os'; +import { resolve } from 'node:path'; -export default defineConfig({ +dotenv.config({ path: resolve(import.meta.dirname, '.env') }); + +export const playwrightHost = process.env.PLAYWRIGHT_HOST ?? '127.0.0.1'; +export const playwrightDbHost = process.env.PLAYWRIGHT_DB_HOST ?? '127.0.0.1'; +export const playwriteBaseUrl = process.env.PLAYWRIGHT_BASE_URL ?? `http://${playwrightHost}:2285`; +export const playwriteSlowMo = parseInt(process.env.PLAYWRIGHT_SLOW_MO ?? '0'); +export const playwrightDisableWebserver = process.env.PLAYWRIGHT_DISABLE_WEBSERVER; + +process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS = '1'; + +const config: PlaywrightTestConfig = { testDir: './src/web/specs', fullyParallel: false, forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: 1, + retries: process.env.CI ? 4 : 0, reporter: 'html', use: { - baseURL: 'http://127.0.0.1:2285', + baseURL: playwriteBaseUrl, trace: 'on-first-retry', + screenshot: 'only-on-failure', + launchOptions: { + slowMo: playwriteSlowMo, + }, }, testMatch: /.*\.e2e-spec\.ts/, + workers: process.env.CI ? 4 : Math.round(cpus().length * 0.75), + projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, + testMatch: /.*\.e2e-spec\.ts/, + workers: 1, + }, + { + name: 'parallel tests', + use: { ...devices['Desktop Chrome'] }, + testMatch: /.*\.parallel-e2e-spec\.ts/, + fullyParallel: true, + workers: process.env.CI ? 3 : Math.max(1, Math.round(cpus().length * 0.75) - 1), }, // { @@ -59,4 +86,8 @@ export default defineConfig({ stderr: 'pipe', reuseExistingServer: true, }, -}); +}; +if (playwrightDisableWebserver) { + delete config.webServer; +} +export default defineConfig(config); diff --git a/e2e/src/api/specs/library.e2e-spec.ts b/e2e/src/api/specs/library.e2e-spec.ts index 59ff74cc43..4d67a84647 100644 --- a/e2e/src/api/specs/library.e2e-spec.ts +++ b/e2e/src/api/specs/library.e2e-spec.ts @@ -1006,7 +1006,7 @@ describe('/libraries', () => { rmSync(`${testAssetDir}/temp/xmp`, { recursive: true, force: true }); }); - it('should switch from using file metadata to file.xmp metadata when asset refreshes', async () => { + it('should switch from using file metadata to file.ext.xmp metadata when asset refreshes', async () => { const library = await utils.createLibrary(admin.accessToken, { ownerId: admin.userId, importPaths: [`${testAssetDirInternal}/temp/xmp`], diff --git a/e2e/src/api/specs/maintenance.e2e-spec.ts b/e2e/src/api/specs/maintenance.e2e-spec.ts new file mode 100644 index 0000000000..b6c7540bc5 --- /dev/null +++ b/e2e/src/api/specs/maintenance.e2e-spec.ts @@ -0,0 +1,172 @@ +import { LoginResponseDto } from '@immich/sdk'; +import { createUserDto } from 'src/fixtures'; +import { errorDto } from 'src/responses'; +import { app, utils } from 'src/utils'; +import request from 'supertest'; +import { beforeAll, describe, expect, it } from 'vitest'; + +describe('/admin/maintenance', () => { + let cookie: string | undefined; + let admin: LoginResponseDto; + let nonAdmin: LoginResponseDto; + + beforeAll(async () => { + await utils.resetDatabase(); + admin = await utils.adminSetup(); + nonAdmin = await utils.userSetup(admin.accessToken, createUserDto.user1); + }); + + // => outside of maintenance mode + + describe('GET ~/server/config', async () => { + it('should indicate we are out of maintenance mode', async () => { + const { status, body } = await request(app).get('/server/config'); + expect(status).toBe(200); + expect(body.maintenanceMode).toBeFalsy(); + }); + }); + + describe('POST /login', async () => { + it('should not work out of maintenance mode', async () => { + const { status, body } = await request(app).post('/admin/maintenance/login').send({ token: 'token' }); + expect(status).toBe(400); + expect(body).toEqual(errorDto.badRequest('Not in maintenance mode')); + }); + }); + + // => enter maintenance mode + + describe.sequential('POST /', () => { + it('should require authentication', async () => { + const { status, body } = await request(app).post('/admin/maintenance').send({ + action: 'end', + }); + expect(status).toBe(401); + expect(body).toEqual(errorDto.unauthorized); + }); + + it('should only work for admins', async () => { + const { status, body } = await request(app) + .post('/admin/maintenance') + .set('Authorization', `Bearer ${nonAdmin.accessToken}`) + .send({ action: 'end' }); + expect(status).toBe(403); + expect(body).toEqual(errorDto.forbidden); + }); + + it('should be a no-op if try to exit maintenance mode', async () => { + const { status } = await request(app) + .post('/admin/maintenance') + .set('Authorization', `Bearer ${admin.accessToken}`) + .send({ action: 'end' }); + expect(status).toBe(201); + }); + + it('should enter maintenance mode', async () => { + const { status, headers } = await request(app) + .post('/admin/maintenance') + .set('Authorization', `Bearer ${admin.accessToken}`) + .send({ + action: 'start', + }); + expect(status).toBe(201); + + cookie = headers['set-cookie'][0].split(';')[0]; + expect(cookie).toEqual( + expect.stringMatching(/^immich_maintenance_token=[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$/), + ); + + await expect + .poll( + async () => { + const { body } = await request(app).get('/server/config'); + return body.maintenanceMode; + }, + { + interval: 5e2, + timeout: 1e4, + }, + ) + .toBeTruthy(); + }); + }); + + // => in maintenance mode + + describe.sequential('in maintenance mode', () => { + describe('GET ~/server/config', async () => { + it('should indicate we are in maintenance mode', async () => { + const { status, body } = await request(app).get('/server/config'); + expect(status).toBe(200); + expect(body.maintenanceMode).toBeTruthy(); + }); + }); + + describe('POST /login', async () => { + it('should fail without cookie or token in body', async () => { + const { status, body } = await request(app).post('/admin/maintenance/login').send({}); + expect(status).toBe(401); + expect(body).toEqual(errorDto.unauthorizedWithMessage('Missing JWT Token')); + }); + + it('should succeed with cookie', async () => { + const { status, body } = await request(app).post('/admin/maintenance/login').set('cookie', cookie!).send({}); + expect(status).toBe(201); + expect(body).toEqual( + expect.objectContaining({ + username: 'Immich Admin', + }), + ); + }); + + it('should succeed with token', async () => { + const { status, body } = await request(app) + .post('/admin/maintenance/login') + .send({ + token: cookie!.split('=')[1].trim(), + }); + expect(status).toBe(201); + expect(body).toEqual( + expect.objectContaining({ + username: 'Immich Admin', + }), + ); + }); + }); + + describe('POST /', async () => { + it('should be a no-op if try to enter maintenance mode', async () => { + const { status } = await request(app) + .post('/admin/maintenance') + .set('cookie', cookie!) + .send({ action: 'start' }); + expect(status).toBe(201); + }); + }); + }); + + // => exit maintenance mode + + describe.sequential('POST /', () => { + it('should exit maintenance mode', async () => { + const { status } = await request(app).post('/admin/maintenance').set('cookie', cookie!).send({ + action: 'end', + }); + + expect(status).toBe(201); + + await expect + .poll( + async () => { + const { body } = await request(app).get('/server/config'); + return body.maintenanceMode; + }, + { + interval: 5e2, + timeout: 1e4, + }, + ) + .toBeFalsy(); + }); + }); +}); diff --git a/e2e/src/api/specs/server.e2e-spec.ts b/e2e/src/api/specs/server.e2e-spec.ts index adf2526856..3dd6f15e71 100644 --- a/e2e/src/api/specs/server.e2e-spec.ts +++ b/e2e/src/api/specs/server.e2e-spec.ts @@ -136,6 +136,7 @@ describe('/server', () => { externalDomain: '', publicUsers: true, isOnboarded: false, + maintenanceMode: false, mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json', mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json', }); diff --git a/e2e/src/generators/timeline.ts b/e2e/src/generators/timeline.ts new file mode 100644 index 0000000000..d4c91d667f --- /dev/null +++ b/e2e/src/generators/timeline.ts @@ -0,0 +1,37 @@ +export { generateTimelineData } from './timeline/model-objects'; + +export { createDefaultTimelineConfig, validateTimelineConfig } from './timeline/timeline-config'; + +export type { + MockAlbum, + MonthSpec, + SerializedTimelineData, + MockTimelineAsset as TimelineAssetConfig, + TimelineConfig, + MockTimelineData as TimelineData, +} from './timeline/timeline-config'; + +export { + getAlbum, + getAsset, + getTimeBucket, + getTimeBuckets, + toAssetResponseDto, + toColumnarFormat, +} from './timeline/rest-response'; + +export type { Changes } from './timeline/rest-response'; + +export { randomImage, randomImageFromString, randomPreview, randomThumbnail } from './timeline/images'; + +export { + SeededRandom, + getMockAsset, + parseTimeBucketKey, + selectRandom, + selectRandomDays, + selectRandomMultiple, +} from './timeline/utils'; + +export { ASSET_DISTRIBUTION, DAY_DISTRIBUTION } from './timeline/distribution-patterns'; +export type { DayPattern, MonthDistribution } from './timeline/distribution-patterns'; diff --git a/e2e/src/generators/timeline/distribution-patterns.ts b/e2e/src/generators/timeline/distribution-patterns.ts new file mode 100644 index 0000000000..ae621fd9c5 --- /dev/null +++ b/e2e/src/generators/timeline/distribution-patterns.ts @@ -0,0 +1,183 @@ +import { generateConsecutiveDays, generateDayAssets } from 'src/generators/timeline/model-objects'; +import { SeededRandom, selectRandomDays } from 'src/generators/timeline/utils'; +import type { MockTimelineAsset } from './timeline-config'; +import { GENERATION_CONSTANTS } from './timeline-config'; + +type AssetDistributionStrategy = (rng: SeededRandom) => number; + +type DayDistributionStrategy = ( + year: number, + month: number, + daysInMonth: number, + totalAssets: number, + ownerId: string, + rng: SeededRandom, +) => MockTimelineAsset[]; + +/** + * Strategies for determining total asset count per month + */ +export const ASSET_DISTRIBUTION: Record = { + empty: null, // Special case - handled separately + sparse: (rng) => rng.nextInt(3, 9), // 3-8 assets + medium: (rng) => rng.nextInt(15, 31), // 15-30 assets + dense: (rng) => rng.nextInt(50, 81), // 50-80 assets + 'very-dense': (rng) => rng.nextInt(80, 151), // 80-150 assets +}; + +/** + * Strategies for distributing assets across days within a month + */ +export const DAY_DISTRIBUTION: Record = { + 'single-day': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // All assets on one day in the middle of the month + const day = Math.floor(daysInMonth / 2); + return generateDayAssets(year, month, day, totalAssets, ownerId, rng); + }, + + 'consecutive-large': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // 3-5 consecutive days with evenly distributed assets + const numDays = Math.min(5, Math.floor(totalAssets / 15)); + const startDay = rng.nextInt(1, daysInMonth - numDays + 2); + return generateConsecutiveDays(year, month, startDay, numDays, totalAssets, ownerId, rng); + }, + + 'consecutive-small': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Multiple consecutive days with 1-3 assets each (side-by-side layout) + const assets: MockTimelineAsset[] = []; + const numDays = Math.min(totalAssets, Math.floor(daysInMonth / 2)); + const startDay = rng.nextInt(1, daysInMonth - numDays + 2); + let assetIndex = 0; + + for (let i = 0; i < numDays && assetIndex < totalAssets; i++) { + const dayAssets = Math.min(3, rng.nextInt(1, 4)); + const actualAssets = Math.min(dayAssets, totalAssets - assetIndex); + // Create a new RNG for this day + const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, startDay + i, actualAssets, ownerId, dayRng)); + assetIndex += actualAssets; + } + return assets; + }, + + alternating: (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Alternate between large (15-25) and small (1-3) days + const assets: MockTimelineAsset[] = []; + let day = 1; + let isLarge = true; + let assetIndex = 0; + + while (assetIndex < totalAssets && day <= daysInMonth) { + const dayAssets = isLarge ? Math.min(25, rng.nextInt(15, 26)) : rng.nextInt(1, 4); + + const actualAssets = Math.min(dayAssets, totalAssets - assetIndex); + // Create a new RNG for this day + const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, day, actualAssets, ownerId, dayRng)); + assetIndex += actualAssets; + + day += isLarge ? 1 : 1; // Could add gaps here + isLarge = !isLarge; + } + return assets; + }, + + 'sparse-scattered': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Spread assets across random days with gaps + const assets: MockTimelineAsset[] = []; + const numDays = Math.min(totalAssets, Math.floor(daysInMonth * GENERATION_CONSTANTS.SPARSE_DAY_COVERAGE)); + const daysWithPhotos = selectRandomDays(daysInMonth, numDays, rng); + let assetIndex = 0; + + for (let i = 0; i < daysWithPhotos.length && assetIndex < totalAssets; i++) { + const dayAssets = + Math.floor(totalAssets / numDays) + (i === daysWithPhotos.length - 1 ? totalAssets % numDays : 0); + // Create a new RNG for this day + const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, daysWithPhotos[i], dayAssets, ownerId, dayRng)); + assetIndex += dayAssets; + } + return assets; + }, + + 'start-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Most assets in first week + const assets: MockTimelineAsset[] = []; + const firstWeekAssets = Math.floor(totalAssets * 0.7); + const remainingAssets = totalAssets - firstWeekAssets; + + // First 7 days + assets.push(...generateConsecutiveDays(year, month, 1, 7, firstWeekAssets, ownerId, rng)); + + // Remaining scattered + if (remainingAssets > 0) { + const midDay = Math.floor(daysInMonth / 2); + // Create a new RNG for the remaining assets + const remainingRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, midDay, remainingAssets, ownerId, remainingRng)); + } + return assets; + }, + + 'end-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Most assets in last week + const assets: MockTimelineAsset[] = []; + const lastWeekAssets = Math.floor(totalAssets * 0.7); + const remainingAssets = totalAssets - lastWeekAssets; + + // Remaining at start + if (remainingAssets > 0) { + // Create a new RNG for the start assets + const startRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, 2, remainingAssets, ownerId, startRng)); + } + + // Last 7 days + const startDay = daysInMonth - 6; + assets.push(...generateConsecutiveDays(year, month, startDay, 7, lastWeekAssets, ownerId, rng)); + return assets; + }, + + 'mid-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => { + // Most assets in middle of month + const assets: MockTimelineAsset[] = []; + const midAssets = Math.floor(totalAssets * 0.7); + const sideAssets = Math.floor((totalAssets - midAssets) / 2); + + // Start + if (sideAssets > 0) { + // Create a new RNG for the start assets + const startRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, 2, sideAssets, ownerId, startRng)); + } + + // Middle + const midStart = Math.floor(daysInMonth / 2) - 3; + assets.push(...generateConsecutiveDays(year, month, midStart, 7, midAssets, ownerId, rng)); + + // End + const endAssets = totalAssets - midAssets - sideAssets; + if (endAssets > 0) { + // Create a new RNG for the end assets + const endRng = new SeededRandom(rng.nextInt(0, 1_000_000)); + assets.push(...generateDayAssets(year, month, daysInMonth - 1, endAssets, ownerId, endRng)); + } + return assets; + }, +}; +export type MonthDistribution = + | 'empty' // 0 assets + | 'sparse' // 3-8 assets + | 'medium' // 15-30 assets + | 'dense' // 50-80 assets + | 'very-dense'; // 80-150 assets + +export type DayPattern = + | 'single-day' // All images in one day + | 'consecutive-large' // Multiple days with 15-25 images each + | 'consecutive-small' // Multiple days with 1-3 images each (side-by-side) + | 'alternating' // Alternating large/small days + | 'sparse-scattered' // Few images scattered across month + | 'start-heavy' // Most images at start of month + | 'end-heavy' // Most images at end of month + | 'mid-heavy'; // Most images in middle of month diff --git a/e2e/src/generators/timeline/images.ts b/e2e/src/generators/timeline/images.ts new file mode 100644 index 0000000000..69ec576714 --- /dev/null +++ b/e2e/src/generators/timeline/images.ts @@ -0,0 +1,111 @@ +import sharp from 'sharp'; +import { SeededRandom } from 'src/generators/timeline/utils'; + +export const randomThumbnail = async (seed: string, ratio: number) => { + const height = 235; + const width = Math.round(height * ratio); + return randomImageFromString(seed, { width, height }); +}; + +export const randomPreview = async (seed: string, ratio: number) => { + const height = 500; + const width = Math.round(height * ratio); + return randomImageFromString(seed, { width, height }); +}; + +export const randomImageFromString = async ( + seed: string = '', + { width = 100, height = 100 }: { width: number; height: number }, +) => { + // Convert string to number for seeding + let seedNumber = 0; + for (let i = 0; i < seed.length; i++) { + seedNumber = (seedNumber << 5) - seedNumber + (seed.codePointAt(i) ?? 0); + seedNumber = seedNumber & seedNumber; // Convert to 32bit integer + } + return randomImage(new SeededRandom(Math.abs(seedNumber)), { width, height }); +}; + +export const randomImage = async (rng: SeededRandom, { width, height }: { width: number; height: number }) => { + const r1 = rng.nextInt(0, 256); + const g1 = rng.nextInt(0, 256); + const b1 = rng.nextInt(0, 256); + const r2 = rng.nextInt(0, 256); + const g2 = rng.nextInt(0, 256); + const b2 = rng.nextInt(0, 256); + const patternType = rng.nextInt(0, 5); + + let svgPattern = ''; + + switch (patternType) { + case 0: { + // Solid color + svgPattern = ` + + `; + break; + } + + case 1: { + // Horizontal stripes + const stripeHeight = 10; + svgPattern = ` + ${Array.from( + { length: height / stripeHeight }, + (_, i) => + ``, + ).join('')} + `; + break; + } + + case 2: { + // Vertical stripes + const stripeWidth = 10; + svgPattern = ` + ${Array.from( + { length: width / stripeWidth }, + (_, i) => + ``, + ).join('')} + `; + break; + } + + case 3: { + // Checkerboard + const squareSize = 10; + svgPattern = ` + ${Array.from({ length: height / squareSize }, (_, row) => + Array.from({ length: width / squareSize }, (_, col) => { + const isEven = (row + col) % 2 === 0; + return ``; + }).join(''), + ).join('')} + `; + break; + } + + case 4: { + // Diagonal stripes + svgPattern = ` + + + + + + + + `; + break; + } + } + + const svgBuffer = Buffer.from(svgPattern); + const jpegData = await sharp(svgBuffer).jpeg({ quality: 50 }).toBuffer(); + return jpegData; +}; diff --git a/e2e/src/generators/timeline/model-objects.ts b/e2e/src/generators/timeline/model-objects.ts new file mode 100644 index 0000000000..f06596fd1a --- /dev/null +++ b/e2e/src/generators/timeline/model-objects.ts @@ -0,0 +1,265 @@ +/** + * Generator functions for timeline model objects + */ + +import { faker } from '@faker-js/faker'; +import { AssetVisibility } from '@immich/sdk'; +import { DateTime } from 'luxon'; +import { writeFileSync } from 'node:fs'; +import { SeededRandom } from 'src/generators/timeline/utils'; +import type { DayPattern, MonthDistribution } from './distribution-patterns'; +import { ASSET_DISTRIBUTION, DAY_DISTRIBUTION } from './distribution-patterns'; +import type { MockTimelineAsset, MockTimelineData, SerializedTimelineData, TimelineConfig } from './timeline-config'; +import { ASPECT_RATIO_WEIGHTS, GENERATION_CONSTANTS, validateTimelineConfig } from './timeline-config'; + +/** + * Generate a random aspect ratio based on weighted probabilities + */ +export function generateAspectRatio(rng: SeededRandom): string { + const random = rng.next(); + let cumulative = 0; + + for (const [ratio, weight] of Object.entries(ASPECT_RATIO_WEIGHTS)) { + cumulative += weight; + if (random < cumulative) { + return ratio; + } + } + return '16:9'; // Default fallback +} + +export function generateThumbhash(rng: SeededRandom): string { + return Array.from({ length: 10 }, () => rng.nextInt(0, 256).toString(16).padStart(2, '0')).join(''); +} + +export function generateDuration(rng: SeededRandom): string { + return `${rng.nextInt(GENERATION_CONSTANTS.MIN_VIDEO_DURATION_SECONDS, GENERATION_CONSTANTS.MAX_VIDEO_DURATION_SECONDS)}.${rng.nextInt(0, 1000).toString().padStart(3, '0')}`; +} + +export function generateUUID(): string { + return faker.string.uuid(); +} + +export function generateAsset( + year: number, + month: number, + day: number, + ownerId: string, + rng: SeededRandom, +): MockTimelineAsset { + const from = DateTime.fromObject({ year, month, day }).setZone('UTC'); + const to = from.endOf('day'); + const date = faker.date.between({ from: from.toJSDate(), to: to.toJSDate() }); + const isVideo = rng.next() < GENERATION_CONSTANTS.VIDEO_PROBABILITY; + + const assetId = generateUUID(); + const hasGPS = rng.next() < GENERATION_CONSTANTS.GPS_PERCENTAGE; + + const ratio = generateAspectRatio(rng); + + const asset: MockTimelineAsset = { + id: assetId, + ownerId, + ratio: Number.parseFloat(ratio.split(':')[0]) / Number.parseFloat(ratio.split(':')[1]), + thumbhash: generateThumbhash(rng), + localDateTime: date.toISOString(), + fileCreatedAt: date.toISOString(), + isFavorite: rng.next() < GENERATION_CONSTANTS.FAVORITE_PROBABILITY, + isTrashed: false, + isVideo, + isImage: !isVideo, + duration: isVideo ? generateDuration(rng) : null, + projectionType: null, + livePhotoVideoId: null, + city: hasGPS ? faker.location.city() : null, + country: hasGPS ? faker.location.country() : null, + people: null, + latitude: hasGPS ? faker.location.latitude() : null, + longitude: hasGPS ? faker.location.longitude() : null, + visibility: AssetVisibility.Timeline, + stack: null, + fileSizeInByte: faker.number.int({ min: 510, max: 5_000_000 }), + checksum: faker.string.alphanumeric({ length: 5 }), + }; + + return asset; +} + +/** + * Generate assets for a specific day + */ +export function generateDayAssets( + year: number, + month: number, + day: number, + assetCount: number, + ownerId: string, + rng: SeededRandom, +): MockTimelineAsset[] { + return Array.from({ length: assetCount }, () => generateAsset(year, month, day, ownerId, rng)); +} + +/** + * Distribute assets evenly across consecutive days + * + * @returns Array of generated timeline assets + */ +export function generateConsecutiveDays( + year: number, + month: number, + startDay: number, + numDays: number, + totalAssets: number, + ownerId: string, + rng: SeededRandom, +): MockTimelineAsset[] { + const assets: MockTimelineAsset[] = []; + const assetsPerDay = Math.floor(totalAssets / numDays); + + for (let i = 0; i < numDays; i++) { + const dayAssets = + i === numDays - 1 + ? totalAssets - assetsPerDay * (numDays - 1) // Remainder on last day + : assetsPerDay; + // Create a new RNG with a different seed for each day + const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000) + i * 100); + assets.push(...generateDayAssets(year, month, startDay + i, dayAssets, ownerId, dayRng)); + } + + return assets; +} + +/** + * Generate assets for a month with specified distribution pattern + */ +export function generateMonthAssets( + year: number, + month: number, + ownerId: string, + distribution: MonthDistribution = 'medium', + pattern: DayPattern = 'consecutive-large', + rng: SeededRandom, +): MockTimelineAsset[] { + const daysInMonth = new Date(year, month, 0).getDate(); + + if (distribution === 'empty') { + return []; + } + + const distributionStrategy = ASSET_DISTRIBUTION[distribution]; + if (!distributionStrategy) { + console.warn(`Unknown distribution: ${distribution}, defaulting to medium`); + return []; + } + const totalAssets = distributionStrategy(rng); + + const dayStrategy = DAY_DISTRIBUTION[pattern]; + if (!dayStrategy) { + console.warn(`Unknown pattern: ${pattern}, defaulting to consecutive-large`); + // Fallback to consecutive-large pattern + const numDays = Math.min(5, Math.floor(totalAssets / 15)); + const startDay = rng.nextInt(1, daysInMonth - numDays + 2); + const assets = generateConsecutiveDays(year, month, startDay, numDays, totalAssets, ownerId, rng); + assets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds); + return assets; + } + + const assets = dayStrategy(year, month, daysInMonth, totalAssets, ownerId, rng); + assets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds); + return assets; +} + +/** + * Main generator function for timeline data + */ +export function generateTimelineData(config: TimelineConfig): MockTimelineData { + validateTimelineConfig(config); + + const buckets = new Map(); + const monthStats: Record = {}; + + const globalRng = new SeededRandom(config.seed || GENERATION_CONSTANTS.DEFAULT_SEED); + faker.seed(globalRng.nextInt(0, 1_000_000)); + for (const monthConfig of config.months) { + const { year, month, distribution, pattern } = monthConfig; + + const monthSeed = globalRng.nextInt(0, 1_000_000); + const monthRng = new SeededRandom(monthSeed); + + const monthAssets = generateMonthAssets( + year, + month, + config.ownerId || generateUUID(), + distribution, + pattern, + monthRng, + ); + + if (monthAssets.length > 0) { + const monthKey = `${year}-${month.toString().padStart(2, '0')}`; + monthStats[monthKey] = { + count: monthAssets.length, + distribution, + pattern, + }; + + // Create bucket key (YYYY-MM-01) + const bucketKey = `${year}-${month.toString().padStart(2, '0')}-01`; + buckets.set(bucketKey, monthAssets); + } + } + + // Create a mock album from random assets + const allAssets = [...buckets.values()].flat(); + + // Select 10-30 random assets for the album (or all assets if less than 10) + const albumSize = Math.min(allAssets.length, globalRng.nextInt(10, 31)); + const selectedAssetConfigs: MockTimelineAsset[] = []; + const usedIndices = new Set(); + + while (selectedAssetConfigs.length < albumSize && usedIndices.size < allAssets.length) { + const randomIndex = globalRng.nextInt(0, allAssets.length); + if (!usedIndices.has(randomIndex)) { + usedIndices.add(randomIndex); + selectedAssetConfigs.push(allAssets[randomIndex]); + } + } + + // Sort selected assets by date (newest first) + selectedAssetConfigs.sort( + (a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds, + ); + + const selectedAssets = selectedAssetConfigs.map((asset) => asset.id); + + const now = new Date().toISOString(); + const album = { + id: generateUUID(), + albumName: 'Test Album', + description: 'A mock album for testing', + assetIds: selectedAssets, + thumbnailAssetId: selectedAssets.length > 0 ? selectedAssets[0] : null, + createdAt: now, + updatedAt: now, + }; + + // Write to file if configured + if (config.writeToFile) { + const outputPath = config.outputPath || '/tmp/timeline-data.json'; + + // Convert Map to object for serialization + const serializedData: SerializedTimelineData = { + buckets: Object.fromEntries(buckets), + album, + }; + + try { + writeFileSync(outputPath, JSON.stringify(serializedData, null, 2)); + console.log(`Timeline data written to ${outputPath}`); + } catch (error) { + console.error(`Failed to write timeline data to ${outputPath}:`, error); + } + } + + return { buckets, album }; +} diff --git a/e2e/src/generators/timeline/rest-response.ts b/e2e/src/generators/timeline/rest-response.ts new file mode 100644 index 0000000000..6fcfe52fc2 --- /dev/null +++ b/e2e/src/generators/timeline/rest-response.ts @@ -0,0 +1,436 @@ +/** + * REST API output functions for converting timeline data to API response formats + */ + +import { + AssetTypeEnum, + AssetVisibility, + UserAvatarColor, + type AlbumResponseDto, + type AssetResponseDto, + type ExifResponseDto, + type TimeBucketAssetResponseDto, + type TimeBucketsResponseDto, + type UserResponseDto, +} from '@immich/sdk'; +import { DateTime } from 'luxon'; +import { signupDto } from 'src/fixtures'; +import { parseTimeBucketKey } from 'src/generators/timeline/utils'; +import type { MockTimelineAsset, MockTimelineData } from './timeline-config'; + +/** + * Convert timeline/asset models to columnar format (parallel arrays) + */ +export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetResponseDto { + const result: TimeBucketAssetResponseDto = { + id: [], + ownerId: [], + ratio: [], + thumbhash: [], + fileCreatedAt: [], + localOffsetHours: [], + isFavorite: [], + isTrashed: [], + isImage: [], + duration: [], + projectionType: [], + livePhotoVideoId: [], + city: [], + country: [], + visibility: [], + }; + + for (const asset of assets) { + result.id.push(asset.id); + result.ownerId.push(asset.ownerId); + result.ratio.push(asset.ratio); + result.thumbhash.push(asset.thumbhash); + result.fileCreatedAt.push(asset.fileCreatedAt); + result.localOffsetHours.push(0); // Assuming UTC for mocks + result.isFavorite.push(asset.isFavorite); + result.isTrashed.push(asset.isTrashed); + result.isImage.push(asset.isImage); + result.duration.push(asset.duration); + result.projectionType.push(asset.projectionType); + result.livePhotoVideoId.push(asset.livePhotoVideoId); + result.city.push(asset.city); + result.country.push(asset.country); + result.visibility.push(asset.visibility); + } + + if (assets.some((a) => a.latitude !== null || a.longitude !== null)) { + result.latitude = assets.map((a) => a.latitude); + result.longitude = assets.map((a) => a.longitude); + } + + result.stack = assets.map(() => null); + return result; +} + +/** + * Extract a single bucket from timeline data (mimics getTimeBucket API) + * Automatically handles both ISO timestamp and simple month formats + * Returns data in columnar format matching the actual API + * When albumId is provided, only returns assets from that album + */ +export function getTimeBucket( + timelineData: MockTimelineData, + timeBucket: string, + isTrashed: boolean | undefined, + isArchived: boolean | undefined, + isFavorite: boolean | undefined, + albumId: string | undefined, + changes: Changes, +): TimeBucketAssetResponseDto { + const bucketKey = parseTimeBucketKey(timeBucket); + let assets = timelineData.buckets.get(bucketKey); + + if (!assets) { + return toColumnarFormat([]); + } + + // Create sets for quick lookups + const deletedAssetIds = new Set(changes.assetDeletions); + const archivedAssetIds = new Set(changes.assetArchivals); + const favoritedAssetIds = new Set(changes.assetFavorites); + + // Filter assets based on trashed/archived status + assets = assets.filter((asset) => + shouldIncludeAsset(asset, isTrashed, isArchived, isFavorite, deletedAssetIds, archivedAssetIds, favoritedAssetIds), + ); + + // Filter to only include assets from the specified album + if (albumId) { + const album = timelineData.album; + if (!album || album.id !== albumId) { + return toColumnarFormat([]); + } + + // Create a Set for faster lookup + const albumAssetIds = new Set([...album.assetIds, ...changes.albumAdditions]); + assets = assets.filter((asset) => albumAssetIds.has(asset.id)); + } + + // Override properties for assets in changes arrays + const assetsWithOverrides = assets.map((asset) => { + if (deletedAssetIds.has(asset.id) || archivedAssetIds.has(asset.id) || favoritedAssetIds.has(asset.id)) { + return { + ...asset, + isFavorite: favoritedAssetIds.has(asset.id) ? true : asset.isFavorite, + isTrashed: deletedAssetIds.has(asset.id) ? true : asset.isTrashed, + visibility: archivedAssetIds.has(asset.id) ? AssetVisibility.Archive : asset.visibility, + }; + } + return asset; + }); + + return toColumnarFormat(assetsWithOverrides); +} + +export type Changes = { + // ids of assets that are newly added to the album + albumAdditions: string[]; + // ids of assets that are newly deleted + assetDeletions: string[]; + // ids of assets that are newly archived + assetArchivals: string[]; + // ids of assets that are newly favorited + assetFavorites: string[]; +}; + +/** + * Helper function to determine if an asset should be included based on filter criteria + * @param asset - The asset to check + * @param isTrashed - Filter for trashed status (undefined means no filter) + * @param isArchived - Filter for archived status (undefined means no filter) + * @param isFavorite - Filter for favorite status (undefined means no filter) + * @param deletedAssetIds - Set of IDs for assets that have been deleted + * @param archivedAssetIds - Set of IDs for assets that have been archived + * @param favoritedAssetIds - Set of IDs for assets that have been favorited + * @returns true if the asset matches all filter criteria + */ +function shouldIncludeAsset( + asset: MockTimelineAsset, + isTrashed: boolean | undefined, + isArchived: boolean | undefined, + isFavorite: boolean | undefined, + deletedAssetIds: Set, + archivedAssetIds: Set, + favoritedAssetIds: Set, +): boolean { + // Determine actual status (property or in changes) + const actuallyTrashed = asset.isTrashed || deletedAssetIds.has(asset.id); + const actuallyArchived = asset.visibility === 'archive' || archivedAssetIds.has(asset.id); + const actuallyFavorited = asset.isFavorite || favoritedAssetIds.has(asset.id); + + // Apply filters + if (isTrashed !== undefined && actuallyTrashed !== isTrashed) { + return false; + } + if (isArchived !== undefined && actuallyArchived !== isArchived) { + return false; + } + if (isFavorite !== undefined && actuallyFavorited !== isFavorite) { + return false; + } + + return true; +} +/** + * Get summary for all buckets (mimics getTimeBuckets API) + * When albumId is provided, only includes buckets that contain assets from that album + */ +export function getTimeBuckets( + timelineData: MockTimelineData, + isTrashed: boolean | undefined, + isArchived: boolean | undefined, + isFavorite: boolean | undefined, + albumId: string | undefined, + changes: Changes, +): TimeBucketsResponseDto[] { + const summary: TimeBucketsResponseDto[] = []; + + // Create sets for quick lookups + const deletedAssetIds = new Set(changes.assetDeletions); + const archivedAssetIds = new Set(changes.assetArchivals); + const favoritedAssetIds = new Set(changes.assetFavorites); + + // If no albumId is specified, return summary for all assets + if (albumId) { + // Filter to only include buckets with assets from the specified album + const album = timelineData.album; + if (!album || album.id !== albumId) { + return []; + } + + // Create a Set for faster lookup + const albumAssetIds = new Set([...album.assetIds, ...changes.albumAdditions]); + for (const removed of changes.assetDeletions) { + albumAssetIds.delete(removed); + } + for (const [bucketKey, assets] of timelineData.buckets) { + // Count how many assets in this bucket are in the album and match trashed/archived filters + const albumAssetsInBucket = assets.filter((asset) => { + // Must be in the album + if (!albumAssetIds.has(asset.id)) { + return false; + } + + return shouldIncludeAsset( + asset, + isTrashed, + isArchived, + isFavorite, + deletedAssetIds, + archivedAssetIds, + favoritedAssetIds, + ); + }); + + if (albumAssetsInBucket.length > 0) { + summary.push({ + timeBucket: bucketKey, + count: albumAssetsInBucket.length, + }); + } + } + } else { + for (const [bucketKey, assets] of timelineData.buckets) { + // Filter assets based on trashed/archived status + const filteredAssets = assets.filter((asset) => + shouldIncludeAsset( + asset, + isTrashed, + isArchived, + isFavorite, + deletedAssetIds, + archivedAssetIds, + favoritedAssetIds, + ), + ); + + if (filteredAssets.length > 0) { + summary.push({ + timeBucket: bucketKey, + count: filteredAssets.length, + }); + } + } + } + + // Sort summary by date (newest first) using luxon + summary.sort((a, b) => { + const dateA = DateTime.fromISO(a.timeBucket); + const dateB = DateTime.fromISO(b.timeBucket); + return dateB.diff(dateA).milliseconds; + }); + + return summary; +} + +const createDefaultOwner = (ownerId: string) => { + const defaultOwner: UserResponseDto = { + id: ownerId, + email: signupDto.admin.email, + name: signupDto.admin.name, + profileImagePath: '', + profileChangedAt: new Date().toISOString(), + avatarColor: UserAvatarColor.Blue, + }; + return defaultOwner; +}; + +/** + * Convert a TimelineAssetConfig to a full AssetResponseDto + * This matches the response from GET /api/assets/:id + */ +export function toAssetResponseDto(asset: MockTimelineAsset, owner?: UserResponseDto): AssetResponseDto { + const now = new Date().toISOString(); + + // Default owner if not provided + const defaultOwner = createDefaultOwner(asset.ownerId); + + const exifInfo: ExifResponseDto = { + make: null, + model: null, + exifImageWidth: asset.ratio > 1 ? 4000 : 3000, + exifImageHeight: asset.ratio > 1 ? Math.round(4000 / asset.ratio) : Math.round(3000 * asset.ratio), + fileSizeInByte: asset.fileSizeInByte, + orientation: '1', + dateTimeOriginal: asset.fileCreatedAt, + modifyDate: asset.fileCreatedAt, + timeZone: asset.latitude === null ? null : 'UTC', + lensModel: null, + fNumber: null, + focalLength: null, + iso: null, + exposureTime: null, + latitude: asset.latitude, + longitude: asset.longitude, + city: asset.city, + country: asset.country, + state: null, + description: null, + }; + + return { + id: asset.id, + deviceAssetId: `device-${asset.id}`, + ownerId: asset.ownerId, + owner: owner || defaultOwner, + libraryId: `library-${asset.ownerId}`, + deviceId: `device-${asset.ownerId}`, + type: asset.isVideo ? AssetTypeEnum.Video : AssetTypeEnum.Image, + originalPath: `/original/${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`, + originalFileName: `${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`, + originalMimeType: asset.isVideo ? 'video/mp4' : 'image/jpeg', + thumbhash: asset.thumbhash, + fileCreatedAt: asset.fileCreatedAt, + fileModifiedAt: asset.fileCreatedAt, + localDateTime: asset.localDateTime, + updatedAt: now, + createdAt: asset.fileCreatedAt, + isFavorite: asset.isFavorite, + isArchived: false, + isTrashed: asset.isTrashed, + visibility: asset.visibility, + duration: asset.duration || '0:00:00.00000', + exifInfo, + livePhotoVideoId: asset.livePhotoVideoId, + tags: [], + people: [], + unassignedFaces: [], + stack: asset.stack, + isOffline: false, + hasMetadata: true, + duplicateId: null, + resized: true, + checksum: asset.checksum, + }; +} + +/** + * Get a single asset by ID from timeline data + * This matches the response from GET /api/assets/:id + */ +export function getAsset( + timelineData: MockTimelineData, + assetId: string, + owner?: UserResponseDto, +): AssetResponseDto | undefined { + // Search through all buckets for the asset + const buckets = [...timelineData.buckets.values()]; + for (const assets of buckets) { + const asset = assets.find((a) => a.id === assetId); + if (asset) { + return toAssetResponseDto(asset, owner); + } + } + return undefined; +} + +/** + * Get a mock album from timeline data + * This matches the response from GET /api/albums/:id + */ +export function getAlbum( + timelineData: MockTimelineData, + ownerId: string, + albumId: string | undefined, + changes: Changes, +): AlbumResponseDto | undefined { + if (!timelineData.album) { + return undefined; + } + + // If albumId is provided and doesn't match, return undefined + if (albumId && albumId !== timelineData.album.id) { + return undefined; + } + + const album = timelineData.album; + const albumOwner = createDefaultOwner(ownerId); + + // Get the actual asset objects from the timeline data + const albumAssets: AssetResponseDto[] = []; + const allAssets = [...timelineData.buckets.values()].flat(); + + for (const assetId of album.assetIds) { + const assetConfig = allAssets.find((a) => a.id === assetId); + if (assetConfig) { + albumAssets.push(toAssetResponseDto(assetConfig, albumOwner)); + } + } + for (const assetId of changes.albumAdditions ?? []) { + const assetConfig = allAssets.find((a) => a.id === assetId); + if (assetConfig) { + albumAssets.push(toAssetResponseDto(assetConfig, albumOwner)); + } + } + + albumAssets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds); + + // For a basic mock album, we don't include any albumUsers (shared users) + // The owner is represented by the owner field, not in albumUsers + const response: AlbumResponseDto = { + id: album.id, + albumName: album.albumName, + description: album.description, + albumThumbnailAssetId: album.thumbnailAssetId, + createdAt: album.createdAt, + updatedAt: album.updatedAt, + ownerId: albumOwner.id, + owner: albumOwner, + albumUsers: [], // Empty array for non-shared album + shared: false, + hasSharedLink: false, + isActivityEnabled: true, + assetCount: albumAssets.length, + assets: albumAssets, + startDate: albumAssets.length > 0 ? albumAssets.at(-1)?.fileCreatedAt : undefined, + endDate: albumAssets.length > 0 ? albumAssets[0].fileCreatedAt : undefined, + lastModifiedAssetTimestamp: albumAssets.length > 0 ? albumAssets[0].fileCreatedAt : undefined, + }; + + return response; +} diff --git a/e2e/src/generators/timeline/timeline-config.ts b/e2e/src/generators/timeline/timeline-config.ts new file mode 100644 index 0000000000..8dbe8399b1 --- /dev/null +++ b/e2e/src/generators/timeline/timeline-config.ts @@ -0,0 +1,200 @@ +import type { AssetVisibility } from '@immich/sdk'; +import { DayPattern, MonthDistribution } from 'src/generators/timeline/distribution-patterns'; + +// Constants for generation parameters +export const GENERATION_CONSTANTS = { + VIDEO_PROBABILITY: 0.15, // 15% of assets are videos + GPS_PERCENTAGE: 0.7, // 70% of assets have GPS data + FAVORITE_PROBABILITY: 0.1, // 10% of assets are favorited + MIN_VIDEO_DURATION_SECONDS: 5, + MAX_VIDEO_DURATION_SECONDS: 300, + DEFAULT_SEED: 12_345, + DEFAULT_OWNER_ID: 'user-1', + MAX_SELECT_ATTEMPTS: 10, + SPARSE_DAY_COVERAGE: 0.4, // 40% of days have photos in sparse pattern +} as const; + +// Aspect ratio distribution weights (must sum to 1) +export const ASPECT_RATIO_WEIGHTS = { + '4:3': 0.35, // 35% 4:3 landscape + '3:2': 0.25, // 25% 3:2 landscape + '16:9': 0.2, // 20% 16:9 landscape + '2:3': 0.1, // 10% 2:3 portrait + '1:1': 0.09, // 9% 1:1 square + '3:1': 0.01, // 1% 3:1 panorama +} as const; + +export type AspectRatio = { + width: number; + height: number; + ratio: number; + name: string; +}; + +// Mock configuration for asset generation - will be transformed to API response formats +export type MockTimelineAsset = { + id: string; + ownerId: string; + ratio: number; + thumbhash: string | null; + localDateTime: string; + fileCreatedAt: string; + isFavorite: boolean; + isTrashed: boolean; + isVideo: boolean; + isImage: boolean; + duration: string | null; + projectionType: string | null; + livePhotoVideoId: string | null; + city: string | null; + country: string | null; + people: string[] | null; + latitude: number | null; + longitude: number | null; + visibility: AssetVisibility; + stack: null; + checksum: string; + fileSizeInByte: number; +}; + +export type MonthSpec = { + year: number; + month: number; // 1-12 + distribution: MonthDistribution; + pattern: DayPattern; +}; + +/** + * Configuration for timeline data generation + */ +export type TimelineConfig = { + ownerId?: string; + months: MonthSpec[]; + seed?: number; + writeToFile?: boolean; + outputPath?: string; +}; + +export type MockAlbum = { + id: string; + albumName: string; + description: string; + assetIds: string[]; // IDs of assets in the album + thumbnailAssetId: string | null; + createdAt: string; + updatedAt: string; +}; + +export type MockTimelineData = { + buckets: Map; + album: MockAlbum; // Mock album created from random assets +}; + +export type SerializedTimelineData = { + buckets: Record; + album: MockAlbum; +}; + +/** + * Validates a TimelineConfig object to ensure all values are within expected ranges + */ +export function validateTimelineConfig(config: TimelineConfig): void { + if (!config.months || config.months.length === 0) { + throw new Error('TimelineConfig must contain at least one month'); + } + + const seenMonths = new Set(); + + for (const month of config.months) { + if (month.month < 1 || month.month > 12) { + throw new Error(`Invalid month: ${month.month}. Must be between 1 and 12`); + } + + if (month.year < 1900 || month.year > 2100) { + throw new Error(`Invalid year: ${month.year}. Must be between 1900 and 2100`); + } + + const monthKey = `${month.year}-${month.month}`; + if (seenMonths.has(monthKey)) { + throw new Error(`Duplicate month found: ${monthKey}`); + } + seenMonths.add(monthKey); + + // Validate distribution if provided + if (month.distribution && !['empty', 'sparse', 'medium', 'dense', 'very-dense'].includes(month.distribution)) { + throw new Error( + `Invalid distribution: ${month.distribution}. Must be one of: empty, sparse, medium, dense, very-dense`, + ); + } + + const validPatterns = [ + 'single-day', + 'consecutive-large', + 'consecutive-small', + 'alternating', + 'sparse-scattered', + 'start-heavy', + 'end-heavy', + 'mid-heavy', + ]; + if (month.pattern && !validPatterns.includes(month.pattern)) { + throw new Error(`Invalid pattern: ${month.pattern}. Must be one of: ${validPatterns.join(', ')}`); + } + } + + // Validate seed if provided + if (config.seed !== undefined && (config.seed < 0 || !Number.isInteger(config.seed))) { + throw new Error('Seed must be a non-negative integer'); + } + + // Validate ownerId if provided + if (config.ownerId !== undefined && config.ownerId.trim() === '') { + throw new Error('Owner ID cannot be an empty string'); + } +} + +/** + * Create a default timeline configuration + */ +export function createDefaultTimelineConfig(): TimelineConfig { + const months: MonthSpec[] = [ + // 2024 - Mix of patterns + { year: 2024, month: 12, distribution: 'very-dense', pattern: 'alternating' }, + { year: 2024, month: 11, distribution: 'dense', pattern: 'consecutive-large' }, + { year: 2024, month: 10, distribution: 'medium', pattern: 'mid-heavy' }, + { year: 2024, month: 9, distribution: 'sparse', pattern: 'consecutive-small' }, + { year: 2024, month: 8, distribution: 'empty', pattern: 'single-day' }, + { year: 2024, month: 7, distribution: 'dense', pattern: 'start-heavy' }, + { year: 2024, month: 6, distribution: 'medium', pattern: 'sparse-scattered' }, + { year: 2024, month: 5, distribution: 'sparse', pattern: 'single-day' }, + { year: 2024, month: 4, distribution: 'very-dense', pattern: 'consecutive-large' }, + { year: 2024, month: 3, distribution: 'empty', pattern: 'single-day' }, + { year: 2024, month: 2, distribution: 'medium', pattern: 'end-heavy' }, + { year: 2024, month: 1, distribution: 'dense', pattern: 'alternating' }, + + // 2023 - Testing year boundaries and more patterns + { year: 2023, month: 12, distribution: 'very-dense', pattern: 'end-heavy' }, + { year: 2023, month: 11, distribution: 'sparse', pattern: 'consecutive-small' }, + { year: 2023, month: 10, distribution: 'empty', pattern: 'single-day' }, + { year: 2023, month: 9, distribution: 'medium', pattern: 'alternating' }, + { year: 2023, month: 8, distribution: 'dense', pattern: 'mid-heavy' }, + { year: 2023, month: 7, distribution: 'sparse', pattern: 'sparse-scattered' }, + { year: 2023, month: 6, distribution: 'medium', pattern: 'consecutive-large' }, + { year: 2023, month: 5, distribution: 'empty', pattern: 'single-day' }, + { year: 2023, month: 4, distribution: 'sparse', pattern: 'single-day' }, + { year: 2023, month: 3, distribution: 'dense', pattern: 'start-heavy' }, + { year: 2023, month: 2, distribution: 'medium', pattern: 'alternating' }, + { year: 2023, month: 1, distribution: 'very-dense', pattern: 'consecutive-large' }, + ]; + + for (let year = 2022; year >= 2000; year--) { + for (let month = 12; month >= 1; month--) { + months.push({ year, month, distribution: 'medium', pattern: 'sparse-scattered' }); + } + } + + return { + months, + seed: 42, + }; +} diff --git a/e2e/src/generators/timeline/utils.ts b/e2e/src/generators/timeline/utils.ts new file mode 100644 index 0000000000..686a8223ef --- /dev/null +++ b/e2e/src/generators/timeline/utils.ts @@ -0,0 +1,186 @@ +import { DateTime } from 'luxon'; +import { GENERATION_CONSTANTS, MockTimelineAsset } from 'src/generators/timeline/timeline-config'; + +/** + * Linear Congruential Generator for deterministic pseudo-random numbers + */ +export class SeededRandom { + private seed: number; + + constructor(seed: number) { + this.seed = seed; + } + + /** + * Generate next random number in range [0, 1) + */ + next(): number { + // LCG parameters from Numerical Recipes + this.seed = (this.seed * 1_664_525 + 1_013_904_223) % 2_147_483_647; + return this.seed / 2_147_483_647; + } + + /** + * Generate random integer in range [min, max) + */ + nextInt(min: number, max: number): number { + return Math.floor(this.next() * (max - min)) + min; + } + + /** + * Generate random boolean with given probability + */ + nextBoolean(probability = 0.5): boolean { + return this.next() < probability; + } +} + +/** + * Select random days using seed variation to avoid collisions. + * + * @param daysInMonth - Total number of days in the month + * @param numDays - Number of days to select + * @param rng - Random number generator instance + * @returns Array of selected day numbers, sorted in descending order + */ +export function selectRandomDays(daysInMonth: number, numDays: number, rng: SeededRandom): number[] { + const selectedDays = new Set(); + const maxAttempts = numDays * GENERATION_CONSTANTS.MAX_SELECT_ATTEMPTS; // Safety limit + let attempts = 0; + + while (selectedDays.size < numDays && attempts < maxAttempts) { + const day = rng.nextInt(1, daysInMonth + 1); + selectedDays.add(day); + attempts++; + } + + // Fallback: if we couldn't select enough random days, fill with sequential days + if (selectedDays.size < numDays) { + for (let day = 1; day <= daysInMonth && selectedDays.size < numDays; day++) { + selectedDays.add(day); + } + } + + return [...selectedDays].toSorted((a, b) => b - a); +} + +/** + * Select item from array using seeded random + */ +export function selectRandom(arr: T[], rng: SeededRandom): T { + if (arr.length === 0) { + throw new Error('Cannot select from empty array'); + } + const index = rng.nextInt(0, arr.length); + return arr[index]; +} + +/** + * Select multiple random items from array using seeded random without duplicates + */ +export function selectRandomMultiple(arr: T[], count: number, rng: SeededRandom): T[] { + if (arr.length === 0) { + throw new Error('Cannot select from empty array'); + } + if (count < 0) { + throw new Error('Count must be non-negative'); + } + if (count > arr.length) { + throw new Error('Count cannot exceed array length'); + } + + const result: T[] = []; + const selectedIndices = new Set(); + + while (result.length < count) { + const index = rng.nextInt(0, arr.length); + if (!selectedIndices.has(index)) { + selectedIndices.add(index); + result.push(arr[index]); + } + } + + return result; +} + +/** + * Parse timeBucket parameter to extract year-month key + * Handles both formats: + * - ISO timestamp: "2024-12-01T00:00:00.000Z" -> "2024-12-01" + * - Simple format: "2024-12-01" -> "2024-12-01" + */ +export function parseTimeBucketKey(timeBucket: string): string { + if (!timeBucket) { + throw new Error('timeBucket parameter cannot be empty'); + } + + const dt = DateTime.fromISO(timeBucket, { zone: 'utc' }); + + if (!dt.isValid) { + // Fallback to regex if not a valid ISO string + const match = timeBucket.match(/^(\d{4}-\d{2}-\d{2})/); + return match ? match[1] : timeBucket; + } + + // Format as YYYY-MM-01 (first day of month) + return `${dt.year}-${String(dt.month).padStart(2, '0')}-01`; +} + +export function getMockAsset( + asset: MockTimelineAsset, + sortedDescendingAssets: MockTimelineAsset[], + direction: 'next' | 'previous', + unit: 'day' | 'month' | 'year' = 'day', +): MockTimelineAsset | null { + const currentDateTime = DateTime.fromISO(asset.localDateTime, { zone: 'utc' }); + + const currentIndex = sortedDescendingAssets.findIndex((a) => a.id === asset.id); + + if (currentIndex === -1) { + return null; + } + + const step = direction === 'next' ? 1 : -1; + const startIndex = currentIndex + step; + + if (direction === 'next' && currentIndex >= sortedDescendingAssets.length - 1) { + return null; + } + if (direction === 'previous' && currentIndex <= 0) { + return null; + } + + const isInDifferentPeriod = (date1: DateTime, date2: DateTime): boolean => { + if (unit === 'day') { + return !date1.startOf('day').equals(date2.startOf('day')); + } else if (unit === 'month') { + return date1.year !== date2.year || date1.month !== date2.month; + } else { + return date1.year !== date2.year; + } + }; + + if (direction === 'next') { + // Search forward in array (backwards in time) + for (let i = startIndex; i < sortedDescendingAssets.length; i++) { + const nextAsset = sortedDescendingAssets[i]; + const nextDate = DateTime.fromISO(nextAsset.localDateTime, { zone: 'utc' }); + + if (isInDifferentPeriod(nextDate, currentDateTime)) { + return nextAsset; + } + } + } else { + // Search backward in array (forwards in time) + for (let i = startIndex; i >= 0; i--) { + const prevAsset = sortedDescendingAssets[i]; + const prevDate = DateTime.fromISO(prevAsset.localDateTime, { zone: 'utc' }); + + if (isInDifferentPeriod(prevDate, currentDateTime)) { + return prevAsset; + } + } + } + + return null; +} diff --git a/e2e/src/mock-network/base-network.ts b/e2e/src/mock-network/base-network.ts new file mode 100644 index 0000000000..f23202ca77 --- /dev/null +++ b/e2e/src/mock-network/base-network.ts @@ -0,0 +1,285 @@ +import { BrowserContext } from '@playwright/test'; +import { playwrightHost } from 'playwright.config'; + +export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserId: string) => { + await context.addCookies([ + { + name: 'immich_is_authenticated', + value: 'true', + domain: playwrightHost, + path: '/', + }, + ]); + await context.route('**/api/users/me', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + id: adminUserId, + email: 'admin@immich.cloud', + name: 'Immich Admin', + profileImagePath: '', + avatarColor: 'orange', + profileChangedAt: '2025-01-22T21:31:23.996Z', + storageLabel: 'admin', + shouldChangePassword: true, + isAdmin: true, + createdAt: '2025-01-22T21:31:23.996Z', + deletedAt: null, + updatedAt: '2025-11-14T00:00:00.369Z', + oauthId: '', + quotaSizeInBytes: null, + quotaUsageInBytes: 20_849_000_159, + status: 'active', + license: null, + }, + }); + }); + await context.route('**/users/me/preferences', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + albums: { + defaultAssetOrder: 'desc', + }, + folders: { + enabled: false, + sidebarWeb: false, + }, + memories: { + enabled: true, + duration: 5, + }, + people: { + enabled: true, + sidebarWeb: false, + }, + sharedLinks: { + enabled: true, + sidebarWeb: false, + }, + ratings: { + enabled: false, + }, + tags: { + enabled: false, + sidebarWeb: false, + }, + emailNotifications: { + enabled: true, + albumInvite: true, + albumUpdate: true, + }, + download: { + archiveSize: 4_294_967_296, + includeEmbeddedVideos: false, + }, + purchase: { + showSupportBadge: true, + hideBuyButtonUntil: '2100-02-12T00:00:00.000Z', + }, + cast: { + gCastEnabled: false, + }, + }, + }); + }); + await context.route('**/server/about', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + version: 'v2.2.3', + versionUrl: 'https://github.com/immich-app/immich/releases/tag/v2.2.3', + licensed: false, + build: '1234567890', + buildUrl: 'https://github.com/immich-app/immich/actions/runs/1234567890', + buildImage: 'e2e', + buildImageUrl: 'https://github.com/immich-app/immich/pkgs/container/immich-server', + repository: 'immich-app/immich', + repositoryUrl: 'https://github.com/immich-app/immich', + sourceRef: 'e2e', + sourceCommit: 'e2eeeeeeeeeeeeeeeeee', + sourceUrl: 'https://github.com/immich-app/immich/commit/e2eeeeeeeeeeeeeeeeee', + nodejs: 'v22.18.0', + exiftool: '13.41', + ffmpeg: '7.1.1-6', + libvips: '8.17.2', + imagemagick: '7.1.2-2', + }, + }); + }); + await context.route('**/api/server/features', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + smartSearch: false, + facialRecognition: false, + duplicateDetection: false, + map: true, + reverseGeocoding: true, + importFaces: false, + sidecar: true, + search: true, + trash: true, + oauth: false, + oauthAutoLaunch: false, + ocr: false, + passwordLogin: true, + configFile: false, + email: false, + }, + }); + }); + await context.route('**/api/server/config', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + loginPageMessage: '', + trashDays: 30, + userDeleteDelay: 7, + oauthButtonText: 'Login with OAuth', + isInitialized: true, + isOnboarded: true, + externalDomain: '', + publicUsers: true, + mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json', + mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json', + maintenanceMode: false, + }, + }); + }); + await context.route('**/api/server/media-types', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + video: [ + '.3gp', + '.3gpp', + '.avi', + '.flv', + '.insv', + '.m2t', + '.m2ts', + '.m4v', + '.mkv', + '.mov', + '.mp4', + '.mpe', + '.mpeg', + '.mpg', + '.mts', + '.vob', + '.webm', + '.wmv', + ], + image: [ + '.3fr', + '.ari', + '.arw', + '.cap', + '.cin', + '.cr2', + '.cr3', + '.crw', + '.dcr', + '.dng', + '.erf', + '.fff', + '.iiq', + '.k25', + '.kdc', + '.mrw', + '.nef', + '.nrw', + '.orf', + '.ori', + '.pef', + '.psd', + '.raf', + '.raw', + '.rw2', + '.rwl', + '.sr2', + '.srf', + '.srw', + '.x3f', + '.avif', + '.gif', + '.jpeg', + '.jpg', + '.png', + '.webp', + '.bmp', + '.heic', + '.heif', + '.hif', + '.insp', + '.jp2', + '.jpe', + '.jxl', + '.svg', + '.tif', + '.tiff', + ], + sidecar: ['.xmp'], + }, + }); + }); + await context.route('**/api/notifications*', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: [], + }); + }); + await context.route('**/api/albums*', async (route, request) => { + if (request.url().endsWith('albums?shared=true') || request.url().endsWith('albums')) { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: [], + }); + } + await route.fallback(); + }); + await context.route('**/api/memories*', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: [], + }); + }); + await context.route('**/api/server/storage', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + diskSize: '100.0 GiB', + diskUse: '74.4 GiB', + diskAvailable: '25.6 GiB', + diskSizeRaw: 107_374_182_400, + diskUseRaw: 79_891_660_800, + diskAvailableRaw: 27_482_521_600, + diskUsagePercentage: 74.4, + }, + }); + }); + await context.route('**/api/server/version-history', async (route) => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: [ + { + id: 'd1fbeadc-cb4f-4db3-8d19-8c6a921d5d8e', + createdAt: '2025-11-15T20:14:01.935Z', + version: '2.2.3', + }, + ], + }); + }); +}; diff --git a/e2e/src/mock-network/timeline-network.ts b/e2e/src/mock-network/timeline-network.ts new file mode 100644 index 0000000000..59bce71dd8 --- /dev/null +++ b/e2e/src/mock-network/timeline-network.ts @@ -0,0 +1,149 @@ +import { BrowserContext, Page, Request, Route } from '@playwright/test'; +import { basename } from 'node:path'; +import { + Changes, + getAlbum, + getAsset, + getTimeBucket, + getTimeBuckets, + randomPreview, + randomThumbnail, + TimelineData, +} from 'src/generators/timeline'; +import { sleep } from 'src/web/specs/timeline/utils'; + +export class TimelineTestContext { + slowBucket = false; + adminId = ''; +} + +export const setupTimelineMockApiRoutes = async ( + context: BrowserContext, + timelineRestData: TimelineData, + changes: Changes, + testContext: TimelineTestContext, +) => { + await context.route('**/api/timeline**', async (route, request) => { + const url = new URL(request.url()); + const pathname = url.pathname; + if (pathname === '/api/timeline/buckets') { + const albumId = url.searchParams.get('albumId') || undefined; + const isTrashed = url.searchParams.get('isTrashed') ? url.searchParams.get('isTrashed') === 'true' : undefined; + const isFavorite = url.searchParams.get('isFavorite') ? url.searchParams.get('isFavorite') === 'true' : undefined; + const isArchived = url.searchParams.get('visibility') + ? url.searchParams.get('visibility') === 'archive' + : undefined; + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: getTimeBuckets(timelineRestData, isTrashed, isArchived, isFavorite, albumId, changes), + }); + } else if (pathname === '/api/timeline/bucket') { + const timeBucket = url.searchParams.get('timeBucket'); + if (!timeBucket) { + return route.continue(); + } + const isTrashed = url.searchParams.get('isTrashed') ? url.searchParams.get('isTrashed') === 'true' : undefined; + const isArchived = url.searchParams.get('visibility') + ? url.searchParams.get('visibility') === 'archive' + : undefined; + const isFavorite = url.searchParams.get('isFavorite') ? url.searchParams.get('isFavorite') === 'true' : undefined; + const albumId = url.searchParams.get('albumId') || undefined; + const assets = getTimeBucket(timelineRestData, timeBucket, isTrashed, isArchived, isFavorite, albumId, changes); + if (testContext.slowBucket) { + await sleep(5000); + } + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: assets, + }); + } + return route.continue(); + }); + + await context.route('**/api/assets/*', async (route, request) => { + const url = new URL(request.url()); + const pathname = url.pathname; + const assetId = basename(pathname); + const asset = getAsset(timelineRestData, assetId); + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: asset, + }); + }); + + await context.route('**/api/assets/*/ocr', async (route) => { + return route.fulfill({ status: 200, contentType: 'application/json', json: [] }); + }); + + await context.route('**/api/assets/*/thumbnail?size=*', async (route, request) => { + const pattern = /\/api\/assets\/(?[^/]+)\/thumbnail\?size=(?preview|thumbnail)/; + const match = request.url().match(pattern); + if (!match?.groups) { + throw new Error(`Invalid URL for thumbnail endpoint: ${request.url()}`); + } + + if (match.groups.size === 'preview') { + if (!route.request().serviceWorker()) { + return route.continue(); + } + const asset = getAsset(timelineRestData, match.groups.assetId); + return route.fulfill({ + status: 200, + headers: { 'content-type': 'image/jpeg', ETag: 'abc123', 'Cache-Control': 'public, max-age=3600' }, + body: await randomPreview( + match.groups.assetId, + (asset?.exifInfo?.exifImageWidth ?? 0) / (asset?.exifInfo?.exifImageHeight ?? 1), + ), + }); + } + if (match.groups.size === 'thumbnail') { + if (!route.request().serviceWorker()) { + return route.continue(); + } + const asset = getAsset(timelineRestData, match.groups.assetId); + return route.fulfill({ + status: 200, + headers: { 'content-type': 'image/jpeg' }, + body: await randomThumbnail( + match.groups.assetId, + (asset?.exifInfo?.exifImageWidth ?? 0) / (asset?.exifInfo?.exifImageHeight ?? 1), + ), + }); + } + return route.continue(); + }); + + await context.route('**/api/albums/**', async (route, request) => { + const pattern = /\/api\/albums\/(?[^/?]+)/; + const match = request.url().match(pattern); + if (!match) { + return route.continue(); + } + const album = getAlbum(timelineRestData, testContext.adminId, match.groups?.albumId, changes); + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: album, + }); + }); +}; + +export const pageRoutePromise = async ( + page: Page, + route: string, + callback: (route: Route, request: Request) => Promise, +) => { + let resolveRequest: ((value: unknown | PromiseLike) => void) | undefined; + const deleteRequest = new Promise((resolve) => { + resolveRequest = resolve; + }); + await page.route(route, async (route, request) => { + await callback(route, request); + const requestJson = request.postDataJSON(); + resolveRequest?.(requestJson); + }); + return deleteRequest; +}; diff --git a/e2e/src/responses.ts b/e2e/src/responses.ts index 27e6091206..9585484355 100644 --- a/e2e/src/responses.ts +++ b/e2e/src/responses.ts @@ -7,6 +7,12 @@ export const errorDto = { message: 'Authentication required', correlationId: expect.any(String), }, + unauthorizedWithMessage: (message: string) => ({ + error: 'Unauthorized', + statusCode: 401, + message, + correlationId: expect.any(String), + }), forbidden: { error: 'Forbidden', statusCode: 403, diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index 8f34bbe40a..15bb112cd8 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -6,12 +6,13 @@ import { CheckExistingAssetsDto, CreateAlbumDto, CreateLibraryDto, + MaintenanceAction, MetadataSearchDto, Permission, PersonCreateDto, QueueCommandDto, QueueName, - QueuesResponseDto, + QueuesResponseLegacyDto, SharedLinkCreateDto, UpdateLibraryDto, UserAdminCreateDto, @@ -36,6 +37,7 @@ import { scanLibrary, searchAssets, setBaseUrl, + setMaintenanceMode, signUpAdmin, tagAssets, updateAdminOnboarding, @@ -52,7 +54,7 @@ import { exec, spawn } from 'node:child_process'; import { createHash } from 'node:crypto'; import { existsSync, mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; -import path, { dirname } from 'node:path'; +import { dirname, resolve } from 'node:path'; import { setTimeout as setAsyncTimeout } from 'node:timers/promises'; import { promisify } from 'node:util'; import pg from 'pg'; @@ -60,6 +62,8 @@ import { io, type Socket } from 'socket.io-client'; import { loginDto, signupDto } from 'src/fixtures'; import { makeRandomImage } from 'src/generators'; import request from 'supertest'; +import { playwrightDbHost, playwrightHost, playwriteBaseUrl } from '../playwright.config'; + export type { Emitter } from '@socket.io/component-emitter'; type CommandResponse = { stdout: string; stderr: string; exitCode: number | null }; @@ -68,12 +72,12 @@ type WaitOptions = { event: EventType; id?: string; total?: number; timeout?: nu type AdminSetupOptions = { onboarding?: boolean }; type FileData = { bytes?: Buffer; filename: string }; -const dbUrl = 'postgres://postgres:postgres@127.0.0.1:5435/immich'; -export const baseUrl = 'http://127.0.0.1:2285'; +const dbUrl = `postgres://postgres:postgres@${playwrightDbHost}:5435/immich`; +export const baseUrl = playwriteBaseUrl; export const shareUrl = `${baseUrl}/share`; export const app = `${baseUrl}/api`; // TODO move test assets into e2e/assets -export const testAssetDir = path.resolve('./test-assets'); +export const testAssetDir = resolve(import.meta.dirname, '../test-assets'); export const testAssetDirInternal = '/test-assets'; export const tempDir = tmpdir(); export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` }); @@ -480,7 +484,7 @@ export const utils = { queueCommand: async (accessToken: string, name: QueueName, queueCommandDto: QueueCommandDto) => runQueueCommandLegacy({ name, queueCommandDto }, { headers: asBearerAuth(accessToken) }), - setAuthCookies: async (context: BrowserContext, accessToken: string, domain = '127.0.0.1') => + setAuthCookies: async (context: BrowserContext, accessToken: string, domain = playwrightHost) => await context.addCookies([ { name: 'immich_access_token', @@ -514,6 +518,42 @@ export const utils = { }, ]), + setMaintenanceAuthCookie: async (context: BrowserContext, token: string, domain = '127.0.0.1') => + await context.addCookies([ + { + name: 'immich_maintenance_token', + value: token, + domain, + path: '/', + expires: 2_058_028_213, + httpOnly: true, + secure: false, + sameSite: 'Lax', + }, + ]), + + enterMaintenance: async (accessToken: string) => { + let setCookie: string[] | undefined; + + await setMaintenanceMode( + { + setMaintenanceModeDto: { + action: MaintenanceAction.Start, + }, + }, + { + headers: asBearerAuth(accessToken), + fetch: (...args: Parameters) => + fetch(...args).then((response) => { + setCookie = response.headers.getSetCookie(); + return response; + }), + }, + ); + + return setCookie; + }, + resetTempFolder: () => { rmSync(`${testAssetDir}/temp`, { recursive: true, force: true }); mkdirSync(`${testAssetDir}/temp`, { recursive: true }); @@ -524,13 +564,13 @@ export const utils = { await updateConfig({ systemConfigDto: defaultConfig }, { headers: asBearerAuth(accessToken) }); }, - isQueueEmpty: async (accessToken: string, queue: keyof QueuesResponseDto) => { + isQueueEmpty: async (accessToken: string, queue: keyof QueuesResponseLegacyDto) => { const queues = await getQueuesLegacy({ headers: asBearerAuth(accessToken) }); const jobCounts = queues[queue].jobCounts; return !jobCounts.active && !jobCounts.waiting; }, - waitForQueueFinish: (accessToken: string, queue: keyof QueuesResponseDto, ms?: number) => { + waitForQueueFinish: (accessToken: string, queue: keyof QueuesResponseLegacyDto, ms?: number) => { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Timed out waiting for queue to empty')), ms || 10_000); diff --git a/e2e/src/web/specs/maintenance.e2e-spec.ts b/e2e/src/web/specs/maintenance.e2e-spec.ts new file mode 100644 index 0000000000..534c05f783 --- /dev/null +++ b/e2e/src/web/specs/maintenance.e2e-spec.ts @@ -0,0 +1,51 @@ +import { LoginResponseDto } from '@immich/sdk'; +import { expect, test } from '@playwright/test'; +import { utils } from 'src/utils'; + +test.describe.configure({ mode: 'serial' }); + +test.describe('Maintenance', () => { + let admin: LoginResponseDto; + + test.beforeAll(async () => { + utils.initSdk(); + await utils.resetDatabase(); + admin = await utils.adminSetup(); + }); + + test('enter and exit maintenance mode', async ({ context, page }) => { + await utils.setAuthCookies(context, admin.accessToken); + + await page.goto('/admin/system-settings?isOpen=maintenance'); + await page.getByRole('button', { name: 'Start maintenance mode' }).click(); + + await expect(page.getByText('Temporarily Unavailable')).toBeVisible({ timeout: 10_000 }); + await page.getByRole('button', { name: 'End maintenance mode' }).click(); + await page.waitForURL('**/admin/system-settings*', { timeout: 10_000 }); + }); + + test('maintenance shows no options to users until they authenticate', async ({ page }) => { + const setCookie = await utils.enterMaintenance(admin.accessToken); + const cookie = setCookie + ?.map((cookie) => cookie.split(';')[0].split('=')) + ?.find(([name]) => name === 'immich_maintenance_token'); + + expect(cookie).toBeTruthy(); + + await expect(async () => { + await page.goto('/'); + await page.waitForURL('**/maintenance?**', { + timeout: 1000, + }); + }).toPass({ timeout: 10_000 }); + + await expect(page.getByText('Temporarily Unavailable')).toBeVisible(); + await expect(page.getByRole('button', { name: 'End maintenance mode' })).toHaveCount(0); + + await page.goto(`/maintenance?${new URLSearchParams({ token: cookie![1] })}`); + await expect(page.getByText('Temporarily Unavailable')).toBeVisible(); + await expect(page.getByRole('button', { name: 'End maintenance mode' })).toBeVisible(); + await page.getByRole('button', { name: 'End maintenance mode' }).click(); + await page.waitForURL('**/auth/login'); + }); +}); diff --git a/e2e/src/web/specs/timeline/timeline.parallel-e2e-spec.ts b/e2e/src/web/specs/timeline/timeline.parallel-e2e-spec.ts new file mode 100644 index 0000000000..6314688abb --- /dev/null +++ b/e2e/src/web/specs/timeline/timeline.parallel-e2e-spec.ts @@ -0,0 +1,864 @@ +import { faker } from '@faker-js/faker'; +import { expect, test } from '@playwright/test'; +import { DateTime } from 'luxon'; +import { + Changes, + createDefaultTimelineConfig, + generateTimelineData, + getAsset, + getMockAsset, + SeededRandom, + selectRandom, + selectRandomMultiple, + TimelineAssetConfig, + TimelineData, +} from 'src/generators/timeline'; +import { setupBaseMockApiRoutes } from 'src/mock-network/base-network'; +import { pageRoutePromise, setupTimelineMockApiRoutes, TimelineTestContext } from 'src/mock-network/timeline-network'; +import { utils } from 'src/utils'; +import { + assetViewerUtils, + cancelAllPollers, + padYearMonth, + pageUtils, + poll, + thumbnailUtils, + timelineUtils, +} from 'src/web/specs/timeline/utils'; + +test.describe.configure({ mode: 'parallel' }); +test.describe('Timeline', () => { + let adminUserId: string; + let timelineRestData: TimelineData; + const assets: TimelineAssetConfig[] = []; + const yearMonths: string[] = []; + const testContext = new TimelineTestContext(); + const changes: Changes = { + albumAdditions: [], + assetDeletions: [], + assetArchivals: [], + assetFavorites: [], + }; + + test.beforeAll(async () => { + test.fail( + process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS !== '1', + 'This test requires env var: PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1', + ); + utils.initSdk(); + adminUserId = faker.string.uuid(); + testContext.adminId = adminUserId; + timelineRestData = generateTimelineData({ ...createDefaultTimelineConfig(), ownerId: adminUserId }); + for (const timeBucket of timelineRestData.buckets.values()) { + assets.push(...timeBucket); + } + for (const yearMonth of timelineRestData.buckets.keys()) { + const [year, month] = yearMonth.split('-'); + yearMonths.push(`${year}-${Number(month)}`); + } + }); + + test.beforeEach(async ({ context }) => { + await setupBaseMockApiRoutes(context, adminUserId); + await setupTimelineMockApiRoutes(context, timelineRestData, changes, testContext); + }); + + test.afterEach(() => { + cancelAllPollers(); + testContext.slowBucket = false; + changes.albumAdditions = []; + changes.assetDeletions = []; + changes.assetArchivals = []; + changes.assetFavorites = []; + }); + + test.describe('/photos', () => { + test('Open /photos', async ({ page }) => { + await page.goto(`/photos`); + await page.waitForSelector('#asset-grid'); + await thumbnailUtils.expectTimelineHasOnScreenAssets(page); + }); + test('Deep link to last photo', async ({ page }) => { + const lastAsset = assets.at(-1)!; + await pageUtils.deepLinkPhotosPage(page, lastAsset.id); + await thumbnailUtils.expectTimelineHasOnScreenAssets(page); + await thumbnailUtils.expectInViewport(page, lastAsset.id); + }); + const rng = new SeededRandom(529); + for (let i = 0; i < 10; i++) { + test('Deep link to random asset ' + i, async ({ page }) => { + const asset = selectRandom(assets, rng); + await pageUtils.deepLinkPhotosPage(page, asset.id); + await thumbnailUtils.expectTimelineHasOnScreenAssets(page); + await thumbnailUtils.expectInViewport(page, asset.id); + }); + } + test('Open /photos, open asset-viewer, browser back', async ({ page }) => { + const rng = new SeededRandom(22); + const asset = selectRandom(assets, rng); + await pageUtils.deepLinkPhotosPage(page, asset.id); + const scrollTopBefore = await timelineUtils.getScrollTop(page); + await thumbnailUtils.clickAssetId(page, asset.id); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.goBack(); + await timelineUtils.locator(page).waitFor(); + const scrollTopAfter = await timelineUtils.getScrollTop(page); + expect(scrollTopAfter).toBe(scrollTopBefore); + }); + test('Open /photos, open asset-viewer, next photo, browser back, back', async ({ page }) => { + const rng = new SeededRandom(49); + const asset = selectRandom(assets, rng); + const assetIndex = assets.indexOf(asset); + const nextAsset = assets[assetIndex + 1]; + await pageUtils.deepLinkPhotosPage(page, asset.id); + const scrollTopBefore = await timelineUtils.getScrollTop(page); + await thumbnailUtils.clickAssetId(page, asset.id); + await assetViewerUtils.waitForViewerLoad(page, asset); + await expect.poll(() => new URL(page.url()).pathname).toBe(`/photos/${asset.id}`); + await page.getByLabel('View next asset').click(); + await assetViewerUtils.waitForViewerLoad(page, nextAsset); + await expect.poll(() => new URL(page.url()).pathname).toBe(`/photos/${nextAsset.id}`); + await page.goBack(); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.goBack(); + await page.waitForURL('**/photos?at=*'); + const scrollTopAfter = await timelineUtils.getScrollTop(page); + expect(Math.abs(scrollTopAfter - scrollTopBefore)).toBeLessThan(5); + }); + test('Open /photos, open asset-viewer, next photo 15x, backwardsArrow', async ({ page }) => { + await pageUtils.deepLinkPhotosPage(page, assets[0].id); + await thumbnailUtils.clickAssetId(page, assets[0].id); + await assetViewerUtils.waitForViewerLoad(page, assets[0]); + for (let i = 1; i <= 15; i++) { + await page.getByLabel('View next asset').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[i]); + } + await page.getByLabel('Go back').click(); + await page.waitForURL('**/photos?at=*'); + await thumbnailUtils.expectInViewport(page, assets[15].id); + await thumbnailUtils.expectBottomIsTimelineBottom(page, assets[15]!.id); + }); + test('Open /photos, open asset-viewer, previous photo 15x, backwardsArrow', async ({ page }) => { + const lastAsset = assets.at(-1)!; + await pageUtils.deepLinkPhotosPage(page, lastAsset.id); + await thumbnailUtils.clickAssetId(page, lastAsset.id); + await assetViewerUtils.waitForViewerLoad(page, lastAsset); + for (let i = 1; i <= 15; i++) { + await page.getByLabel('View previous asset').click(); + await assetViewerUtils.waitForViewerLoad(page, assets.at(-1 - i)!); + } + await page.getByLabel('Go back').click(); + await page.waitForURL('**/photos?at=*'); + await thumbnailUtils.expectInViewport(page, assets.at(-1 - 15)!.id); + await thumbnailUtils.expectTopIsTimelineTop(page, assets.at(-1 - 15)!.id); + }); + }); + test.describe('keyboard', () => { + /** + * This text tests keyboard nativation, and also ensures that the scroll-to-asset behavior + * scrolls the minimum amount. That is, if you are navigating using right arrow (auto scrolling + * as necessary downwards), then the asset should always be at the lowest row of the grid. + */ + test('Next/previous asset - ArrowRight/ArrowLeft', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await thumbnailUtils.withAssetId(page, assets[0].id).focus(); + const rightKey = 'ArrowRight'; + const leftKey = 'ArrowLeft'; + for (let i = 1; i < 15; i++) { + await page.keyboard.press(rightKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + for (let i = 15; i <= 20; i++) { + await page.keyboard.press(rightKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + expect(await thumbnailUtils.expectBottomIsTimelineBottom(page, assets.at(i)!.id)); + } + // now test previous asset + for (let i = 19; i >= 15; i--) { + await page.keyboard.press(leftKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + for (let i = 14; i > 0; i--) { + await page.keyboard.press(leftKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + expect(await thumbnailUtils.expectTopIsTimelineTop(page, assets.at(i)!.id)); + } + }); + test('Next/previous asset - Tab/Shift+Tab', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await thumbnailUtils.withAssetId(page, assets[0].id).focus(); + const rightKey = 'Tab'; + const leftKey = 'Shift+Tab'; + for (let i = 1; i < 15; i++) { + await page.keyboard.press(rightKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + for (let i = 15; i <= 20; i++) { + await page.keyboard.press(rightKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + // now test previous asset + for (let i = 19; i >= 15; i--) { + await page.keyboard.press(leftKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + for (let i = 14; i > 0; i--) { + await page.keyboard.press(leftKey); + await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id); + } + }); + test('Next/previous day - d, Shift+D', async ({ page }) => { + await pageUtils.openPhotosPage(page); + let asset = assets[0]; + await timelineUtils.locator(page).hover(); + await page.keyboard.press('d'); + await assetViewerUtils.expectActiveAssetToBe(page, asset.id); + for (let i = 0; i < 15; i++) { + await page.keyboard.press('d'); + const next = getMockAsset(asset, assets, 'next', 'day')!; + await assetViewerUtils.expectActiveAssetToBe(page, next.id); + asset = next; + } + for (let i = 0; i < 15; i++) { + await page.keyboard.press('Shift+D'); + const previous = getMockAsset(asset, assets, 'previous', 'day')!; + await assetViewerUtils.expectActiveAssetToBe(page, previous.id); + asset = previous; + } + }); + test('Next/previous month - m, Shift+M', async ({ page }) => { + await pageUtils.openPhotosPage(page); + let asset = assets[0]; + await timelineUtils.locator(page).hover(); + await page.keyboard.press('m'); + await assetViewerUtils.expectActiveAssetToBe(page, asset.id); + for (let i = 0; i < 15; i++) { + await page.keyboard.press('m'); + const next = getMockAsset(asset, assets, 'next', 'month')!; + await assetViewerUtils.expectActiveAssetToBe(page, next.id); + asset = next; + } + for (let i = 0; i < 15; i++) { + await page.keyboard.press('Shift+M'); + const previous = getMockAsset(asset, assets, 'previous', 'month')!; + await assetViewerUtils.expectActiveAssetToBe(page, previous.id); + asset = previous; + } + }); + test('Next/previous year - y, Shift+Y', async ({ page }) => { + await pageUtils.openPhotosPage(page); + let asset = assets[0]; + await timelineUtils.locator(page).hover(); + await page.keyboard.press('y'); + await assetViewerUtils.expectActiveAssetToBe(page, asset.id); + for (let i = 0; i < 15; i++) { + await page.keyboard.press('y'); + const next = getMockAsset(asset, assets, 'next', 'year')!; + await assetViewerUtils.expectActiveAssetToBe(page, next.id); + asset = next; + } + for (let i = 0; i < 15; i++) { + await page.keyboard.press('Shift+Y'); + const previous = getMockAsset(asset, assets, 'previous', 'year')!; + await assetViewerUtils.expectActiveAssetToBe(page, previous.id); + asset = previous; + } + }); + test('Navigate to time - g', async ({ page }) => { + const rng = new SeededRandom(4782); + await pageUtils.openPhotosPage(page); + for (let i = 0; i < 10; i++) { + const asset = selectRandom(assets, rng); + await pageUtils.goToAsset(page, asset.fileCreatedAt); + await thumbnailUtils.expectInViewport(page, asset.id); + } + }); + }); + test.describe('selection', () => { + test('Select day, unselect day', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await pageUtils.selectDay(page, 'Wed, Dec 11, 2024'); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(4); + await pageUtils.selectDay(page, 'Wed, Dec 11, 2024'); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(0); + }); + test('Select asset, click asset to select', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await thumbnailUtils.withAssetId(page, assets[1].id).hover(); + await thumbnailUtils.selectButton(page, assets[1].id).click(); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(1); + // no need to hover, once selection is active + await thumbnailUtils.clickAssetId(page, assets[2].id); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(2); + }); + test('Select asset, click unselect asset', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await thumbnailUtils.withAssetId(page, assets[1].id).hover(); + await thumbnailUtils.selectButton(page, assets[1].id).click(); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(1); + await thumbnailUtils.clickAssetId(page, assets[1].id); + // the hover uses a checked button too, so just move mouse away + await page.mouse.move(0, 0); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(0); + }); + test('Select asset, shift-hover candidates, shift-click end', async ({ page }) => { + await pageUtils.openPhotosPage(page); + const asset = assets[0]; + await thumbnailUtils.withAssetId(page, asset.id).hover(); + await thumbnailUtils.selectButton(page, asset.id).click(); + await page.keyboard.down('Shift'); + await thumbnailUtils.withAssetId(page, assets[2].id).hover(); + await expect( + thumbnailUtils.locator(page).locator('.absolute.top-0.h-full.w-full.bg-immich-primary.opacity-40'), + ).toHaveCount(3); + await thumbnailUtils.selectButton(page, assets[2].id).click(); + await page.keyboard.up('Shift'); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(3); + }); + test('Add multiple to selection - Select day, shift-click end', async ({ page }) => { + await pageUtils.openPhotosPage(page); + await thumbnailUtils.withAssetId(page, assets[0].id).hover(); + await thumbnailUtils.selectButton(page, assets[0].id).click(); + await thumbnailUtils.clickAssetId(page, assets[2].id); + await page.keyboard.down('Shift'); + await thumbnailUtils.clickAssetId(page, assets[4].id); + await page.mouse.move(0, 0); + await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(4); + }); + }); + test.describe('scroll', () => { + test('Open /photos, random click scrubber 20x', async ({ page }) => { + test.slow(); + await pageUtils.openPhotosPage(page); + const rng = new SeededRandom(6637); + const selectedMonths = selectRandomMultiple(yearMonths, 20, rng); + for (const month of selectedMonths) { + await page.locator(`[data-segment-year-month="${month}"]`).click({ force: true }); + const visibleMockAssetsYearMonths = await poll(page, async () => { + const assetIds = await thumbnailUtils.getAllInViewport( + page, + (assetId: string) => getYearMonth(assets, assetId) === month, + ); + const visibleMockAssetsYearMonths: string[] = []; + for (const assetId of assetIds!) { + const yearMonth = getYearMonth(assets, assetId); + visibleMockAssetsYearMonths.push(yearMonth); + if (yearMonth === month) { + return [yearMonth]; + } + } + }); + if (page.isClosed()) { + return; + } + expect(visibleMockAssetsYearMonths).toContain(month); + } + }); + test('Deep link to last photo, scroll up', async ({ page }) => { + const lastAsset = assets.at(-1)!; + await pageUtils.deepLinkPhotosPage(page, lastAsset.id); + + await timelineUtils.locator(page).hover(); + for (let i = 0; i < 100; i++) { + await page.mouse.wheel(0, -100); + await page.waitForTimeout(25); + } + + await thumbnailUtils.expectInViewport(page, '14e5901f-fd7f-40c0-b186-4d7e7fc67968'); + }); + test('Deep link to first bucket, scroll down', async ({ page }) => { + const lastAsset = assets.at(0)!; + await pageUtils.deepLinkPhotosPage(page, lastAsset.id); + await timelineUtils.locator(page).hover(); + for (let i = 0; i < 100; i++) { + await page.mouse.wheel(0, 100); + await page.waitForTimeout(25); + } + await thumbnailUtils.expectInViewport(page, 'b7983a13-4b4e-4950-a731-f2962d9a1555'); + }); + test('Deep link to last photo, drag scrubber to scroll up', async ({ page }) => { + const lastAsset = assets.at(-1)!; + await pageUtils.deepLinkPhotosPage(page, lastAsset.id); + const lastMonth = yearMonths.at(-1); + const firstScrubSegment = page.locator(`[data-segment-year-month="${yearMonths[0]}"]`); + const lastScrubSegment = page.locator(`[data-segment-year-month="${lastMonth}"]`); + const sourcebox = (await lastScrubSegment.boundingBox())!; + const targetBox = (await firstScrubSegment.boundingBox())!; + await firstScrubSegment.hover(); + const currentY = sourcebox.y; + await page.mouse.move(sourcebox.x + sourcebox?.width / 2, currentY); + await page.mouse.down(); + await page.mouse.move(sourcebox.x + sourcebox?.width / 2, targetBox.y, { steps: 100 }); + await page.mouse.up(); + await thumbnailUtils.expectInViewport(page, assets[0].id); + }); + test('Deep link to first bucket, drag scrubber to scroll down', async ({ page }) => { + await pageUtils.deepLinkPhotosPage(page, assets[0].id); + const firstScrubSegment = page.locator(`[data-segment-year-month="${yearMonths[0]}"]`); + const sourcebox = (await firstScrubSegment.boundingBox())!; + await firstScrubSegment.hover(); + const currentY = sourcebox.y; + await page.mouse.move(sourcebox.x + sourcebox?.width / 2, currentY); + await page.mouse.down(); + const height = page.viewportSize()?.height; + expect(height).toBeDefined(); + await page.mouse.move(sourcebox.x + sourcebox?.width / 2, height! - 10, { + steps: 100, + }); + await page.mouse.up(); + await thumbnailUtils.expectInViewport(page, assets.at(-1)!.id); + }); + test('Buckets cancel on scroll', async ({ page }) => { + await pageUtils.openPhotosPage(page); + testContext.slowBucket = true; + const failedUris: string[] = []; + page.on('requestfailed', (request) => { + failedUris.push(request.url()); + }); + const offscreenSegment = page.locator(`[data-segment-year-month="${yearMonths[12]}"]`); + await offscreenSegment.click({ force: true }); + const lastSegment = page.locator(`[data-segment-year-month="${yearMonths.at(-1)!}"]`); + await lastSegment.click({ force: true }); + const uris = await poll(page, async () => (failedUris.length > 0 ? failedUris : null)); + expect(uris).toEqual(expect.arrayContaining([expect.stringContaining(padYearMonth(yearMonths[12]!))])); + }); + }); + test.describe('/albums', () => { + test('Open album', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + await thumbnailUtils.expectInViewport(page, album.assetIds[0]); + }); + test('Deep link to last photo', async ({ page }) => { + const album = timelineRestData.album; + const lastAsset = album.assetIds.at(-1); + await pageUtils.deepLinkAlbumPage(page, album.id, lastAsset!); + await thumbnailUtils.expectInViewport(page, album.assetIds.at(-1)!); + await thumbnailUtils.expectBottomIsTimelineBottom(page, album.assetIds.at(-1)!); + }); + test('Add photos to album pre-selects existing', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + await page.getByLabel('Add photos').click(); + const asset = getAsset(timelineRestData, album.assetIds[0])!; + await pageUtils.goToAsset(page, asset.fileCreatedAt); + await thumbnailUtils.expectInViewport(page, asset.id); + await thumbnailUtils.expectSelectedReadonly(page, asset.id); + }); + test('Add photos to album', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + await page.locator('nav button[aria-label="Add photos"]').click(); + const asset = getAsset(timelineRestData, album.assetIds[0])!; + await pageUtils.goToAsset(page, asset.fileCreatedAt); + await thumbnailUtils.expectInViewport(page, asset.id); + await thumbnailUtils.expectSelectedReadonly(page, asset.id); + await pageUtils.selectDay(page, 'Tue, Feb 27, 2024'); + const put = pageRoutePromise(page, `**/api/albums/${album.id}/assets`, async (route, request) => { + const requestJson = request.postDataJSON(); + await route.fulfill({ + status: 200, + contentType: 'application/json', + json: requestJson.ids.map((id: string) => ({ id, success: true })), + }); + changes.albumAdditions.push(...requestJson.ids); + }); + await page.getByText('Done').click(); + await expect(put).resolves.toEqual({ + ids: [ + 'c077ea7b-cfa1-45e4-8554-f86c00ee5658', + '040fd762-dbbc-486d-a51a-2d84115e6229', + '86af0b5f-79d3-4f75-bab3-3b61f6c72b23', + ], + }); + const addedAsset = getAsset(timelineRestData, 'c077ea7b-cfa1-45e4-8554-f86c00ee5658')!; + await pageUtils.goToAsset(page, addedAsset.fileCreatedAt); + await thumbnailUtils.expectInViewport(page, 'c077ea7b-cfa1-45e4-8554-f86c00ee5658'); + await thumbnailUtils.expectInViewport(page, '040fd762-dbbc-486d-a51a-2d84115e6229'); + await thumbnailUtils.expectInViewport(page, '86af0b5f-79d3-4f75-bab3-3b61f6c72b23'); + }); + }); + test.describe('/trash', () => { + test('open /photos, trash photo, open /trash, restore', async ({ page }) => { + await pageUtils.openPhotosPage(page); + const assetToTrash = assets[0]; + await thumbnailUtils.withAssetId(page, assetToTrash.id).hover(); + await thumbnailUtils.selectButton(page, assetToTrash.id).click(); + await page.getByLabel('Menu').click(); + const deleteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + changes.assetDeletions.push(...requestJson.ids); + await route.fulfill({ + status: 200, + contentType: 'application/json', + json: requestJson.ids.map((id: string) => ({ id, success: true })), + }); + }); + await page.getByRole('menuitem').getByText('Delete').click(); + await expect(deleteRequest).resolves.toEqual({ + force: false, + ids: [assetToTrash.id], + }); + await page.getByText('Trash', { exact: true }).click(); + await thumbnailUtils.expectInViewport(page, assetToTrash.id); + await thumbnailUtils.withAssetId(page, assetToTrash.id).hover(); + await thumbnailUtils.selectButton(page, assetToTrash.id).click(); + const restoreRequest = pageRoutePromise(page, '**/api/trash/restore/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + changes.assetDeletions = changes.assetDeletions.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 200, + contentType: 'application/json', + json: { count: requestJson.ids.length }, + }); + }); + await page.getByText('Restore', { exact: true }).click(); + await expect(restoreRequest).resolves.toEqual({ + ids: [assetToTrash.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToTrash.id)).toHaveCount(0); + await page.getByText('Photos', { exact: true }).click(); + await thumbnailUtils.expectInViewport(page, assetToTrash.id); + }); + test('open album, trash photo, open /trash, restore', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + const assetToTrash = getAsset(timelineRestData, album.assetIds[0])!; + await thumbnailUtils.withAssetId(page, assetToTrash.id).hover(); + await thumbnailUtils.selectButton(page, assetToTrash.id).click(); + await page.getByLabel('Menu').click(); + const deleteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + changes.assetDeletions.push(...requestJson.ids); + await route.fulfill({ + status: 200, + contentType: 'application/json', + json: requestJson.ids.map((id: string) => ({ id, success: true })), + }); + }); + await page.getByRole('menuitem').getByText('Delete').click(); + await expect(deleteRequest).resolves.toEqual({ + force: false, + ids: [assetToTrash.id], + }); + await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.getByText('Trash', { exact: true }).click(); + await timelineUtils.waitForTimelineLoad(page); + await thumbnailUtils.expectInViewport(page, assetToTrash.id); + await thumbnailUtils.withAssetId(page, assetToTrash.id).hover(); + await thumbnailUtils.selectButton(page, assetToTrash.id).click(); + const restoreRequest = pageRoutePromise(page, '**/api/trash/restore/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + changes.assetDeletions = changes.assetDeletions.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 200, + contentType: 'application/json', + json: { count: requestJson.ids.length }, + }); + }); + await page.getByText('Restore', { exact: true }).click(); + await expect(restoreRequest).resolves.toEqual({ + ids: [assetToTrash.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToTrash.id)).toHaveCount(0); + await pageUtils.openAlbumPage(page, album.id); + await thumbnailUtils.expectInViewport(page, assetToTrash.id); + }); + }); + test.describe('/archive', () => { + test('open /photos, archive photo, open /archive, unarchive', async ({ page }) => { + await pageUtils.openPhotosPage(page); + const assetToArchive = assets[0]; + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + await page.getByLabel('Menu').click(); + const archive = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'archive') { + return await route.continue(); + } + await route.fulfill({ + status: 204, + }); + changes.assetArchivals.push(...requestJson.ids); + }); + await page.getByRole('menuitem').getByText('Archive').click(); + await expect(archive).resolves.toEqual({ + visibility: 'archive', + ids: [assetToArchive.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0); + await page.getByRole('link').getByText('Archive').click(); + await thumbnailUtils.expectInViewport(page, assetToArchive.id); + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + const unarchiveRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'timeline') { + return await route.continue(); + } + changes.assetArchivals = changes.assetArchivals.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Unarchive').click(); + await expect(unarchiveRequest).resolves.toEqual({ + visibility: 'timeline', + ids: [assetToArchive.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0); + await page.getByText('Photos', { exact: true }).click(); + await thumbnailUtils.expectInViewport(page, assetToArchive.id); + }); + test('open /archive, favorite photo, unfavorite', async ({ page }) => { + const assetToFavorite = assets[0]; + changes.assetArchivals.push(assetToFavorite.id); + await pageUtils.openArchivePage(page); + const favorite = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + const isFavorite = requestJson.isFavorite; + if (isFavorite) { + changes.assetFavorites.push(...requestJson.ids); + } + await route.fulfill({ + status: 204, + }); + }); + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + await page.getByLabel('Favorite').click(); + await expect(favorite).resolves.toEqual({ + isFavorite: true, + ids: [assetToFavorite.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(1); + await thumbnailUtils.expectInViewport(page, assetToFavorite.id); + await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id); + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + const unFavoriteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + changes.assetFavorites = changes.assetFavorites.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Remove from favorites').click(); + await expect(unFavoriteRequest).resolves.toEqual({ + isFavorite: false, + ids: [assetToFavorite.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(1); + await thumbnailUtils.expectThumbnailIsNotFavorite(page, assetToFavorite.id); + }); + test('open album, archive photo, open album, unarchive', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + const assetToArchive = getAsset(timelineRestData, album.assetIds[0])!; + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + await page.getByLabel('Menu').click(); + const archive = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'archive') { + return await route.continue(); + } + changes.assetArchivals.push(...requestJson.ids); + await route.fulfill({ + status: 204, + }); + }); + await page.getByRole('menuitem').getByText('Archive').click(); + await expect(archive).resolves.toEqual({ + visibility: 'archive', + ids: [assetToArchive.id], + }); + await thumbnailUtils.expectThumbnailIsArchive(page, assetToArchive.id); + await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.getByRole('link').getByText('Archive').click(); + await timelineUtils.waitForTimelineLoad(page); + await thumbnailUtils.expectInViewport(page, assetToArchive.id); + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + const unarchiveRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'timeline') { + return await route.continue(); + } + changes.assetArchivals = changes.assetArchivals.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Unarchive').click(); + await expect(unarchiveRequest).resolves.toEqual({ + visibility: 'timeline', + ids: [assetToArchive.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0); + await pageUtils.openAlbumPage(page, album.id); + await thumbnailUtils.expectInViewport(page, assetToArchive.id); + }); + }); + test.describe('/favorite', () => { + test('open /photos, favorite photo, open /favorites, remove favorite, open /photos', async ({ page }) => { + await pageUtils.openPhotosPage(page); + const assetToFavorite = assets[0]; + + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + const favorite = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + const isFavorite = requestJson.isFavorite; + if (isFavorite) { + changes.assetFavorites.push(...requestJson.ids); + } + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Favorite').click(); + await expect(favorite).resolves.toEqual({ + isFavorite: true, + ids: [assetToFavorite.id], + }); + // ensure thumbnail still exists and has favorite icon + await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id); + await page.getByRole('link').getByText('Favorites').click(); + await thumbnailUtils.expectInViewport(page, assetToFavorite.id); + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + const unFavoriteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + changes.assetFavorites = changes.assetFavorites.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Remove from favorites').click(); + await expect(unFavoriteRequest).resolves.toEqual({ + isFavorite: false, + ids: [assetToFavorite.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(0); + await page.getByText('Photos', { exact: true }).click(); + await thumbnailUtils.expectInViewport(page, assetToFavorite.id); + }); + test('open /favorites, archive photo, unarchive photo', async ({ page }) => { + await pageUtils.openFavorites(page); + const assetToArchive = getAsset(timelineRestData, 'ad31e29f-2069-4574-b9a9-ad86523c92cb')!; + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + await page.getByLabel('Menu').click(); + const archive = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'archive') { + return await route.continue(); + } + await route.fulfill({ + status: 204, + }); + changes.assetArchivals.push(...requestJson.ids); + }); + await page.getByRole('menuitem').getByText('Archive').click(); + await expect(archive).resolves.toEqual({ + visibility: 'archive', + ids: [assetToArchive.id], + }); + await page.getByRole('link').getByText('Archive').click(); + await thumbnailUtils.expectInViewport(page, assetToArchive.id); + await thumbnailUtils.expectThumbnailIsNotArchive(page, assetToArchive.id); + await thumbnailUtils.withAssetId(page, assetToArchive.id).hover(); + await thumbnailUtils.selectButton(page, assetToArchive.id).click(); + const unarchiveRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.visibility !== 'timeline') { + return await route.continue(); + } + changes.assetArchivals = changes.assetArchivals.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Unarchive').click(); + await expect(unarchiveRequest).resolves.toEqual({ + visibility: 'timeline', + ids: [assetToArchive.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0); + await thumbnailUtils.expectThumbnailIsNotArchive(page, assetToArchive.id); + }); + test('Open album, favorite photo, open /favorites, remove favorite, Open album', async ({ page }) => { + const album = timelineRestData.album; + await pageUtils.openAlbumPage(page, album.id); + const assetToFavorite = getAsset(timelineRestData, album.assetIds[0])!; + + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + const favorite = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + const isFavorite = requestJson.isFavorite; + if (isFavorite) { + changes.assetFavorites.push(...requestJson.ids); + } + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Favorite').click(); + await expect(favorite).resolves.toEqual({ + isFavorite: true, + ids: [assetToFavorite.id], + }); + // ensure thumbnail still exists and has favorite icon + await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id); + await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.getByRole('link').getByText('Favorites').click(); + await timelineUtils.waitForTimelineLoad(page); + await pageUtils.goToAsset(page, assetToFavorite.fileCreatedAt); + await thumbnailUtils.expectInViewport(page, assetToFavorite.id); + await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover(); + await thumbnailUtils.selectButton(page, assetToFavorite.id).click(); + const unFavoriteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => { + const requestJson = request.postDataJSON(); + if (requestJson.isFavorite === undefined) { + return await route.continue(); + } + changes.assetFavorites = changes.assetFavorites.filter((id) => !requestJson.ids.includes(id)); + await route.fulfill({ + status: 204, + }); + }); + await page.getByLabel('Remove from favorites').click(); + await expect(unFavoriteRequest).resolves.toEqual({ + isFavorite: false, + ids: [assetToFavorite.id], + }); + await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(0); + await pageUtils.openAlbumPage(page, album.id); + await thumbnailUtils.expectInViewport(page, assetToFavorite.id); + }); + }); +}); + +const getYearMonth = (assets: TimelineAssetConfig[], assetId: string) => { + const mockAsset = assets.find((mockAsset) => mockAsset.id === assetId)!; + const dateTime = DateTime.fromISO(mockAsset.fileCreatedAt!); + return dateTime.year + '-' + dateTime.month; +}; diff --git a/e2e/src/web/specs/timeline/utils.ts b/e2e/src/web/specs/timeline/utils.ts new file mode 100644 index 0000000000..0b49f02941 --- /dev/null +++ b/e2e/src/web/specs/timeline/utils.ts @@ -0,0 +1,238 @@ +import { BrowserContext, expect, Page } from '@playwright/test'; +import { DateTime } from 'luxon'; +import { TimelineAssetConfig } from 'src/generators/timeline'; + +export const sleep = (ms: number) => { + return new Promise((resolve) => setTimeout(resolve, ms)); +}; + +export const padYearMonth = (yearMonth: string) => { + const [year, month] = yearMonth.split('-'); + return `${year}-${month.padStart(2, '0')}`; +}; + +export async function throttlePage(context: BrowserContext, page: Page) { + const session = await context.newCDPSession(page); + await session.send('Network.emulateNetworkConditions', { + offline: false, + downloadThroughput: (1.5 * 1024 * 1024) / 8, + uploadThroughput: (750 * 1024) / 8, + latency: 40, + connectionType: 'cellular3g', + }); + await session.send('Emulation.setCPUThrottlingRate', { rate: 10 }); +} + +let activePollsAbortController = new AbortController(); + +export const cancelAllPollers = () => { + activePollsAbortController.abort(); + activePollsAbortController = new AbortController(); +}; + +export const poll = async ( + page: Page, + query: () => Promise, + callback?: (result: Awaited | undefined) => boolean, +) => { + let result; + const timeout = Date.now() + 10_000; + const signal = activePollsAbortController.signal; + + const terminate = callback || ((result: Awaited | undefined) => !!result); + while (!terminate(result) && Date.now() < timeout) { + if (signal.aborted) { + return; + } + try { + result = await query(); + } catch { + // ignore + } + if (signal.aborted) { + return; + } + if (page.isClosed()) { + return; + } + try { + await page.waitForTimeout(50); + } catch { + return; + } + } + if (!result) { + // rerun to trigger error if any + result = await query(); + } + return result; +}; + +export const thumbnailUtils = { + locator(page: Page) { + return page.locator('[data-thumbnail-focus-container]'); + }, + withAssetId(page: Page, assetId: string) { + return page.locator(`[data-thumbnail-focus-container][data-asset="${assetId}"]`); + }, + selectButton(page: Page, assetId: string) { + return page.locator(`[data-thumbnail-focus-container][data-asset="${assetId}"] button`); + }, + selectedAsset(page: Page) { + return page.locator('[data-thumbnail-focus-container]:has(button[aria-checked])'); + }, + async clickAssetId(page: Page, assetId: string) { + await thumbnailUtils.withAssetId(page, assetId).click(); + }, + async queryThumbnailInViewport(page: Page, collector: (assetId: string) => boolean) { + const assetIds: string[] = []; + for (const thumb of await this.locator(page).all()) { + const box = await thumb.boundingBox(); + if (box) { + const assetId = await thumb.evaluate((e) => e.dataset.asset); + if (collector?.(assetId!)) { + return [assetId!]; + } + assetIds.push(assetId!); + } + } + return assetIds; + }, + async getFirstInViewport(page: Page) { + return await poll(page, () => thumbnailUtils.queryThumbnailInViewport(page, () => true)); + }, + async getAllInViewport(page: Page, collector: (assetId: string) => boolean) { + return await poll(page, () => thumbnailUtils.queryThumbnailInViewport(page, collector)); + }, + async expectThumbnailIsFavorite(page: Page, assetId: string) { + await expect(thumbnailUtils.withAssetId(page, assetId).locator('[data-icon-favorite]')).toHaveCount(1); + }, + async expectThumbnailIsNotFavorite(page: Page, assetId: string) { + await expect(thumbnailUtils.withAssetId(page, assetId).locator('[data-icon-favorite]')).toHaveCount(0); + }, + async expectThumbnailIsArchive(page: Page, assetId: string) { + await expect(thumbnailUtils.withAssetId(page, assetId).locator('[data-icon-archive]')).toHaveCount(1); + }, + async expectThumbnailIsNotArchive(page: Page, assetId: string) { + await expect(thumbnailUtils.withAssetId(page, assetId).locator('[data-icon-archive]')).toHaveCount(0); + }, + async expectSelectedReadonly(page: Page, assetId: string) { + // todo - need a data attribute for selected + await expect( + page.locator( + `[data-thumbnail-focus-container][data-asset="${assetId}"] > .group.cursor-not-allowed > .rounded-xl`, + ), + ).toBeVisible(); + }, + async expectTimelineHasOnScreenAssets(page: Page) { + const first = await thumbnailUtils.getFirstInViewport(page); + if (page.isClosed()) { + return; + } + expect(first).toBeTruthy(); + }, + async expectInViewport(page: Page, assetId: string) { + const box = await poll(page, () => thumbnailUtils.withAssetId(page, assetId).boundingBox()); + if (page.isClosed()) { + return; + } + expect(box).toBeTruthy(); + }, + async expectBottomIsTimelineBottom(page: Page, assetId: string) { + const box = await thumbnailUtils.withAssetId(page, assetId).boundingBox(); + const gridBox = await timelineUtils.locator(page).boundingBox(); + if (page.isClosed()) { + return; + } + expect(box!.y + box!.height).toBeCloseTo(gridBox!.y + gridBox!.height, 0); + }, + async expectTopIsTimelineTop(page: Page, assetId: string) { + const box = await thumbnailUtils.withAssetId(page, assetId).boundingBox(); + const gridBox = await timelineUtils.locator(page).boundingBox(); + if (page.isClosed()) { + return; + } + expect(box!.y).toBeCloseTo(gridBox!.y, 0); + }, +}; +export const timelineUtils = { + locator(page: Page) { + return page.locator('#asset-grid'); + }, + async waitForTimelineLoad(page: Page) { + await expect(timelineUtils.locator(page)).toBeInViewport(); + await expect.poll(() => thumbnailUtils.locator(page).count()).toBeGreaterThan(0); + }, + async getScrollTop(page: Page) { + const queryTop = () => + page.evaluate(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return document.querySelector('#asset-grid').scrollTop; + }); + await expect.poll(queryTop).toBeGreaterThan(0); + return await queryTop(); + }, +}; + +export const assetViewerUtils = { + locator(page: Page) { + return page.locator('#immich-asset-viewer'); + }, + async waitForViewerLoad(page: Page, asset: TimelineAssetConfig) { + await page + .locator(`img[draggable="false"][src="/api/assets/${asset.id}/thumbnail?size=preview&c=${asset.thumbhash}"]`) + .or(page.locator(`video[poster="/api/assets/${asset.id}/thumbnail?size=preview&c=${asset.thumbhash}"]`)) + .waitFor(); + }, + async expectActiveAssetToBe(page: Page, assetId: string) { + const activeElement = () => + page.evaluate(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return document.activeElement?.dataset?.asset; + }); + await expect(poll(page, activeElement, (result) => result === assetId)).resolves.toBe(assetId); + }, +}; +export const pageUtils = { + async deepLinkPhotosPage(page: Page, assetId: string) { + await page.goto(`/photos?at=${assetId}`); + await timelineUtils.waitForTimelineLoad(page); + }, + async openPhotosPage(page: Page) { + await page.goto(`/photos`); + await timelineUtils.waitForTimelineLoad(page); + }, + async openFavorites(page: Page) { + await page.goto(`/favorites`); + await timelineUtils.waitForTimelineLoad(page); + }, + async openAlbumPage(page: Page, albumId: string) { + await page.goto(`/albums/${albumId}`); + await timelineUtils.waitForTimelineLoad(page); + }, + async openArchivePage(page: Page) { + await page.goto(`/archive`); + await timelineUtils.waitForTimelineLoad(page); + }, + async deepLinkAlbumPage(page: Page, albumId: string, assetId: string) { + await page.goto(`/albums/${albumId}?at=${assetId}`); + await timelineUtils.waitForTimelineLoad(page); + }, + async goToAsset(page: Page, assetDate: string) { + await timelineUtils.locator(page).hover(); + const stringDate = DateTime.fromISO(assetDate).toFormat('MMddyyyy,hh:mm:ss.SSSa'); + await page.keyboard.press('g'); + await page.locator('#datetime').pressSequentially(stringDate); + await page.getByText('Confirm').click(); + }, + async selectDay(page: Page, day: string) { + await page.getByTitle(day).hover(); + await page.locator('[data-group] .w-8').click(); + }, + async pauseTestDebug() { + console.log('NOTE: pausing test indefinately for debug'); + await new Promise(() => void 0); + }, +}; diff --git a/e2e/src/web/specs/user-admin.e2e-spec.ts b/e2e/src/web/specs/user-admin.e2e-spec.ts index 611a1b3dec..7a2cd77177 100644 --- a/e2e/src/web/specs/user-admin.e2e-spec.ts +++ b/e2e/src/web/specs/user-admin.e2e-spec.ts @@ -54,12 +54,16 @@ test.describe('User Administration', () => { await page.getByRole('button', { name: 'Edit' }).click(); await expect(page.getByLabel('Admin User')).not.toBeChecked(); - await page.getByText('Admin User').click(); + await page.getByLabel('Admin User').click(); await expect(page.getByLabel('Admin User')).toBeChecked(); await page.getByRole('button', { name: 'Confirm' }).click(); - const updated = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) }); - expect(updated.isAdmin).toBe(true); + await expect + .poll(async () => { + const userAdmin = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) }); + return userAdmin.isAdmin; + }) + .toBe(true); }); test('revoke admin access', async ({ context, page }) => { @@ -79,11 +83,15 @@ test.describe('User Administration', () => { await page.getByRole('button', { name: 'Edit' }).click(); await expect(page.getByLabel('Admin User')).toBeChecked(); - await page.getByText('Admin User').click(); + await page.getByLabel('Admin User').click(); await expect(page.getByLabel('Admin User')).not.toBeChecked(); await page.getByRole('button', { name: 'Confirm' }).click(); - const updated = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) }); - expect(updated.isAdmin).toBe(false); + await expect + .poll(async () => { + const userAdmin = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) }); + return userAdmin.isAdmin; + }) + .toBe(false); }); }); diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 341d2ba189..1c7388b6ec 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -9,7 +9,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, - "target": "es2022", + "target": "es2023", "sourceMap": true, "outDir": "./dist", "incremental": true, diff --git a/i18n/af.json b/i18n/af.json index 68e020b76e..9d61e72c04 100644 --- a/i18n/af.json +++ b/i18n/af.json @@ -17,7 +17,6 @@ "add_birthday": "Voeg 'n verjaarsdag by", "add_endpoint": "Voeg Koppelvlakpunt by", "add_exclusion_pattern": "Voeg uitsgluitingspatrone by", - "add_import_path": "Voeg invoerpad by", "add_location": "Voeg ligging by", "add_more_users": "Voeg meer gebruikers by", "add_partner": "Voeg vennoot by", @@ -101,7 +100,6 @@ "job_status": "Werkstatus", "library_created": "Biblioteek geskep: {library}", "library_deleted": "Biblioteek verwyder", - "library_import_path_description": "Spesifiseer 'n leer om in te neem. Hierdie leer, en al die sub leers, gaan deursoek word vir prente en videos.", "library_scanning": "Periodieke Soek", "library_scanning_description": "Stel periodieke deursoek van biblioteek in", "library_scanning_enable_description": "Aktiveer periodieke biblioteekskandering", diff --git a/i18n/ar.json b/i18n/ar.json index 229fa316f7..933ba67871 100644 --- a/i18n/ar.json +++ b/i18n/ar.json @@ -17,7 +17,6 @@ "add_birthday": "أضف تاريخ الميلاد", "add_endpoint": "اضف نقطة نهاية", "add_exclusion_pattern": "إضافة نمط إستثناء", - "add_import_path": "إضافة مسار الإستيراد", "add_location": "إضافة موقع", "add_more_users": "إضافة مستخدمين آخرين", "add_partner": "أضف شريكًا", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# فشلت}}", "library_created": "تم إنشاء المكتبة: {library}", "library_deleted": "تم حذف المكتبة", - "library_import_path_description": "حدد مجلدًا للاستيراد. سيتم فحص هذا المجلد، بما في ذلك المجلدات الفرعية، بحثًا عن الصور ومقاطع الفيديو.", "library_scanning": "المسح الدوري", "library_scanning_description": "إعداد مسح المكتبة الدوري", "library_scanning_enable_description": "تفعيل مسح المكتبة الدوري", @@ -154,6 +152,18 @@ "machine_learning_min_detection_score_description": "الحد الأدنى لنقطة الثقة لاكتشاف الوجه، تتراوح من 0 إلى 1. القيم الأقل ستكشف عن المزيد من الوجوه ولكن قد تؤدي إلى نتائج إيجابية خاطئة.", "machine_learning_min_recognized_faces": "الحد الأدنى لعدد الوجوه المتعرف عليها", "machine_learning_min_recognized_faces_description": "الحد الأدنى لعدد الوجوه المتعرف عليها لإنشاء شخص. زيادة هذا الرقم يجعل التعرف على الوجوه أكثر دقة على حساب زيادة احتمال عدم تعيين الوجه لشخص ما.", + "machine_learning_ocr": "التعرف البصري على الحروف", + "machine_learning_ocr_description": "استخدم التعلم الآلي للتعرف على النصوص في الصور", + "machine_learning_ocr_enabled": "تفعيل التعرف البصري على الحروف", + "machine_learning_ocr_enabled_description": "في حال تعطيل هذه الميزة، لن تخضع الصور لعملية التعرف على النصوص.", + "machine_learning_ocr_max_resolution": "أقصى دقة", + "machine_learning_ocr_max_resolution_description": "سيتم تغيير حجم المعاينات التي تتجاوز هذه الدقة مع الحفاظ على نسبة العرض إلى الارتفاع. القيم الأعلى توفر دقة أكبر، ولكنها تستغرق وقتًا أطول للمعالجة وتستهلك المزيد من الذاكرة.", + "machine_learning_ocr_min_detection_score": "الحد الأدنى لدرجة الكشف", + "machine_learning_ocr_min_detection_score_description": "لحد الأدنى لدرجة الثقة المطلوبة لاكتشاف النص، وتتراوح قيمتها من 0 إلى 1. ستؤدي القيم الأقل إلى اكتشاف المزيد من النصوص ولكنها قد تؤدي إلى نتائج إيجابية خاطئة.", + "machine_learning_ocr_min_recognition_score": "الحد الأدنى لدرجة التعرّف", + "machine_learning_ocr_min_score_recognition_description": "الحد الأدنى لدرجة الثقة المطلوبة للنصوص المكتشفة ليتم التعرف عليها، وتتراوح من 0 إلى 1. ستؤدي القيم الأقل إلى التعرف على المزيد من النصوص ولكنها قد تؤدي إلى نتائج إيجابية خاطئة.", + "machine_learning_ocr_model": "نموذج التعرف البصري على الحروف", + "machine_learning_ocr_model_description": "تتميز نماذج الخوادم بدقة أكبر من نماذج الأجهزة المحمولة، ولكنها تستغرق وقتًا أطول في المعالجة وتستهلك ذاكرة أكبر.", "machine_learning_settings": "إعدادات التعلم الآلي", "machine_learning_settings_description": "إدارة ميزات وإعدادات التعلم الآلي", "machine_learning_smart_search": "البحث الذكي", @@ -211,6 +221,8 @@ "notification_email_ignore_certificate_errors_description": "تجاهل أخطاء التحقق من صحة شهادة TLS (غير مستحسن)", "notification_email_password_description": "كلمة المرور المستخدمة للمصادقة مع خادم البريد الإلكتروني", "notification_email_port_description": "منفذ خادم البريد الإلكتروني (مثلاً 25، 465، أو 587)", + "notification_email_secure": "بروتوكول نقل البريد البسيط الآمن SMTPS", + "notification_email_secure_description": "استخدم بروتوكول SMTPS (بروتوكول SMTP عبر TLS)", "notification_email_sent_test_email_button": "إرسال بريد إلكتروني تجريبي وحفظ التعديلات", "notification_email_setting_description": "إعدادات إرسال إشعارات البريد الإلكتروني", "notification_email_test_email": "إرسال بريد تجريبي", @@ -243,6 +255,7 @@ "oauth_storage_quota_default_description": "الحصة بالجيجابايت التي سيتم استخدامها عندما لا يتم توفير مطالبة.", "oauth_timeout": "نفاذ وقت الطلب", "oauth_timeout_description": "نفاذ وقت الطلب بالميلي ثانية", + "ocr_job_description": "استخدم التعلم الآلي للتعرف على النصوص في الصور", "password_enable_description": "تسجيل الدخول باستخدام البريد الكتروني وكلمة المرور", "password_settings": "تسجيل الدخول بكلمة المرور", "password_settings_description": "إدارة تسجيل الدخول بكلمة المرور", @@ -402,11 +415,11 @@ "advanced_settings_prefer_remote_subtitle": "تكون بعض الأجهزة بطيئة للغاية في تحميل الصور المصغرة من الأصول المحلية. قم بتفعيل هذا الخيار لتحميل الصور البعيدة بدلاً من ذلك.", "advanced_settings_prefer_remote_title": "تفضل الصور البعيدة", "advanced_settings_proxy_headers_subtitle": "عرف عناوين الوكيل التي يستخدمها Immich لارسال كل طلب شبكي", - "advanced_settings_proxy_headers_title": "عناوين الوكيل", + "advanced_settings_proxy_headers_title": "عناوين الوكيل المخصصة [تجريبية]", "advanced_settings_readonly_mode_subtitle": "تتيح هذه الميزة وضع العرض فقط، حيث يمكن للمستخدم معاينة الصور فقط، بينما يتم تعطيل جميع الخيارات الأخرى مثل تحديد عدة صور، أو مشاركتها، أو بثها، أو حذفها. يمكن تفعيل/تعطيل وضع العرض فقط من خلال صورة المستخدم في الشاشة الرئيسية", "advanced_settings_readonly_mode_title": "وضع القراءة فقط", "advanced_settings_self_signed_ssl_subtitle": "تخطي التحقق من شهادة SSL لخادم النقطة النهائي. مكلوب للشهادات الموقعة ذاتيا.", - "advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا", + "advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا [تجريبية]", "advanced_settings_sync_remote_deletions_subtitle": "حذف او استعادة تلقائي للاصول على هذا الجهاز عند تنفيذ العملية على الويب", "advanced_settings_sync_remote_deletions_title": "مزامنة عمليات الحذف عن بعد [تجريبي]", "advanced_settings_tile_subtitle": "إعدادات المستخدم المتقدمة", @@ -466,10 +479,14 @@ "api_key_description": "سيتم عرض هذه القيمة مرة واحدة فقط. يرجى التأكد من نسخها قبل إغلاق النافذة.", "api_key_empty": "يجب ألا يكون اسم مفتاح API فارغًا", "api_keys": "مفاتيح API", + "app_architecture_variant": "متغير (الهندسة المعمارية)", "app_bar_signout_dialog_content": "هل أنت متأكد أنك تريد تسجيل الخروج؟", "app_bar_signout_dialog_ok": "نعم", "app_bar_signout_dialog_title": "خروج", + "app_download_links": "روابط تحميل التطبيق", "app_settings": "إعدادات التطبيق", + "app_stores": "متاجر التطبيقات", + "app_update_available": "تحديث التطبيق متاح", "appears_in": "يظهر في", "apply_count": "تطبيق ({count, number})", "archive": "الأرشيف", @@ -553,6 +570,7 @@ "backup_albums_sync": "مزامنة ألبومات النسخ الاحتياطي", "backup_all": "الجميع", "backup_background_service_backup_failed_message": "فشل في النسخ الاحتياطي للأصول. جارٍ إعادة المحاولة…", + "backup_background_service_complete_notification": "تم الانتهاء من النسخ الاحتياطي للأصول", "backup_background_service_connection_failed_message": "فشل في الاتصال بالخادم. جارٍ إعادة المحاولة…", "backup_background_service_current_upload_notification": "تحميل {filename}", "backup_background_service_default_notification": "التحقق من الأصول الجديدة…", @@ -662,6 +680,8 @@ "change_password_description": "هذه إما هي المرة الأولى التي تقوم فيها بتسجيل الدخول إلى النظام أو أنه تم تقديم طلب لتغيير كلمة المرور الخاصة بك. الرجاء إدخال كلمة المرور الجديدة أدناه.", "change_password_form_confirm_password": "تأكيد كلمة المرور", "change_password_form_description": "مرحبًا {name}،\n\nاما ان تكون هذه هي المرة الأولى التي تقوم فيها بالتسجيل في النظام أو تم تقديم طلب لتغيير كلمة المرور الخاصة بك. الرجاء إدخال كلمة المرور الجديدة أدناه.", + "change_password_form_log_out": "تسجيل الخروج من جميع الأجهزة الأخرى", + "change_password_form_log_out_description": "يُنصح بتسجيل الخروج من جميع الأجهزة الأخرى", "change_password_form_new_password": "كلمة المرور الجديدة", "change_password_form_password_mismatch": "كلمة المرور غير مطابقة", "change_password_form_reenter_new_password": "أعد إدخال كلمة مرور جديدة", @@ -689,7 +709,7 @@ "client_cert_invalid_msg": "ملف شهادة عميل غير صالحة او كلمة سر غير صحيحة", "client_cert_remove_msg": "تم ازالة شهادة العميل", "client_cert_subtitle": "يدعم صيغ PKCS12 (.p12, .pfx)فقط. استيراد/ازالة الشهادات متاح فقط قبل تسجيل الدخول", - "client_cert_title": "شهادة مستخدم SSL", + "client_cert_title": "شهادة مستخدم SSL [تجريبية]", "clockwise": "باتجاه عقارب الساعة", "close": "إغلاق", "collapse": "طي", @@ -739,6 +759,7 @@ "create": "انشاء", "create_album": "إنشاء ألبوم", "create_album_page_untitled": "بدون اسم", + "create_api_key": "إنشاء مفتاح API", "create_library": "إنشاء مكتبة", "create_link": "إنشاء رابط", "create_link_to_share": "إنشاء رابط للمشاركة", @@ -768,6 +789,7 @@ "daily_title_text_date_year": "E ، MMM DD ، yyyy", "dark": "معتم", "dark_theme": "تبديل المظهر الداكن", + "date": "تاريخ", "date_after": "التارخ بعد", "date_and_time": "التاريخ و الوقت", "date_before": "التاريخ قبل", @@ -870,8 +892,6 @@ "edit_description_prompt": "الرجاء اختيار وصف جديد:", "edit_exclusion_pattern": "تعديل نمط الاستبعاد", "edit_faces": "تعديل الوجوه", - "edit_import_path": "تعديل مسار الاستيراد", - "edit_import_paths": "تعديل مسارات الاستيراد", "edit_key": "تعديل المفتاح", "edit_link": "تغيير الرابط", "edit_location": "تعديل الموقع", @@ -943,7 +963,6 @@ "failed_to_stack_assets": "فشل في تكديس المحتويات", "failed_to_unstack_assets": "فشل في فصل المحتويات", "failed_to_update_notification_status": "فشل في تحديث حالة الإشعار", - "import_path_already_exists": "مسار الاستيراد هذا موجود مسبقًا.", "incorrect_email_or_password": "بريد أو كلمة مرور غير صحيحة", "paths_validation_failed": "فشل في التحقق من {paths, plural, one {# مسار} other {# مسارات}}", "profile_picture_transparent_pixels": "لا يمكن أن تحتوي صور الملف الشخصي على أجزاء/بكسلات شفافة. يرجى التكبير و/أو تحريك الصورة.", @@ -953,7 +972,6 @@ "unable_to_add_assets_to_shared_link": "تعذر إضافة المحتويات إلى الرابط المشترك", "unable_to_add_comment": "تعذر إضافة التعليق", "unable_to_add_exclusion_pattern": "تعذر إضافة نمط الإستبعاد", - "unable_to_add_import_path": "تعذر إضافة مسار الإستيراد", "unable_to_add_partners": "تعذر إضافة الشركاء", "unable_to_add_remove_archive": "تعذر {archived, select, true {إزالة المحتوى من} other {إضافة المحتوى إلى}} الأرشيف", "unable_to_add_remove_favorites": "تعذر {favorite, select, true {إضافة المحتوى إلى} other {إزالة المحتوى من}} المفضلة", @@ -976,12 +994,10 @@ "unable_to_delete_asset": "غير قادر على حذف المحتوى", "unable_to_delete_assets": "حدث خطأ أثناء حذف المحتويات", "unable_to_delete_exclusion_pattern": "غير قادر على حذف نمط الاستبعاد", - "unable_to_delete_import_path": "غير قادر على حذف مسار الاستيراد", "unable_to_delete_shared_link": "غير قادر على حذف الرابط المشترك", "unable_to_delete_user": "غير قادر على حذف المستخدم", "unable_to_download_files": "غير قادر على تنزيل الملفات", "unable_to_edit_exclusion_pattern": "غير قادر على تعديل نمط الاستبعاد", - "unable_to_edit_import_path": "غير قادر على تحرير مسار الاستيراد", "unable_to_empty_trash": "غير قادر على إفراغ سلة المهملات", "unable_to_enter_fullscreen": "غير قادر على الدخول إلى وضع ملء الشاشة", "unable_to_exit_fullscreen": "غير قادر على الخروج من وضع ملء الشاشة", @@ -1037,6 +1053,7 @@ "exif_bottom_sheet_description_error": "خطأ في تحديث الوصف", "exif_bottom_sheet_details": "تفاصيل", "exif_bottom_sheet_location": "موقع", + "exif_bottom_sheet_no_description": "لا يوجد وصف", "exif_bottom_sheet_people": "الناس", "exif_bottom_sheet_person_add_person": "اضف اسما", "exit_slideshow": "خروج من العرض التقديمي", @@ -1075,6 +1092,7 @@ "features_setting_description": "إدارة ميزات التطبيق", "file_name": "إسم الملف", "file_name_or_extension": "اسم الملف أو امتداده", + "file_size": "حجم الملف", "filename": "اسم الملف", "filetype": "نوع الملف", "filter": "تصفية", @@ -1114,7 +1132,7 @@ "hash_asset": "عمل Hash للأصل (للملف)", "hashed_assets": "أصول (ملفات) تم عمل Hash لها", "hashing": "يتم عمل Hash", - "header_settings_add_header_tip": "اضاف راس", + "header_settings_add_header_tip": "إضافة رأس الصفحة", "header_settings_field_validator_msg": "القيمة لا يمكن ان تكون فارغة", "header_settings_header_name_input": "اسم الرأس", "header_settings_header_value_input": "قيمة الرأس", @@ -1238,6 +1256,7 @@ "local_media_summary": "ملخص الملفات المحلية", "local_network": "شبكة محلية", "local_network_sheet_info": "سيتصل التطبيق بالخادم من خلال عنوان URL هذا عند استخدام شبكة Wi-Fi المحددة", + "location": "موقع", "location_permission": "اذن الموقع", "location_permission_content": "من أجل استخدام ميزة التبديل التلقائي، يحتاج Immich إلى إذن موقع دقيق حتى يتمكن من قراءة اسم شبكة Wi-Fi الحالية", "location_picker_choose_on_map": "اختر على الخريطة", @@ -1342,6 +1361,8 @@ "minute": "دقيقة", "minutes": "دقائق", "missing": "المفقودة", + "mobile_app": "تطبيق الجوال", + "mobile_app_download_onboarding_note": "قم بتنزيل التطبيق المصاحب للهاتف المحمول باستخدام الخيارات التالية", "model": "نموذج", "month": "شهر", "monthly_title_text_date_format": "ط ط ط", @@ -1360,6 +1381,8 @@ "my_albums": "ألبوماتي", "name": "الاسم", "name_or_nickname": "الاسم أو اللقب", + "navigate": "التنقل", + "navigate_to_time": "انتقل إلى الوقت", "network_requirement_photos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية للصور", "network_requirement_videos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية لمقاطع الفيديو", "network_requirements": "متطلبات الشبكة", @@ -1369,6 +1392,7 @@ "never": "أبداً", "new_album": "البوم جديد", "new_api_key": "مفتاح API جديد", + "new_date_range": "نطاق تاريخ جديد", "new_password": "كلمة المرور الجديدة", "new_person": "شخص جديد", "new_pin_code": "رمز PIN الجديد", @@ -1419,6 +1443,9 @@ "notifications": "إشعارات", "notifications_setting_description": "إدارة الإشعارات", "oauth": "OAuth", + "obtainium_configurator": "مُهيئ Obtainium", + "obtainium_configurator_instructions": "استخدم Obtainium لتثبيت تطبيق Android وتحديثه مباشرةً من صفحة إصدارات Immich على GitHub. أنشئ مفتاح API واختر الإصدار المناسب لإنشاء رابط تهيئة Obtainium الخاص بك", + "ocr": "التعرف البصري على الحروف", "official_immich_resources": "الموارد الرسمية لشركة Immich", "offline": "غير متصل", "offset": "ازاحة", @@ -1523,6 +1550,9 @@ "play_memories": "تشغيل الذكريات", "play_motion_photo": "تشغيل الصور المتحركة", "play_or_pause_video": "تشغيل الفيديو أو إيقافه مؤقتًا", + "play_original_video": "تشغيل الفيديو الأصلي", + "play_original_video_setting_description": "تفضيل تشغيل مقاطع الفيديو الأصلية بدلاً من مقاطع الفيديو المحولة. إذا لم يكن الملف الأصلي متوافقًا، فقد لا يتم تشغيله بشكل صحيح.", + "play_transcoded_video": "تشغيل الفيديو المُعاد ترميزه", "please_auth_to_access": "الرجاء القيام بالمصادقة للوصول", "port": "المنفذ", "preferences_settings_subtitle": "ادارة تفضيلات التطبيق", @@ -1659,6 +1689,7 @@ "reset_sqlite_confirmation": "هل أنت متأكد من رغبتك في إعادة ضبط قاعدة بيانات SQLite؟ ستحتاج إلى تسجيل الخروج ثم تسجيل الدخول مرة أخرى لإعادة مزامنة البيانات", "reset_sqlite_success": "تم إعادة تعيين قاعدة بيانات SQLite بنجاح", "reset_to_default": "إعادة التعيين إلى الافتراضي", + "resolution": "دقة", "resolve_duplicates": "معالجة النسخ المكررة", "resolved_all_duplicates": "تم حل جميع التكرارات", "restore": "الاستعاده من سلة المهملات", @@ -1677,6 +1708,7 @@ "running": "قيد التشغيل", "save": "حفظ", "save_to_gallery": "حفظ الى المعرض", + "saved": "تم الحفظ", "saved_api_key": "تم حفظ مفتاح الـ API", "saved_profile": "تم حفظ الملف", "saved_settings": "تم حفظ الإعدادات", @@ -1693,6 +1725,9 @@ "search_by_description_example": "يوم المشي لمسافات طويلة في سابا", "search_by_filename": "البحث بإسم الملف أو نوعه", "search_by_filename_example": "كـ IMG_1234.JPG أو PNG", + "search_by_ocr": "البحث عن طريق التعرف البصري على الحروف", + "search_by_ocr_example": "لاتيه", + "search_camera_lens_model": "بحث نموذج العدسة...", "search_camera_make": "البحث حسب الشركة المصنعة للكاميرا...", "search_camera_model": "البحث حسب موديل الكاميرا...", "search_city": "البحث حسب المدينة...", @@ -1709,6 +1744,7 @@ "search_filter_location_title": "اختر الموقع", "search_filter_media_type": "نوع الوسائط", "search_filter_media_type_title": "اختر نوع الوسائط", + "search_filter_ocr": "البحث عن طريق التعرف البصري على الحروف", "search_filter_people_title": "اختر الاشخاص", "search_for": "البحث عن", "search_for_existing_person": "البحث عن شخص موجود", @@ -1771,6 +1807,7 @@ "server_online": "الخادم متصل", "server_privacy": "خصوصية الخادم", "server_stats": "إحصائيات الخادم", + "server_update_available": "تحديث الخادم متاح", "server_version": "إصدار الخادم", "set": "‏تحديد", "set_as_album_cover": "تحديد كغلاف للألبوم", @@ -1799,6 +1836,8 @@ "setting_notifications_subtitle": "اضبط تفضيلات الإخطار", "setting_notifications_total_progress_subtitle": "التقدم التحميل العام (تم القيام به/إجمالي الأصول)", "setting_notifications_total_progress_title": "إظهار النسخ الاحتياطي الخلفية التقدم المحرز", + "setting_video_viewer_auto_play_subtitle": "بدء تشغيل مقاطع الفيديو تلقائيًا عند فتحها", + "setting_video_viewer_auto_play_title": "تشغيل الفيديوهات تلقائيًا", "setting_video_viewer_looping_title": "تكرار مقطع فيديو تلقائيًا", "setting_video_viewer_original_video_subtitle": "عند بث فيديو من الخادم، شغّل النسخة الأصلية حتى مع توفر ترميز بديل. قد يؤدي ذلك إلى تقطيع اثناء العرض . تُشغّل الفيديوهات المتوفرة محليًا بجودة أصلية بغض النظر عن هذا الإعداد.", "setting_video_viewer_original_video_title": "اجبار عرض الفديو الاصلي", @@ -1978,6 +2017,7 @@ "theme_setting_three_stage_loading_title": "تمكين تحميل ثلاث مراحل", "they_will_be_merged_together": "سيتم دمجهم معًا", "third_party_resources": "موارد الطرف الثالث", + "time": "وقت", "time_based_memories": "ذكريات استنادًا للوقت", "timeline": "الخط الزمني", "timezone": "المنطقة الزمنية", @@ -2010,6 +2050,7 @@ "troubleshoot": "استكشاف المشاكل", "type": "النوع", "unable_to_change_pin_code": "تفيير رمز PIN غير ممكن", + "unable_to_check_version": "تعذر التحقق من إصدار التطبيق أو الخادم", "unable_to_setup_pin_code": "انشاء رمز PIN غير ممكن", "unarchive": "أخرج من الأرشيف", "unarchive_action_prompt": "{count} ازيل من الارشيف", diff --git a/i18n/az.json b/i18n/az.json index 53e7f55db6..d08d76ed46 100644 --- a/i18n/az.json +++ b/i18n/az.json @@ -17,7 +17,6 @@ "add_birthday": "Doğum günü əlavə et", "add_endpoint": "Son nöqtə əlavə et", "add_exclusion_pattern": "Çıxarma nümunəsi əlavə et", - "add_import_path": "İdxal yolu əlavə et", "add_location": "Məkan əlavə et", "add_more_users": "Daha çox istifadəçi əlavə et", "add_partner": "Partnyor əlavə et", @@ -85,7 +84,6 @@ "jobs_failed": "{jobCount, plural, other {# uğursuz}}", "library_created": "{library} kitabxanası yaradıldı", "library_deleted": "Kitabxana silindi", - "library_import_path_description": "İdxal olunacaq qovluöu seçin. Bu qovluq, alt qovluqlar daxil olmaqla şəkil və videolar üçün skan ediləcəkdir.", "library_scanning": "Periodik skan", "library_scanning_description": "Periodik kitabxana skanını confiqurasiya et", "library_scanning_enable_description": "Periodik kitabxana skanını aktivləşdir", diff --git a/i18n/be.json b/i18n/be.json index a8bd54b400..3a871c6728 100644 --- a/i18n/be.json +++ b/i18n/be.json @@ -17,7 +17,6 @@ "add_birthday": "Дадаць дзень нараджэння", "add_endpoint": "Дадаць кропку доступу", "add_exclusion_pattern": "Дадаць шаблон выключэння", - "add_import_path": "Дадаць шлях імпарту", "add_location": "Дадайце месца", "add_more_users": "Дадаць больш карыстальнікаў", "add_partner": "Дадаць партнёра", @@ -318,8 +317,6 @@ "edit_description": "Рэдагаваць апісанне", "edit_description_prompt": "Выберыце новае апісанне:", "edit_faces": "Рэдагаваць твары", - "edit_import_path": "Рэдагаваць шлях імпарту", - "edit_import_paths": "Рэдагаваць шляхі імпарту", "edit_key": "Рэдагаваць ключ", "edit_link": "Рэдагаваць спасылку", "edit_location": "Рэдагаваць месцазнаходжанне", @@ -398,6 +395,8 @@ "partner_list_user_photos": "Фота карыстальніка {user}", "pause": "Прыпыніць", "people": "Людзі", + "permanent_deletion_warning": "Папярэджанне аб канчатковым выдаленні", + "permanent_deletion_warning_setting_description": "Паказаць папярэджанне пры канчатковым выдаленні рэсурсаў", "permission_onboarding_back": "Назад", "permission_onboarding_continue_anyway": "Усё адно працягнуць", "photos": "Фота", diff --git a/i18n/bg.json b/i18n/bg.json index a59cc4d67d..651917e1b0 100644 --- a/i18n/bg.json +++ b/i18n/bg.json @@ -17,7 +17,6 @@ "add_birthday": "Добави дата на раждане", "add_endpoint": "Добави крайна точка", "add_exclusion_pattern": "Добави модел за изключване", - "add_import_path": "Добави път за импортиране", "add_location": "Дoбави местоположение", "add_more_users": "Добави още потребители", "add_partner": "Добави партньор", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Сменете избора за {album}", "add_to_albums": "Добавяне в албуми", "add_to_albums_count": "Добавяне в албуми ({count})", + "add_to_bottom_bar": "Добави към", "add_to_shared_album": "Добави към споделен албум", "add_upload_to_stack": "Добави качените в група", "add_url": "Добави URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# неуспешни}}", "library_created": "Създадена библиотека: {library}", "library_deleted": "Библиотека е изтрита", - "library_import_path_description": "Посочете папка за импортиране. Тази папка, включително подпапките, ще бъдат сканирани за изображения и видеоклипове.", "library_scanning": "Периодично сканиране", "library_scanning_description": "Конфигурирай периодично сканиране на библиотеката", "library_scanning_enable_description": "Включване на периодичното сканиране на библиотеката", @@ -151,9 +150,21 @@ "machine_learning_max_recognition_distance": "Максимално разстояние за разпознаване", "machine_learning_max_recognition_distance_description": "Максимално разстояние между две лица, за да се считат за едно и също лице, в диапазона 0-2. Намаляването му може да предотврати определянето на две лица като едно и също лице, а увеличаването му може да предотврати определянето на едно и също лице като две различни лица. Имайте предвид, че е по-лесно да се слеят две лица, отколкото да се раздели едно лице на две, така че по възможност изберете по-ниска стойност.", "machine_learning_min_detection_score": "Минимална оценка за откриване", - "machine_learning_min_detection_score_description": "Минимална оценка на доверието, за да бъде считано лице като открито - от 0 до 1. По-ниските стойности ще открият повече лица, но може да доведат до фалшиви положителни резултати.", + "machine_learning_min_detection_score_description": "Минимална оценка на доверие, за да бъде считано лице като открито - от 0 до 1. По-ниските стойности ще открият повече лица, но може да доведат до фалшиви положителни резултати.", "machine_learning_min_recognized_faces": "Минимум разпознати лица", "machine_learning_min_recognized_faces_description": "Минималният брой разпознати лица, необходими за създаването на лице. Увеличаването му прави разпознаването на лица по-прецизно за сметка на увеличаването на вероятността дадено лице да не бъде причислено към лице.", + "machine_learning_ocr": "Разпознаване на текст", + "machine_learning_ocr_description": "Използвайте машинно обучение за разпознаване на текст в изображенията", + "machine_learning_ocr_enabled": "Включи разпознаване на текст", + "machine_learning_ocr_enabled_description": "Ако е забранено, няма да се прави разпознаване на текст в изображенията.", + "machine_learning_ocr_max_resolution": "Максимална резолюция", + "machine_learning_ocr_max_resolution_description": "Изображения с резолюция над зададената ще бъдат преоразмерени при запазване на пропорцията. Голяма стойност позволява по-прецизно разпознаване, но обработката използва повече време и повече памет.", + "machine_learning_ocr_min_detection_score": "Минимална оценка за откриванe", + "machine_learning_ocr_min_detection_score_description": "Минималната оценка на доверие за откриване на текст може да бъде между 0 и 1. По-ниска стойност ще открива повече текст, но може да доведе до грешни резултати.", + "machine_learning_ocr_min_recognition_score": "Минимална оценкa за откриване", + "machine_learning_ocr_min_score_recognition_description": "Минимална оценка на доверие, за да бъде считан текст като открит - от 0 до 1. По-ниските стойности ще открият повече текст, но може да доведат до фалшиви положителни резултати.", + "machine_learning_ocr_model": "Модел за разпознаване на текст", + "machine_learning_ocr_model_description": "Сървърните модели са по-точни от мобилните модели, но изискват повече време и използват повече памет.", "machine_learning_settings": "Настройки на машинното обучение", "machine_learning_settings_description": "Управление на функциите и настройките за машинно обучение", "machine_learning_smart_search": "Интелигентно Търсене", @@ -245,6 +256,7 @@ "oauth_storage_quota_default_description": "Квота в GiB, която да се използва, когато не е посочено друго.", "oauth_timeout": "Време на изчакване при заявка", "oauth_timeout_description": "Време за изчакване на отговор на заявка, в милисекунди", + "ocr_job_description": "Използване на машинно обучение за разпознаване на текст в изображенията", "password_enable_description": "Влизане с имейл и парола", "password_settings": "Вписване с парола", "password_settings_description": "Управление на настройките за влизане с парола", @@ -417,6 +429,7 @@ "age_months": "Възраст {months, plural, one {# месец} other {# месеци}}", "age_year_months": "Възраст 1 година, {months, plural, one {# месец} other {# месеци}}", "age_years": "{years, plural, other {Година #}}", + "album": "Албум", "album_added": "Албумът е добавен", "album_added_notification_setting_description": "Получавайте известие по имейл, когато бъдете добавени към споделен албум", "album_cover_updated": "Обложката на албума е актуализирана", @@ -462,6 +475,7 @@ "allow_edits": "Позволяване на редакции", "allow_public_user_to_download": "Позволете на публичен потребител да може да изтегля", "allow_public_user_to_upload": "Позволете на публичния потребител да може да качва", + "allowed": "Разрешено", "alt_text_qr_code": "Изображение на QR код", "anti_clockwise": "Обратно на часовниковата стрелка", "api_key": "API ключ", @@ -669,6 +683,8 @@ "change_password_description": "Това е или първият път, когато влизате в системата, или е направена заявка за промяна на паролата ви. Моля, въведете новата парола по-долу.", "change_password_form_confirm_password": "Потвърди паролата", "change_password_form_description": "Здравейте {name},\n\nТова или е първото ви вписване в системата или има подадена заявка за смяна на паролата. Моля, въведете нова парола в полето по-долу.", + "change_password_form_log_out": "Излизане от профила на всички други устройства", + "change_password_form_log_out_description": "Препоръчваме да се излезе от профила на всички други устройства", "change_password_form_new_password": "Нова парола", "change_password_form_password_mismatch": "Паролите не съвпадат", "change_password_form_reenter_new_password": "Повтори новата парола", @@ -776,6 +792,7 @@ "daily_title_text_date_year": "E, dd MMM yyyy", "dark": "Тъмен", "dark_theme": "Тъмна тема", + "date": "Дата", "date_after": "Дата след", "date_and_time": "Дата и час", "date_before": "Дата преди", @@ -878,8 +895,6 @@ "edit_description_prompt": "Моля, избери ново описание:", "edit_exclusion_pattern": "Редактиране на шаблон за изключване", "edit_faces": "Редактиране на лица", - "edit_import_path": "Редактиране на пътя за импортиране", - "edit_import_paths": "Редактиране на пътища за импортиране", "edit_key": "Редактиране на ключ", "edit_link": "Редактиране на линк", "edit_location": "Редактиране на местоположението", @@ -951,7 +966,6 @@ "failed_to_stack_assets": "Неуспешно подреждане на обекти", "failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти", "failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията", - "import_path_already_exists": "Този път за импортиране вече съществува.", "incorrect_email_or_password": "Неправилен имейл или парола", "paths_validation_failed": "{paths, plural, one {# път} other {# пътища}} не преминаха валидация", "profile_picture_transparent_pixels": "Профилните снимки не могат да имат прозрачни пиксели. Моля, увеличете и/или преместете изображението.", @@ -961,7 +975,6 @@ "unable_to_add_assets_to_shared_link": "Неуспешно добавяне на обекти в споделен линк", "unable_to_add_comment": "Неуспешно добавяне на коментар", "unable_to_add_exclusion_pattern": "Неуспешно добавяне на шаблон за изключение", - "unable_to_add_import_path": "Неуспешно добавяне на път за импортиране", "unable_to_add_partners": "Неуспешно добавяне на партньори", "unable_to_add_remove_archive": "Неуспешно {archived, select, true {премахване на обект от} other {добавяне на обект в}} архива", "unable_to_add_remove_favorites": "Неуспешно {favorite, select, true {добавяне на обект в} other {премахване на обект от}} любими", @@ -984,12 +997,10 @@ "unable_to_delete_asset": "Не може да изтрие файла", "unable_to_delete_assets": "Грешка при изтриване на файлове", "unable_to_delete_exclusion_pattern": "Не може да изтрие шаблон за изключване", - "unable_to_delete_import_path": "Пътят за импортиране не може да се изтрие", "unable_to_delete_shared_link": "Споделената връзка не може да се изтрие", "unable_to_delete_user": "Не може да изтрие потребител", "unable_to_download_files": "Не могат да се изтеглят файловете", "unable_to_edit_exclusion_pattern": "Не може да се редактира шаблон за изключване", - "unable_to_edit_import_path": "Пътят за импортиране не може да се редактира", "unable_to_empty_trash": "Неуспешно изпразване на кошчето", "unable_to_enter_fullscreen": "Не може да се отвори в цял екран", "unable_to_exit_fullscreen": "Не може да излезе от цял екран", @@ -1084,6 +1095,7 @@ "features_setting_description": "Управление на функциите на приложението", "file_name": "Име на файла", "file_name_or_extension": "Име на файл или разширение", + "file_size": "Размер на файла", "filename": "Име на файл", "filetype": "Тип на файл", "filter": "Филтър", @@ -1179,6 +1191,8 @@ "import_path": "Път за импортиране", "in_albums": "В {count, plural, one {# албум} other {# албума}}", "in_archive": "В архив", + "in_year": "{year} г.", + "in_year_selector": "През", "include_archived": "Включване на архивирани", "include_shared_albums": "Включване на споделени албуми", "include_shared_partner_assets": "Включване на споделените с партньор елементи", @@ -1215,6 +1229,7 @@ "language_setting_description": "Изберете предпочитан език", "large_files": "Големи файлове", "last": "Последен", + "last_months": "{count, plural, one {Последния месец} other {Последните # месеца}}", "last_seen": "Последно видяно", "latest_version": "Последна версия", "latitude": "Ширина", @@ -1247,6 +1262,7 @@ "local_media_summary": "Обобщение на локалните файлове", "local_network": "Локална мрежа", "local_network_sheet_info": "Приложението ще се свърже със сървъра на този URL, когато устройството е свързано към зададената Wi-Fi мрежа", + "location": "Място", "location_permission": "Разрешение за местоположение", "location_permission_content": "За да работи функцията автоматично превключване, Immich се нуждае от разрешение за точно местоположение, за да може да чете името на текущата Wi-Fi мрежа", "location_picker_choose_on_map": "Избери на карта", @@ -1296,6 +1312,10 @@ "main_menu": "Главно меню", "make": "Марка", "manage_geolocation": "Управление на местоположенията", + "manage_media_access_rationale": "Това разрешение е необходимо за правилно преместване на обекти в кошчето и за възстановяване от там.", + "manage_media_access_settings": "Отвори Настройки", + "manage_media_access_subtitle": "Разрешете приложението Immich да управлява и мести медийни файлове.", + "manage_media_access_title": "Управление на медийни файлове", "manage_shared_links": "Управление на споделени връзки", "manage_sharing_with_partners": "Управление на споделянето с партньори", "manage_the_app_settings": "Управление на настройките на приложението", @@ -1359,6 +1379,7 @@ "more": "Още", "move": "Премести", "move_off_locked_folder": "Извади от заключената папка", + "move_to": "Премести към", "move_to_lock_folder_action_prompt": "{count} са добавени в заключената папка", "move_to_locked_folder": "Премести в заключена папка", "move_to_locked_folder_confirmation": "Тези снимки и видеа ще бъдат изтрити от всички албуми и ще са достъпни само в заключената папка", @@ -1388,6 +1409,7 @@ "new_pin_code": "Нов PIN код", "new_pin_code_subtitle": "Това е първи достъп до заключена папка. Създайте PIN код за защитен достъп до тази страница", "new_timeline": "Нова времева линия", + "new_update": "Ново обновление", "new_user_created": "Създаден нов потребител", "new_version_available": "НАЛИЧНА НОВА ВЕРСИЯ", "newest_first": "Най-новите първи", @@ -1403,6 +1425,7 @@ "no_cast_devices_found": "Няма намерени устройства за предаване", "no_checksum_local": "Липсват контролни суми - не може да се получат локални обекти", "no_checksum_remote": "Липсват контролни суми - не може да се получат обекти от сървъра", + "no_devices": "Няма оторизирани устройства", "no_duplicates_found": "Не бяха открити дубликати.", "no_exif_info_available": "Няма exif информация", "no_explore_results_message": "Качете още снимки, за да разгледате колекцията си.", @@ -1419,6 +1442,7 @@ "no_results_description": "Опитайте със синоним или по-обща ключова дума", "no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си", "no_uploads_in_progress": "Няма качване в момента", + "not_allowed": "Не е разрешено", "not_available": "Неналично", "not_in_any_album": "Не е в никой албум", "not_selected": "Не е избрано", @@ -1435,6 +1459,7 @@ "oauth": "OAuth", "obtainium_configurator": "Конфигуратор за получаване", "obtainium_configurator_instructions": "Използвайте Obtainium за инсталация и обновяване на приложението за Android директно от GitHub на Immich. Създайте API ключ и изберете вариант за да създадете Obtainium конфигурационен линк", + "ocr": "Оптично разпознаване на текст", "official_immich_resources": "Официална информация за Immich", "offline": "Офлайн", "offset": "Отместване", @@ -1528,6 +1553,8 @@ "photos_count": "{count, plural, one {{count, number} Снимка} other {{count, number} Снимки}}", "photos_from_previous_years": "Снимки от предходни години", "pick_a_location": "Избери локация", + "pick_custom_range": "Произволен период", + "pick_date_range": "Изберете период", "pin_code_changed_successfully": "Успешно сменен PIN код", "pin_code_reset_successfully": "Успешно нулиран PIN код", "pin_code_setup_successfully": "Успешно зададен PIN код", @@ -1539,6 +1566,9 @@ "play_memories": "Възпроизвеждане на спомени", "play_motion_photo": "Възпроизведи Motion Photo", "play_or_pause_video": "Възпроизвеждане или пауза на видео", + "play_original_video": "Пусни оригиналното видео", + "play_original_video_setting_description": "Предпочитане на показване на оригиналното видео, вместо транскодирани. Ако формата на оригиналния файл не се поддържа, възпроизвеждането може да бъде неправилно.", + "play_transcoded_video": "Покажи транскодирано видео", "please_auth_to_access": "Моля, удостовери за достъп", "port": "Порт", "preferences_settings_subtitle": "Управление на предпочитанията на приложението", @@ -1675,6 +1705,7 @@ "reset_sqlite_confirmation": "Наистина ли искате да нулирате базата данни SQLite? Ще трябва да излезете от системата и да се впишете отново за нова синхронизация на данните", "reset_sqlite_success": "Успешно нулиране на базата данни SQLite", "reset_to_default": "Връщане на фабрични настройки", + "resolution": "Резолюция", "resolve_duplicates": "Реши дубликатите", "resolved_all_duplicates": "Всички дубликати са решени", "restore": "Възстановяване", @@ -1693,6 +1724,7 @@ "running": "Изпълняване", "save": "Запази", "save_to_gallery": "Запази в галерията", + "saved": "Записано", "saved_api_key": "Запазен API Key", "saved_profile": "Запазен профил", "saved_settings": "Запазени настройки", @@ -1709,6 +1741,9 @@ "search_by_description_example": "Разходка в Сапа", "search_by_filename": "Търси по име на файла или разширение", "search_by_filename_example": "например IMG_1234.JPG или PNG", + "search_by_ocr": "Търсене на текст", + "search_by_ocr_example": "Lattе", + "search_camera_lens_model": "Търсене на модел на обектива...", "search_camera_make": "Търси производител на камерата...", "search_camera_model": "Търси модел на камерата...", "search_city": "Търси град...", @@ -1725,6 +1760,7 @@ "search_filter_location_title": "Избери място", "search_filter_media_type": "Тип на файла", "search_filter_media_type_title": "Избери тип на файла", + "search_filter_ocr": "Търсене нa текст", "search_filter_people_title": "Избери хора", "search_for": "Търси за", "search_for_existing_person": "Търси съществуващ човек", @@ -1981,7 +2017,7 @@ "template": "Шаблон", "theme": "Тема", "theme_selection": "Избор на тема", - "theme_selection_description": "Автоматично задаване на светла или тъмна тема въз основа на системните предпочитания на вашия браузър", + "theme_selection_description": "Автоматично задаване на светла или тъмна тема спрямо системните предпочитания на браузъра ви", "theme_setting_asset_list_storage_indicator_title": "Показвай индикатор за хранилището в заглавията на обектите", "theme_setting_asset_list_tiles_per_row_title": "Брой обекти на ред ({count})", "theme_setting_colorful_interface_subtitle": "Нанеси основен цвят върху фоновите повърхности.", @@ -1997,7 +2033,9 @@ "theme_setting_three_stage_loading_title": "Включи три-степенно зареждане", "they_will_be_merged_together": "Те ще бъдат обединени", "third_party_resources": "Ресурси от трети страни", + "time": "Време", "time_based_memories": "Спомени, базирани на времето", + "time_based_memories_duration": "Продължителност в секунди за показване на всяка картина.", "timeline": "Хронология", "timezone": "Часова зона", "to_archive": "Архивирай", @@ -2138,6 +2176,7 @@ "welcome": "Добре дошли", "welcome_to_immich": "Добре дошли в Immich", "wifi_name": "Wi-Fi мрежа", + "workflow": "Работен процес", "wrong_pin_code": "Грешен PIN код", "year": "Година", "years_ago": "преди {years, plural, one {# година} other {# години}}", diff --git a/i18n/bi.json b/i18n/bi.json index 58c84f95d9..c5c9edbbb1 100644 --- a/i18n/bi.json +++ b/i18n/bi.json @@ -12,12 +12,28 @@ "add_a_name": "Putem nam blo hem", "add_a_title": "Putem wan name blo hem", "add_exclusion_pattern": "Putem wan paten wae hemi karem aot", - "add_import_path": "Putem wan pat blo import", "add_location": "Putem wan place blo hem", "add_more_users": "Putem mor man", "readonly_mode_enabled": "Mod blo yu no save janjem i on", "reassigned_assets_to_new_person": "Janjem{count, plural, one {# asset} other {# assets}} blo nu man", "reassing_hint": "janjem ol sumtin yu bin joos i go blo wan man", "recent-albums": "album i no old tu mas", - "recent_searches": "lukabout wea i no old tu mas" + "recent_searches": "lukabout wea i no old tu mas", + "time_based_memories_duration": "hao mus second blo wan wan imij i stap lo scrin.", + "timezone": "taemzon", + "to_change_password": "janjem pasword", + "to_login": "Login", + "to_multi_select": "to jusem mani", + "to_parent": "go lo parent", + "to_select": "to selectem", + "to_trash": "toti", + "toggle_settings": "sho settings", + "total": "Total", + "trash": "Toti", + "trash_action_prompt": "{count} igo lo plaes lo toti", + "trash_all": "Putem ol i go lo toti", + "trash_count": "Toti {count, number}", + "trash_emptied": "basket blo toti i empti nomo", + "trash_no_results_message": "Foto mo video lo basket blo toti yu save lukem lo plaes ia.", + "trash_page_delete_all": "Delete oli ol" } diff --git a/i18n/bn.json b/i18n/bn.json index 813aadea7e..0dd2f46726 100644 --- a/i18n/bn.json +++ b/i18n/bn.json @@ -17,7 +17,6 @@ "add_birthday": "একটি জন্মদিন যোগ করুন", "add_endpoint": "এন্ডপয়েন্ট যোগ করুন", "add_exclusion_pattern": "বহির্ভূতকরণ নমুনা", - "add_import_path": "ইমপোর্ট করার পাথ যুক্ত করুন", "add_location": "অবস্থান যুক্ত করুন", "add_more_users": "আরো ব্যবহারকারী যুক্ত করুন", "add_partner": "অংশীদার যোগ করুন", @@ -111,7 +110,6 @@ "jobs_failed": "{jobCount, plural, other {# ব্যর্থ}}", "library_created": "লাইব্রেরি তৈরি করা হয়েছেঃ {library}", "library_deleted": "লাইব্রেরি মুছে ফেলা হয়েছে", - "library_import_path_description": "ইম্পোর্ট/যোগ করার জন্য একটি ফোল্ডার নির্দিষ্ট করুন। সাবফোল্ডার সহ এই ফোল্ডারটি ছবি এবং ভিডিওর জন্য স্ক্যান করা হবে।", "library_scanning": "পর্যায়ক্রমিক স্ক্যানিং", "library_scanning_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং কনফিগার করুন", "library_scanning_enable_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং সক্ষম করুন", diff --git a/i18n/br.json b/i18n/br.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/br.json @@ -0,0 +1 @@ +{} diff --git a/i18n/ca.json b/i18n/ca.json index d35132d7c4..764bc3d024 100644 --- a/i18n/ca.json +++ b/i18n/ca.json @@ -17,7 +17,6 @@ "add_birthday": "Afegeix la data de naixement", "add_endpoint": "afegir endpoint", "add_exclusion_pattern": "Afegir un patró d'exclusió", - "add_import_path": "Afegir una ruta d'importació", "add_location": "Afegir la ubicació", "add_more_users": "Afegir més usuaris", "add_partner": "Afegir company/a", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Commutar selecció de {album}", "add_to_albums": "Afegir als àlbums", "add_to_albums_count": "Afegir als àlbums ({count})", + "add_to_bottom_bar": "Afegir a", "add_to_shared_album": "Afegir a un àlbum compartit", "add_upload_to_stack": "Afegeix la càrrega a la pila", "add_url": "Afegir URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# fallides}}", "library_created": "Bilbioteca creada: {library}", "library_deleted": "Bilbioteca eliminada", - "library_import_path_description": "Especifiqueu una carpeta a importar. Aquesta carpeta, incloses les seves subcarpetes, serà escanejada per cercar-hi imatges i vídeos.", "library_scanning": "Escaneig periòdic", "library_scanning_description": "Configurar l'escaneig periòdic de bilbioteques", "library_scanning_enable_description": "Habilita l'escaneig periòdic de biblioteques", @@ -154,6 +153,18 @@ "machine_learning_min_detection_score_description": "La puntuació mínima de confiança per detectar una cara és de 0 a 1. Valors més baixos detectaran més cares, però poden donar lloc a falsos positius.", "machine_learning_min_recognized_faces": "Nombre mínim de cares reconegudes", "machine_learning_min_recognized_faces_description": "El nombre mínim de cares reconegudes per crear una persona. Augmentar aquest valor fa que el reconeixement facial sigui més precís, però augmenta la possibilitat que una cara no sigui assignada a una persona.", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "Fes servir machine learning per reconèixer text a imatges", + "machine_learning_ocr_enabled": "Activar OCR", + "machine_learning_ocr_enabled_description": "Si està desactivat, les imatges no seran objecte de reconeixement de text.", + "machine_learning_ocr_max_resolution": "Màxima resolució", + "machine_learning_ocr_max_resolution_description": "Vista prèvia per sobre d'aquesta resolució serà reescalada per preservar la relació d'aspecte. Resolucions altes són més precises, però triguen més i gasten més memòria.", + "machine_learning_ocr_min_detection_score": "Puntuació mínima de detecció", + "machine_learning_ocr_min_detection_score_description": "Puntuació de mínima confiança per la detecció del text entre 0-1. Valors baixos detectaran més text pero pot donar falsos positius.", + "machine_learning_ocr_min_recognition_score": "Puntuació mínima de reconeixement", + "machine_learning_ocr_min_score_recognition_description": "Puntuació de confiança mínima pel reconeixement del text entre 0-1. Valors baixos reconeixen més text però pot donar falsos positius.", + "machine_learning_ocr_model": "Model OCR", + "machine_learning_ocr_model_description": "Models de servidor són més precisos que els de móbil, pero triguen més a processar i usen més memòria.", "machine_learning_settings": "Configuració d'aprenentatge automàtic", "machine_learning_settings_description": "Gestiona funcions i configuració d'aprenentatge automàtic", "machine_learning_smart_search": "Cerca intel·ligent", @@ -211,6 +222,8 @@ "notification_email_ignore_certificate_errors_description": "Ignora els errors de validació de certificat TLS (no recomanat)", "notification_email_password_description": "Contrasenya per a autenticar-se amb el servidor de correu electrònic", "notification_email_port_description": "Port del servidor de correu electrònic (p.ex. 25, 465 o 587)", + "notification_email_secure": "SMTPS", + "notification_email_secure_description": "Fes servir SMTPS (SMTP sobre TLS)", "notification_email_sent_test_email_button": "Envia correu de prova i desa", "notification_email_setting_description": "Configuració per l'enviament de notificacions per correu electrònic", "notification_email_test_email": "Envia correu de prova", @@ -243,6 +256,7 @@ "oauth_storage_quota_default_description": "Quota disponible en GB quan no s'estableixi cap valor (Entreu 0 per a quota il·limitada).", "oauth_timeout": "Solicitud caducada", "oauth_timeout_description": "Timeout per a sol·licituds en mil·lisegons", + "ocr_job_description": "Fes servir machine learning per reconèixer text a les imatges", "password_enable_description": "Inicia sessió amb correu electrònic i contrasenya", "password_settings": "Inici de sessió amb contrasenya", "password_settings_description": "Gestiona la configuració de l'inici de sessió amb contrasenya", @@ -402,11 +416,11 @@ "advanced_settings_prefer_remote_subtitle": "Alguns dispositius són molt lents en carregar miniatures dels elements locals. Activeu aquest paràmetre per carregar imatges remotes en el seu lloc.", "advanced_settings_prefer_remote_title": "Prefereix imatges remotes", "advanced_settings_proxy_headers_subtitle": "Definiu les capçaleres de proxy que Immich per enviar amb cada sol·licitud de xarxa", - "advanced_settings_proxy_headers_title": "Capçaleres de proxy", + "advanced_settings_proxy_headers_title": "Capçaleres de proxy particulars [EXPERIMENTAL]", "advanced_settings_readonly_mode_subtitle": "Habilita el només de lectura mode on les fotos poden ser només vist, a coses els agrada seleccionant imatges múltiples, compartint, càsting, elimina és tot discapacitat. Habilita/Desactiva només de lectura via avatar d'usuari des de la pantalla major", "advanced_settings_readonly_mode_title": "Mode de només lectura", "advanced_settings_self_signed_ssl_subtitle": "Omet la verificació del certificat SSL del servidor. Requerit per a certificats autosignats.", - "advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats", + "advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats [EXPERIMENTAL]", "advanced_settings_sync_remote_deletions_subtitle": "Suprimeix o restaura automàticament un actiu en aquest dispositiu quan es realitzi aquesta acció al web", "advanced_settings_sync_remote_deletions_title": "Sincronitza les eliminacions remotes", "advanced_settings_tile_subtitle": "Configuració avançada de l'usuari", @@ -415,6 +429,7 @@ "age_months": "{months, plural, one {# mes} other {# mesos}}", "age_year_months": "Un any i {months, plural, one {# mes} other {# mesos}}", "age_years": "{years, plural, one {# any} other {# anys}}", + "album": "Àlbum", "album_added": "Àlbum afegit", "album_added_notification_setting_description": "Rep una notificació per correu quan siguis afegit a un àlbum compartit", "album_cover_updated": "Portada de l'àlbum actualitzada", @@ -460,16 +475,21 @@ "allow_edits": "Permet editar", "allow_public_user_to_download": "Permet que l'usuari públic pugui descarregar", "allow_public_user_to_upload": "Permet que l'usuari públic pugui carregar", + "allowed": "Permès", "alt_text_qr_code": "Codi QR", "anti_clockwise": "En sentit antihorari", "api_key": "Clau API", "api_key_description": "Aquest valor només es mostrarà una vegada. Assegureu-vos de copiar-lo abans de tancar la finestra.", "api_key_empty": "El nom de la clau de l'API no pot estar buit", "api_keys": "Claus API", + "app_architecture_variant": "Variant (Arquitectura)", "app_bar_signout_dialog_content": "Estàs segur que vols tancar la sessió?", "app_bar_signout_dialog_ok": "Sí", "app_bar_signout_dialog_title": "Tanca la sessió", + "app_download_links": "App descarrega enllaços", "app_settings": "Configuració de l'app", + "app_stores": "Botiga App", + "app_update_available": "Actualització App disponible", "appears_in": "Apareix a", "apply_count": "Aplicar ({count, number})", "archive": "Arxiu", @@ -553,6 +573,7 @@ "backup_albums_sync": "Sincronització d'àlbums de còpia de seguretat", "backup_all": "Tots", "backup_background_service_backup_failed_message": "No s'ha pogut copiar els elements. Tornant a intentar…", + "backup_background_service_complete_notification": "Backup completat d'actius", "backup_background_service_connection_failed_message": "No s'ha pogut connectar al servidor. Tornant a intentar…", "backup_background_service_current_upload_notification": "Pujant {filename}", "backup_background_service_default_notification": "Cercant nous elements…", @@ -662,6 +683,8 @@ "change_password_description": "Aquesta és la primera vegada que inicieu la sessió al sistema o s'ha fet una sol·licitud per canviar la contrasenya. Introduïu la nova contrasenya a continuació.", "change_password_form_confirm_password": "Confirma la contrasenya", "change_password_form_description": "Hola {name},\n\nAquesta és la primera vegada que inicies sessió al sistema o bé s'ha sol·licitat canviar la teva contrasenya. Si us plau, introdueix la nova contrasenya a continuació.", + "change_password_form_log_out": "Fer fora de tots els altres dispositius", + "change_password_form_log_out_description": "Es recomana fer fora de tots els altres dispositius", "change_password_form_new_password": "Nova contrasenya", "change_password_form_password_mismatch": "Les contrasenyes no coincideixen", "change_password_form_reenter_new_password": "Torna a introduir la nova contrasenya", @@ -739,6 +762,7 @@ "create": "Crea", "create_album": "Crear un àlbum", "create_album_page_untitled": "Sense títol", + "create_api_key": "Crear clau API", "create_library": "Crea una llibreria", "create_link": "Crear enllaç", "create_link_to_share": "Crear enllaç per compartir", @@ -768,6 +792,7 @@ "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Fosc", "dark_theme": "Canviar a tema fosc", + "date": "Data", "date_after": "Data posterior a", "date_and_time": "Data i hora", "date_before": "Data anterior a", @@ -870,8 +895,6 @@ "edit_description_prompt": "Si us plau, selecciona una nova descripció:", "edit_exclusion_pattern": "Edita patró d'exclusió", "edit_faces": "Edita les cares", - "edit_import_path": "Edita la ruta d'importació", - "edit_import_paths": "Edita les rutes d'importació", "edit_key": "Edita clau", "edit_link": "Edita enllaç", "edit_location": "Edita ubicació", @@ -943,7 +966,6 @@ "failed_to_stack_assets": "No s'han pogut apilar els elements", "failed_to_unstack_assets": "No s'han pogut desapilar els elements", "failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions", - "import_path_already_exists": "Aquesta ruta d'importació ja existeix.", "incorrect_email_or_password": "Correu electrònic o contrasenya incorrectes", "paths_validation_failed": "{paths, plural, one {# ruta} other {# rutes}} no ha pogut validar", "profile_picture_transparent_pixels": "Les fotos de perfil no poden tenir píxels transparents. Per favor, feu zoom in, mogueu la imatge o ambdues.", @@ -953,7 +975,6 @@ "unable_to_add_assets_to_shared_link": "No s'han pogut afegir els elements a l'enllaç compartit", "unable_to_add_comment": "No es pot afegir el comentari", "unable_to_add_exclusion_pattern": "No s'ha pogut afegir el patró d’exclusió", - "unable_to_add_import_path": "No s'ha pogut afegir la ruta d'importació", "unable_to_add_partners": "No es poden afegir companys", "unable_to_add_remove_archive": "No s'ha pogut {archived, select, true {eliminar l'element de} other {afegir l'element a}} l'arxiu", "unable_to_add_remove_favorites": "No s'ha pogut {favorite, select, true {afegir l'element als} other {eliminar l'element dels}} preferits", @@ -976,12 +997,10 @@ "unable_to_delete_asset": "No es pot suprimir el recurs", "unable_to_delete_assets": "S'ha produït un error en suprimir recursos", "unable_to_delete_exclusion_pattern": "No es pot suprimir el patró d'exclusió", - "unable_to_delete_import_path": "No es pot suprimir la ruta d'importació", "unable_to_delete_shared_link": "No es pot suprimir l'enllaç compartit", "unable_to_delete_user": "No es pot eliminar l'usuari", "unable_to_download_files": "No es poden descarregar fitxers", "unable_to_edit_exclusion_pattern": "No es pot editar el patró d'exclusió", - "unable_to_edit_import_path": "No es pot editar la ruta d'importació", "unable_to_empty_trash": "No es pot buidar la paperera", "unable_to_enter_fullscreen": "No es pot entrar a la pantalla completa", "unable_to_exit_fullscreen": "No es pot sortir de la pantalla completa", @@ -1076,6 +1095,7 @@ "features_setting_description": "Administrar les funcions de l'aplicació", "file_name": "Nom de l'arxiu", "file_name_or_extension": "Nom de l'arxiu o extensió", + "file_size": "Mida del fitxer", "filename": "Nom del fitxer", "filetype": "Tipus d'arxiu", "filter": "Filtrar", @@ -1171,6 +1191,8 @@ "import_path": "Ruta d'importació", "in_albums": "A {count, plural, one {# àlbum} other {# àlbums}}", "in_archive": "En arxiu", + "in_year": "En {year}", + "in_year_selector": "En", "include_archived": "Incloure arxivats", "include_shared_albums": "Inclou àlbums compartits", "include_shared_partner_assets": "Incloure elements dels companys", @@ -1207,6 +1229,7 @@ "language_setting_description": "Seleccioneu el vostre idioma", "large_files": "Fitxers Grans", "last": "Últim", + "last_months": "{count, plural, one {Últim mes} other {Últims # mesos}}", "last_seen": "Vist per últim cop", "latest_version": "Última versió", "latitude": "Latitud", @@ -1239,6 +1262,7 @@ "local_media_summary": "Resum de Mitjans Locals", "local_network": "Xarxa local", "local_network_sheet_info": "L'aplicació es connectarà al servidor mitjançant aquest URL quan utilitzeu la xarxa Wi-Fi especificada", + "location": "Localització", "location_permission": "Permís d'ubicació", "location_permission_content": "Per utilitzar la funció de canvi automàtic, Immich necessita un permís d'ubicació precisa perquè pugui llegir el nom de la xarxa Wi-Fi actual", "location_picker_choose_on_map": "Escollir en el mapa", @@ -1288,6 +1312,10 @@ "main_menu": "Menú principal", "make": "Fabricant", "manage_geolocation": "Gestioneu la vostra ubicació", + "manage_media_access_rationale": "Aquest permís es necessari per a la correcta gestió dels actius que es mouen a la paperera i es restauren d'ella.", + "manage_media_access_settings": "Configuració oberta", + "manage_media_access_subtitle": "Permet a l'Immich gestionar i moure fitxers multimèdia.", + "manage_media_access_title": "Accés a la gestió de mitjans", "manage_shared_links": "Administrar enllaços compartits", "manage_sharing_with_partners": "Gestiona la compartició amb els companys", "manage_the_app_settings": "Gestioneu la configuració de l'aplicació", @@ -1344,12 +1372,14 @@ "minutes": "Minuts", "missing": "Restants", "mobile_app": "Aplicació mòbil", + "mobile_app_download_onboarding_note": "Descarregar la App de mòbil fent servir les seguents opcions", "model": "Model", "month": "Mes", "monthly_title_text_date_format": "MMMM y", "more": "Més", "move": "Moure", "move_off_locked_folder": "Moure fora de la carpeta bloquejada", + "move_to": "Moure a", "move_to_lock_folder_action_prompt": "{count} afegides a la carpeta protegida", "move_to_locked_folder": "Moure a la carpeta bloquejada", "move_to_locked_folder_confirmation": "Aquestes fotos i vídeos seran eliminades de tots els àlbums, i només podran ser vistes des de la carpeta bloquejada", @@ -1363,6 +1393,7 @@ "name": "Nom", "name_or_nickname": "Nom o sobrenom", "navigate": "Navegar", + "navigate_to_time": "Navegar a un punt en el temps", "network_requirement_photos_upload": "Fes servir dades mòbils per a còpies de seguretat de fotos", "network_requirement_videos_upload": "Fes servir dades mòbils per a còpies de seguretat de videos", "network_requirements": "Requeriments de Xarxa", @@ -1372,11 +1403,13 @@ "never": "Mai", "new_album": "Nou Àlbum", "new_api_key": "Nova clau de l'API", + "new_date_range": "Navegar a un reng de dates", "new_password": "Nova contrasenya", "new_person": "Persona nova", "new_pin_code": "Nou codi PIN", "new_pin_code_subtitle": "Aquesta és la primera vegada que accedeixes a la carpeta bloquejada. Crea una codi PIN i accedeix de manera segura a aquesta pàgina", "new_timeline": "Nova Línia de Temps", + "new_update": "Nova actualització", "new_user_created": "Nou usuari creat", "new_version_available": "NOVA VERSIÓ DISPONIBLE", "newest_first": "El més nou primer", @@ -1392,6 +1425,7 @@ "no_cast_devices_found": "No s'han trobat dispositius per transmetre", "no_checksum_local": "Cap checksum disponible - no s'han pogut carregar els recursos locals", "no_checksum_remote": "Cap checksum disponible - no s'ha pogut obtenir el recurs remot", + "no_devices": "No hi ha dispositius autoritzats", "no_duplicates_found": "No s'han trobat duplicats.", "no_exif_info_available": "No hi ha informació d'exif disponible", "no_explore_results_message": "Penja més fotos per explorar la teva col·lecció.", @@ -1408,6 +1442,7 @@ "no_results_description": "Proveu un sinònim o una paraula clau més general", "no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa", "no_uploads_in_progress": "Cap pujada en progrés", + "not_allowed": "No permès", "not_available": "N/A", "not_in_any_album": "En cap àlbum", "not_selected": "No seleccionat", @@ -1422,6 +1457,9 @@ "notifications": "Notificacions", "notifications_setting_description": "Gestiona les notificacions", "oauth": "OAuth", + "obtainium_configurator": "Configurador Obtainium", + "obtainium_configurator_instructions": "Utilitza Obtainium per instal·lar una actualització a la app directament des de Github-Immich. Crear una clau API i seleccionar una variant per crear un enllaç a la configuració Obtainium", + "ocr": "OCR", "official_immich_resources": "Recursos oficials d'Immich", "offline": "Fora de línia", "offset": "Diferència", @@ -1515,6 +1553,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos d'anys anteriors", "pick_a_location": "Triar una ubicació", + "pick_custom_range": "Rang personalitzat", + "pick_date_range": "Seleccioni un rang de dates", "pin_code_changed_successfully": "Codi PIN canviat correctament", "pin_code_reset_successfully": "S'ha restablert correctament el codi PIN", "pin_code_setup_successfully": "S'ha configurat correctament un codi PIN", @@ -1526,6 +1566,9 @@ "play_memories": "Reproduir records", "play_motion_photo": "Reproduir Fotos en Moviment", "play_or_pause_video": "Reproduir o posar en pausa el vídeo", + "play_original_video": "Veure el video original", + "play_original_video_setting_description": "Preferir la reproducció del video original sobre el video recodificat. Si el video original no es compatible potser no es reprodueixi correctament.", + "play_transcoded_video": "Veure el video recodificat", "please_auth_to_access": "Per favor, autentica't per accedir", "port": "Port", "preferences_settings_subtitle": "Gestiona les preferències de l'aplicació", @@ -1662,6 +1705,7 @@ "reset_sqlite_confirmation": "Segur que vols reiniciar la base de dades SQLite? Hauràs de tancar la sessió i tornar a accedir per a resincronitzar les dades", "reset_sqlite_success": "S'ha reiniciat la base de dades correctament", "reset_to_default": "Restableix els valors predeterminats", + "resolution": "Resolució", "resolve_duplicates": "Resoldre duplicats", "resolved_all_duplicates": "Tots els duplicats resolts", "restore": "Recupera", @@ -1680,6 +1724,7 @@ "running": "En execució", "save": "Desa", "save_to_gallery": "Desa a galeria", + "saved": "Guardat", "saved_api_key": "Clau d'API guardada", "saved_profile": "Perfil guardat", "saved_settings": "Configuració guardada", @@ -1696,6 +1741,9 @@ "search_by_description_example": "Jornada de senderisme a Sapa", "search_by_filename": "Cerca per nom de fitxer o extensió", "search_by_filename_example": "per exemple IMG_1234.JPG o PNG", + "search_by_ocr": "Buscar per OCR", + "search_by_ocr_example": "Després", + "search_camera_lens_model": "Buscar model de lents....", "search_camera_make": "Buscar per fabricant de càmara...", "search_camera_model": "Buscar per model de càmera...", "search_city": "Buscar per ciutat...", @@ -1712,6 +1760,7 @@ "search_filter_location_title": "Selecciona l'ubicació", "search_filter_media_type": "Tipus de multimèdia", "search_filter_media_type_title": "Selecciona tipus de multimèdia", + "search_filter_ocr": "Buscar per OCR", "search_filter_people_title": "Selecciona persones", "search_for": "Cercar", "search_for_existing_person": "Busca una persona existent", @@ -1984,7 +2033,9 @@ "theme_setting_three_stage_loading_title": "Activa la càrrega en tres etapes", "they_will_be_merged_together": "Es combinaran", "third_party_resources": "Recursos de tercers", + "time": "Temps", "time_based_memories": "Records basats en el temps", + "time_based_memories_duration": "Quants segons es mostrarà cada imatge.", "timeline": "Cronologia", "timezone": "Fus horari", "to_archive": "Arxivar", @@ -2125,6 +2176,7 @@ "welcome": "Benvingut", "welcome_to_immich": "Benvingut a immich", "wifi_name": "Nom Wi-Fi", + "workflow": "Flux de treball", "wrong_pin_code": "Codi PIN incorrecte", "year": "Any", "years_ago": "Fa {years, plural, one {# any} other {# anys}}", diff --git a/i18n/cs.json b/i18n/cs.json index 0f649dac9b..7205926696 100644 --- a/i18n/cs.json +++ b/i18n/cs.json @@ -17,7 +17,6 @@ "add_birthday": "Přidat datum narození", "add_endpoint": "Přidat koncový bod", "add_exclusion_pattern": "Přidat vzor vyloučení", - "add_import_path": "Přidat cestu importu", "add_location": "Přidat polohu", "add_more_users": "Přidat další uživatele", "add_partner": "Přidat partnera", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Přepnout výběr pro {album}", "add_to_albums": "Přidat do alb", "add_to_albums_count": "Přidat do alb ({count})", + "add_to_bottom_bar": "Přidat do", "add_to_shared_album": "Přidat do sdíleného alba", "add_upload_to_stack": "Přidat nahrané do zásobníku", "add_url": "Přidat URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, one {# neúspěšný} few {# neúspěšné} other {# neúspěšných}}", "library_created": "Vytvořena knihovna: {library}", "library_deleted": "Knihovna smazána", - "library_import_path_description": "Zadejte složku, kterou chcete importovat. Tato složka bude prohledána včetně podsložek a budou v ní hledány obrázky a videa.", + "library_details": "Podrobnosti o knihovně", + "library_folder_description": "Zadejte složku, kterou chcete importovat. Tato složka, včetně podsložek, bude prohledána pro obrázky a videa.", + "library_remove_exclusion_pattern_prompt": "Opravdu chcete odstranit tento vzor vyloučení?", + "library_remove_folder_prompt": "Opravdu chcete odstranit tuto složku importu?", "library_scanning": "Pravidelné prohledávání", "library_scanning_description": "Nastavení pravidelného prohledávání knihovny", "library_scanning_enable_description": "Povolit pravidelné prohledávání knihovny", "library_settings": "Externí knihovna", "library_settings_description": "Správa nastavení externí knihovny", "library_tasks_description": "Vyhledávání nových nebo změněných položek v externích knihovnách", + "library_updated": "Knihovna aktualizována", "library_watching_enable_description": "Sledovat změny souborů v externích knihovnách", "library_watching_settings": "Sledování knihovny [EXPERIMENTÁLNÍ]", "library_watching_settings_description": "Automatické sledování změněných souborů", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Povolit chytré vyhledávání", "machine_learning_smart_search_enabled_description": "Pokud je vypnuto, obrázky nebudou kódovány pro inteligentní vyhledávání.", "machine_learning_url_description": "URL serveru strojového učení. Pokud je zadáno více URL adres, budou jednotlivé servery zkoušeny postupně, dokud jeden z nich neodpoví úspěšně, a to v pořadí od prvního k poslednímu. Servery, které neodpoví, budou dočasně ignorovány, dokud nebudou opět online.", + "maintenance_settings": "Údržba", + "maintenance_settings_description": "Přepnout Immich do režimu údržby.", + "maintenance_start": "Zahájit režim údržby", + "maintenance_start_error": "Nepodařilo se zahájit režim údržby.", "manage_concurrency": "Správa souběžnosti", "manage_log_settings": "Správa nastavení protokolu", "map_dark_style": "Tmavý motiv", @@ -430,6 +438,7 @@ "age_months": "{months, plural, one {# měsíc} few {# měsíce} other {# měsíců}}", "age_year_months": "1 rok a {months, plural, one {# měsíc} few {# měsíce} other {# měsíců}}", "age_years": "{years, plural, one {# rok} few {# roky} other {# let}}", + "album": "Album", "album_added": "Přidáno album", "album_added_notification_setting_description": "Dostávat e-mailové oznámení, když jste přidáni do sdíleného alba", "album_cover_updated": "Obal alba aktualizován", @@ -475,6 +484,7 @@ "allow_edits": "Povolit úpravy", "allow_public_user_to_download": "Povolit veřejnosti stahovat", "allow_public_user_to_upload": "Povolit veřejnosti nahrávat", + "allowed": "Povoleno", "alt_text_qr_code": "Obrázek QR kódu", "anti_clockwise": "Proti směru hodinových ručiček", "api_key": "API klíč", @@ -894,8 +904,6 @@ "edit_description_prompt": "Vyberte nový popis:", "edit_exclusion_pattern": "Upravit vzor vyloučení", "edit_faces": "Upravit obličeje", - "edit_import_path": "Upravit cestu importu", - "edit_import_paths": "Úpravit importní cesty", "edit_key": "Upravit klíč", "edit_link": "Upravit odkaz", "edit_location": "Upravit polohu", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Nepodařilo se seskupit položky", "failed_to_unstack_assets": "Nepodařilo se zrušit seskupení položek", "failed_to_update_notification_status": "Nepodařilo se aktualizovat stav oznámení", - "import_path_already_exists": "Tato cesta importu již existuje.", "incorrect_email_or_password": "Nesprávný e-mail nebo heslo", + "library_folder_already_exists": "Tato importní cesta již existuje.", "paths_validation_failed": "{paths, plural, one {# cesta neprošla} few {# cesty neprošly} other {# cest neprošlo}} kontrolou", "profile_picture_transparent_pixels": "Profilové obrázky nemohou mít průhledné pixely. Obrázek si prosím zvětšete nebo posuňte.", "quota_higher_than_disk_size": "Nastavili jste kvótu vyšší, než je velikost disku", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Nelze přidat položky do sdíleného odkazu", "unable_to_add_comment": "Nelze přidat komentář", "unable_to_add_exclusion_pattern": "Nelze přidat vzor vyloučení", - "unable_to_add_import_path": "Nelze přidat cestu importu", "unable_to_add_partners": "Nelze přidat partnery", "unable_to_add_remove_archive": "Nelze {archived, select, true {odstranit položku z} other {přidat položku do}} archivu", "unable_to_add_remove_favorites": "Nelze {favorite, select, true {oblíbit položku} other {zrušit oblíbení položky}}", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Nelze odstranit položku", "unable_to_delete_assets": "Chyba při odstraňování položek", "unable_to_delete_exclusion_pattern": "Nelze odstranit vzor vyloučení", - "unable_to_delete_import_path": "Nelze odstranit cestu importu", "unable_to_delete_shared_link": "Nepodařilo se odstranit sdílený odkaz", "unable_to_delete_user": "Nelze odstranit uživatele", "unable_to_download_files": "Nelze stáhnout soubory", "unable_to_edit_exclusion_pattern": "Nelze upravit vzor vyloučení", - "unable_to_edit_import_path": "Nelze upravit cestu importu", "unable_to_empty_trash": "Nelze vyprázdnit koš", "unable_to_enter_fullscreen": "Nelze přejít do režimu celé obrazovky", "unable_to_exit_fullscreen": "Nelze ukončit zobrazení na celou obrazovku", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Nelze aktualizovat uživatele", "unable_to_upload_file": "Nepodařilo se nahrát soubor" }, + "exclusion_pattern": "Vzor vyloučení", "exif": "Exif", "exif_bottom_sheet_description": "Přidat popis...", "exif_bottom_sheet_description_error": "Chyba při aktualizaci popisu", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Procházení zobrazení složek s fotografiemi a videi v souborovém systému", "forgot_pin_code_question": "Zapomněli jste PIN?", "forward": "Dopředu", + "full_path": "Úplná cesta: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Tato funkce načítá externí zdroje z Googlu, aby mohla fungovat.", "general": "Obecné", @@ -1196,6 +1203,8 @@ "import_path": "Cesta importu", "in_albums": "{count, plural, one {V # albu} few {Ve # albech} other {V # albech}}", "in_archive": "V archivu", + "in_year": "V roce {year}", + "in_year_selector": "V roce", "include_archived": "Včetně archivovaných", "include_shared_albums": "Včetně sdílených alb", "include_shared_partner_assets": "Včetně sdílených položek partnera", @@ -1232,6 +1241,7 @@ "language_setting_description": "Vyberte upřednostňovaný jazyk", "large_files": "Velké soubory", "last": "Poslední", + "last_months": "{count, plural, one {Poslední měsíc} few {Poslední # měsíce} other {Posledních # měsíců}}", "last_seen": "Naposledy viděno", "latest_version": "Nejnovější verze", "latitude": "Zeměpisná šířka", @@ -1241,6 +1251,8 @@ "let_others_respond": "Nechte ostatní reagovat", "level": "Úroveň", "library": "Knihovna", + "library_add_folder": "Přidat složku", + "library_edit_folder": "Upravit složku", "library_options": "Možnosti knihovny", "library_page_device_albums": "Alba v zařízení", "library_page_new_album": "Nové album", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Povolit automatickou smyčku videa v prohlížeči.", "main_branch_warning": "Používáte vývojovou verzi; důrazně doporučujeme používat verzi z vydání!", "main_menu": "Hlavní nabídka", + "maintenance_description": "Immich byl přepnut do režimu údržby.", + "maintenance_end": "Ukončit režim údržby", + "maintenance_end_error": "Nepodařilo se ukončit režim údržby.", + "maintenance_logged_in_as": "Aktuálně přihlášen jako {user}", + "maintenance_title": "Dočasně nedostupné", "make": "Výrobce", "manage_geolocation": "Spravovat polohu", + "manage_media_access_rationale": "Toto oprávnění je vyžadováno pro správné zacházení s přesunem položek do koše a jejich obnovováním z něj.", + "manage_media_access_settings": "Otevřít nastavení", + "manage_media_access_subtitle": "Povolte aplikaci Immich spravovat a přesouvat soubory médií.", + "manage_media_access_title": "Přístup ke správě médií", "manage_shared_links": "Spravovat sdílené odkazy", "manage_sharing_with_partners": "Správa sdílení s partnery", "manage_the_app_settings": "Správa nastavení aplikace", @@ -1377,6 +1398,7 @@ "more": "Více", "move": "Přesunout", "move_off_locked_folder": "Přesunout z uzamčené složky", + "move_to": "Přesunout do", "move_to_lock_folder_action_prompt": "{count} přidaných do uzamčené složky", "move_to_locked_folder": "Přesunout do uzamčené složky", "move_to_locked_folder_confirmation": "Tyto fotky a videa budou odstraněny ze všech alb a bude je možné zobrazit pouze v uzamčené složce", @@ -1406,6 +1428,7 @@ "new_pin_code": "Nový PIN kód", "new_pin_code_subtitle": "Poprvé přistupujete k uzamčené složce. Vytvořte si kód PIN pro bezpečný přístup na tuto stránku", "new_timeline": "Nová časová osa", + "new_update": "Nová aktualizace", "new_user_created": "Vytvořen nový uživatel", "new_version_available": "NOVÁ VERZE K DISPOZICI", "newest_first": "Nejnovější první", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "Nebyla nalezena žádná zařízení", "no_checksum_local": "Není k dispozici kontrolní součet - nelze načíst místní položky", "no_checksum_remote": "Není k dispozici kontrolní součet - nelze načíst vzdálenou položku", + "no_devices": "Žádná autorizovaná zařízení", "no_duplicates_found": "Nebyly nalezeny žádné duplicity.", "no_exif_info_available": "Exif není k dispozici", "no_explore_results_message": "Nahrajte další fotografie a prozkoumejte svou sbírku.", "no_favorites_message": "Přidejte si oblíbené položky a rychle najděte své nejlepší obrázky a videa", "no_libraries_message": "Vytvořte si externí knihovnu pro zobrazení fotografií a videí", "no_local_assets_found": "Nebyly nalezeny žádné místní položky s tímto kontrolním součtem", + "no_location_set": "Není nastavena poloha", "no_locked_photos_message": "Fotky a videa v uzamčené složce jsou skryté a při procházení nebo vyhledávání v knihovně se nezobrazují.", "no_name": "Bez jména", "no_notifications": "Žádná oznámení", @@ -1437,6 +1462,7 @@ "no_results_description": "Zkuste použít synonymum nebo obecnější klíčové slovo", "no_shared_albums_message": "Vytvořte si album a sdílejte fotografie a videa s lidmi ve své síti", "no_uploads_in_progress": "Neprobíhá žádné nahrávání", + "not_allowed": "Nepovoleno", "not_available": "Není k dispozici", "not_in_any_album": "Bez alba", "not_selected": "Není vybráno", @@ -1451,8 +1477,8 @@ "notifications": "Oznámení", "notifications_setting_description": "Správa oznámení", "oauth": "OAuth", - "obtainium_configurator": "Obtainium konfigurátor", - "obtainium_configurator_instructions": "Pomocí Obtainia nainstalujte a aktualizujte aplikaci pro Android přímo z vydání na Immich GitHubu. Vytvořte API klíč a vyberte variantu pro vytvoření konfiguračního odkazu Obtainia", + "obtainium_configurator": "Konfigurátor Obtainium", + "obtainium_configurator_instructions": "Pomocí aplikace Obtainium nainstalujte a aktualizujte aplikaci pro Android přímo z vydání na GitHubu Immich. Vytvořte API klíč a vyberte variantu pro vytvoření konfiguračního odkazu pro Obtainium", "ocr": "OCR", "official_immich_resources": "Oficiální zdroje Immich", "offline": "Offline", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} fotka} few {{count, number} fotky} other {{count, number} fotek}}", "photos_from_previous_years": "Fotky z předchozích let", "pick_a_location": "Vyberte polohu", + "pick_custom_range": "Vlastní rozsah", + "pick_date_range": "Vyberte rozsah dat", "pin_code_changed_successfully": "PIN kód byl úspěšně změněn", "pin_code_reset_successfully": "PIN kód úspěšně resetován", "pin_code_setup_successfully": "PIN kód úspěšně nastaven", @@ -1814,6 +1842,8 @@ "server_offline": "Server offline", "server_online": "Server online", "server_privacy": "Ochrana soukromí serveru", + "server_restarting_description": "Tato stránka se za chvíli obnoví.", + "server_restarting_title": "Server se restartuje", "server_stats": "Statistiky serveru", "server_update_available": "K dispozici je aktualizace serveru", "server_version": "Verze serveru", @@ -2027,6 +2057,7 @@ "third_party_resources": "Zdroje třetích stran", "time": "Čas", "time_based_memories": "Časové vzpomínky", + "time_based_memories_duration": "Počet sekund k zobrazení každého obrázku.", "timeline": "Časová osa", "timezone": "Časové pásmo", "to_archive": "Archivovat", @@ -2167,6 +2198,7 @@ "welcome": "Vítejte", "welcome_to_immich": "Vítejte v Immichi", "wifi_name": "Název Wi-Fi", + "workflow": "Pracovní postup", "wrong_pin_code": "Chybný PIN kód", "year": "Rok", "years_ago": "Před {years, plural, one {rokem} other {# lety}}", diff --git a/i18n/cv.json b/i18n/cv.json index fe5bb3c2fc..0dde498d08 100644 --- a/i18n/cv.json +++ b/i18n/cv.json @@ -17,7 +17,6 @@ "add_birthday": "Ҫуралнӑ кун хушӑр", "add_endpoint": "Вӗҫӗмлӗ пӑнчӑ хушар", "add_exclusion_pattern": "Кӑларса пӑрахмалли йӗрке хуш", - "add_import_path": "Импорт ҫулне хуш", "add_location": "Вырӑн хуш", "add_more_users": "Усӑҫсем ытларах хуш", "add_partner": "Мӑшӑр хуш", diff --git a/i18n/da.json b/i18n/da.json index 5bb67dd83d..698951ca28 100644 --- a/i18n/da.json +++ b/i18n/da.json @@ -17,7 +17,6 @@ "add_birthday": "Tilføj en fødselsdag", "add_endpoint": "Tilføj endepunkt", "add_exclusion_pattern": "Tilføj udelukkelsesmønster", - "add_import_path": "Tilføj importsti", "add_location": "Tilføj placering", "add_more_users": "Tilføj flere brugere", "add_partner": "Tilføj partner", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Skift selektion for {album}", "add_to_albums": "Tilføj til albummer", "add_to_albums_count": "Tilføj til albummer({count})", + "add_to_bottom_bar": "Tilføj til", "add_to_shared_album": "Tilføj til delt album", "add_upload_to_stack": "Tilføj upload til stack", "add_url": "Tilføj URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, one {# fejlet} other {# fejlede}}", "library_created": "Skabte bibliotek: {library}", "library_deleted": "Bibliotek slettet", - "library_import_path_description": "Angiv en mappe, der skal importeres. Denne mappe, inklusive undermapper, vil blive scannet for billeder og videoer.", "library_scanning": "Periodisk scanning", "library_scanning_description": "Konfigurer periodisk biblioteksscanning", "library_scanning_enable_description": "Aktiver periodisk biblioteksscanning", @@ -173,6 +172,10 @@ "machine_learning_smart_search_enabled": "Aktiver smart søgning", "machine_learning_smart_search_enabled_description": "Hvis deaktiveret, vil billeder ikke blive kodet til smart søgning.", "machine_learning_url_description": "URL’en for maskinlæringsserveren. Hvis mere end én URL angives, vil hver server blive forsøgt én ad gangen, indtil en svarer succesfuldt, i rækkefølge fra første til sidste. Servere, der ikke svarer, vil midlertidigt blive ignoreret, indtil de kommer online igen.", + "maintenance_settings": "Vedligeholdelse", + "maintenance_settings_description": "Sæt Immich i vedligeholdelsestilstand.", + "maintenance_start": "Start vedligeholdelsestilstand", + "maintenance_start_error": "Vedligeholdelsestilstand kunne ikke startes.", "manage_concurrency": "Administrer antallet af samtidige opgaver", "manage_log_settings": "Administrer logindstillinger", "map_dark_style": "Mørk tema", @@ -301,7 +304,7 @@ "storage_template_settings_description": "Administrer mappestrukturen og filnavnet for den uploadede mediefil", "storage_template_user_label": "{label} er brugerens Lagringsmærkat", "system_settings": "Systemindstillinger", - "tag_cleanup_job": "\"Tag\" cleanup", + "tag_cleanup_job": "\"Tag\"-oprydning", "template_email_available_tags": "Du kan bruge følgende variabler i din skabelon: {tags}", "template_email_if_empty": "Hvis skabelonen er tom, vil standard-e-mailen blive brugt.", "template_email_invite_album": "Inviterings albumskabelon", @@ -377,11 +380,11 @@ "transcoding_two_pass_encoding_setting_description": "Transkoder af to omgange for at producere bedre indkodede videoer. Når den maksimale bitrate er slået til (som det kræver for at det fungerer med H.264 og HEVC), bruger denne tilstand en bitrateinterval baseret på den maksimale birate og ignorerer CRF. For VP9, kan CRF bruges hvis den maksimale bitrate er slået fra.", "transcoding_video_codec": "Videocodec", "transcoding_video_codec_description": "VP9 har en højere effektivitet og webkompatibilitet, men indkodningen tager længere tid. HEVC har lignende ydelse, men har lavere webkompatibilitet og er hurtig at transkode, men giver meget større filer. AV1 er det mest effektive codec, men mangler understøttelse på ældre enheder.", - "trash_enabled_description": "Aktivér skraldefunktioner", + "trash_enabled_description": "Aktivér \"Papirkurvs\"-funktioner", "trash_number_of_days": "Antal dage", - "trash_number_of_days_description": "Antal dage aktiver i skraldespanden skal beholdes inden de fjernes permanent", - "trash_settings": "Skraldeindstillinger", - "trash_settings_description": "Administrér skraldeindstillinger", + "trash_number_of_days_description": "Antal dage elementer i papirkurven skal beholdes inden de fjernes permanent", + "trash_settings": "Papirkurvs-indstillinger", + "trash_settings_description": "Administrér papirkurvs-indstillinger", "unlink_all_oauth_accounts": "Ophæv link til alle OAuth konti", "unlink_all_oauth_accounts_description": "Husk at fjerne linket til alle OAuth konti før du migrerer til en ny udbyder.", "unlink_all_oauth_accounts_prompt": "Er du sikker på, at du vil ophæve link til alle OAuth konti? Dette vil nulstille OAuth ID for hver bruger og kan ikke fortrydes.", @@ -430,6 +433,7 @@ "age_months": "Alder {months, plural, one {# måned} other {# måneder}}", "age_year_months": "Alder 1 år, {months, plural, one {# måned} other {# måneder}}", "age_years": "{years, plural, other {Alder #}}", + "album": "Album", "album_added": "Album tilføjet", "album_added_notification_setting_description": "Modtag en emailnotifikation når du bliver tilføjet til en delt album", "album_cover_updated": "Albumcover opdateret", @@ -475,6 +479,7 @@ "allow_edits": "Tillad redigeringer", "allow_public_user_to_download": "Tillad offentlige brugere til at hente", "allow_public_user_to_upload": "Tillad offentlige brugere til at uploade", + "allowed": "Tilladt", "alt_text_qr_code": "QR-kode billede", "anti_clockwise": "Mod uret", "api_key": "API-nøgle", @@ -522,7 +527,7 @@ "asset_offline_description": "Denne eksterne mediefil kan ikke længere findes på drevet. Kontakt venligst din Immich-administrator for hjælp.", "asset_restored_successfully": "Elementet blev gendannet succesfuldt", "asset_skipped": "Sprunget over", - "asset_skipped_in_trash": "I skraldespand", + "asset_skipped_in_trash": "I papirkurv", "asset_trashed": "Objekt kasseret", "asset_troubleshoot": "Fejlsøg på objekt", "asset_uploaded": "Uploadet", @@ -894,8 +899,6 @@ "edit_description_prompt": "Vælg venligst en ny beskrivelse:", "edit_exclusion_pattern": "Redigér udelukkelsesmønster", "edit_faces": "Redigér ansigter", - "edit_import_path": "Redigér import-sti", - "edit_import_paths": "Redigér import-stier", "edit_key": "Redigér nøgle", "edit_link": "Rediger link", "edit_location": "Rediger placering", @@ -967,7 +970,6 @@ "failed_to_stack_assets": "Det lykkedes ikke at stable mediefiler", "failed_to_unstack_assets": "Det lykkedes ikke at fjerne gruperingen af mediefiler", "failed_to_update_notification_status": "Kunne ikke uploade notifikations status", - "import_path_already_exists": "Denne importsti findes allerede.", "incorrect_email_or_password": "Forkert email eller kodeord", "paths_validation_failed": "{paths, plural, one {# sti} other {# stier}} slog fejl ved validering", "profile_picture_transparent_pixels": "Profilbilleder kan ikke have gennemsigtige pixels. Zoom venligst ind og/eller flyt billedet.", @@ -977,7 +979,6 @@ "unable_to_add_assets_to_shared_link": "Kan ikke tilføje mediefiler til det delte link", "unable_to_add_comment": "Ikke i stand til at tilføje kommentar", "unable_to_add_exclusion_pattern": "Kunne ikke tilføje udelukkelsesmønster", - "unable_to_add_import_path": "Kunne ikke tilføje importsti", "unable_to_add_partners": "Ikke i stand til at tilføje partnere", "unable_to_add_remove_archive": "Kan Ikke {archived, select, true {fjerne aktiv fra} other {tilføje aktiv til}} Arkiv", "unable_to_add_remove_favorites": "Kan ikke {favorite, select, true {tilføje aktiv til} other {fjerne aktiv fra}} favoritter", @@ -1000,13 +1001,11 @@ "unable_to_delete_asset": "Kan ikke slette mediefil", "unable_to_delete_assets": "Fejl i sletning af mediefiler", "unable_to_delete_exclusion_pattern": "Kunne ikke slette udelukkelsesmønster", - "unable_to_delete_import_path": "Kunne ikke slette importsti", "unable_to_delete_shared_link": "Kunne ikke slette delt link", "unable_to_delete_user": "Ikke i stand til at slette bruger", "unable_to_download_files": "Kan ikke downloade filer", "unable_to_edit_exclusion_pattern": "Kunne ikke redigere udelukkelsesmønster", - "unable_to_edit_import_path": "Kunne ikke redigere importsti", - "unable_to_empty_trash": "Ikke i stand til at tømme skraldespand", + "unable_to_empty_trash": "Ikke i stand til at tømme papirkurv", "unable_to_enter_fullscreen": "Kan ikke aktivere fuldskærmstilstand", "unable_to_exit_fullscreen": "Kan ikke forlade fuldskærmstilstand", "unable_to_get_comments_number": "Kan ikke få antallet af kommentarer", @@ -1031,7 +1030,7 @@ "unable_to_reset_pin_code": "Kunne ikke nulstille din PIN kode", "unable_to_resolve_duplicate": "Kunne ikke opklare duplikat", "unable_to_restore_assets": "Kunne ikke gendanne medierfil", - "unable_to_restore_trash": "Ikke i stand til at gendanne fra skraldespanden", + "unable_to_restore_trash": "Ikke i stand til at gendanne fra papirkurv", "unable_to_restore_user": "Ikke i stand til at gendanne bruger", "unable_to_save_album": "Ikke i stand til at gemme album", "unable_to_save_api_key": "Kunne ikke gemme API-nøgle", @@ -1196,6 +1195,8 @@ "import_path": "Import-sti", "in_albums": "I {count, plural, one {# album} other {# albummer}}", "in_archive": "I arkiv", + "in_year": "I {year}", + "in_year_selector": "I", "include_archived": "Inkluder arkiveret", "include_shared_albums": "Inkludér delte albummer", "include_shared_partner_assets": "Inkludér delte partnermedier", @@ -1232,6 +1233,7 @@ "language_setting_description": "Vælg dit foretrukne sprog", "large_files": "Store filer", "last": "Sidste", + "last_months": "{count, plural, one {Sidste måned} other {Sidste # måneder}}", "last_seen": "Sidst set", "latest_version": "Seneste version", "latitude": "Breddegrad", @@ -1312,8 +1314,17 @@ "loop_videos_description": "Aktivér for at genafspille videoer automatisk i detaljeret visning.", "main_branch_warning": "Du bruger en udviklingsversion; vi anbefaler kraftigt at bruge en udgivelsesversion!", "main_menu": "Hovedmenu", + "maintenance_description": "Immich er blevet sat i vedligeholdelsestilstand.", + "maintenance_end": "Afslut vedligeholdelsestilstand", + "maintenance_end_error": "Vedligeholdelsestilstand kunne ikke afsluttes.", + "maintenance_logged_in_as": "Aktuelt logget ind som {user}", + "maintenance_title": "Midlertidigt Utilgængelig", "make": "Producent", "manage_geolocation": "Administrer placering", + "manage_media_access_rationale": "Denne tilladelse er påkrævet for korrekt håndtering af flytning af elementer til papirkurven og gendannelse af dem fra den.", + "manage_media_access_settings": "Åben instillinger", + "manage_media_access_subtitle": "Tillad Immich appen at administrere og flytte mediefiler.", + "manage_media_access_title": "Mediestyringsadgang", "manage_shared_links": "Håndter delte links", "manage_sharing_with_partners": "Administrér deling med partnere", "manage_the_app_settings": "Administrer appindstillinger", @@ -1377,12 +1388,13 @@ "more": "Mere", "move": "Flyt", "move_off_locked_folder": "Flyt ud af låst mappe", + "move_to": "Flyt til", "move_to_lock_folder_action_prompt": "{count} føjet til den låste mappe", "move_to_locked_folder": "Flyt til låst mappe", "move_to_locked_folder_confirmation": "Disse billeder og videoer vil blive fjernet fra alle albums, og vil kun være synlig fra den låste mappe", "moved_to_archive": "Flyttede {count, plural, one {# mediefil} other {# mediefiler}} til arkivet", "moved_to_library": "Flyttede {count, plural, one {# mediefil} other {# mediefiler}} til biblioteket", - "moved_to_trash": "Flyttet til skraldespand", + "moved_to_trash": "Flyttet til papirkurv", "multiselect_grid_edit_date_time_err_read_only": "Kan ikke redigere datoen på skrivebeskyttet elementer. Springer over", "multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af skrivebeskyttet elementer. Springer over", "mute_memories": "Dæmp minder", @@ -1406,6 +1418,7 @@ "new_pin_code": "Ny PIN kode", "new_pin_code_subtitle": "Dette er første gang du tilgår den låste mappe. Lav en PIN kode for sikkert at tilgå denne side", "new_timeline": "Ny tidslinje", + "new_update": "Ny opdatering", "new_user_created": "Ny bruger oprettet", "new_version_available": "NY VERSION TILGÆNGELIG", "newest_first": "Nyeste først", @@ -1421,6 +1434,7 @@ "no_cast_devices_found": "Ingen Cast-enheder fundet", "no_checksum_local": "Ingen checksum tilgængelig – kan ikke hente lokale objekter", "no_checksum_remote": "Ingen checksum tilgængelig – kan ikke hente eksterne objekter", + "no_devices": "Ingen godkendte enheder", "no_duplicates_found": "Ingen duplikater fundet.", "no_exif_info_available": "Ingen tilgængelig exif information", "no_explore_results_message": "Upload flere billeder for at udforske din samling.", @@ -1437,6 +1451,7 @@ "no_results_description": "Prøv et synonym eller et mere generelt søgeord", "no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk", "no_uploads_in_progress": "Ingen upload i gang", + "not_allowed": "Ikke tilladt", "not_available": "ikke tilgængelig", "not_in_any_album": "Ikke i noget album", "not_selected": "Ikke valgt", @@ -1547,6 +1562,8 @@ "photos_count": "{count, plural, one {{count, number} Billede} other {{count, number} Billeder}}", "photos_from_previous_years": "Billeder fra tidligere år", "pick_a_location": "Vælg et sted", + "pick_custom_range": "Brugerdefineret periode", + "pick_date_range": "Vælg et datointerval", "pin_code_changed_successfully": "Ændring af PIN kode vellykket", "pin_code_reset_successfully": "Nulstilling af PIN kode vellykket", "pin_code_setup_successfully": "Opsætning af PIN kode vellykket", @@ -1718,7 +1735,7 @@ "save_to_gallery": "Gem til galleri", "saved": "Gemt", "saved_api_key": "Gemt API-nøgle", - "saved_profile": "Gemte profil", + "saved_profile": "Gemt profil", "saved_settings": "Gemte indstillinger", "say_something": "Skriv noget", "scaffold_body_error_occurred": "Der opstod en fejl", @@ -1734,7 +1751,7 @@ "search_by_filename": "Søg efter filnavn eller filtypenavn", "search_by_filename_example": "dvs. IMG_1234.JPG eller PNG", "search_by_ocr": "Søg via OCR", - "search_by_ocr_example": "Latte", + "search_by_ocr_example": "Søg efter tekst i dine billeder", "search_camera_lens_model": "Søg objektiv model...", "search_camera_make": "Søg efter kameraproducent...", "search_camera_model": "Søg efter kameramodel...", @@ -1763,7 +1780,7 @@ "search_options": "Søgemuligheder", "search_page_categories": "Kategorier", "search_page_motion_photos": "Bevægelsesbilleder", - "search_page_no_objects": "Ingen elementer er tilgængelige", + "search_page_no_objects": "Ingen elementinfomation er tilgængelig", "search_page_no_places": "Ingen placeringsinformation er tilgængelig", "search_page_screenshots": "Skærmbilleder", "search_page_search_photos_videos": "Søg i dine billeder og videoer", @@ -1814,6 +1831,8 @@ "server_offline": "Server offline", "server_online": "Server online", "server_privacy": "Serverens privatliv", + "server_restarting_description": "Denne side opdateres om et øjeblik.", + "server_restarting_title": "Serveren genstarter", "server_stats": "Serverstatus", "server_update_available": "Serveropdatering er tilgængelig", "server_version": "Server version", @@ -1843,10 +1862,10 @@ "setting_notifications_single_progress_title": "Vis detaljeret baggrundsuploadstatus", "setting_notifications_subtitle": "Tilpas dine notifikationspræferencer", "setting_notifications_total_progress_subtitle": "Samlet uploadstatus (færdige/samlet antal elementer)", - "setting_notifications_total_progress_title": "Vis samlet baggrundsuploadstatus", + "setting_notifications_total_progress_title": "Vis samlet baggrunds upload status", "setting_video_viewer_auto_play_subtitle": "Begynd automatisk at afspille videoer, når de åbnes", "setting_video_viewer_auto_play_title": "Automatisk afspilning af videoer", - "setting_video_viewer_looping_title": "Looper", + "setting_video_viewer_looping_title": "Genafspilning", "setting_video_viewer_original_video_subtitle": "Når der streames video fra serveren, afspil da den originale selv når en omkodet udgave er tilgængelig. Kan føre til buffering. Videoer, der er tilgængelige lokalt, afspilles i original kvalitet uanset denne indstilling.", "setting_video_viewer_original_video_title": "Tving original video", "settings": "Indstillinger", @@ -1902,7 +1921,7 @@ "shared_link_info_chip_metadata": "EXIF", "shared_link_manage_links": "Håndter delte links", "shared_link_options": "Muligheder for delt link", - "shared_link_password_description": "Kræv et kodeord for at få adgang til dette delte link", + "shared_link_password_description": "Kodeord krævet for at få adgang til dette delte link", "shared_links": "Delte links", "shared_links_description": "Del billeder og videoer med et link", "shared_photos_and_videos_count": "{assetCount, plural, other {# delte billeder & videoer.}}", @@ -1935,8 +1954,8 @@ "show_search_options": "Vis søgeindstillinger", "show_shared_links": "Vis delte links", "show_slideshow_transition": "Vis overgang til diasshow", - "show_supporter_badge": "Supportermærke", - "show_supporter_badge_description": "Vis et supportermærke", + "show_supporter_badge": "Supporter skilt", + "show_supporter_badge_description": "Vis et supporter ikon", "show_text_search_menu": "Vis tekstsøgningsmenu", "shuffle": "Bland", "sidebar": "Sidebjælke", @@ -1971,7 +1990,7 @@ "start_date_before_end_date": "Startdato skal ligge før slutdato", "state": "Stat", "status": "Status", - "stop_casting": "Stop støbning", + "stop_casting": "Stop casting", "stop_motion_photo": "Stopmotionbillede", "stop_photo_sharing": "Stop med at dele dine billeder?", "stop_photo_sharing_description": "{partner} vil ikke længere kunne tilgå dine billeder.", @@ -2027,17 +2046,18 @@ "third_party_resources": "Tredjepartsressourcer", "time": "Tid", "time_based_memories": "Tidsbaserede minder", + "time_based_memories_duration": "Antal sekunder, hvert billede skal vises.", "timeline": "Tidslinje", "timezone": "Tidszone", "to_archive": "Arkivér", "to_change_password": "Skift adgangskode", "to_favorite": "Gør til favorit", "to_login": "Login", - "to_multi_select": "For at vælge flere", - "to_parent": "Gå op", + "to_multi_select": "for at vælge flere", + "to_parent": "Gå et niveau op", "to_select": "for at vælge", "to_trash": "Papirkurv", - "toggle_settings": "Slå indstillinger til eller fra", + "toggle_settings": "Skift indstillinger", "total": "Total", "total_usage": "Samlet forbrug", "trash": "Papirkurv", @@ -2054,13 +2074,13 @@ "trash_page_restore_all": "Gendan alt", "trash_page_select_assets_btn": "Vælg elementer", "trash_page_title": "Papirkurv ({count})", - "trashed_items_will_be_permanently_deleted_after": "Mediefiler i skraldespanden vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.", + "trashed_items_will_be_permanently_deleted_after": "Mediefiler i papirkurven vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.", "troubleshoot": "Fejlfinding", "type": "Type", "unable_to_change_pin_code": "Kunne ikke ændre PIN kode", "unable_to_check_version": "Kan ikke tjekke app- eller serverversion", "unable_to_setup_pin_code": "Kunne ikke sætte PIN kode", - "unarchive": "Afakivér", + "unarchive": "Af Akivér", "unarchive_action_prompt": "{count} slettet fra Arkiv", "unarchived_count": "{count, plural, other {Uarkiveret #}}", "undo": "Fortryd", @@ -2167,6 +2187,7 @@ "welcome": "Velkommen", "welcome_to_immich": "Velkommen til Immich", "wifi_name": "Wi-Fi navn", + "workflow": "Arbejdsproces", "wrong_pin_code": "Forkert PIN kode", "year": "År", "years_ago": "{years, plural, one {# år} other {# år}} siden", diff --git a/i18n/de.json b/i18n/de.json index 0cae9c0762..fc6270b138 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -17,7 +17,6 @@ "add_birthday": "Geburtsdatum hinzufügen", "add_endpoint": "Endpunkt hinzufügen", "add_exclusion_pattern": "Ausschlussmuster hinzufügen", - "add_import_path": "Importpfad hinzufügen", "add_location": "Standort hinzufügen", "add_more_users": "Weitere Nutzer hinzufügen", "add_partner": "Partner hinzufügen", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# fehlgeschlagen}}", "library_created": "Bibliothek erstellt: {library}", "library_deleted": "Bibliothek gelöscht", - "library_import_path_description": "Gib einen Ordner für den Import an. Dieser Ordner, einschließlich der Unterordner, wird nach Bildern und Videos durchsucht.", "library_scanning": "Periodisches Scannen", "library_scanning_description": "Regelmäßiges Durchsuchen der Bibliothek einstellen", "library_scanning_enable_description": "Regelmäßiges Scannen der Bibliothek aktivieren", @@ -150,7 +148,7 @@ "machine_learning_max_detection_distance_description": "Maximaler Unterschied zwischen zwei Bildern, um sie als Duplikate zu betrachten, im Bereich von 0,001-0,1. Bei höheren Werten werden mehr Duplikate erkannt, aber es kann zu falsch-positiven Ergebnissen kommen.", "machine_learning_max_recognition_distance": "Maximaler Erkennungsabstand", "machine_learning_max_recognition_distance_description": "Maximaler Abstand zwischen zwei Gesichtern, die als dieselbe Person angesehen werden, von 0-2. Ein niedrigerer Wert kann verhindern, dass zwei Personen als dieselbe Person eingestuft werden, während ein höherer Wert verhindern kann, dass ein und dieselbe Person als zwei verschiedene Personen eingestuft wird. Bitte beachte dabei, dass es einfacher ist, zwei Personen zu verschmelzen, als eine Person in zwei zu teilen, also wähle nach Möglichkeit einen niedrigeren Schwellenwert.", - "machine_learning_min_detection_score": "Minimale Erkennungsrate", + "machine_learning_min_detection_score": "Mindest-Erkennungs Wert", "machine_learning_min_detection_score_description": "Minimale Konfidenzrate für die Erkennung eines Gesichts von 0-1. Bei niedrigeren Werten werden mehr Gesichter erkannt, aber es kann zu falsch-positiven Ergebnissen kommen.", "machine_learning_min_recognized_faces": "Mindestens erkannte Gesichter", "machine_learning_min_recognized_faces_description": "Die Mindestanzahl von erkannten Gesichtern, damit eine Person erstellt werden kann. Eine Erhöhung dieses Wertes macht die Gesichtserkennung präziser, erhöht aber die Wahrscheinlichkeit, dass ein Gesicht nicht zu einer Person zugeordnet wird.", @@ -162,7 +160,7 @@ "machine_learning_ocr_max_resolution_description": "Vorschauen über dieser Auflösung werden unter Beibehaltung des Seitenverhältnisses verkleinert. Höhere Werte sind genauer, benötigen jedoch mehr Zeit für die Verarbeitung und verbrauchen mehr Speicher.", "machine_learning_ocr_min_detection_score": "Minimaler Erkennungswert", "machine_learning_ocr_min_detection_score_description": "Minimale Konfidenzrate für die Texterkennung von 0–1. Niedrigere Werte führen dazu, dass mehr Text erkannt wird, können jedoch zu falsch-positiven Ergebnissen führen.", - "machine_learning_ocr_min_recognition_score": "Minimale Erkennungsrate", + "machine_learning_ocr_min_recognition_score": "Mindest-Erkennungswert", "machine_learning_ocr_min_score_recognition_description": "Minimale Konfidenzrate für die Erkennung von erkanntem Text von 0–1. Niedrigere Werte führen dazu, dass mehr Text erkannt wird, können jedoch zu falsch-positiven Ergebnissen führen.", "machine_learning_ocr_model": "OCR Modell", "machine_learning_ocr_model_description": "Server Modelle sind genauer als mobile Modelle, brauchen aber länger zur Verarbeitung und brauchen mehr Speicher.", @@ -475,6 +473,7 @@ "allow_edits": "Bearbeiten erlauben", "allow_public_user_to_download": "Erlaube öffentlichen Benutzern, herunterzuladen", "allow_public_user_to_upload": "Erlaube öffentlichen Benutzern, hochzuladen", + "allowed": "Erlaubt", "alt_text_qr_code": "QR-Code Bild", "anti_clockwise": "Gegen den Uhrzeigersinn", "api_key": "API-Schlüssel", @@ -894,8 +893,6 @@ "edit_description_prompt": "Bitte wähle eine neue Beschreibung:", "edit_exclusion_pattern": "Ausschlussmuster bearbeiten", "edit_faces": "Gesichter bearbeiten", - "edit_import_path": "Importpfad bearbeiten", - "edit_import_paths": "Importpfade bearbeiten", "edit_key": "Schlüssel bearbeiten", "edit_link": "Link bearbeiten", "edit_location": "Standort bearbeiten", @@ -967,7 +964,6 @@ "failed_to_stack_assets": "Dateien konnten nicht gestapelt werden", "failed_to_unstack_assets": "Dateien konnten nicht entstapelt werden", "failed_to_update_notification_status": "Benachrichtigungsstatus aktualisieren fehlgeschlagen", - "import_path_already_exists": "Dieser Importpfad existiert bereits.", "incorrect_email_or_password": "Ungültige E-Mail oder Passwort", "paths_validation_failed": "{paths, plural, one {# Pfad konnte} other {# Pfade konnten}} nicht validiert werden", "profile_picture_transparent_pixels": "Profilbilder dürfen keine transparenten Pixel haben. Bitte zoome heran und/oder verschiebe das Bild.", @@ -977,7 +973,6 @@ "unable_to_add_assets_to_shared_link": "Datei konnte nicht zum geteilten Link hinzugefügt werden", "unable_to_add_comment": "Es kann kein Kommentar hinzufügt werden", "unable_to_add_exclusion_pattern": "Ausschlussmuster konnte nicht hinzugefügt werden", - "unable_to_add_import_path": "Importpfad konnte nicht hinzugefügt werden", "unable_to_add_partners": "Es können keine Partner hinzufügt werden", "unable_to_add_remove_archive": "Datei konnte nicht {archived, select, true {aus dem Archiv entfernt} other {zum Archiv hinzugefügt}} werden", "unable_to_add_remove_favorites": "Datei konnte nicht {favorite, select, true {von den Favoriten entfernt} other {zu den Favoriten hinzugefügt}} werden", @@ -1000,12 +995,10 @@ "unable_to_delete_asset": "Datei konnte nicht gelöscht werden", "unable_to_delete_assets": "Fehler beim Löschen von Dateien", "unable_to_delete_exclusion_pattern": "Ausschlussmuster konnte nicht gelöscht werden", - "unable_to_delete_import_path": "Importpfad konnte nicht gelöscht werden", "unable_to_delete_shared_link": "Geteilter Link kann nicht gelöscht werden", "unable_to_delete_user": "Nutzer konnte nicht gelöscht werden", "unable_to_download_files": "Dateien konnten nicht heruntergeladen werden", "unable_to_edit_exclusion_pattern": "Ausschlussmuster konnte nicht bearbeitet werden", - "unable_to_edit_import_path": "Importpfad konnte nicht bearbeitet werden", "unable_to_empty_trash": "Papierkorb konnte nicht geleert werden", "unable_to_enter_fullscreen": "Vollbildmodus kann nicht aktiviert werden", "unable_to_exit_fullscreen": "Vollbildmodus kann nicht deaktiviert werden", @@ -1196,6 +1189,8 @@ "import_path": "Importpfad", "in_albums": "In {count, plural, one {# Album} other {# Alben}}", "in_archive": "Im Archiv", + "in_year": "Im Jahr {year}", + "in_year_selector": "Im Jahr", "include_archived": "Archivierte Dateien einbeziehen", "include_shared_albums": "Freigegebene Alben einbeziehen", "include_shared_partner_assets": "Geteilte Partner-Dateien mit einbeziehen", @@ -1232,6 +1227,7 @@ "language_setting_description": "Wähle deine bevorzugte Sprache", "large_files": "Große Dateien", "last": "Letzte", + "last_months": "{count, plural, one {Letzter Monat} other {Letzte # Monate}}", "last_seen": "Zuletzt gesehen", "latest_version": "Aktuelle Version", "latitude": "Breitengrad", @@ -1301,7 +1297,7 @@ "login_form_server_empty": "Serveradresse eingeben.", "login_form_server_error": "Es Konnte sich nicht mit dem Server verbunden werden.", "login_has_been_disabled": "Die Anmeldung wurde deaktiviert.", - "login_password_changed_error": "Fehler beim Ändern deines Passwort", + "login_password_changed_error": "Fehler beim Ändern deines Passwortes", "login_password_changed_success": "Passwort erfolgreich geändert", "logout_all_device_confirmation": "Bist du sicher, dass du alle Geräte abmelden willst?", "logout_this_device_confirmation": "Bist du sicher, dass du dieses Gerät abmelden willst?", @@ -1314,6 +1310,10 @@ "main_menu": "Hauptmenü", "make": "Marke", "manage_geolocation": "Standort verwalten", + "manage_media_access_rationale": "Diese Berechtigung wird benötigt, um Dateien ordnungsgemäß in den Papierkorb schieben und daraus wiederherstellen zu können.", + "manage_media_access_settings": "Einstellungen öffnen", + "manage_media_access_subtitle": "Erlaube Immich, Mediendateien zu verwalten und zu verschieben.", + "manage_media_access_title": "Verwaltung von Mediendateien", "manage_shared_links": "Freigegebene Links verwalten", "manage_sharing_with_partners": "Gemeinsame Nutzung mit Partnern verwalten", "manage_the_app_settings": "App-Einstellungen verwalten", @@ -1361,7 +1361,7 @@ "menu": "Menü", "merge": "Zusammenführen", "merge_people": "Personen zusammenführen", - "merge_people_limit": "Du kannst nur bis zu 5 Gesichter auf einmal zusammenführen", + "merge_people_limit": "Du kannst maximal 5 Gesichter auf einmal zusammenführen", "merge_people_prompt": "Willst du diese Personen zusammenführen? Diese Aktion kann nicht rückgängig gemacht werden.", "merge_people_successfully": "Personen erfolgreich zusammengeführt", "merged_people_count": "{count, plural, one {# Person} other {# Personen}} zusammengefügt", @@ -1377,6 +1377,7 @@ "more": "Mehr", "move": "Verschieben", "move_off_locked_folder": "Aus dem gesperrten Ordner verschieben", + "move_to": "Verschieben nach", "move_to_lock_folder_action_prompt": "{count} zum gesperrten Ordner hinzugefügt", "move_to_locked_folder": "In den gesperrten Ordner verschieben", "move_to_locked_folder_confirmation": "Diese Fotos und Videos werden aus allen Alben entfernt und können nur noch im gesperrten Ordner angezeigt werden", @@ -1406,6 +1407,7 @@ "new_pin_code": "Neuer PIN-Code", "new_pin_code_subtitle": "Dies ist dein erster Zugriff auf den gesperrten Ordner. Erstelle einen PIN-Code für den sicheren Zugriff auf diese Seite", "new_timeline": "Neue Zeitleiste", + "new_update": "Neues Update", "new_user_created": "Neuer Benutzer wurde erstellt", "new_version_available": "NEUE VERSION VERFÜGBAR", "newest_first": "Neueste zuerst", @@ -1421,6 +1423,7 @@ "no_cast_devices_found": "Keine Geräte zum Übertragen gefunden", "no_checksum_local": "Prüfsumme nicht verfügbar - kann lokale Datei/en nicht laden", "no_checksum_remote": "Prüfsumme nicht verfügbar - kann entfernte Datei/en nicht laden", + "no_devices": "Keine verwendeten Geräte", "no_duplicates_found": "Es wurden keine Duplikate gefunden.", "no_exif_info_available": "Keine EXIF-Informationen vorhanden", "no_explore_results_message": "Lade weitere Fotos hoch, um deine Sammlung zu erkunden.", @@ -1437,6 +1440,7 @@ "no_results_description": "Versuche es mit einem Synonym oder einem allgemeineren Stichwort", "no_shared_albums_message": "Erstelle ein Album, um Fotos und Videos mit Personen in deinem Netzwerk zu teilen", "no_uploads_in_progress": "Kein Upload in Bearbeitung", + "not_allowed": "Nicht erlaubt", "not_available": "N/A", "not_in_any_album": "In keinem Album", "not_selected": "Nicht ausgewählt", @@ -1547,6 +1551,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos von vorherigen Jahren", "pick_a_location": "Wähle einen Ort", + "pick_custom_range": "Benutzerdefinierter Zeitraum", + "pick_date_range": "Wähle einen Zeitraum", "pin_code_changed_successfully": "PIN-Code erfolgreich geändert", "pin_code_reset_successfully": "PIN-Code erfolgreich zurückgesetzt", "pin_code_setup_successfully": "PIN-Code erfolgreich festgelegt", @@ -2027,6 +2033,7 @@ "third_party_resources": "Drittanbieter-Quellen", "time": "Zeit", "time_based_memories": "Zeitbasierte Erinnerungen", + "time_based_memories_duration": "Anzahl der Sekunden, die jedes Bild angezeigt wird.", "timeline": "Zeitleiste", "timezone": "Zeitzone", "to_archive": "Archivieren", diff --git a/i18n/el.json b/i18n/el.json index 0ff48a02ba..ffe33c6d02 100644 --- a/i18n/el.json +++ b/i18n/el.json @@ -17,7 +17,6 @@ "add_birthday": "Προσθήκη γενεθλίων", "add_endpoint": "Προσθήκη τελικού σημείου", "add_exclusion_pattern": "Προσθήκη μοτίβου αποκλεισμού", - "add_import_path": "Προσθήκη μονοπατιού εισαγωγής", "add_location": "Προσθήκη τοποθεσίας", "add_more_users": "Προσθήκη επιπλέον χρηστών", "add_partner": "Προσθήκη συνεργάτη", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, one {# απέτυχε} other {# απέτυχαν}}", "library_created": "Δημιουργήθηκε η βιβλιοθήκη: {library}", "library_deleted": "Η βιβλιοθήκη διαγράφηκε", - "library_import_path_description": "Καθορίστε έναν φάκελο για εισαγωγή. Αυτός ο φάκελος, συμπεριλαμβανομένων των υποφακέλων του, θα σαρωθεί για εικόνες και βίντεο.", "library_scanning": "Περιοδική Σάρωση", "library_scanning_description": "Ρύθμιση περιοδικής σάρωσης βιβλιοθήκης", "library_scanning_enable_description": "Ενεργοποίηση περιοδικής σάρωσης βιβλιοθήκης", @@ -873,8 +871,6 @@ "edit_description_prompt": "Παρακαλώ επιλέξτε νέα περιγραφή:", "edit_exclusion_pattern": "Επεξεργασία μοτίβου αποκλεισμού", "edit_faces": "Επεξεργασία προσώπων", - "edit_import_path": "Επεξεργασία διαδρομής εισαγωγής", - "edit_import_paths": "Επεξεργασία Διαδρομών Εισαγωγής", "edit_key": "Επεξεργασία κλειδιού", "edit_link": "Επεξεργασία συνδέσμου", "edit_location": "Επεξεργασία τοποθεσίας", @@ -946,7 +942,6 @@ "failed_to_stack_assets": "Αποτυχία στην συμπίεση των στοιχείων", "failed_to_unstack_assets": "Αποτυχία στην αποσυμπίεση των στοιχείων", "failed_to_update_notification_status": "Αποτυχία ενημέρωσης της κατάστασης ειδοποίησης", - "import_path_already_exists": "Αυτή η διαδρομή εισαγωγής υπάρχει ήδη.", "incorrect_email_or_password": "Λανθασμένο email ή κωδικός πρόσβασης", "paths_validation_failed": "{paths, plural, one {# διαδρομή} other {# διαδρομές}} απέτυχαν κατά την επικύρωση", "profile_picture_transparent_pixels": "Οι εικόνες προφίλ δεν μπορούν να έχουν διαφανή εικονοστοιχεία. Παρακαλώ μεγεθύνετε ή/και μετακινήστε την εικόνα.", @@ -956,7 +951,6 @@ "unable_to_add_assets_to_shared_link": "Αδυναμία προσθήκης στοιχείου στον κοινόχρηστο σύνδεσμο", "unable_to_add_comment": "Αδυναμία προσθήκης σχολίου", "unable_to_add_exclusion_pattern": "Αδυναμία προσθήκης μοτίβου αποκλεισμού", - "unable_to_add_import_path": "Αδυναμία προσθήκης διαδρομής εισαγωγής", "unable_to_add_partners": "Αδυναμία προσθήκης συνεργατών", "unable_to_add_remove_archive": "Αδυναμία {archived, select, true {αφαίρεσης του στοιχείου από το} other {προσθήκης του στοιχείου στο}} αρχείο", "unable_to_add_remove_favorites": "Αδυναμία {favorite, select, true {προσθήκης του στοιχείου στα} other {αφαίρεσης του στοιχείου από τα}} αγαπημένα", @@ -979,12 +973,10 @@ "unable_to_delete_asset": "Αδυναμία διαγραφής στοιχείου", "unable_to_delete_assets": "Σφάλμα κατα τη διαγραφή στοιχείων", "unable_to_delete_exclusion_pattern": "Αδυναμία διαγραφής μοτίβου αποκλεισμού", - "unable_to_delete_import_path": "Αδυναμία διαγραφής διαδρομής εισαγωγής", "unable_to_delete_shared_link": "Αδυναμία διαγραφής κοινόχρηστου συνδέσμου", "unable_to_delete_user": "Αδυναμία διαγραφής χρήστη", "unable_to_download_files": "Αδυναμία λήψης αρχείων", "unable_to_edit_exclusion_pattern": "Αδυναμία επεξεργασίας μοτίβου αποκλεισμού", - "unable_to_edit_import_path": "Αδυναμία επεξεργασίας διαδρομής εισαγωγής", "unable_to_empty_trash": "Αδυναμία αδειάσματος του κάδου απορριμμάτων", "unable_to_enter_fullscreen": "Αδυναμία μετάβασης σε πλήρη οθόνη", "unable_to_exit_fullscreen": "Αδυναμία εξόδου από πλήρη οθόνη", diff --git a/i18n/en.json b/i18n/en.json index c64f940ff8..8ec590ec61 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -7,6 +7,7 @@ "action_common_update": "Update", "actions": "Actions", "active": "Active", + "active_count": "Active: {count}", "activity": "Activity", "activity_changed": "Activity is {enabled, select, true {enabled} other {disabled}}", "add": "Add", @@ -17,7 +18,6 @@ "add_birthday": "Add a birthday", "add_endpoint": "Add endpoint", "add_exclusion_pattern": "Add exclusion pattern", - "add_import_path": "Add import path", "add_location": "Add location", "add_more_users": "Add more users", "add_partner": "Add partner", @@ -68,6 +68,7 @@ "confirm_reprocess_all_faces": "Are you sure you want to reprocess all faces? This will also clear named people.", "confirm_user_password_reset": "Are you sure you want to reset {user}'s password?", "confirm_user_pin_code_reset": "Are you sure you want to reset {user}'s PIN code?", + "copy_config_to_clipboard_description": "Copy the current system config as a JSON object to the clipboard", "create_job": "Create job", "cron_expression": "Cron expression", "cron_expression_description": "Set the scanning interval using the cron format. For more information please refer to e.g. Crontab Guru", @@ -75,6 +76,8 @@ "disable_login": "Disable login", "duplicate_detection_job_description": "Run machine learning on assets to detect similar images. Relies on Smart Search", "exclusion_pattern_description": "Exclusion patterns lets you ignore files and folders when scanning your library. This is useful if you have folders that contain files you don't want to import, such as RAW files.", + "export_config_as_json_description": "Download the current system config as a JSON file", + "external_libraries_page_description": "Admin external library page", "external_library_management": "External Library Management", "face_detection": "Face detection", "face_detection_description": "Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. \"Refresh\" (re-)processes all assets. \"Reset\" additionally clears all current face data. \"Missing\" queues assets that haven't been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.", @@ -103,23 +106,28 @@ "image_thumbnail_description": "Small thumbnail with stripped metadata, used when viewing groups of photos like the main timeline", "image_thumbnail_quality_description": "Thumbnail quality from 1-100. Higher is better, but produces larger files and can reduce app responsiveness.", "image_thumbnail_title": "Thumbnail Settings", + "import_config_from_json_description": "Import system config by uploading a JSON config file", "job_concurrency": "{job} concurrency", "job_created": "Job created", "job_not_concurrency_safe": "This job is not concurrency-safe.", "job_settings": "Job Settings", "job_settings_description": "Manage job concurrency", - "job_status": "Job Status", "jobs_delayed": "{jobCount, plural, other {# delayed}}", "jobs_failed": "{jobCount, plural, other {# failed}}", + "jobs_over_time": "Jobs over time", "library_created": "Created library: {library}", "library_deleted": "Library deleted", - "library_import_path_description": "Specify a folder to import. This folder, including subfolders, will be scanned for images and videos.", + "library_details": "Library details", + "library_folder_description": "Specify a folder to import. This folder, including subfolders, will be scanned for images and videos.", + "library_remove_exclusion_pattern_prompt": "Are you sure you want to remove this exclusion pattern?", + "library_remove_folder_prompt": "Are you sure you want to remove this import folder?", "library_scanning": "Periodic Scanning", "library_scanning_description": "Configure periodic library scanning", "library_scanning_enable_description": "Enable periodic library scanning", "library_settings": "External Library", "library_settings_description": "Manage external library settings", "library_tasks_description": "Scan external libraries for new and/or changed assets", + "library_updated": "Updated library", "library_watching_enable_description": "Watch external libraries for file changes", "library_watching_settings": "Library watching [EXPERIMENTAL]", "library_watching_settings_description": "Automatically watch for changed files", @@ -174,7 +182,12 @@ "machine_learning_smart_search_enabled": "Enable smart search", "machine_learning_smart_search_enabled_description": "If disabled, images will not be encoded for smart search.", "machine_learning_url_description": "The URL of the machine learning server. If more than one URL is provided, each server will be attempted one-at-a-time until one responds successfully, in order from first to last. Servers that don't respond will be temporarily ignored until they come back online.", + "maintenance_settings": "Maintenance", + "maintenance_settings_description": "Put Immich into maintenance mode.", + "maintenance_start": "Start maintenance mode", + "maintenance_start_error": "Failed to start maintenance mode.", "manage_concurrency": "Manage Concurrency", + "manage_concurrency_description": "Navigate to the jobs page to manage job concurrency", "manage_log_settings": "Manage log settings", "map_dark_style": "Dark style", "map_enable_description": "Enable map features", @@ -264,10 +277,14 @@ "password_settings_description": "Manage password login settings", "paths_validated_successfully": "All paths validated successfully", "person_cleanup_job": "Person cleanup", + "queue_details": "Queue Details", + "queues": "Job Queues", + "queues_page_description": "Admin job queues page", "quota_size_gib": "Quota Size (GiB)", "refreshing_all_libraries": "Refreshing all libraries", "registration": "Admin Registration", "registration_description": "Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative tasks, and additional users will be created by you.", + "remove_failed_jobs": "Remove failed jobs", "require_password_change_on_login": "Require user to change password on first login", "reset_settings_to_default": "Reset settings to default", "reset_settings_to_recent_saved": "Reset settings to the recent saved settings", @@ -280,8 +297,10 @@ "server_public_users_description": "All users (name and email) are listed when adding a user to shared albums. When disabled, the user list will only be available to admin users.", "server_settings": "Server Settings", "server_settings_description": "Manage server settings", + "server_stats_page_description": "Admin server statistics page", "server_welcome_message": "Welcome message", "server_welcome_message_description": "A message that is displayed on the login page.", + "settings_page_description": "Admin settings page", "sidecar_job": "Sidecar metadata", "sidecar_job_description": "Discover or synchronize sidecar metadata from the filesystem", "slideshow_duration_description": "Number of seconds to display each image", @@ -401,6 +420,7 @@ "user_settings": "User Settings", "user_settings_description": "Manage user settings", "user_successfully_removed": "User {email} has been successfully removed.", + "users_page_description": "Admin users page", "version_check_enabled_description": "Enable version check", "version_check_implications": "The version check feature relies on periodic communication with github.com", "version_check_settings": "Version Check", @@ -721,6 +741,7 @@ "collapse_all": "Collapse all", "color": "Color", "color_theme": "Color theme", + "command": "Command", "comment_deleted": "Comment deleted", "comment_options": "Comment options", "comments_and_likes": "Comments & likes", @@ -897,8 +918,6 @@ "edit_description_prompt": "Please select a new description:", "edit_exclusion_pattern": "Edit exclusion pattern", "edit_faces": "Edit faces", - "edit_import_path": "Edit import path", - "edit_import_paths": "Edit Import Paths", "edit_key": "Edit key", "edit_link": "Edit link", "edit_location": "Edit location", @@ -970,8 +989,8 @@ "failed_to_stack_assets": "Failed to stack assets", "failed_to_unstack_assets": "Failed to un-stack assets", "failed_to_update_notification_status": "Failed to update notification status", - "import_path_already_exists": "This import path already exists.", "incorrect_email_or_password": "Incorrect email or password", + "library_folder_already_exists": "This import path already exists.", "paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation", "profile_picture_transparent_pixels": "Profile pictures cannot have transparent pixels. Please zoom in and/or move the image.", "quota_higher_than_disk_size": "You set a quota higher than the disk size", @@ -980,7 +999,6 @@ "unable_to_add_assets_to_shared_link": "Unable to add assets to shared link", "unable_to_add_comment": "Unable to add comment", "unable_to_add_exclusion_pattern": "Unable to add exclusion pattern", - "unable_to_add_import_path": "Unable to add import path", "unable_to_add_partners": "Unable to add partners", "unable_to_add_remove_archive": "Unable to {archived, select, true {remove asset from} other {add asset to}} archive", "unable_to_add_remove_favorites": "Unable to {favorite, select, true {add asset to} other {remove asset from}} favorites", @@ -1003,12 +1021,10 @@ "unable_to_delete_asset": "Unable to delete asset", "unable_to_delete_assets": "Error deleting assets", "unable_to_delete_exclusion_pattern": "Unable to delete exclusion pattern", - "unable_to_delete_import_path": "Unable to delete import path", "unable_to_delete_shared_link": "Unable to delete shared link", "unable_to_delete_user": "Unable to delete user", "unable_to_download_files": "Unable to download files", "unable_to_edit_exclusion_pattern": "Unable to edit exclusion pattern", - "unable_to_edit_import_path": "Unable to edit import path", "unable_to_empty_trash": "Unable to empty trash", "unable_to_enter_fullscreen": "Unable to enter fullscreen", "unable_to_exit_fullscreen": "Unable to exit fullscreen", @@ -1059,6 +1075,7 @@ "unable_to_update_user": "Unable to update user", "unable_to_upload_file": "Unable to upload file" }, + "exclusion_pattern": "Exclusion pattern", "exif": "Exif", "exif_bottom_sheet_description": "Add Description...", "exif_bottom_sheet_description_error": "Error updating description", @@ -1089,6 +1106,7 @@ "external_network_sheet_info": "When not on the preferred Wi-Fi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom", "face_unassigned": "Unassigned", "failed": "Failed", + "failed_count": "Failed: {count}", "failed_to_authenticate": "Failed to authenticate", "failed_to_load_assets": "Failed to load assets", "failed_to_load_folder": "Failed to load folder", @@ -1118,6 +1136,7 @@ "folders_feature_description": "Browsing the folder view for the photos and videos on the file system", "forgot_pin_code_question": "Forgot your PIN?", "forward": "Forward", + "full_path": "Full path: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "This feature loads external resources from Google in order to work.", "general": "General", @@ -1154,6 +1173,7 @@ "hide_named_person": "Hide person {name}", "hide_password": "Hide password", "hide_person": "Hide person", + "hide_text_recognition": "Hide text recognition", "hide_unnamed_people": "Hide unnamed people", "home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.", "home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping", @@ -1247,6 +1267,8 @@ "let_others_respond": "Let others respond", "level": "Level", "library": "Library", + "library_add_folder": "Add folder", + "library_edit_folder": "Edit folder", "library_options": "Library options", "library_page_device_albums": "Albums on Device", "library_page_new_album": "New album", @@ -1318,6 +1340,11 @@ "loop_videos_description": "Enable to automatically loop a video in the detail viewer.", "main_branch_warning": "You're using a development version; we strongly recommend using a release version!", "main_menu": "Main menu", + "maintenance_description": "Immich has been put into maintenance mode.", + "maintenance_end": "End maintenance mode", + "maintenance_end_error": "Failed to end maintenance mode.", + "maintenance_logged_in_as": "Currently logged in as {user}", + "maintenance_title": "Temporarily Unavailable", "make": "Make", "manage_geolocation": "Manage location", "manage_media_access_rationale": "This permission is required for proper handling of moving assets to the trash and restoring them from it.", @@ -1440,6 +1467,7 @@ "no_favorites_message": "Add favorites to quickly find your best pictures and videos", "no_libraries_message": "Create an external library to view your photos and videos", "no_local_assets_found": "No local assets found with this checksum", + "no_location_set": "No location set", "no_locked_photos_message": "Photos and videos in the locked folder are hidden and won't show up as you browse or search your library.", "no_name": "No Name", "no_notifications": "No notifications", @@ -1484,6 +1512,7 @@ "online": "Online", "only_favorites": "Only favorites", "open": "Open", + "open_bottom_sheet_info": "Information", "open_in_map_view": "Open in map view", "open_in_openstreetmap": "Open in OpenStreetMap", "open_the_search_filters": "Open the search filters", @@ -1499,6 +1528,7 @@ "other_variables": "Other variables", "owned": "Owned", "owner": "Owner", + "page": "Page", "partner": "Partner", "partner_can_access": "{partner} can access", "partner_can_access_assets": "All your photos and videos except those in Archived and Deleted", @@ -1832,6 +1862,8 @@ "server_offline": "Server Offline", "server_online": "Server Online", "server_privacy": "Server Privacy", + "server_restarting_description": "This page will refresh momentarily.", + "server_restarting_title": "Server is restarting", "server_stats": "Server Stats", "server_update_available": "Server update is available", "server_version": "Server Version", @@ -1955,6 +1987,7 @@ "show_slideshow_transition": "Show slideshow transition", "show_supporter_badge": "Supporter badge", "show_supporter_badge_description": "Show a supporter badge", + "show_text_recognition": "Show text recognition", "show_text_search_menu": "Show text search menu", "shuffle": "Shuffle", "sidebar": "Sidebar", @@ -2025,6 +2058,7 @@ "tags": "Tags", "tap_to_run_job": "Tap to run job", "template": "Template", + "text_recognition": "Text recognition", "theme": "Theme", "theme_selection": "Theme selection", "theme_selection_description": "Automatically set the theme to light or dark based on your browser's system preference", @@ -2057,6 +2091,7 @@ "to_select": "to select", "to_trash": "Trash", "toggle_settings": "Toggle settings", + "toggle_theme_description": "Toggle theme", "total": "Total", "total_usage": "Total usage", "trash": "Trash", @@ -2165,6 +2200,7 @@ "view_album": "View Album", "view_all": "View All", "view_all_users": "View all users", + "view_asset_owners": "View asset owners", "view_details": "View Details", "view_in_timeline": "View in timeline", "view_link": "View link", @@ -2181,6 +2217,7 @@ "viewer_unstack": "Un-Stack", "visibility_changed": "Visibility changed for {count, plural, one {# person} other {# people}}", "waiting": "Waiting", + "waiting_count": "Waiting: {count}", "warning": "Warning", "week": "Week", "welcome": "Welcome", diff --git a/i18n/eo.json b/i18n/eo.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/eo.json @@ -0,0 +1 @@ +{} diff --git a/i18n/es.json b/i18n/es.json index c2260b2012..a5766eed93 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -17,7 +17,6 @@ "add_birthday": "Agregar un cumpleaños", "add_endpoint": "Agregar endpoint", "add_exclusion_pattern": "Agregar patrón de exclusión", - "add_import_path": "Agregar ruta de importación", "add_location": "Agregar ubicación", "add_more_users": "Agregar más usuarios", "add_partner": "Agregar compañero", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Alternar selección para el {album}", "add_to_albums": "Incluir en álbumes", "add_to_albums_count": "Incluir en {count} álbumes", + "add_to_bottom_bar": "Añadir a", "add_to_shared_album": "Incluir en álbum compartido", "add_upload_to_stack": "Añadir archivo y apilar", "add_url": "Agregar URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, one {# fallido} other {# fallidos}}", "library_created": "La biblioteca ha sido creada: {library}", "library_deleted": "Biblioteca eliminada", - "library_import_path_description": "Indica una carpeta para importar. Esta carpeta y sus subcarpetas serán escaneadas en busca de elementos multimedia.", + "library_details": "Detalles de la biblioteca", + "library_folder_description": "Especifica una carpeta para importar. Esta carpeta, incluidas sus subcarpetas, se analizará en busca de imágenes y vídeos.", + "library_remove_exclusion_pattern_prompt": "¿Estás seguro de que quieres eliminar este patrón de exclusión?", + "library_remove_folder_prompt": "¿Estás seguro de que quieres eliminar esta carpeta de importación?", "library_scanning": "Escaneo periódico", "library_scanning_description": "Configurar el escaneo periódico de la biblioteca", "library_scanning_enable_description": "Activar el escaneo periódico de la biblioteca", "library_settings": "Biblioteca externa", "library_settings_description": "Administrar configuración biblioteca externa", "library_tasks_description": "Buscar elementos nuevos o modificados en bibliotecas externas", + "library_updated": "Biblioteca actualizada", "library_watching_enable_description": "Vigilar las bibliotecas externas para detectar cambios en los archivos", "library_watching_settings": "Vigilancia de la biblioteca [EXPERIMENTAL]", "library_watching_settings_description": "Vigilar automaticamente en busca de archivos modificados", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Habilitar búsqueda inteligente", "machine_learning_smart_search_enabled_description": "Al desactivarlo las imágenes no se procesarán para usar la búsqueda inteligente.", "machine_learning_url_description": "La URL del servidor de aprendizaje automático. Si se proporciona más de una URL se intentará acceder a cada servidor sucesivamente hasta que uno responda correctamente en el orden especificado. Los servidores que no respondan serán ignorados temporalmente hasta que vuelvan a estar en línea.", + "maintenance_settings": "Mantenimiento", + "maintenance_settings_description": "Poner Immich en modo de mantenimiento.", + "maintenance_start": "Iniciar el modo de mantenimiento", + "maintenance_start_error": "Error al iniciar el modo de mantenimiento.", "manage_concurrency": "Ajustes de concurrencia", "manage_log_settings": "Administrar la configuración de los registros", "map_dark_style": "Estilo oscuro", @@ -430,6 +438,7 @@ "age_months": "Tiempo {months, plural, one {# mes} other {# meses}}", "age_year_months": "1 año, {months, plural, one {# mes} other {# meses}}", "age_years": "Edad {years, plural, one {# año} other {# años}}", + "album": "Álbum", "album_added": "Álbum agregado", "album_added_notification_setting_description": "Reciba una notificación por correo electrónico cuando lo agreguen a un álbum compartido", "album_cover_updated": "Portada del álbum actualizada", @@ -475,6 +484,7 @@ "allow_edits": "Permitir edición", "allow_public_user_to_download": "Permitir descargas a los usuarios públicos", "allow_public_user_to_upload": "Permitir a los usuarios públicos subir fotos", + "allowed": "Permitido", "alt_text_qr_code": "Código QR", "anti_clockwise": "En sentido antihorario", "api_key": "Clave API", @@ -487,7 +497,7 @@ "app_bar_signout_dialog_title": "Cerrar sesión", "app_download_links": "Enlaces de Descarga de la Aplicación", "app_settings": "Ajustes de la aplicacion", - "app_stores": "App Stores", + "app_stores": "Tiendas de Aplicaciones", "app_update_available": "Actualización de aplicación está disponible", "appears_in": "Aparece en", "apply_count": "Aplicar ({count, number})", @@ -496,14 +506,14 @@ "archive_or_unarchive_photo": "Archivar o restaurar foto", "archive_page_no_archived_assets": "No se encontraron elementos archivados", "archive_page_title": "Archivo ({count})", - "archive_size": "Tamaño del archivo", + "archive_size": "Tamaño de archivo comprimido", "archive_size_description": "Configure el tamaño del archivo para descargas (en GB)", "archived": "Archivado", "archived_count": "{count, plural, one {# archivado} other {# archivados}}", "are_these_the_same_person": "¿Son la misma persona?", - "are_you_sure_to_do_this": "¿Estas seguro de que quieres hacer esto?", - "asset_action_delete_err_read_only": "No se pueden borrar el archivo(s) de solo lectura, omitiendo", - "asset_action_share_err_offline": "No se pudo obtener el archivo(s) sin conexión, omitiendo", + "are_you_sure_to_do_this": "¿Estás seguro de que quieres hacer esto?", + "asset_action_delete_err_read_only": "No se puede borrar archivo(s) de solo lectura, omitiendo", + "asset_action_share_err_offline": "No se pudo obtener archivo(s) sin conexión, omitiendo", "asset_added_to_album": "Agregado al álbum", "asset_adding_to_album": "Agregando al álbum…", "asset_description_updated": "La descripción del elemento ha sido actualizada", @@ -669,7 +679,7 @@ "cannot_merge_people": "No se pueden fusionar personas", "cannot_undo_this_action": "¡No puedes deshacer esta acción!", "cannot_update_the_description": "No se puede actualizar la descripción", - "cast": "Enviar contenido", + "cast": "Transmitir", "cast_description": "Configura los posibles destinos de retransmisión", "change_date": "Cambiar fecha", "change_description": "Cambiar descripción", @@ -744,7 +754,7 @@ "control_bottom_app_bar_edit_location": "Editar ubicación", "control_bottom_app_bar_edit_time": "Editar fecha y hora", "control_bottom_app_bar_share_link": "Enlace para compartir", - "control_bottom_app_bar_share_to": "Enviar", + "control_bottom_app_bar_share_to": "Compartir a", "control_bottom_app_bar_trash_from_immich": "Mover a la papelera", "copied_image_to_clipboard": "Imagen copiada al portapapeles.", "copied_to_clipboard": "¡Copiado al portapapeles!", @@ -894,8 +904,6 @@ "edit_description_prompt": "Por favor selecciona una nueva descripción:", "edit_exclusion_pattern": "Editar patrón de exclusión", "edit_faces": "Editar rostros", - "edit_import_path": "Editar ruta de importación", - "edit_import_paths": "Editar ruta de importación", "edit_key": "Editar clave", "edit_link": "Editar enlace", "edit_location": "Editar ubicación", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "No se pudieron agrupar los archivos", "failed_to_unstack_assets": "Error al desagrupar los archivos", "failed_to_update_notification_status": "Error al actualizar el estado de la notificación", - "import_path_already_exists": "Esta ruta de importación ya existe.", "incorrect_email_or_password": "Contraseña o email incorrecto", + "library_folder_already_exists": "Esta ruta de importación ya existe.", "paths_validation_failed": "Falló la validación en {paths, plural, one {# carpeta} other {# carpetas}}", "profile_picture_transparent_pixels": "Las imágenes de perfil no pueden tener píxeles transparentes. Por favor amplíe y/o mueva la imagen.", "quota_higher_than_disk_size": "Se ha establecido una cuota superior al tamaño del disco", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "No se pueden agregar archivos al enlace compartido", "unable_to_add_comment": "No se puede agregar comentario", "unable_to_add_exclusion_pattern": "No se puede agregar el patrón de exclusión", - "unable_to_add_import_path": "No se puede agregar la ruta de importación", "unable_to_add_partners": "No se pueden agregar compañeros", "unable_to_add_remove_archive": "No se puede archivar {archived, select, true {remove asset from} other {add asset to}}", "unable_to_add_remove_favorites": "{favorite, select, true {No se pudo agregar el elemento a los favoritos} other {No se pudo eliminar el elemento de los favoritos}}", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "No se puede eliminar el archivo", "unable_to_delete_assets": "Error al eliminar archivos", "unable_to_delete_exclusion_pattern": "No se puede eliminar el patrón de exclusión", - "unable_to_delete_import_path": "No se puede eliminar la ruta de importación", "unable_to_delete_shared_link": "No se puede eliminar el enlace compartido", "unable_to_delete_user": "No se puede eliminar el usuario", "unable_to_download_files": "No se pueden descargar archivos", "unable_to_edit_exclusion_pattern": "No se puede editar el patrón de exclusión", - "unable_to_edit_import_path": "No se puede editar la ruta de importación", "unable_to_empty_trash": "No se puede vaciar la papelera", "unable_to_enter_fullscreen": "No se puede acceder al modo pantalla completa", "unable_to_exit_fullscreen": "No se puede salir del modo pantalla completa", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "No se puede actualizar el usuario", "unable_to_upload_file": "Error al subir el archivo" }, + "exclusion_pattern": "Patrón de exclusión", "exif": "EXIF", "exif_bottom_sheet_description": "Agregar descripción…", "exif_bottom_sheet_description_error": "Error al actualizar la descripción", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Explorar la vista de carpetas para las fotos y los videos en el sistema de archivos", "forgot_pin_code_question": "¿Olvidaste tu código PIN?", "forward": "Avanzar", + "full_path": "Ruta completa: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Esta funcionalidad carga recursos externos desde Google para poder funcionar.", "general": "General", @@ -1196,6 +1203,8 @@ "import_path": "Importar ruta", "in_albums": "En {count, plural, one {# álbum} other {# álbumes}}", "in_archive": "En archivo", + "in_year": "En {year}", + "in_year_selector": "En", "include_archived": "Incluir archivados", "include_shared_albums": "Incluir álbumes compartidos", "include_shared_partner_assets": "Incluir elementos compartidos por compañeros", @@ -1232,6 +1241,7 @@ "language_setting_description": "Selecciona tu idioma preferido", "large_files": "Archivos Grandes", "last": "Último", + "last_months": "{count, plural, one {Último mes} other {Últimos # meses}}", "last_seen": "Ultima vez visto", "latest_version": "Última versión", "latitude": "Latitud", @@ -1241,6 +1251,8 @@ "let_others_respond": "Permitir que otros respondan", "level": "Nivel", "library": "Biblioteca", + "library_add_folder": "Añadir carpeta", + "library_edit_folder": "Editar carpeta", "library_options": "Opciones de biblioteca", "library_page_device_albums": "Álbumes en el dispositivo", "library_page_new_album": "Nuevo álbum", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Habilite la reproducción automática de un video en el visor de detalles.", "main_branch_warning": "Está utilizando una versión de desarrollo; ¡le recomendamos encarecidamente que utilice una versión de lanzamiento!", "main_menu": "Menú principal", + "maintenance_description": "Immich se ha puesto en modo de mantenimiento.", + "maintenance_end": "Finalizar el modo de mantenimiento", + "maintenance_end_error": "Error al finalizar el modo de mantenimiento.", + "maintenance_logged_in_as": "Sesión iniciada actualmente como {user}", + "maintenance_title": "No disponible temporalmente", "make": "Marca", "manage_geolocation": "Administrar ubicación", + "manage_media_access_rationale": "Este permiso se requiere para mover recursos a la papelera correctamente, así como para restaurarlos desde la misma.", + "manage_media_access_settings": "Abrir configuración", + "manage_media_access_subtitle": "Permitir a la app Immich gestionar y mover archivos multimedia.", + "manage_media_access_title": "Acceso a gestión de archivos multimedia", "manage_shared_links": "Administrar enlaces compartidos", "manage_sharing_with_partners": "Gestionar el uso compartido con compañeros", "manage_the_app_settings": "Administrar la configuración de la aplicación", @@ -1377,6 +1398,7 @@ "more": "Mas", "move": "Mover", "move_off_locked_folder": "Sacar de la carpeta protegida", + "move_to": "Mover a", "move_to_lock_folder_action_prompt": "{count} agregado(s) a la carpeta protegida", "move_to_locked_folder": "Mover a la carpeta protegida", "move_to_locked_folder_confirmation": "Estas fotos y vídeos se eliminarán de todos los álbumes; solo se podrán ver en la carpeta protegida", @@ -1406,6 +1428,7 @@ "new_pin_code": "Nuevo PIN", "new_pin_code_subtitle": "Esta es la primera vez que accedes a la carpeta protegida. Crea un código PIN seguro para acceder a esta página", "new_timeline": "Nueva Línea de tiempo", + "new_update": "Nueva actualización", "new_user_created": "Nuevo usuario creado", "new_version_available": "NUEVA VERSIÓN DISPONIBLE", "newest_first": "El más reciente primero", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "No se encontraron dispositivos de transmisión", "no_checksum_local": "Suma de verificación no disponible. No se pueden obtener los elementos locales", "no_checksum_remote": "Suma de verificación no disponible. No se puede obtener el elemento remoto", + "no_devices": "Dispositivos no autorizados", "no_duplicates_found": "No se encontraron duplicados.", "no_exif_info_available": "No hay información exif disponible", "no_explore_results_message": "Sube más fotos para explorar tu colección.", "no_favorites_message": "Agregue favoritos para encontrar rápidamente sus mejores fotos y videos", "no_libraries_message": "Crea una biblioteca externa para ver tus fotos y vídeos", "no_local_assets_found": "No se encontraron elementos locales con esta suma de comprobación", + "no_location_set": "No se ha establecido ninguna ubicación", "no_locked_photos_message": "Las fotos y los vídeos de la carpeta protegida se mantienen ocultos; no aparecerán cuando veas o busques elementos en tu biblioteca.", "no_name": "Sin nombre", "no_notifications": "Ninguna notificación", @@ -1437,6 +1462,7 @@ "no_results_description": "Pruebe con un sinónimo o una palabra clave más general", "no_shared_albums_message": "Crea un álbum para compartir fotos y vídeos con personas de tu red", "no_uploads_in_progress": "No hay cargas en progreso", + "not_allowed": "No permitido", "not_available": "N/D", "not_in_any_album": "Sin álbum", "not_selected": "No seleccionado", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos de años anteriores", "pick_a_location": "Elige una ubicación", + "pick_custom_range": "Rango personalizado", + "pick_date_range": "Seleccione un rango de fechas", "pin_code_changed_successfully": "PIN cambiado exitosamente", "pin_code_reset_successfully": "PIN restablecido exitosamente", "pin_code_setup_successfully": "PIN establecido exitosamente", @@ -1814,6 +1842,8 @@ "server_offline": "Servidor desconectado", "server_online": "Servidor en línea", "server_privacy": "Privacidad del Servidor", + "server_restarting_description": "Esta página se actualizará en breve.", + "server_restarting_title": "El servidor se está reiniciando", "server_stats": "Estadísticas del servidor", "server_update_available": "Actualización de servidor disponible", "server_version": "Versión del servidor", @@ -2027,6 +2057,7 @@ "third_party_resources": "Recursos de terceros", "time": "Tiempo", "time_based_memories": "Recuerdos basados en tiempo", + "time_based_memories_duration": "Número de segundos que se mostrará cada imagen.", "timeline": "Cronología", "timezone": "Zona horaria", "to_archive": "Archivar", @@ -2167,6 +2198,7 @@ "welcome": "Bienvenido", "welcome_to_immich": "Bienvenido a Immich", "wifi_name": "Nombre Wi-Fi", + "workflow": "Flujo de trabajo", "wrong_pin_code": "Código PIN incorrecto", "year": "Año", "years_ago": "Hace {years, plural, one {# año} other {# años}}", diff --git a/i18n/et.json b/i18n/et.json index 7e611d3ec3..9b9cd08985 100644 --- a/i18n/et.json +++ b/i18n/et.json @@ -17,7 +17,6 @@ "add_birthday": "Lisa sünnipäev", "add_endpoint": "Lisa lõpp-punkt", "add_exclusion_pattern": "Lisa välistamismuster", - "add_import_path": "Lisa imporditee", "add_location": "Lisa asukoht", "add_more_users": "Lisa rohkem kasutajaid", "add_partner": "Lisa partner", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Muuda albumi {album} valikut", "add_to_albums": "Lisa albumitesse", "add_to_albums_count": "Lisa albumitesse ({count})", + "add_to_bottom_bar": "Lisa", "add_to_shared_album": "Lisa jagatud albumisse", "add_upload_to_stack": "Virnasta üleslaaditud üksus", "add_url": "Lisa URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# ebaõnnestus}}", "library_created": "Lisatud kogu: {library}", "library_deleted": "Kogu kustutatud", - "library_import_path_description": "Määra kaust, mida importida. Sellest kaustast ning alamkaustadest otsitakse pilte ja videosid.", + "library_details": "Kogu detailid", + "library_folder_description": "Vali kaust, mida importida. Sellest kaustast ja alamkaustadest otsitakse pilte ja videosid.", + "library_remove_exclusion_pattern_prompt": "Kas oled kindel, et soovid selle välistamismustri eemaldada?", + "library_remove_folder_prompt": "Kas oled kindel, et soovid selle impordikausta eemaldada?", "library_scanning": "Perioodiline skaneerimine", "library_scanning_description": "Seadista kogu perioodiline skaneerimine", "library_scanning_enable_description": "Luba kogu perioodiline skaneerimine", "library_settings": "Väline kogu", "library_settings_description": "Halda välise kogu seadeid", "library_tasks_description": "Otsi välistest kogudest uusi ja muutunud üksuseid", + "library_updated": "Kogu uuendatud", "library_watching_enable_description": "Jälgi välises kogus failide muudatusi", "library_watching_settings": "Kogu jälgimine [EKSPERIMENTAALNE]", "library_watching_settings_description": "Jälgi automaatselt muutunud faile", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Luba nutiotsing", "machine_learning_smart_search_enabled_description": "Kui keelatud, siis ei kodeerita pilte nutiotsingu jaoks.", "machine_learning_url_description": "Masinõppe serveri URL. Kui ette on antud rohkem kui üks URL, proovitakse neid järjest ükshaaval, kuni üks edukalt vastab. Servereid, mis ei vasta, ignoreeritakse ajutiselt, kuni ühendus taastub.", + "maintenance_settings": "Hooldus", + "maintenance_settings_description": "Pane Immich hooldusrežiimi.", + "maintenance_start": "Käivita hooldusrežiim", + "maintenance_start_error": "Hooldusrežiimi käivitamine ebaõnnestus.", "manage_concurrency": "Halda samaaegsust", "manage_log_settings": "Halda logi seadeid", "map_dark_style": "Tume stiil", @@ -430,6 +438,7 @@ "age_months": "Vanus {months, plural, one {# kuu} other {# kuud}}", "age_year_months": "Vanus 1 aasta, {months, plural, one {# kuu} other {# kuud}}", "age_years": "{years, plural, other {Vanus #}}", + "album": "Album", "album_added": "Album lisatud", "album_added_notification_setting_description": "Saa teavitus e-posti teel, kui sind lisatakse jagatud albumisse", "album_cover_updated": "Albumi kaanepilt muudetud", @@ -475,6 +484,7 @@ "allow_edits": "Luba muutmine", "allow_public_user_to_download": "Luba avalikul kasutajal alla laadida", "allow_public_user_to_upload": "Luba avalikul kasutajal üles laadida", + "allowed": "Lubatud", "alt_text_qr_code": "QR kood", "anti_clockwise": "Vastupäeva", "api_key": "API võti", @@ -894,8 +904,6 @@ "edit_description_prompt": "Palun vali uus kirjeldus:", "edit_exclusion_pattern": "Muuda välistamismustrit", "edit_faces": "Muuda nägusid", - "edit_import_path": "Muuda imporditeed", - "edit_import_paths": "Muuda imporditeid", "edit_key": "Muuda võtit", "edit_link": "Muuda linki", "edit_location": "Muuda asukohta", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Üksuste virnastamine ebaõnnestus", "failed_to_unstack_assets": "Üksuste eraldamine ebaõnnestus", "failed_to_update_notification_status": "Teavituste seisundi uuendamine ebaõnnestus", - "import_path_already_exists": "See imporditee on juba olemas.", "incorrect_email_or_password": "Vale e-posti aadress või parool", + "library_folder_already_exists": "See imporditee on juba olemas.", "paths_validation_failed": "{paths, plural, one {# tee} other {# teed}} ei valideerunud", "profile_picture_transparent_pixels": "Profiilipildis ei tohi olla läbipaistvaid piksleid. Palun suumi sisse ja/või liiguta pilti.", "quota_higher_than_disk_size": "Määratud kvoot on suurem kui kettamaht", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Üksuste jagatud lingile lisamine ebaõnnestus", "unable_to_add_comment": "Kommentaari lisamine ebaõnnestus", "unable_to_add_exclusion_pattern": "Välistamismustri lisamine ebaõnnestus", - "unable_to_add_import_path": "Imporditee lisamine ebaõnnestus", "unable_to_add_partners": "Partnerite lisamine ebaõnnestus", "unable_to_add_remove_archive": "{archived, select, true {Üksuse arhiivist taastamine} other {Üksuse arhiveerimine}} ebaõnnestus", "unable_to_add_remove_favorites": "Üksuse {favorite, select, true {lemmikuks lisamine} other {lemmikutest eemaldamine}} ebaõnnestus", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Üksuse kustutamine ebaõnnestus", "unable_to_delete_assets": "Viga üksuste kustutamisel", "unable_to_delete_exclusion_pattern": "Välistamismustri kustutamine ebaõnnestus", - "unable_to_delete_import_path": "Imporditee kustutamine ebaõnnestus", "unable_to_delete_shared_link": "Jagatud lingi kustutamine ebaõnnestus", "unable_to_delete_user": "Kasutaja kustutamine ebaõnnestus", "unable_to_download_files": "Failide allalaadimine ebaõnnestus", "unable_to_edit_exclusion_pattern": "Välistamismustri muutmine ebaõnnestus", - "unable_to_edit_import_path": "Imporditee muutmine ebaõnnestus", "unable_to_empty_trash": "Prügikasti tühjendamine ebaõnnestus", "unable_to_enter_fullscreen": "Täisekraanile lülitamine ebaõnnestus", "unable_to_exit_fullscreen": "Täisekraanilt väljumine ebaõnnestus", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Kasutaja muutmine ebaõnnestus", "unable_to_upload_file": "Faili üleslaadimine ebaõnnestus" }, + "exclusion_pattern": "Välistamismuster", "exif": "Exif", "exif_bottom_sheet_description": "Lisa kirjeldus...", "exif_bottom_sheet_description_error": "Viga kirjelduse muutmisel", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Kaustavaate abil failisüsteemis olevate fotode ja videote sirvimine", "forgot_pin_code_question": "Unustasid oma PIN-koodi?", "forward": "Edasi", + "full_path": "Täielik tee: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "See funktsionaalsus laadib töötamiseks Google'st väliseid ressursse.", "general": "Üldine", @@ -1151,6 +1158,7 @@ "hide_named_person": "Peida isik {name}", "hide_password": "Peida parool", "hide_person": "Peida isik", + "hide_text_recognition": "Peida tekstituvastus", "hide_unnamed_people": "Peida nimetud isikud", "home_page_add_to_album_conflicts": "{added} üksust lisati albumisse {album}. {failed} üksust oli juba albumis.", "home_page_add_to_album_err_local": "Lokaalseid üksuseid ei saa veel albumisse lisada, jäetakse vahele", @@ -1196,6 +1204,8 @@ "import_path": "Imporditee", "in_albums": "{count, plural, one {# albumis} other {# albumis}}", "in_archive": "Arhiivis", + "in_year": "Aastal {year}", + "in_year_selector": "Aastal", "include_archived": "Kaasa arhiveeritud", "include_shared_albums": "Kaasa jagatud albumid", "include_shared_partner_assets": "Kaasa partneri jagatud üksused", @@ -1232,6 +1242,7 @@ "language_setting_description": "Vali oma eelistatud keel", "large_files": "Suured failid", "last": "Viimane", + "last_months": "{count, plural, one {Eelmine kuu} other {Eelmised # kuud}}", "last_seen": "Viimati nähtud", "latest_version": "Uusim versioon", "latitude": "Laiuskraad", @@ -1241,6 +1252,8 @@ "let_others_respond": "Luba teistel vastata", "level": "Tase", "library": "Kogu", + "library_add_folder": "Lisa kaust", + "library_edit_folder": "Muuda kausta", "library_options": "Kogu seaded", "library_page_device_albums": "Albumid seadmes", "library_page_new_album": "Uus album", @@ -1312,8 +1325,17 @@ "loop_videos_description": "Lülita sisse, et detailvaates videot automaatselt taasesitada.", "main_branch_warning": "Sa kasutad arendusversiooni; soovitame tungivalt kasutada väljalaskeversiooni!", "main_menu": "Peamenüü", + "maintenance_description": "Immich on hooldusrežiimis.", + "maintenance_end": "Lõpeta hooldusrežiim", + "maintenance_end_error": "Hooldusrežiimi lõpetamine ebaõnnestus.", + "maintenance_logged_in_as": "Logitud sisse kasutajana {user}", + "maintenance_title": "Ajutiselt mittesaadaval", "make": "Mark", "manage_geolocation": "Halda asukohta", + "manage_media_access_rationale": "Seda luba on vaja üksuste prügikasti liigutamiseks ja sealt taastamiseks.", + "manage_media_access_settings": "Ava seaded", + "manage_media_access_subtitle": "Luba Immich'i rakendusel multimeediafaile hallata ja liigutada.", + "manage_media_access_title": "Üksuste haldamise ligipääs", "manage_shared_links": "Halda jagatud linke", "manage_sharing_with_partners": "Halda partneritega jagamist", "manage_the_app_settings": "Halda rakenduse seadeid", @@ -1377,6 +1399,7 @@ "more": "Rohkem", "move": "Liiguta", "move_off_locked_folder": "Liiguta lukustatud kaustast välja", + "move_to": "Liiguta", "move_to_lock_folder_action_prompt": "{count} lisatud lukustatud kausta", "move_to_locked_folder": "Liiguta lukustatud kausta", "move_to_locked_folder_confirmation": "Need fotod ja videod eemaldatakse kõigist albumitest ning nad on nähtavad ainult lukustatud kaustas", @@ -1406,6 +1429,7 @@ "new_pin_code": "Uus PIN-kood", "new_pin_code_subtitle": "See on sul esimene kord lukustatud kausta kasutada. Turvaliseks ligipääsuks loo PIN-kood", "new_timeline": "Uus ajajoon", + "new_update": "Uus uuendus", "new_user_created": "Uus kasutaja lisatud", "new_version_available": "UUS VERSIOON SAADAVAL", "newest_first": "Uuemad eespool", @@ -1421,12 +1445,14 @@ "no_cast_devices_found": "Edastamise seadmeid ei leitud", "no_checksum_local": "Kontrollsumma pole saadaval - lokaalse üksuse pärimine ebaõnnestus", "no_checksum_remote": "Kontrollsumma pole saadaval - kaugüksuse pärimine ebaõnnestus", + "no_devices": "Autoriseeritud seadmeid pole", "no_duplicates_found": "Ühtegi duplikaati ei leitud.", "no_exif_info_available": "Exif info pole saadaval", "no_explore_results_message": "Oma kogu avastamiseks laadi üles rohkem fotosid.", "no_favorites_message": "Lisa lemmikud, et oma parimaid fotosid ja videosid kiiresti leida", "no_libraries_message": "Lisa väline kogu oma fotode ja videote vaatamiseks", "no_local_assets_found": "Selle kontrollsummaga lokaalseid üksuseid ei leitud", + "no_location_set": "Asukoht pole määratud", "no_locked_photos_message": "Lukustatud kaustas olevad fotod ja videod on peidetud ning need pole kogu sirvimisel ja otsimisel nähtavad.", "no_name": "Nimetu", "no_notifications": "Teavitusi pole", @@ -1437,6 +1463,7 @@ "no_results_description": "Proovi sünonüümi või üldisemat märksõna", "no_shared_albums_message": "Lisa album, et fotosid ja videosid teistega jagada", "no_uploads_in_progress": "Üleslaadimisi käimas ei ole", + "not_allowed": "Keelatud", "not_available": "Pole saadaval", "not_in_any_album": "Pole üheski albumis", "not_selected": "Ei ole valitud", @@ -1547,6 +1574,8 @@ "photos_count": "{count, plural, one {{count, number} foto} other {{count, number} fotot}}", "photos_from_previous_years": "Fotod varasematest aastatest", "pick_a_location": "Vali asukoht", + "pick_custom_range": "Kohandatud vahemik", + "pick_date_range": "Vali kuupäevavahemik", "pin_code_changed_successfully": "PIN-kood edukalt muudetud", "pin_code_reset_successfully": "PIN-kood edukalt lähtestatud", "pin_code_setup_successfully": "PIN-kood edukalt seadistatud", @@ -1814,6 +1843,8 @@ "server_offline": "Serveriga ühendus puudub", "server_online": "Server ühendatud", "server_privacy": "Serveri privaatsus", + "server_restarting_description": "Leht värskendatakse hetkeliselt.", + "server_restarting_title": "Server taaskäivitub", "server_stats": "Serveri statistika", "server_update_available": "Serveri uuendus on saadaval", "server_version": "Serveri versioon", @@ -1937,6 +1968,7 @@ "show_slideshow_transition": "Kuva slaidiesitluse üleminekud", "show_supporter_badge": "Toetaja märk", "show_supporter_badge_description": "Kuva toetaja märki", + "show_text_recognition": "Kuva tekstituvastust", "show_text_search_menu": "Kuva tekstiotsingu menüüd", "shuffle": "Juhuslik", "sidebar": "Külgmenüü", @@ -2007,6 +2039,7 @@ "tags": "Sildid", "tap_to_run_job": "Puuduta tööte käivitamiseks", "template": "Mall", + "text_recognition": "Tekstituvastus", "theme": "Teema", "theme_selection": "Teema valik", "theme_selection_description": "Sea automaatselt hele või tume teema vastavalt veebilehitseja eelistustele", @@ -2027,6 +2060,7 @@ "third_party_resources": "Kolmanda osapoole ressursid", "time": "Aeg", "time_based_memories": "Ajapõhised mälestused", + "time_based_memories_duration": "Aeg sekundites, kui kaua igat pilti kuvada.", "timeline": "Ajajoon", "timezone": "Ajavöönd", "to_archive": "Arhiivi", @@ -2142,7 +2176,7 @@ "video_hover_setting_description": "Esita video eelvaade, kui hiirt selle kohal hõljutada. Isegi kui keelatud, saab taasesituse alustada taasesitusnupu kohal hõljutades.", "videos": "Videod", "videos_count": "{count, plural, one {# video} other {# videot}}", - "view": "Vaade", + "view": "Vaata", "view_album": "Vaata albumit", "view_all": "Vaata kõiki", "view_all_users": "Vaata kõiki kasutajaid", @@ -2167,6 +2201,7 @@ "welcome": "Tere tulemast", "welcome_to_immich": "Tere tulemast Immich'isse", "wifi_name": "WiFi-võrgu nimi", + "workflow": "Töövoog", "wrong_pin_code": "Vale PIN-kood", "year": "Aasta", "years_ago": "{years, plural, one {# aasta} other {# aastat}} tagasi", diff --git a/i18n/eu.json b/i18n/eu.json index 291a62a7a1..0a6a93ab36 100644 --- a/i18n/eu.json +++ b/i18n/eu.json @@ -17,7 +17,6 @@ "add_birthday": "Urtebetetzea gehitu", "add_endpoint": "Endpoint-a gehitu", "add_exclusion_pattern": "Bazterketa eredua gehitu", - "add_import_path": "Inportazio bidea gehitu", "add_location": "Kokapena gehitu", "add_more_users": "Erabiltzaile gehiago gehitu", "add_partner": "Kidea gehitu", diff --git a/i18n/fa.json b/i18n/fa.json index f8e47af9c1..0ad0a84190 100644 --- a/i18n/fa.json +++ b/i18n/fa.json @@ -15,23 +15,28 @@ "add_a_title": "افزودن عنوان", "add_birthday": "افزودن تاریخ تولد", "add_exclusion_pattern": "افزودن الگوی استثنا", - "add_import_path": "افزودن مسیر ورودی", "add_location": "افزودن مکان", "add_more_users": "افزودن کاربرهای بیشتر", "add_partner": "افزودن شریک", "add_path": "افزودن مسیر", "add_photos": "افزودن عکس ها", + "add_tag": "افزودن تگ", "add_to": "افزودن به …", "add_to_album": "افزودن به آلبوم", "add_to_album_bottom_sheet_added": "به آلبوم {album} اضافه شد", "add_to_album_bottom_sheet_already_exists": "قبلا در آلبوم {album} موجود است", "add_to_album_bottom_sheet_some_local_assets": "برخی از محتواهای محلی را نشد به آلبوم اضافه کرد", + "add_to_albums": "افزودن به آلبوم", + "add_to_albums_count": "افزودن به آلبوم ها {count}", "add_to_shared_album": "افزودن به آلبوم اشتراکی", + "add_upload_to_stack": "افزودن فایل ارسالی به مجموعه", + "add_url": "افزودن آدرس URL", "added_to_archive": "به آرشیو اضافه شد", "added_to_favorites": "به علاقه مندی ها اضافه شد", "added_to_favorites_count": "{count, number} تا به علاقه مندی ها اضافه شد", "admin": { "add_exclusion_pattern_description": "الگوهای استثنا را اضافه کنید. پشتیبانی از گلابینگ با استفاده از *, ** و ? وجود دارد. برای نادیده گرفتن تمام فایل‌ها در هر دایرکتوری با نام \"Raw\"، از \"**/Raw/**\" استفاده کنید. برای نادیده گرفتن تمام فایل‌هایی که با \".tif\" پایان می‌یابند، از \"**/*.tif\" استفاده کنید. برای نادیده گرفتن یک مسیر مطلق، از \"/path/to/ignore/**\" استفاده کنید.", + "admin_user": "ادمین", "authentication_settings": "تنظیمات احراز هویت", "authentication_settings_description": "مدیریت رمز عبور، OAuth، و سایر تنظیمات احراز هویت", "authentication_settings_disable_all": "آیا مطمئن هستید که می‌خواهید تمام روش‌های ورود را غیرفعال کنید؟ ورود به طور کامل غیرفعال خواهد شد.", @@ -79,7 +84,6 @@ "job_status": "وضعیت کار", "library_created": "کتابخانه ایجاد شده: {library}", "library_deleted": "کتابخانه حذف شد", - "library_import_path_description": "یک پوشه برای وارد کردن مشخص کنید. این پوشه، به همراه زیرپوشه‌ها، برای یافتن تصاویر و ویدیوها اسکن خواهد شد.", "library_scanning": "اسکن دوره ای", "library_scanning_description": "تنظیم اسکن دوره‌ای کتابخانه", "library_scanning_enable_description": "فعال کردن اسکن دوره‌ای کتابخانه", diff --git a/i18n/fi.json b/i18n/fi.json index ac2007fa3a..106cb65d16 100644 --- a/i18n/fi.json +++ b/i18n/fi.json @@ -17,7 +17,6 @@ "add_birthday": "Lisää syntymäpäivä", "add_endpoint": "Lisää päätepiste", "add_exclusion_pattern": "Lisää poissulkemismalli", - "add_import_path": "Lisää tuontipolku", "add_location": "Lisää sijainti", "add_more_users": "Lisää käyttäjiä", "add_partner": "Lisää kumppani", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Vaihda albumin {album} valintaa", "add_to_albums": "Lisää albumeihin", "add_to_albums_count": "Lisää albumeihin ({count})", + "add_to_bottom_bar": "Lisää", "add_to_shared_album": "Lisää jaettuun albumiin", "add_upload_to_stack": "Lisää kuvapinoon", "add_url": "Lisää URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# epäonnistunutta}}", "library_created": "Kirjasto {library} luotu", "library_deleted": "Kirjasto poistettu", - "library_import_path_description": "Määritä kansio joka tuodaan. Kuvat ja videot skannataan tästä kansiosta, sekä alikansioista.", "library_scanning": "Ajoittainen skannaus", "library_scanning_description": "Määritä ajoittaiset kirjastojen skannaukset", "library_scanning_enable_description": "Ota käyttöön ajoittaiset kirjastojen skannaukset", @@ -160,8 +159,8 @@ "machine_learning_ocr_enabled_description": "Jos asetus on pois päältä, kuvia ei prosessoida tekstin tunnistamiseksi.", "machine_learning_ocr_max_resolution": "Maksimiresoluutio", "machine_learning_ocr_max_resolution_description": "Tätä suuremmat esikatselukuvat tullaan pienentämään samassa kuvasuhteessa. Suuremmat arvot ovat tarkempia, mutta kestävät pidempään prosessoida ja käyttävät enemmän muistia.", - "machine_learning_ocr_min_detection_score": "Pienin paikannuksen pistemäärä", - "machine_learning_ocr_min_detection_score_description": "Pienin arvo tekstin paikannukselle varmuudelle välillä 0-1. Pienemmät arvot paikantavat enemmän tekstiä, mutta saattavat johtaa useampaan väärään positiiviseen.", + "machine_learning_ocr_min_detection_score": "Tunnistuksen vähimmäispistemäärä", + "machine_learning_ocr_min_detection_score_description": "Tekstin tunnistuksen vähimmäisluottamusarvo (0–1). Pienemmät arvot tunnistavat enemmän tekstiä, mutta voivat johtaa virheellisiin osumiin.", "machine_learning_ocr_min_recognition_score": "Pienin tunnistuksen pistemäärä", "machine_learning_ocr_min_score_recognition_description": "Pienin arvo tekstin tunnistuksen varmuudelle välillä 0-1. Pienemmät arvot tunnistavat enemmän tekstiä, mutta saattavat johtaa useampaan väärään positiiviseen.", "machine_learning_ocr_model": "OCR-malli", @@ -430,6 +429,7 @@ "age_months": "Ikä {months, plural, one {# kuukausi} other {# kuukautta}}", "age_year_months": "Ikä 1 vuosi, {months, plural, one {# kuukausi} other {# kuukautta}}", "age_years": "{years, plural, other {Ikä #v}}", + "album": "Albumi", "album_added": "Albumi lisätty", "album_added_notification_setting_description": "Saa sähköpostia kun sinut lisätään jaettuun albumiin", "album_cover_updated": "Albumin kansikuva päivitetty", @@ -475,6 +475,7 @@ "allow_edits": "Salli muutokset", "allow_public_user_to_download": "Salli julkisten käyttäjien ladata tiedostoja", "allow_public_user_to_upload": "Salli julkisten käyttäjien lähettää tiedostoja", + "allowed": "Sallittu", "alt_text_qr_code": "QR-koodi", "anti_clockwise": "Vastapäivään", "api_key": "API-avain", @@ -683,7 +684,7 @@ "change_password_form_confirm_password": "Vahvista salasana", "change_password_form_description": "Hei {name},\n\nTämä on joko ensimmäinen kerta, kun kirjaudut järjestelmään, tai sinulta on pyydetty salasanan vaihtoa. Ole hyvä ja syötä uusi salasana alle.", "change_password_form_log_out": "Kirjaudu ulos kaikilta muilta laitteilta", - "change_password_form_log_out_description": "On suositeltavaa kirjautua ulos kaikilta muilta laitteilta", + "change_password_form_log_out_description": "On suositeltavaa kirjautua ulos kaikilta laitteilta", "change_password_form_new_password": "Uusi salasana", "change_password_form_password_mismatch": "Salasanat eivät täsmää", "change_password_form_reenter_new_password": "Uusi salasana uudelleen", @@ -894,8 +895,6 @@ "edit_description_prompt": "Valitse uusi kuvaus:", "edit_exclusion_pattern": "Muokkaa poissulkemismallia", "edit_faces": "Muokkaa kasvoja", - "edit_import_path": "Muokkaa tuontipolkua", - "edit_import_paths": "Muokkaa tuontipolkuja", "edit_key": "Muokkaa avainta", "edit_link": "Muokkaa linkkiä", "edit_location": "Muokkaa sijaintia", @@ -967,7 +966,6 @@ "failed_to_stack_assets": "Medioiden pinoaminen epäonnistui", "failed_to_unstack_assets": "Medioiden pinoamisen purku epäonnistui", "failed_to_update_notification_status": "Ilmoituksen tilan päivittäminen epäonnistui", - "import_path_already_exists": "Tämä tuontipolku on jo olemassa.", "incorrect_email_or_password": "Väärä sähköpostiosoite tai salasana", "paths_validation_failed": "{paths, plural, one {# polun} other {# polun}} validointi epäonnistui", "profile_picture_transparent_pixels": "Profiilikuvassa ei voi olla läpinäkyviä pikseleitä. Zoomaa lähemmäs ja/tai siirrä kuvaa.", @@ -977,7 +975,6 @@ "unable_to_add_assets_to_shared_link": "Medioiden lisääminen jaettuun linkkiin epäonnistui", "unable_to_add_comment": "Kommentin lisääminen epäonnistui", "unable_to_add_exclusion_pattern": "Ei voida lisätä poissulkemismallia", - "unable_to_add_import_path": "Tuontipolkua ei voitu lisätä", "unable_to_add_partners": "Kumppaneita ei voitu lisätä", "unable_to_add_remove_archive": "Ei voida {archived, select, true {poistaa kohdetta arkistosta} other {lisätä kohdetta arkistoon}}", "unable_to_add_remove_favorites": "Ei voida {favorite, select, true {lisätä kohdetta suosikkeihin} other {poistaa kohdetta suosikeista}}", @@ -1000,12 +997,10 @@ "unable_to_delete_asset": "Kohteen poistaminen epäonnistui", "unable_to_delete_assets": "Virhe kohteen poistamisessa", "unable_to_delete_exclusion_pattern": "Ei voida poistaa poissulkemismallia", - "unable_to_delete_import_path": "Tuontipolkua ei voitu poistaa", "unable_to_delete_shared_link": "Jaetun linkin poistaminen epäonnistui", "unable_to_delete_user": "Käyttäjän poistaminen epäonnistui", "unable_to_download_files": "Tiedostojen lataaminen epäonnistui", "unable_to_edit_exclusion_pattern": "Ei voida muokata poissulkemismallia", - "unable_to_edit_import_path": "Tuontipolkua ei voitu muokata", "unable_to_empty_trash": "Roskakorin tyhjentäminen epäonnistui", "unable_to_enter_fullscreen": "Koko ruudun tilaan siirtyminen epäonnistui", "unable_to_exit_fullscreen": "Koko ruudun tilasta poistuminen epäonnistui", @@ -1551,7 +1546,7 @@ "pin_code_reset_successfully": "PIN-koodin nollaus onnistui", "pin_code_setup_successfully": "PIN-koodin asettaminen onnistui", "pin_verification": "PIN-koodin vahvistus", - "place": "Sijainti", + "place": "Paikka", "places": "Paikat", "places_count": "{count, plural, one {{count, number} Paikka} other {{count, number} Paikkaa}}", "play": "Toista", @@ -1716,6 +1711,7 @@ "running": "Käynnissä", "save": "Tallenna", "save_to_gallery": "Tallenna galleriaan", + "saved": "Tallennettu", "saved_api_key": "API-avain tallennettu", "saved_profile": "Profiili tallennettu", "saved_settings": "Asetukset tallennettu", @@ -2026,6 +2022,7 @@ "third_party_resources": "Kolmannen osapuolen resurssit", "time": "Aika", "time_based_memories": "Aikaan perustuvat muistot", + "time_based_memories_duration": "Kuvien näyttöaika sekunteina.", "timeline": "Aikajana", "timezone": "Aikavyöhyke", "to_archive": "Arkistoi", diff --git a/i18n/fil.json b/i18n/fil.json index 23257ce2fd..413ed85828 100644 --- a/i18n/fil.json +++ b/i18n/fil.json @@ -62,7 +62,6 @@ "exclusion_pattern_description": "Maaaring gamitin ang mga pattern na pangbukod para hindi pansinin ang ilang file o folder habang binabasa ang iyong library. Mainam itong solusyon para sa mga folder na may file na ayaw niyong ma-import, tulad ng mga RAW na file.", "force_delete_user_warning": "BABALA: Tatanggalin itong user at lahat ng asset nila, Hindi ito mababawi at ang kanilang files ay hindi na mababalik", "image_format": "Format", - "library_import_path_description": "Tukuyin ang folder na i-import. Ang folder na ito, kasama ang subfolders, ay mag sa-scan para sa mga imahe at mga videos.", "note_cannot_be_changed_later": "TANDAAN: Hindi na ito pwede baguhin sa susunod!", "server_welcome_message_description": "Mensahe na ipapakita sa login page.", "user_restore_description": "Ang account ni {user} ay maibabalik." diff --git a/i18n/fr.json b/i18n/fr.json index 789afffc38..6c32aac0f1 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -4,7 +4,7 @@ "account_settings": "Paramètres du compte", "acknowledge": "Compris", "action": "Action", - "action_common_update": "Mise à jour", + "action_common_update": "Mettre à jour", "actions": "Actions", "active": "En cours", "activity": "Activité", @@ -17,7 +17,6 @@ "add_birthday": "Ajouter un anniversaire", "add_endpoint": "Ajouter une adresse", "add_exclusion_pattern": "Ajouter un schéma d'exclusion", - "add_import_path": "Ajouter un chemin à importer", "add_location": "Ajouter une localisation", "add_more_users": "Ajouter plus d'utilisateurs", "add_partner": "Ajouter un partenaire", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Basculer la sélection pour {album}", "add_to_albums": "Ajouter aux albums", "add_to_albums_count": "Ajouter aux albums ({count})", + "add_to_bottom_bar": "Ajouter à", "add_to_shared_album": "Ajouter à l'album partagé", "add_upload_to_stack": "Ajouter les éléments téléversés à la pile", "add_url": "Ajouter l'URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# en échec}}", "library_created": "Bibliothèque créée : {library}", "library_deleted": "Bibliothèque supprimée", - "library_import_path_description": "Spécifier un dossier à importer. Ce dossier, y compris ses sous-dossiers, sera analysé à la recherche d'images et de vidéos.", + "library_details": "Détails de la bibliothèque", + "library_folder_description": "Renseignez un dossier à importer. Ce dossier et ses sous-dossiers seront scannés pour leurs images et vidéos.", + "library_remove_exclusion_pattern_prompt": "Êtes-vous sûr de vouloir supprimer ce schéma d'exclusion ?", + "library_remove_folder_prompt": "Êtes-vous sûr de vouloir supprimer ce dossier d'import ?", "library_scanning": "Analyse périodique", "library_scanning_description": "Configurer l'analyse périodique de la bibliothèque", "library_scanning_enable_description": "Activer l'analyse périodique de la bibliothèque", "library_settings": "Bibliothèque externe", "library_settings_description": "Gestion des paramètres des bibliothèques externes", "library_tasks_description": "Scanner les bibliothèques externes pour les nouveaux et/ou les éléments modifiés", + "library_updated": "Bibliothèque mise à jour", "library_watching_enable_description": "Surveiller les modifications de fichiers dans les bibliothèques externes", "library_watching_settings": "Surveillance de bibliothèque [EXPÉRIMENTAL]", "library_watching_settings_description": "Surveiller automatiquement les fichiers modifiés", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Activer la recherche intelligente", "machine_learning_smart_search_enabled_description": "Si cette option est désactivée, les images ne seront pas encodées pour la recherche intelligente.", "machine_learning_url_description": "L’URL du serveur d'apprentissage automatique. Si plusieurs URL sont fournies, chaque serveur sera essayé un par un jusqu’à ce que l’un d’eux réponde avec succès, dans l’ordre de la première à la dernière. Les serveurs ne répondant pas seront temporairement ignorés jusqu'à ce qu'ils soient de nouveau opérationnels.", + "maintenance_settings": "Maintenance", + "maintenance_settings_description": "Mettre Immich en mode maintenance.", + "maintenance_start": "Démarrer le mode maintenance", + "maintenance_start_error": "Échec du démarrage du mode maintenance.", "manage_concurrency": "Gérer du multitâche", "manage_log_settings": "Gérer les paramètres de journalisation", "map_dark_style": "Thème sombre", @@ -430,6 +438,7 @@ "age_months": "Âge {months, plural, one {# mois} other {# mois}}", "age_year_months": "Âge 1 an, {months, plural, one {# mois} other {# mois}}", "age_years": "Âge {years, plural, one {# an} other {# ans}}", + "album": "Album", "album_added": "Album ajouté", "album_added_notification_setting_description": "Recevoir une notification par courriel lorsque vous êtes ajouté(e) à un album partagé", "album_cover_updated": "Couverture de l'album mise à jour", @@ -475,6 +484,7 @@ "allow_edits": "Autoriser les modifications", "allow_public_user_to_download": "Permettre le téléchargement par des utilisateurs non connectés", "allow_public_user_to_upload": "Permettre l'envoi par des utilisateurs non connectés", + "allowed": "Autorisé", "alt_text_qr_code": "Image du code QR", "anti_clockwise": "Sens anti-horaire", "api_key": "Clé API", @@ -724,7 +734,7 @@ "comments_are_disabled": "Les commentaires sont désactivés", "common_create_new_album": "Créer un nouvel album", "completed": "Complété", - "confirm": "Confirmez", + "confirm": "Confirmer", "confirm_admin_password": "Confirmez le mot de passe Admin", "confirm_delete_face": "Êtes-vous sûr de vouloir supprimer le visage de {name} du média ?", "confirm_delete_shared_link": "Voulez-vous vraiment supprimer ce lien partagé ?", @@ -894,8 +904,6 @@ "edit_description_prompt": "Choisir une nouvelle description :", "edit_exclusion_pattern": "Modifier le schéma d'exclusion", "edit_faces": "Modifier les visages", - "edit_import_path": "Modifier le chemin d'importation", - "edit_import_paths": "Modifier les chemins d'importation", "edit_key": "Modifier la clé", "edit_link": "Modifier le lien", "edit_location": "Modifier la localisation", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Impossible d'empiler les médias", "failed_to_unstack_assets": "Impossible de dépiler les médias", "failed_to_update_notification_status": "Erreur de mise à jour du statut des notifications", - "import_path_already_exists": "Ce chemin d'importation existe déjà.", "incorrect_email_or_password": "Courriel ou mot de passe incorrect", + "library_folder_already_exists": "Ce chemin d'import existe déjà.", "paths_validation_failed": "Validation échouée pour {paths, plural, one {# un chemin} other {# plusieurs chemins}}", "profile_picture_transparent_pixels": "Les images de profil ne peuvent pas avoir de pixels transparents. Veuillez agrandir et/ou déplacer l'image.", "quota_higher_than_disk_size": "Le quota saisi est supérieur à l'espace disponible", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Impossible d'ajouter des médias au lien partagé", "unable_to_add_comment": "Impossible d'ajouter un commentaire", "unable_to_add_exclusion_pattern": "Impossible d'ajouter un schéma d'exclusion", - "unable_to_add_import_path": "Impossible d'ajouter le chemin d'importation", "unable_to_add_partners": "Impossible d'ajouter des partenaires", "unable_to_add_remove_archive": "Impossible {archived, select, true {de supprimer des médias de} other {d'ajouter des médias à}} l'archive", "unable_to_add_remove_favorites": "Impossible {favorite, select, true {d'ajouter des médias aux} other {de supprimer des médias des}} favoris", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Impossible de supprimer le média", "unable_to_delete_assets": "Erreur lors de la suppression des médias", "unable_to_delete_exclusion_pattern": "Impossible de supprimer le modèle d'exclusion", - "unable_to_delete_import_path": "Impossible de supprimer le chemin d'importation", "unable_to_delete_shared_link": "Impossible de supprimer le lien de partage", "unable_to_delete_user": "Impossible de supprimer l'utilisateur", "unable_to_download_files": "Impossible de télécharger les fichiers", "unable_to_edit_exclusion_pattern": "Impossible de modifier le modèle d'exclusion", - "unable_to_edit_import_path": "Impossible de modifier le chemin d'importation", "unable_to_empty_trash": "Impossible de vider la corbeille", "unable_to_enter_fullscreen": "Mode plein écran indisponible", "unable_to_exit_fullscreen": "Impossible de sortir du mode plein écran", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Impossible de mettre à jour l'utilisateur", "unable_to_upload_file": "Impossible d'envoyer le fichier" }, + "exclusion_pattern": "Schéma d'exclusion", "exif": "Exif", "exif_bottom_sheet_description": "Ajouter une description...", "exif_bottom_sheet_description_error": "Erreur de mise à jour de la description", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Parcourir l'affichage par dossiers pour les photos et les vidéos sur le système de fichiers", "forgot_pin_code_question": "Code PIN oublié ?", "forward": "Avant", + "full_path": "Chemin complet : {path}", "gcast_enabled": "Diffusion Google Cast", "gcast_enabled_description": "Cette fonctionnalité charge des ressources externes depuis Google pour fonctionner.", "general": "Général", @@ -1196,6 +1203,8 @@ "import_path": "Chemin d'importation", "in_albums": "Dans {count, plural, one {# album} other {# albums}}", "in_archive": "Dans les archives", + "in_year": "Dans {year}", + "in_year_selector": "Dans", "include_archived": "Inclure les archives", "include_shared_albums": "Inclure les albums partagés", "include_shared_partner_assets": "Inclure les médias partagés du partenaire", @@ -1232,6 +1241,7 @@ "language_setting_description": "Sélectionnez votre langue préférée", "large_files": "Fichiers volumineux", "last": "Dernier", + "last_months": "{count, plural, one {Dernier mois} other {Derniers # mois}}", "last_seen": "Dernièrement utilisé", "latest_version": "Dernière version", "latitude": "Latitude", @@ -1241,6 +1251,8 @@ "let_others_respond": "Laisser les autres réagir", "level": "Niveau", "library": "Bibliothèque", + "library_add_folder": "Ajouter un dossier", + "library_edit_folder": "Modifier un dossier", "library_options": "Options de bibliothèque", "library_page_device_albums": "Albums sur l'appareil", "library_page_new_album": "Nouvel album", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Activer pour voir la vidéo en boucle dans le lecteur détaillé.", "main_branch_warning": "Vous utilisez une version de développement. Nous vous recommandons fortement d'utiliser une version stable !", "main_menu": "Menu principal", + "maintenance_description": "Immich a été mis en mode maintenance.", + "maintenance_end": "Arrêter le mode maintenance", + "maintenance_end_error": "Échec de l'arrêt du mode maintenance.", + "maintenance_logged_in_as": "Actuellement connecté en tant que {user}", + "maintenance_title": "Temporairement non disponible", "make": "Marque", "manage_geolocation": "Gérer la localisation", + "manage_media_access_rationale": "Cette autorisation est nécessaire pour gérer correctement le déplacement de médias vers la corbeille et la restauration depuis celle-ci.", + "manage_media_access_settings": "Ouvrir les paramètres", + "manage_media_access_subtitle": "Autoriser l'application Immich à gérer et déplacer des fichiers de média.", + "manage_media_access_title": "Accès à la gestion de médias", "manage_shared_links": "Gérer les liens partagés", "manage_sharing_with_partners": "Gérer le partage avec les partenaires", "manage_the_app_settings": "Gérer les paramètres de l'application", @@ -1377,6 +1398,7 @@ "more": "Plus", "move": "Déplacer", "move_off_locked_folder": "Déplacer en dehors du dossier verrouillé", + "move_to": "Déplacer vers", "move_to_lock_folder_action_prompt": "{count} ajouté(s) au dossier verrouillé", "move_to_locked_folder": "Déplacer dans le dossier verrouillé", "move_to_locked_folder_confirmation": "Ces photos et vidéos seront retirées de tous les albums et ne seront visibles que dans le dossier verrouillé", @@ -1406,6 +1428,7 @@ "new_pin_code": "Nouveau code PIN", "new_pin_code_subtitle": "C'est votre premier accès au dossier verrouillé. Créez un code PIN pour sécuriser l'accès à cette page", "new_timeline": "Nouvelle vue chronologique", + "new_update": "Nouvelle mise à jour", "new_user_created": "Nouvel utilisateur créé", "new_version_available": "NOUVELLE VERSION DISPONIBLE", "newest_first": "Récents en premier", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "Aucun appareil de diffusion trouvé", "no_checksum_local": "Aucune empreinte numerique disponible - impossible de récupérer les médias locaux", "no_checksum_remote": "Aucune empreinte numérique disponible - impossible de récupérer les médias distants", + "no_devices": "Aucun appareil autorisé", "no_duplicates_found": "Aucun doublon n'a été trouvé.", "no_exif_info_available": "Aucune information exif disponible", "no_explore_results_message": "Envoyez plus de photos pour explorer votre bibliothèque.", "no_favorites_message": "Ajouter des photos et vidéos à vos favoris pour les retrouver plus rapidement", "no_libraries_message": "Créer une bibliothèque externe pour voir vos photos et vidéos dans un autre espace de stockage", "no_local_assets_found": "Aucun média local trouvé avec cette empreinte numerique", + "no_location_set": "Aucune localisation definie", "no_locked_photos_message": "Les photos et vidéos du dossier verrouillé sont masqués et ne s'afficheront pas dans votre galerie ou la recherche.", "no_name": "Pas de nom", "no_notifications": "Pas de notification", @@ -1437,6 +1462,7 @@ "no_results_description": "Essayez un synonyme ou un mot-clé plus général", "no_shared_albums_message": "Créer un album pour partager vos photos et vidéos avec les personnes de votre réseau", "no_uploads_in_progress": "Pas d'envoi en cours", + "not_allowed": "Non autorisé", "not_available": "N/A", "not_in_any_album": "Dans aucun album", "not_selected": "Non sélectionné", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}", "photos_from_previous_years": "Photos des années précédentes", "pick_a_location": "Choisissez une localisation", + "pick_custom_range": "Période personnalisée", + "pick_date_range": "Sélectionner une période de dates", "pin_code_changed_successfully": "Code PIN changé avec succès", "pin_code_reset_successfully": "Réinitialisation du code PIN réussie", "pin_code_setup_successfully": "Définition du code PIN réussie", @@ -1814,6 +1842,8 @@ "server_offline": "Serveur hors ligne", "server_online": "Serveur en ligne", "server_privacy": "Vie privée pour le serveur", + "server_restarting_description": "Cette page va se rafraîchir dans quelques instants.", + "server_restarting_title": "Le serveur redémarre", "server_stats": "Statistiques du serveur", "server_update_available": "Une mise à jour du serveur est disponible", "server_version": "Version du serveur", @@ -2027,6 +2057,7 @@ "third_party_resources": "Ressources tierces", "time": "Horaire", "time_based_memories": "Souvenirs basés sur la date", + "time_based_memories_duration": "Durée en secondes d'affichage de chaque image.", "timeline": "Vue chronologique", "timezone": "Fuseau horaire", "to_archive": "Archiver", @@ -2167,6 +2198,7 @@ "welcome": "Bienvenue", "welcome_to_immich": "Bienvenue sur Immich", "wifi_name": "Nom du réseau wifi", + "workflow": "Flux de travail", "wrong_pin_code": "Code PIN erroné", "year": "Année", "years_ago": "Il y a {years, plural, one {# an} other {# ans}}", diff --git a/i18n/ga.json b/i18n/ga.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/ga.json @@ -0,0 +1 @@ +{} diff --git a/i18n/gl.json b/i18n/gl.json index c2e955960d..3aac86e684 100644 --- a/i18n/gl.json +++ b/i18n/gl.json @@ -17,7 +17,6 @@ "add_birthday": "Engadir cumpreanos", "add_endpoint": "Engadir punto final", "add_exclusion_pattern": "Engadir patrón de exclusión", - "add_import_path": "Engadir ruta de importación", "add_location": "Engadir localización", "add_more_users": "Engadir máis usuarios", "add_partner": "Engadir compañeiro/a", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Alternar selección para {album}", "add_to_albums": "Engadir a álbums", "add_to_albums_count": "Engadir a {count} álbums", + "add_to_bottom_bar": "Engadir a", "add_to_shared_album": "Engadir ao álbum compartido", "add_upload_to_stack": "Engade cargar á pila", "add_url": "Engadir URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# fallados}}", "library_created": "Biblioteca creada: {library}", "library_deleted": "Biblioteca eliminada", - "library_import_path_description": "Especifique un cartafol para importar. Este cartafol, incluídos os subcartafoles, escanearase en busca de imaxes e vídeos.", "library_scanning": "Escaneo periódico", "library_scanning_description": "Configurar o escaneo periódico da biblioteca", "library_scanning_enable_description": "Activar o escaneo periódico da biblioteca", @@ -120,7 +119,7 @@ "library_settings_description": "Xestionar a configuración da biblioteca externa", "library_tasks_description": "Escanear bibliotecas externas en busca de activos novos e/ou modificados", "library_watching_enable_description": "Vixiar bibliotecas externas para detectar cambios nos ficheiros", - "library_watching_settings": "Vixilancia da biblioteca (EXPERIMENTAL)", + "library_watching_settings": "Vixilancia da biblioteca [EXPERIMENTAL]", "library_watching_settings_description": "Vixiar automaticamente os ficheiros modificados", "logging_enable_description": "Activar rexistro", "logging_level_description": "Cando estea activado, que nivel de rexistro usar.", @@ -154,6 +153,18 @@ "machine_learning_min_detection_score_description": "Puntuación mínima de confianza para que unha cara sexa detectada, de 0 a 1. Valores máis baixos detectarán máis caras pero poden resultar en falsos positivos.", "machine_learning_min_recognized_faces": "Mínimo de caras recoñecidas", "machine_learning_min_recognized_faces_description": "O número mínimo de caras recoñecidas para que se cree unha persoa. Aumentar isto fai que o Recoñecemento Facial sexa máis preciso a costa de aumentar a posibilidade de que unha cara non se asigne a unha persoa.", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "Emprega aprendizaxe automática para recoñecer texto en imaxes", + "machine_learning_ocr_enabled": "Activa o OCR", + "machine_learning_ocr_enabled_description": "Se está desactivado, as imaxes non se someterán a recoñecemento de texto.", + "machine_learning_ocr_max_resolution": "Resolución máxima", + "machine_learning_ocr_max_resolution_description": "As previsualizacións por enriba desta resolución redimensionaranse mantendo a proporción. Os valores máis altos son máis precisos, pero tardan máis en procesarse e usan máis memoria.", + "machine_learning_ocr_min_detection_score": "Puntuación mínima de detección", + "machine_learning_ocr_min_detection_score_description": "Puntuación mínima de confianza para que o texto sexa detectado, de 0 a 1. Os valores máis baixos detectarán máis texto, pero poden producir falsos positivos.", + "machine_learning_ocr_min_recognition_score": "Puntuación mínima de recoñecemento", + "machine_learning_ocr_min_score_recognition_description": "Puntuación mínima de confianza para que o texto detectado sexa recoñecido, de 0 a 1. Os valores máis baixos recoñecerán máis texto, pero poden producir falsos positivos.", + "machine_learning_ocr_model": "Modelo OCR", + "machine_learning_ocr_model_description": "Os modelos de servidor son máis precisos que os modelos móbiles, pero tardan máis en procesarse e usan máis memoria.", "machine_learning_settings": "Configuración da Aprendizaxe Automática", "machine_learning_settings_description": "Xestionar funcións e configuracións da aprendizaxe automática", "machine_learning_smart_search": "Busca Intelixente", @@ -245,6 +256,7 @@ "oauth_storage_quota_default_description": "Cota en GiB a empregar cando non se proporciona ningunha declaración.", "oauth_timeout": "Tempo máximo de espera da solicitude", "oauth_timeout_description": "Tempo máximo de espera para as solicitudes en milisegundos", + "ocr_job_description": "Emprega aprendizaxe automática para recoñecer texto en imaxes", "password_enable_description": "Iniciar sesión con correo electrónico e contrasinal", "password_settings": "Inicio de sesión con contrasinal", "password_settings_description": "Xestionar a configuración de inicio de sesión con contrasinal", @@ -404,11 +416,11 @@ "advanced_settings_prefer_remote_subtitle": "Algúns dispositivos tardan moito en cargar as miniaturas de ficheiros locais. Active esta opción para cargar imaxes remotas no seu lugar.", "advanced_settings_prefer_remote_title": "Preferir imaxes remotas", "advanced_settings_proxy_headers_subtitle": "Definir cabeceiras de proxy que Immich debería enviar con cada solicitude de rede", - "advanced_settings_proxy_headers_title": "Cabeceiras de Proxy", + "advanced_settings_proxy_headers_title": "Cabeceiras de proxy personalizadas [EXPERIMENTAL]", "advanced_settings_readonly_mode_subtitle": "Activa o modo de só lectura, no que as fotos só se poden visualizar; opcións como seleccionar varias imaxes, compartir, enviar a outros dispositivos ou eliminar están deshabilitadas. Active/desactive o modo de só lectura a través do avatar do usuario na pantalla principal", "advanced_settings_readonly_mode_title": "Modo de só lectura", "advanced_settings_self_signed_ssl_subtitle": "Omite a verificación do certificado SSL para o punto final do servidor. Requirido para certificados autofirmados.", - "advanced_settings_self_signed_ssl_title": "Permitir certificados SSL autofirmados", + "advanced_settings_self_signed_ssl_title": "Permitir certificados SSL autofirmados [EXPERIMENTAL]", "advanced_settings_sync_remote_deletions_subtitle": "Eliminar ou restaurar automaticamente un activo neste dispositivo cando esa acción se realiza na web", "advanced_settings_sync_remote_deletions_title": "Sincronizar eliminacións remotas [EXPERIMENTAL]", "advanced_settings_tile_subtitle": "Configuración de usuario avanzado", @@ -417,6 +429,7 @@ "age_months": "Idade: {months, plural, one {# mes} other {# meses}}", "age_year_months": "Idade: 1 ano e {months, plural, one {# mes} other {# meses}}", "age_years": "Idade: {years, plural, one {# ano} other {# anos}}", + "album": "Álbum", "album_added": "Álbum engadido", "album_added_notification_setting_description": "Recibir unha notificación por correo electrónico cando sexa engadido a un álbum compartido", "album_cover_updated": "Portada do álbum actualizada", @@ -462,6 +475,7 @@ "allow_edits": "Permitir edicións", "allow_public_user_to_download": "Permitir que o usuario público descargue", "allow_public_user_to_upload": "Permitir que o usuario público cargue", + "allowed": "Permitido", "alt_text_qr_code": "Imaxe de código QR", "anti_clockwise": "Sentido antihorario", "api_key": "Chave API", @@ -474,6 +488,8 @@ "app_bar_signout_dialog_title": "Pechar sesión", "app_download_links": "Ligazóns de Descarga da Aplicación", "app_settings": "Configuración da Aplicación", + "app_stores": "Tendas de aplicacións", + "app_update_available": "Hai unha actualización da aplicación dispoñible", "appears_in": "Aparece en", "apply_count": "Aplicar ({count, number})", "archive": "Arquivo", @@ -557,6 +573,7 @@ "backup_albums_sync": "Sincronización de álbums da copia de seguridade", "backup_all": "Todo", "backup_background_service_backup_failed_message": "Erro ao facer copia de seguridade dos activos. Reintentando…", + "backup_background_service_complete_notification": "Copia de seguridade dos recursos completada", "backup_background_service_connection_failed_message": "Erro ao conectar co servidor. Reintentando…", "backup_background_service_current_upload_notification": "Subindo {filename}", "backup_background_service_default_notification": "Comprobando novos activos…", @@ -666,6 +683,8 @@ "change_password_description": "Esta é a primeira vez que inicia sesión no sistema ou solicitouse un cambio do seu contrasinal. Introduza o novo contrasinal a continuación.", "change_password_form_confirm_password": "Confirmar Contrasinal", "change_password_form_description": "Ola {name},\n\nEsta é a primeira vez que inicia sesión no sistema ou solicitouse un cambio do seu contrasinal. Introduza o novo contrasinal a continuación.", + "change_password_form_log_out": "Pechar sesión en todos os outros dispositivos", + "change_password_form_log_out_description": "Recoméndase pechar sesión en todos os outros dispositivos", "change_password_form_new_password": "Novo Contrasinal", "change_password_form_password_mismatch": "Os contrasinais non coinciden", "change_password_form_reenter_new_password": "Reintroducir Novo Contrasinal", @@ -692,8 +711,8 @@ "client_cert_import_success_msg": "Certificado de cliente importado", "client_cert_invalid_msg": "Ficheiro de certificado inválido ou contrasinal incorrecto", "client_cert_remove_msg": "Certificado de cliente eliminado", - "client_cert_subtitle": "Só admite o formato PKCS12 (.p12, .pfx). A importación/eliminación de certificados só está dispoñible antes de iniciar sesión", - "client_cert_title": "Certificado de Cliente SSL", + "client_cert_subtitle": "Soporta só o formato PKCS12 (.p12, .pfx). A importación ou eliminación de certificados está dispoñible só antes de iniciar sesión", + "client_cert_title": "Certificado de cliente SSL [EXPERIMENTAL]", "clockwise": "Sentido horario", "close": "Pechar", "collapse": "Contraer", @@ -743,6 +762,7 @@ "create": "Crear", "create_album": "Crear álbum", "create_album_page_untitled": "Sen título", + "create_api_key": "Crear chave API", "create_library": "Crear Biblioteca", "create_link": "Crear ligazón", "create_link_to_share": "Crear ligazón para compartir", @@ -772,6 +792,7 @@ "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Escuro", "dark_theme": "Alternar tema escuro", + "date": "Data", "date_after": "Data posterior a", "date_and_time": "Data e Hora", "date_before": "Data anterior a", @@ -874,8 +895,6 @@ "edit_description_prompt": "Por favor, seleccione unha nova descrición:", "edit_exclusion_pattern": "Editar patrón de exclusión", "edit_faces": "Editar caras", - "edit_import_path": "Editar ruta de importación", - "edit_import_paths": "Editar Rutas de Importación", "edit_key": "Editar chave", "edit_link": "Editar ligazón", "edit_location": "Editar localización", @@ -947,7 +966,6 @@ "failed_to_stack_assets": "Erro ao apilar activos", "failed_to_unstack_assets": "Erro ao desapilar activos", "failed_to_update_notification_status": "Erro ao actualizar o estado das notificacións", - "import_path_already_exists": "Esta ruta de importación xa existe.", "incorrect_email_or_password": "Correo electrónico ou contrasinal incorrectos", "paths_validation_failed": "{paths, plural, one {# ruta fallou} other {# rutas fallaron}} na validación", "profile_picture_transparent_pixels": "As imaxes de perfil non poden ter píxeles transparentes. Por favor, faga zoom e/ou mova a imaxe.", @@ -957,7 +975,6 @@ "unable_to_add_assets_to_shared_link": "Non se puideron engadir activos á ligazón compartida", "unable_to_add_comment": "Non se puido engadir o comentario", "unable_to_add_exclusion_pattern": "Non se puido engadir o patrón de exclusión", - "unable_to_add_import_path": "Non se puido engadir a ruta de importación", "unable_to_add_partners": "Non se puideron engadir compañeiros/as", "unable_to_add_remove_archive": "Non se puido {archived, select, true {eliminar activo do} other {engadir activo ao}} arquivo", "unable_to_add_remove_favorites": "Non se puido {favorite, select, true {engadir activo a} other {eliminar activo de}} favoritos", @@ -980,12 +997,10 @@ "unable_to_delete_asset": "Non se puido eliminar o activo", "unable_to_delete_assets": "Erro ao eliminar activos", "unable_to_delete_exclusion_pattern": "Non se puido eliminar o patrón de exclusión", - "unable_to_delete_import_path": "Non se puido eliminar a ruta de importación", "unable_to_delete_shared_link": "Non se puido eliminar a ligazón compartida", "unable_to_delete_user": "Non se puido eliminar o usuario", "unable_to_download_files": "Non se puideron descargar os ficheiros", "unable_to_edit_exclusion_pattern": "Non se puido editar o patrón de exclusión", - "unable_to_edit_import_path": "Non se puido editar a ruta de importación", "unable_to_empty_trash": "Non se puido baleirar o lixo", "unable_to_enter_fullscreen": "Non se puido entrar en pantalla completa", "unable_to_exit_fullscreen": "Non se puido saír da pantalla completa", @@ -1080,6 +1095,7 @@ "features_setting_description": "Xestionar as funcións da aplicación", "file_name": "Nome do ficheiro", "file_name_or_extension": "Nome do ficheiro ou extensión", + "file_size": "Tamaño do arquivo", "filename": "Nome do ficheiro", "filetype": "Tipo de ficheiro", "filter": "Filtro", @@ -1119,7 +1135,7 @@ "hash_asset": "Facer hash do recurso", "hashed_assets": "Recursos cun hash", "hashing": "Aplicando hash", - "header_settings_add_header_tip": "Engadir Cabeceira", + "header_settings_add_header_tip": "Engadir cabeceira", "header_settings_field_validator_msg": "O valor non pode estar baleiro", "header_settings_header_name_input": "Nome da cabeceira", "header_settings_header_value_input": "Valor da cabeceira", @@ -1175,6 +1191,8 @@ "import_path": "Ruta de importación", "in_albums": "En {count, plural, one {# álbum} other {# álbums}}", "in_archive": "No arquivo", + "in_year": "No {year}", + "in_year_selector": "No", "include_archived": "Incluír arquivados", "include_shared_albums": "Incluír álbums compartidos", "include_shared_partner_assets": "Incluír activos de compañeiro/a compartidos", @@ -1211,6 +1229,7 @@ "language_setting_description": "Seleccione a súa lingua preferida", "large_files": "Ficheiros Grandes", "last": "Último/a", + "last_months": "{count, plural, one {O mes pasado} other {Os últimos # meses}}", "last_seen": "Visto por última vez", "latest_version": "Última Versión", "latitude": "Latitude", @@ -1243,6 +1262,7 @@ "local_media_summary": "Resumo de Contido Local", "local_network": "Rede local", "local_network_sheet_info": "A aplicación conectarase ao servidor a través desta URL cando use a rede wifi especificada", + "location": "Localización", "location_permission": "Permiso de localización", "location_permission_content": "Para usar a función de cambio automático, Immich necesita permiso de localización precisa para poder ler o nome da rede wifi actual", "location_picker_choose_on_map": "Elixir no mapa", @@ -1292,6 +1312,10 @@ "main_menu": "Menú principal", "make": "Marca", "manage_geolocation": "Xestionar a localización", + "manage_media_access_rationale": "Requírese este permiso para xestionar correctamente o traslado dos recursos ao lixo e a súa restauración desde el.", + "manage_media_access_settings": "Abrir axustes", + "manage_media_access_subtitle": "Permitir que a aplicación Immich xestione e mova ficheiros multimedia.", + "manage_media_access_title": "Acceso á xestión de medios", "manage_shared_links": "Xestionar ligazóns compartidas", "manage_sharing_with_partners": "Xestionar compartición con compañeiros/as", "manage_the_app_settings": "Xestionar a configuración da aplicación", @@ -1348,13 +1372,14 @@ "minutes": "Minutos", "missing": "Faltantes", "mobile_app": "Aplicación Móbil", - "mobile_app_download_onboarding_note": "Podes acceder a estas opcións de novo dende a páxina de Utilidades.", + "mobile_app_download_onboarding_note": "Descarga a aplicación móbil complementaria usando as seguintes opcións", "model": "Modelo", "month": "Mes", "monthly_title_text_date_format": "MMMM a", "more": "Máis", "move": "Mover", "move_off_locked_folder": "Mover fóra do cartafol bloqueado", + "move_to": "Mover a", "move_to_lock_folder_action_prompt": "{count} engadido/a ao cartafol bloqueado", "move_to_locked_folder": "Mover ao cartafol bloqueado", "move_to_locked_folder_confirmation": "Estas fotos e vídeo eliminaranse de todos os álbums e só serán visíbeis dende o cartafol bloqueado", @@ -1384,6 +1409,7 @@ "new_pin_code": "Novo código PIN", "new_pin_code_subtitle": "Esta é a túa primeira vez accedendo á carpeta segura. Crea un código PIN para acceder de maneira segura a esta páxina", "new_timeline": "Nova liña de tempo", + "new_update": "Nova actualización", "new_user_created": "Novo usuario creado", "new_version_available": "NOVA VERSIÓN DISPOÑIBLE", "newest_first": "Máis recentes primeiro", @@ -1399,6 +1425,7 @@ "no_cast_devices_found": "Non se atoparon dispositivos de transmisión", "no_checksum_local": "Non hai suma de verificación dispoñible - non se poden obter os activos locais", "no_checksum_remote": "Non hai suma de verificación dispoñible - non se pode obter o activo remoto", + "no_devices": "Dispositivos non autorizados", "no_duplicates_found": "Non se atoparon duplicados.", "no_exif_info_available": "Non hai información EXIF dispoñible", "no_explore_results_message": "Suba máis fotos para explorar a súa colección.", @@ -1415,6 +1442,7 @@ "no_results_description": "Probe cun sinónimo ou palabra chave máis xeral", "no_shared_albums_message": "Cree un álbum para compartir fotos e vídeos con persoas na súa rede", "no_uploads_in_progress": "Non hai cargas en curso", + "not_allowed": "Non permitido", "not_available": "Non dispoñible", "not_in_any_album": "Non está en ningún álbum", "not_selected": "Non seleccionado", @@ -1430,7 +1458,8 @@ "notifications_setting_description": "Xestionar notificacións", "oauth": "OAuth", "obtainium_configurator": "Configurador de Obtainium", - "obtainium_configurator_instructions": "Por favor, crea unha chave API e selecciona unha variante para xerar a túa ligazón de configuración de Obtainium.", + "obtainium_configurator_instructions": "Emprega Obtainium para instalar e actualizar a aplicación de Android directamente desde o lanzamento do GitHub de Immich. Crea unha chave API e selecciona unha variante para xerar o teu enlace de configuración de Obtainium", + "ocr": "OCR", "official_immich_resources": "Recursos Oficiais de Immich", "offline": "Fóra de liña", "offset": "Desprazamento", @@ -1524,6 +1553,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos de anos anteriores", "pick_a_location": "Elixir unha localización", + "pick_custom_range": "Rango personalizado", + "pick_date_range": "Seleccionar un rango de datas", "pin_code_changed_successfully": "Código PIN cambiado correctamente", "pin_code_reset_successfully": "Código PIN restablecido correctamente", "pin_code_setup_successfully": "Código PIN configurado correctamente", @@ -1535,6 +1566,9 @@ "play_memories": "Reproducir recordos", "play_motion_photo": "Reproducir Foto en Movemento", "play_or_pause_video": "Reproducir ou pausar vídeo", + "play_original_video": "Reproducir o vídeo orixinal", + "play_original_video_setting_description": "Preferir a reprodución dos vídeos orixinais en vez dos vídeos transcodificados. Se o recurso orixinal non é compatible, pode que non se reproduza correctamente.", + "play_transcoded_video": "Reproducir vídeo transcodificado", "please_auth_to_access": "Por favor, autentícate para acceder", "port": "Porto", "preferences_settings_subtitle": "Xestionar as preferencias da aplicación", @@ -1671,6 +1705,7 @@ "reset_sqlite_confirmation": "Estás seguro de que queres restablecer a base de datos SQLite? Terás que pechar a sesión e iniciar sesión de novo para sincronizar os datos outra vez", "reset_sqlite_success": "Base de datos SQLite restablecida correctamente", "reset_to_default": "Restablecer ao predeterminado", + "resolution": "Resolución", "resolve_duplicates": "Resolver duplicados", "resolved_all_duplicates": "Resolvéronse todos os duplicados", "restore": "Restaurar", @@ -1689,6 +1724,7 @@ "running": "Executándose", "save": "Gardar", "save_to_gallery": "Gardar na galería", + "saved": "Gardo", "saved_api_key": "Chave API gardada", "saved_profile": "Perfil gardado", "saved_settings": "Configuración gardada", @@ -1705,6 +1741,9 @@ "search_by_description_example": "Día de sendeirismo en Sapa", "search_by_filename": "Buscar por nome de ficheiro ou extensión", "search_by_filename_example": "p. ex. IMG_1234.JPG ou PNG", + "search_by_ocr": "Buscar mediante OCR", + "search_by_ocr_example": "Latte", + "search_camera_lens_model": "Buscar modelo de lente...", "search_camera_make": "Buscar marca de cámara...", "search_camera_model": "Buscar modelo de cámara...", "search_city": "Buscar cidade...", @@ -1721,6 +1760,7 @@ "search_filter_location_title": "Seleccionar localización", "search_filter_media_type": "Tipo de Medio", "search_filter_media_type_title": "Seleccionar tipo de medio", + "search_filter_ocr": "Buscar por OCR", "search_filter_people_title": "Seleccionar persoas", "search_for": "Buscar por", "search_for_existing_person": "Buscar persoa existente", @@ -1783,6 +1823,7 @@ "server_online": "Servidor En Liña", "server_privacy": "Privacidade do Servidor", "server_stats": "Estatísticas do Servidor", + "server_update_available": "Hai unha actualización do servidor dispoñible", "server_version": "Versión do Servidor", "set": "Establecer", "set_as_album_cover": "Establecer como portada do álbum", @@ -1992,7 +2033,9 @@ "theme_setting_three_stage_loading_title": "Activar carga en tres etapas", "they_will_be_merged_together": "Fusionaranse xuntos", "third_party_resources": "Recursos de Terceiros", + "time": "Hora", "time_based_memories": "Recordos baseados no tempo", + "time_based_memories_duration": "Número de segundos para mostrar cada imaxe.", "timeline": "Liña de tempo", "timezone": "Fuso horario", "to_archive": "Arquivar", @@ -2024,6 +2067,7 @@ "troubleshoot": "Solucionar problemas", "type": "Tipo", "unable_to_change_pin_code": "Non é posible cambiar o código PIN", + "unable_to_check_version": "Non se puido verificar a versión da aplicación ou do servidor", "unable_to_setup_pin_code": "Non é posible configurar o código PIN", "unarchive": "Desarquivar", "unarchive_action_prompt": "{count} eliminados do Arquivo", @@ -2132,6 +2176,7 @@ "welcome": "Benvido/a", "welcome_to_immich": "Benvido/a a Immich", "wifi_name": "Nome da wifi", + "workflow": "Fluxo de traballo", "wrong_pin_code": "Código PIN incorrecto", "year": "Ano", "years_ago": "Hai {years, plural, one {# ano} other {# anos}}", diff --git a/i18n/gsw.json b/i18n/gsw.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/gsw.json @@ -0,0 +1 @@ +{} diff --git a/i18n/gu.json b/i18n/gu.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/gu.json @@ -0,0 +1 @@ +{} diff --git a/i18n/he.json b/i18n/he.json index 3d3a82e9e1..362f2b72d3 100644 --- a/i18n/he.json +++ b/i18n/he.json @@ -17,7 +17,6 @@ "add_birthday": "הוספת יום הולדת", "add_endpoint": "הוסף כתובת URL", "add_exclusion_pattern": "הוספת דפוס החרגה", - "add_import_path": "הוספת נתיב יבוא", "add_location": "הוספת מיקום", "add_more_users": "הוספת עוד משתמשים", "add_partner": "הוספת שותף", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# נכשלו}}", "library_created": "נוצרה ספרייה: {library}", "library_deleted": "ספרייה נמחקה", - "library_import_path_description": "ציין תיקיה לייבוא. תיקייה זו, כולל תיקיות משנה, תיסרק עבור תמונות וסרטונים.", "library_scanning": "סריקה תקופתית", "library_scanning_description": "הגדר סריקת ספרייה תקופתית", "library_scanning_enable_description": "אפשר סריקת ספרייה תקופתית", @@ -120,7 +118,7 @@ "library_settings_description": "ניהול הגדרות ספרייה חיצונית", "library_tasks_description": "סרוק ספריות חיצוניות עבור תמונות חדשות ו/או שהשתנו", "library_watching_enable_description": "עקוב אחר שינויי קבצים בספריות חיצוניות", - "library_watching_settings": "צפיית ספרייה (ניסיוני)", + "library_watching_settings": "צפייה בספרייה [ניסיוני]", "library_watching_settings_description": "עקוב אוטומטית אחר שינויי קבצים", "logging_enable_description": "אפשר רישום ביומן", "logging_level_description": "כאשר פועל, באיזה רמת יומן לתעד.", @@ -154,6 +152,18 @@ "machine_learning_min_detection_score_description": "ציון ביטחון מינימלי לאיתור פנים מ-0 עד 1. ערכים נמוכים יותר יאתרו יותר פנים אך עלולים לגרום לתוצאות חיוביות שגויות.", "machine_learning_min_recognized_faces": "מינימום פנים מזוהים", "machine_learning_min_recognized_faces_description": "המספר המינימלי של פנים מזוהים ליצירת אדם. הגדלת ערך זה הופכת את זיהוי הפנים למדויק יותר בעלות של הגברת הסיכוי שלא יוקצו פנים לאדם.", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "השתמש בלמידת מכונה לזיהוי טקסט בתמונות", + "machine_learning_ocr_enabled": "הפעלת OCR", + "machine_learning_ocr_enabled_description": "אם מבוטל, תמונות לא יעברו זיהוי טקסט.", + "machine_learning_ocr_max_resolution": "רזולוציה מירבית", + "machine_learning_ocr_max_resolution_description": "תצוגות מקדימות מעל רזולוציה זו ישונו תוך שמירה על יחס גובה לרוחב. ערכים גבוהים הם מדויקים יותר, אך דורשים יותר זמן עיבוד וזיכרון.", + "machine_learning_ocr_min_detection_score": "ציון איתור מזערי", + "machine_learning_ocr_min_detection_score_description": "ציון ביטחון מזערי לאיתור טקסט בטווח 0-1. ערכים נמוכים יאתרו יותר טקסט אך עלולים לגרום לאיתורים שגויים.", + "machine_learning_ocr_min_recognition_score": "ציון זיהוי מזערי", + "machine_learning_ocr_min_score_recognition_description": "ציון ביטחון מזערי לזיהוי טקסט שאותר בטווח 0-1. ערכים נמוכים יזהו יותר טקסט אך עלולים לגרום לזיהויים שגויים.", + "machine_learning_ocr_model": "מודל OCR", + "machine_learning_ocr_model_description": "מודלי שרת הינם מדויקים יותר ממודלי טלפון, אך לוקחים יותר זמן עיבוד וצורכים יותר זיכרון.", "machine_learning_settings": "הגדרות למידת מכונה", "machine_learning_settings_description": "ניהול התכונות וההגדרות של למידת המכונה", "machine_learning_smart_search": "חיפוש חכם", @@ -211,6 +221,8 @@ "notification_email_ignore_certificate_errors_description": "התעלם משגיאות אימות תעודת TLS (לא מומלץ)", "notification_email_password_description": "סיסמה לשימוש בעת אימות עם שרת הדוא\"ל", "notification_email_port_description": "יציאה של שרת הדוא\"ל (למשל 25, 465, או 587)", + "notification_email_secure": "SMTPS", + "notification_email_secure_description": "השתמש ב-SMTPS (פרוטוקול SMTP מעל TLS)", "notification_email_sent_test_email_button": "שלח דוא\"ל בדיקה ושמור", "notification_email_setting_description": "הגדרות לשליחת התראות דוא\"ל", "notification_email_test_email": "שלח דוא\"ל בדיקה", @@ -243,6 +255,7 @@ "oauth_storage_quota_default_description": "מכסה ב-GiB לשימוש כאשר לא מסופקת דרישה.", "oauth_timeout": "הבקשה נכשלה – הזמן הקצוב הסתיים", "oauth_timeout_description": "זמן קצוב לבקשות (במילישניות)", + "ocr_job_description": "השתמש בלמידת מכונה לזיהוי טקסט בתמונות", "password_enable_description": "התחבר עם דוא\"ל וסיסמה", "password_settings": "סיסמת התחברות", "password_settings_description": "ניהול הגדרות סיסמת התחברות", @@ -333,7 +346,7 @@ "transcoding_max_b_frames": "B-פריימים מרביים", "transcoding_max_b_frames_description": "ערכים גבוהים יותר משפרים את יעילות הדחיסה, אך מאטים את הקידוד. ייתכן שלא יהיה תואם עם האצת חומרה במכשירים ישנים יותר. 0 משבית את B-פריימים, בעוד ש1- מגדיר את הערך זה באופן אוטומטי.", "transcoding_max_bitrate": "קצב סיביות מרבי", - "transcoding_max_bitrate_description": "קביעת קצב סיביות מרבי יכולה להפוך את גדלי הקבצים לצפויים יותר בעלות קלה לאיכות. ב-720p, ערכים טיפוסיים הם 2600 kbit/s עבור VP9 או HEVC, או 4500 kbit/s עבור H.264. מושבת אם מוגדר ל-0.", + "transcoding_max_bitrate_description": "קביעת קצב סיביות מרבי יכולה להפוך את גדלי הקבצים לצפויים יותר בעלות קלה לאיכות. ב-720p, ערכים טיפוסיים הם 2600 kbit/s עבור VP9 או HEVC, או 4500 kbit/s עבור H.264. מושבת אם מוגדר ל-0. אם לא הוגדרו יחידות, ייעשה שימוש ב-k (עבור kbit/s)ף כלומר 5000, 5000k ו-5M (עבור Mbit/s) שקולים.", "transcoding_max_keyframe_interval": "מרווח תמונת מפתח מרבי", "transcoding_max_keyframe_interval_description": "מגדיר את מרחק הפריימים המרבי בין תמונות מפתח. ערכים נמוכים גורעים את יעילות הדחיסה, אך משפרים את זמני החיפוש ועשויים לשפר את האיכות בסצנות עם תנועה מהירה. 0 מגדיר ערך זה באופן אוטומטי.", "transcoding_optimal_description": "סרטונים גבוהים מרזולוציית היעד או לא בפורמט מקובל", @@ -351,7 +364,7 @@ "transcoding_target_resolution": "רזולוציה יעד", "transcoding_target_resolution_description": "רזולוציות גבוהות יותר יכולות לשמר פרטים רבים יותר אך לוקחות זמן רב יותר לקידוד, יש להן גדלי קבצים גדולים יותר, ויכולות להפחית את תגובתיות היישום.", "transcoding_temporal_aq": "AQ מבוסס זמן", - "transcoding_temporal_aq_description": "חל רק על NVENC. מגביר את האיכות של סצנות עם רמת פירוט גבוהה בהילוך איטי. ייתכן שלא יהיה תואם למכשירים ישנים יותר.", + "transcoding_temporal_aq_description": "חל רק על NVENC. כימות מסתגל לפי זמן מגביר את האיכות של סצנות עם רמת פירוט גבוהה בהילוך איטי. ייתכן שלא יהיה תואם למכשירים ישנים יותר.", "transcoding_threads": "תהליכונים", "transcoding_threads_description": "ערכים גבוהים יותר מובילים לקידוד מהיר יותר, אך משאירים פחות מקום לשרת לעבד משימות אחרות בעודו פעיל. ערך זה לא אמור להיות יותר ממספר ליבות המעבד. ממקסם את הניצול אם מוגדר ל-0.", "transcoding_tone_mapping": "מיפוי גוונים", @@ -402,11 +415,11 @@ "advanced_settings_prefer_remote_subtitle": "במכשירים מסוימים טעינת תמונות ממוזערות מקבצים מקומיים עלולה להיות איטית במיוחד. הפעל הגדרה זו כדי לטעון תמונות מרוחקות במקום זאת.", "advanced_settings_prefer_remote_title": "העדף תמונות מרוחקות", "advanced_settings_proxy_headers_subtitle": "הגדר proxy headers שהיישום צריך לשלוח עם כל בקשת רשת", - "advanced_settings_proxy_headers_title": "כותרות פרוקסי", + "advanced_settings_proxy_headers_title": "כותרות פרוקסי [ניסיוני]", "advanced_settings_readonly_mode_subtitle": "מאפשר את מצב לקריאה בלבד בו התמונות ניתנות לצפייה בלבד, דברים כמו בחירת תמונות מרובות, שיתוף, שידור, מחיקה הם כולם מושבתים. אפשר/השבת מצב לקריאה בלבד באמצעות יצגן המשתמש מהמסך הראשי", - "advanced_settings_readonly_mode_title": "מצב לקריאה בלבד", + "advanced_settings_readonly_mode_title": "מצב קריאה בלבד", "advanced_settings_self_signed_ssl_subtitle": "מדלג על אימות תעודת SSL עבור כתובת URL של השרת. דרוש עבור תעודות בחתימה עצמית.", - "advanced_settings_self_signed_ssl_title": "התר תעודות SSL בחתימה עצמית", + "advanced_settings_self_signed_ssl_title": "התר תעודות SSL בחתימה עצמית [ניסיוני]", "advanced_settings_sync_remote_deletions_subtitle": "מחק או שחזר תמונה במכשיר זה באופן אוטומטי כאשר פעולה זו נעשית בדפדפן", "advanced_settings_sync_remote_deletions_title": "סנכרן מחיקות שבוצעו במכשירים אחרים [נסיוני]", "advanced_settings_tile_subtitle": "הגדרות משתמש מתקדם", @@ -466,10 +479,14 @@ "api_key_description": "הערך הזה יוצג רק פעם אחת. נא לוודא שהעתקת אותו לפני סגירת החלון.", "api_key_empty": "מפתח ה-API שלך לא אמור להיות ריק", "api_keys": "מפתחות API", + "app_architecture_variant": "וריאנט (ארכיטקטורה)", "app_bar_signout_dialog_content": "האם את/ה בטוח/ה שברצונך להתנתק?", "app_bar_signout_dialog_ok": "כן", "app_bar_signout_dialog_title": "התנתק", + "app_download_links": "קישורים להורדת האפליקציה", "app_settings": "הגדרות יישום", + "app_stores": "חנויות אפליקציה", + "app_update_available": "יש עדכון לאפליקציה", "appears_in": "מופיע ב", "apply_count": "החל ({count, number})", "archive": "ארכיון", @@ -553,6 +570,7 @@ "backup_albums_sync": "סנכרון אלבומי גיבוי", "backup_all": "הכל", "backup_background_service_backup_failed_message": "נכשל בגיבוי תמונות. מנסה שוב…", + "backup_background_service_complete_notification": "גיבוי הנכסים הושלם", "backup_background_service_connection_failed_message": "נכשל בהתחברות לשרת. מנסה שוב…", "backup_background_service_current_upload_notification": "מעלה {filename}", "backup_background_service_default_notification": "מחפש תמונות חדשות…", @@ -662,6 +680,8 @@ "change_password_description": "זאת או הפעם הראשונה שהתחברת למערכת או שנעשתה בקשה לשינוי הסיסמה שלך. נא להזין את הסיסמה החדשה למטה.", "change_password_form_confirm_password": "אשר סיסמה", "change_password_form_description": "הי {name},\n\nזאת או הפעם הראשונה שאת/ה מתחבר/ת למערכת או שנעשתה בקשה לשינוי הסיסמה שלך. נא להזין את הסיסמה החדשה למטה.", + "change_password_form_log_out": "התנתק מכל שאר המכשירים", + "change_password_form_log_out_description": "מומלץ להתנתק מכל שאר הרכיבים", "change_password_form_new_password": "סיסמה חדשה", "change_password_form_password_mismatch": "סיסמאות לא תואמות", "change_password_form_reenter_new_password": "הכנס שוב סיסמה חדשה", @@ -689,7 +709,7 @@ "client_cert_invalid_msg": "קובץ תעודה לא תקין או סיסמה שגויה", "client_cert_remove_msg": "תעודת לקוח הוסרה", "client_cert_subtitle": "תומך בפורמט PKCS12 (.p12, .pfx) בלבד. ייבוא/הסרה של תעודה זמינה רק לפני התחברות", - "client_cert_title": "תעודת לקוח SSL", + "client_cert_title": "תעודת לקוח SSL [ניסיוני]", "clockwise": "עם כיוון השעון", "close": "סגור", "collapse": "כווץ", @@ -739,6 +759,7 @@ "create": "צור", "create_album": "צור אלבום", "create_album_page_untitled": "ללא כותרת", + "create_api_key": "יצירת מפתח API", "create_library": "צור ספרייה", "create_link": "צור קישור", "create_link_to_share": "צור קישור לשיתוף", @@ -768,6 +789,7 @@ "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "כהה", "dark_theme": "הפעל/כבה מצב כהה", + "date": "תאריך", "date_after": "תאריך אחרי", "date_and_time": "תאריך ושעה", "date_before": "תאריך לפני", @@ -870,8 +892,6 @@ "edit_description_prompt": "אנא בחר תיאור חדש:", "edit_exclusion_pattern": "ערוך דפוס החרגה", "edit_faces": "ערוך פנים", - "edit_import_path": "ערוך נתיב יבוא", - "edit_import_paths": "ערוך נתיבי ייבוא", "edit_key": "ערוך מפתח", "edit_link": "ערוך קישור", "edit_location": "ערוך מיקום", @@ -943,7 +963,6 @@ "failed_to_stack_assets": "יצירת ערימת תמונות נכשלה", "failed_to_unstack_assets": "ביטול ערימת תמונות נכשלה", "failed_to_update_notification_status": "שגיאה בעדכון ההתראה", - "import_path_already_exists": "נתיב הייבוא הזה כבר קיים.", "incorrect_email_or_password": "דוא\"ל או סיסמה שגויים", "paths_validation_failed": "{paths, plural, one {נתיב # נכשל} other {# נתיבים נכשלו}} אימות", "profile_picture_transparent_pixels": "תמונות פרופיל אינן יכולות לכלול פיקסלים שקופים. נא להגדיל ו/או להזיז את התמונה.", @@ -953,7 +972,6 @@ "unable_to_add_assets_to_shared_link": "לא ניתן להוסיף תמונות לקישור משותף", "unable_to_add_comment": "לא ניתן להוסיף תגובה", "unable_to_add_exclusion_pattern": "לא ניתן להוסיף דפוס החרגה", - "unable_to_add_import_path": "לא ניתן להוסיף נתיב ייבוא", "unable_to_add_partners": "לא ניתן להוסיף שותפים", "unable_to_add_remove_archive": "לא ניתן {archived, select, true {להסיר תמונה מ} other {להוסיף תמונה ל}}ארכיון", "unable_to_add_remove_favorites": "לא ניתן {favorite, select, true {להוסיף תמונה ל} other {להסיר תמונה מ}}מועדפים", @@ -976,12 +994,10 @@ "unable_to_delete_asset": "לא ניתן למחוק את התמונה", "unable_to_delete_assets": "שגיאה במחיקת התמונות", "unable_to_delete_exclusion_pattern": "לא ניתן למחוק דפוס החרגה", - "unable_to_delete_import_path": "לא ניתן למחוק את נתיב הייבוא", "unable_to_delete_shared_link": "לא ניתן למחוק קישור משותף", "unable_to_delete_user": "לא ניתן למחוק משתמש", "unable_to_download_files": "לא ניתן להוריד קבצים", "unable_to_edit_exclusion_pattern": "לא ניתן לערוך דפוס החרגה", - "unable_to_edit_import_path": "לא ניתן לערוך את נתיב הייבוא", "unable_to_empty_trash": "לא ניתן לרוקן אשפה", "unable_to_enter_fullscreen": "לא ניתן להיכנס למסך מלא", "unable_to_exit_fullscreen": "לא ניתן לצאת ממסך מלא", @@ -1037,6 +1053,7 @@ "exif_bottom_sheet_description_error": "שגיאה בעדכון התיאור", "exif_bottom_sheet_details": "פרטים", "exif_bottom_sheet_location": "מיקום", + "exif_bottom_sheet_no_description": "ללא תיאור", "exif_bottom_sheet_people": "אנשים", "exif_bottom_sheet_person_add_person": "הוסף שם", "exit_slideshow": "צא ממצגת שקופיות", @@ -1075,6 +1092,7 @@ "features_setting_description": "ניהול תכונות היישום", "file_name": "שם הקובץ", "file_name_or_extension": "שם קובץ או סיומת", + "file_size": "גודל קובץ", "filename": "שם קובץ", "filetype": "סוג קובץ", "filter": "סנן", @@ -1238,6 +1256,7 @@ "local_media_summary": "סיכום של מדיה מקומית", "local_network": "רשת מקומית", "local_network_sheet_info": "היישום יתחבר לשרת דרך הכתובת הזאת כאשר משתמשים ברשת האינטרנט האלחוטי שמצוינת", + "location": "מיקום", "location_permission": "הרשאת מיקום", "location_permission_content": "כדי להשתמש בתכונת ההחלפה האוטומטית, היישום צריך הרשאה למיקום מדויק על מנת לקרוא את השם של רשת האינטרנט האלחוטי", "location_picker_choose_on_map": "בחר על מפה", @@ -1287,6 +1306,8 @@ "main_menu": "תפריט ראשי", "make": "תוצרת", "manage_geolocation": "נהל מיקום", + "manage_media_access_settings": "פתח הגדרות", + "manage_media_access_subtitle": "אפשר לאפליקציית Immich לנהל ולהזיז קבצי מדיה.", "manage_shared_links": "ניהול קישורים משותפים", "manage_sharing_with_partners": "ניהול שיתוף עם שותפים", "manage_the_app_settings": "ניהול הגדרות האפליקציה", @@ -1342,6 +1363,8 @@ "minute": "דקה", "minutes": "דקות", "missing": "חסרים", + "mobile_app": "אפליקציה לטלפון", + "mobile_app_download_onboarding_note": "הורד את האפליקציה המלווה באחת מהאפשרויות הבאות", "model": "דגם", "month": "חודש", "monthly_title_text_date_format": "MMMM y", @@ -1360,6 +1383,8 @@ "my_albums": "האלבומים שלי", "name": "שם", "name_or_nickname": "שם או כינוי", + "navigate": "נווט", + "navigate_to_time": "נווט אל זמן", "network_requirement_photos_upload": "השתמש בנתונים ניידים לגיבוי תמונות", "network_requirement_videos_upload": "השתמש בנתונים ניידים לגיבוי סרטונים", "network_requirements": "דרישות רשת", @@ -1369,11 +1394,13 @@ "never": "אף פעם", "new_album": "אלבום חדש", "new_api_key": "מפתח API חדש", + "new_date_range": "טווח תאריך חדש", "new_password": "סיסמה חדשה", "new_person": "אדם חדש", "new_pin_code": "קוד PIN חדש", "new_pin_code_subtitle": "זאת הפעם הראשונה שנכנסת לתיקיה הנעולה. צור קוד PIN כדי לאבטח את הגישה לדף זה", "new_timeline": "ציר הזמן החדש", + "new_update": "עדכון חדש", "new_user_created": "משתמש חדש נוצר", "new_version_available": "גרסה חדשה זמינה", "newest_first": "החדש ביותר ראשון", @@ -1419,6 +1446,9 @@ "notifications": "התראות", "notifications_setting_description": "ניהול התראות", "oauth": "OAuth", + "obtainium_configurator": "הגדרות Obtainium", + "obtainium_configurator_instructions": "השתמש ב-Obtainium כגדי להתקין ולעדכן את אפליקציית האנדרואיד ישירות לגרסאות הגיטהאב של Immich. צור מפתח API ובחר וריאנט כדי ליצור קישור קונפיגורציה עבור Obtainium", + "ocr": "OCR", "official_immich_resources": "מקורות רשמיים של Immich", "offline": "לא מקוון", "offset": "קיזוז", @@ -1523,6 +1553,9 @@ "play_memories": "נגן זכרונות", "play_motion_photo": "הפעל תמונה עם תנועה", "play_or_pause_video": "הפעל או השהה סרטון", + "play_original_video": "נגן את הווידיאו המקורי", + "play_original_video_setting_description": "העדף לנגן סרטונים המקוריים על פני סרטונים משועתקים. אם הסרטון המקורי אינו תואם הוא עלול להתנגן לא נכון.", + "play_transcoded_video": "נגן סרטון משועתק", "please_auth_to_access": "אנא אמת את זהותך כדי לגשת", "port": "יציאה", "preferences_settings_subtitle": "ניהול העדפות יישום", @@ -1659,6 +1692,7 @@ "reset_sqlite_confirmation": "האם אתה בטוח שברצונך לאפס את מסד הנתונים SQLite? יהיה עליך להתנתק ולהתחבר מחדש כדי לסנכרן את הנתונים מחדש", "reset_sqlite_success": "איפוס מסד הנתונים SQLite בוצע בהצלחה", "reset_to_default": "אפס לברירת מחדל", + "resolution": "רזולוציה", "resolve_duplicates": "פתור כפילויות", "resolved_all_duplicates": "כל הכפילויות נפתרו", "restore": "שחזר", @@ -1677,6 +1711,7 @@ "running": "פועל", "save": "שמור", "save_to_gallery": "שמור לגלריה", + "saved": "נשמר", "saved_api_key": "מפתח API שמור", "saved_profile": "פרופיל שמור", "saved_settings": "הגדרות שמורות", @@ -1693,6 +1728,9 @@ "search_by_description_example": "יום טיול בסאפה", "search_by_filename": "חיפוש לפי שם קובץ או סיומת", "search_by_filename_example": "לדוגמא IMG_1234.JPG או PNG", + "search_by_ocr": "חיפוש לפי OCR", + "search_by_ocr_example": "לאטה", + "search_camera_lens_model": "חיפוש סוג עדשה...", "search_camera_make": "חיפוש תוצרת המצלמה...", "search_camera_model": "חפש דגם המצלמה...", "search_city": "חיפוש עיר...", @@ -1709,6 +1747,7 @@ "search_filter_location_title": "בחר מיקום", "search_filter_media_type": "סוג מדיה", "search_filter_media_type_title": "בחר סוג מדיה", + "search_filter_ocr": "חיפוש לפי OCR", "search_filter_people_title": "בחר אנשים", "search_for": "חיפוש", "search_for_existing_person": "חיפוש אדם קיים", @@ -1771,6 +1810,7 @@ "server_online": "החיבור לשרת פעיל", "server_privacy": "פרטיות השרת", "server_stats": "סטטיסטיקות שרת", + "server_update_available": "עדכון שרת זמין", "server_version": "גרסת שרת", "set": "הגדר", "set_as_album_cover": "הגדר כעטיפת האלבום", @@ -1799,6 +1839,8 @@ "setting_notifications_subtitle": "התאם את העדפות ההתראה שלך", "setting_notifications_total_progress_subtitle": "התקדמות העלאה כללית (בוצע/סה״כ תמונות)", "setting_notifications_total_progress_title": "הראה סה״כ התקדמות גיבוי ברקע", + "setting_video_viewer_auto_play_subtitle": "נגן סרטונים אוטומטית כשהם נפתחים", + "setting_video_viewer_auto_play_title": "נגן סרטונים אוטומטית", "setting_video_viewer_looping_title": "הפעלה חוזרת", "setting_video_viewer_original_video_subtitle": "כאשר מזרימים סרטון מהשרת, נגן את המקורי אפילו כשהמרת קידוד זמינה. עלול להוביל לתקיעות. סרטונים זמינים מקומית מנוגנים באיכות מקורית ללא קשר להגדרה זו.", "setting_video_viewer_original_video_title": "כפה סרטון מקורי", @@ -1978,6 +2020,7 @@ "theme_setting_three_stage_loading_title": "אפשר טעינה בשלושה שלבים", "they_will_be_merged_together": "הם יתמזגו יחד", "third_party_resources": "משאבי צד שלישי", + "time": "זמן", "time_based_memories": "זכרונות מבוססי זמן", "timeline": "ציר זמן", "timezone": "אזור זמן", @@ -2010,6 +2053,7 @@ "troubleshoot": "פתור בעיות", "type": "סוג", "unable_to_change_pin_code": "לא ניתן לשנות את קוד ה PIN", + "unable_to_check_version": "לא ניתן לבדוק את גרסאת האפליקציה או השרת", "unable_to_setup_pin_code": "לא ניתן להגדיר קוד PIN", "unarchive": "הוצא מארכיון", "unarchive_action_prompt": "{count} הוסרו מהארכיון", diff --git a/i18n/hi.json b/i18n/hi.json index fb1698c0a2..7f4f3dfb29 100644 --- a/i18n/hi.json +++ b/i18n/hi.json @@ -1,7 +1,7 @@ { "about": "बारे में", - "account": "अभिलेख", - "account_settings": "अभिलेख व्यवस्था", + "account": "खाता", + "account_settings": "खाता सेटिंग्स", "acknowledge": "स्वीकार करें", "action": "कार्रवाई", "action_common_update": "अद्यतन", @@ -17,7 +17,6 @@ "add_birthday": "अपने जन्मदिन का उल्लेख करें", "add_endpoint": "endpoint डालें", "add_exclusion_pattern": "अपवाद उदाहरण डालें", - "add_import_path": "आयात पथ डालें", "add_location": "स्थान डालें", "add_more_users": "अधिक उपयोगकर्ता डालें", "add_partner": "जोड़ीदार डालें", @@ -32,6 +31,7 @@ "add_to_album_toggle": "{album} के लिए चयन टॉगल करें", "add_to_albums": "एकाधिक एल्बम में डाले", "add_to_albums_count": "एल्बमों में डालें ({count})", + "add_to_bottom_bar": "इसमें जोड़ें", "add_to_shared_album": "शेयर किए गए एल्बम में डालें", "add_upload_to_stack": "स्टैक में अपलोड करें", "add_url": "URL डालें", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# असफल}}", "library_created": "निर्मित संग्रह: {library}", "library_deleted": "संग्रह हटा दिया गया", - "library_import_path_description": "आयात करने के लिए एक फ़ोल्डर निर्दिष्ट करें। सबफ़ोल्डर्स सहित इस फ़ोल्डर को छवियों और वीडियो के लिए स्कैन किया जाएगा।", "library_scanning": "सामयिक स्कैनिंग", "library_scanning_description": "सामयिक लाइब्रेरी स्कैनिंग कॉन्फ़िगर करें", "library_scanning_enable_description": "सामयिक लाइब्रेरी स्कैनिंग सक्षम करें", @@ -173,6 +172,10 @@ "machine_learning_smart_search_enabled": "स्मार्ट खोज सक्षम करें", "machine_learning_smart_search_enabled_description": "यदि अक्षम किया गया है, तो स्मार्ट खोज के लिए छवियों को एन्कोड नहीं किया जाएगा।", "machine_learning_url_description": "मशीन लर्निंग सर्वर का URL। यदि एक से अधिक URL दिए गए हैं, तो प्रत्येक सर्वर को एक-एक करके कोशिश किया जाएगा, पहले से आखिरी तक, जब तक कोई सफलतापूर्वक प्रतिक्रिया न दे। जो सर्वर प्रतिक्रिया नहीं देते, उन्हें अस्थायी रूप से नजरअंदाज किया जाएगा जब तक वे फिर से ऑनलाइन न हों।", + "maintenance_settings": "रखरखाव", + "maintenance_settings_description": "Immich को मेंटेनेंस मोड में रखें।", + "maintenance_start": "रखरखाव मोड शुरू करें", + "maintenance_start_error": "मेंटेनेंस मोड शुरू नहीं हो सका।", "manage_concurrency": "समवर्तीता प्रबंधित करें", "manage_log_settings": "लॉग सेटिंग प्रबंधित करें", "map_dark_style": "डार्क शैली", @@ -366,7 +369,7 @@ "transcoding_target_resolution": "लक्ष्य संकल्प", "transcoding_target_resolution_description": "उच्च रिज़ॉल्यूशन अधिक विवरण संरक्षित कर सकते हैं लेकिन एन्कोड करने में अधिक समय लेते हैं, फ़ाइल आकार बड़े होते हैं, और ऐप प्रतिक्रियाशीलता को कम कर सकते हैं।", "transcoding_temporal_aq": "अस्थायी AQ", - "transcoding_temporal_aq_description": "केवल एनवीईएनसी पर लागू होता है।", + "transcoding_temporal_aq_description": "केवल NVENC पर लागू होता है। टेम्पोरल अडैप्टिव क्वांटाइज़ेशन उच्च-विस्तार, कम-गति वाले दृश्यों की गुणवत्ता बढ़ाता है। हो सकता है कि यह पुराने उपकरणों के साथ संगत न हो।", "transcoding_threads": "थ्रेड्स", "transcoding_threads_description": "उच्च मान तेज़ एन्कोडिंग की ओर ले जाते हैं, लेकिन सक्रिय रहते हुए सर्वर के लिए अन्य कार्यों को संसाधित करने के लिए कम जगह छोड़ते हैं।", "transcoding_tone_mapping": "टोन-मैपिंग", @@ -417,11 +420,11 @@ "advanced_settings_prefer_remote_subtitle": "कुछ डिवाइस स्थानीय एसेट से थंबनेल लोड करने में बहुत धीमे होते हैं। इसके बजाय, दूरस्थ इमेज लोड करने के लिए इस सेटिंग को सक्रिय करें।", "advanced_settings_prefer_remote_title": "दूरस्थ छवियों को प्राथमिकता दें", "advanced_settings_proxy_headers_subtitle": "प्रत्येक नेटवर्क अनुरोध के साथ इम्मिच द्वारा भेजे जाने वाले प्रॉक्सी हेडर को परिभाषित करें", - "advanced_settings_proxy_headers_title": "प्रॉक्सी हेडर", + "advanced_settings_proxy_headers_title": "कस्टम प्रॉक्सी हेडर [प्रायोगिक]", "advanced_settings_readonly_mode_subtitle": "रीड-ओनली प्रणाली को सक्षम करता है जहां चित्र को केवल देखा जा सकता है, एकाधिक चित्रों का चयन करना, साझा करना, कास्टिंग करना, हटाना जैसी सभी चीज़ें अक्षम हैं। मुख्य स्क्रीन में उपयोगकर्ता- अवतार के माध्यम से रीड-ओनली प्रणाली को सक्षम/अक्षम करें", "advanced_settings_readonly_mode_title": "रीड-ओनली प्रणाली", "advanced_settings_self_signed_ssl_subtitle": "सर्वर एंडपॉइंट के लिए SSL प्रमाणपत्र सत्यापन को छोड़ देता है। स्व-हस्ताक्षरित प्रमाणपत्रों के लिए आवश्यक है।", - "advanced_settings_self_signed_ssl_title": "स्व-हस्ताक्षरित SSL प्रमाणपत्रों की अनुमति दें", + "advanced_settings_self_signed_ssl_title": "स्व-हस्ताक्षरित SSL प्रमाणपत्रों की अनुमति दें [प्रायोगिक]", "advanced_settings_sync_remote_deletions_subtitle": "वेब पर कार्रवाई किए जाने पर इस डिवाइस पर किसी संपत्ति को स्वचालित रूप से हटाएँ या पुनर्स्थापित करें", "advanced_settings_sync_remote_deletions_title": "दूरस्थ विलोपन सिंक करें [प्रायोगिक]", "advanced_settings_tile_subtitle": "उन्नत उपयोगकर्ता सेटिंग्स", @@ -430,6 +433,7 @@ "age_months": "आयु {months, plural, one {# month} other {# months}}", "age_year_months": "आयु 1 वर्ष, {months, plural, one {# month} other {# months}}", "age_years": "{years, plural, other {Age #}}", + "album": "एल्बम", "album_added": "एल्बम डाला गया", "album_added_notification_setting_description": "जब आपको किसी साझा एल्बम में जोड़ा जाए तो एक ईमेल सूचना प्राप्त करें", "album_cover_updated": "एल्बम कवर अपडेट किया गया", @@ -475,6 +479,7 @@ "allow_edits": "संपादन की अनुमति दें", "allow_public_user_to_download": "सार्वजनिक उपयोगकर्ता को डाउनलोड करने की अनुमति दें", "allow_public_user_to_upload": "सार्वजनिक उपयोगकर्ता को अपलोड करने की अनुमति दें", + "allowed": "अनुमत", "alt_text_qr_code": "क्यूआर कोड छवि", "anti_clockwise": "वामावर्त", "api_key": "एपीआई की", @@ -710,8 +715,8 @@ "client_cert_import_success_msg": "क्लाइंट प्रमाणपत्र आयात किया गया है", "client_cert_invalid_msg": "अमान्य प्रमाणपत्र फ़ाइल या गलत पासवर्ड", "client_cert_remove_msg": "क्लाइंट प्रमाणपत्र हटा दिया गया है", - "client_cert_subtitle": "केवल PKCS12 (.p12, .pfx) फ़ॉर्मैट का समर्थन करता है। प्रमाणपत्र आयात/हटाएँ केवल लॉगिन से पहले उपलब्ध हैं", - "client_cert_title": "SSL क्लाइंट प्रमाणपत्र", + "client_cert_subtitle": "केवल PKCS12 (.p12, .pfx) प्रारूप का समर्थन करता है। प्रमाणपत्र आयात/निकालना केवल लॉगिन से पहले ही उपलब्ध है।", + "client_cert_title": "SSL क्लाइंट प्रमाणपत्र [प्रायोगिक]", "clockwise": "दक्षिणावर्त", "close": "बंद करें", "collapse": "गिर जाना", @@ -894,8 +899,6 @@ "edit_description_prompt": "कृपया एक नया विवरण चुनें:", "edit_exclusion_pattern": "बहिष्करण पैटर्न संपादित करें", "edit_faces": "चेहरे संपादित करें", - "edit_import_path": "आयात पथ संपादित करें", - "edit_import_paths": "आयात पथ संपादित करें", "edit_key": "कुंजी संपादित करें", "edit_link": "लिंक संपादित करें", "edit_location": "स्थान संपादित करें", @@ -967,7 +970,6 @@ "failed_to_stack_assets": "परिसंपत्तियों का ढेर लगाने में विफल", "failed_to_unstack_assets": "परिसंपत्तियों का ढेर खोलने में विफल", "failed_to_update_notification_status": "सूचना की स्थिति अपडेट करने में विफल", - "import_path_already_exists": "यह आयात पथ पहले से मौजूद है।", "incorrect_email_or_password": "गलत ईमेल या पासवर्ड", "paths_validation_failed": "{paths, plural, one {# पथ} other {# पथ}} सत्यापन में विफल रहे", "profile_picture_transparent_pixels": "प्रोफ़ाइल चित्रों में पारदर्शी पिक्सेल नहीं हो सकते।", @@ -977,7 +979,6 @@ "unable_to_add_assets_to_shared_link": "साझा लिंक में संपत्ति डालने में असमर्थ", "unable_to_add_comment": "टिप्पणी डालने में असमर्थ", "unable_to_add_exclusion_pattern": "बहिष्करण पैटर्न डालने में असमर्थ", - "unable_to_add_import_path": "आयात पथ डालने में असमर्थ", "unable_to_add_partners": "साझेदार डालने में असमर्थ", "unable_to_add_remove_archive": "{archived, select, true {एसेट को संग्रह से हटाने में असमर्थ} other {एसेट को संग्रह में जोड़ने में असमर्थ}}", "unable_to_add_remove_favorites": "{favorite, select, true {एसेट को पसंदीदा में जोड़ने में असमर्थ} other {एसेट को पसंदीदा से हटाने में असमर्थ}}", @@ -1000,12 +1001,10 @@ "unable_to_delete_asset": "संपत्ति हटाने में असमर्थ", "unable_to_delete_assets": "संपत्तियों को हटाने में त्रुटि", "unable_to_delete_exclusion_pattern": "बहिष्करण पैटर्न को हटाने में असमर्थ", - "unable_to_delete_import_path": "आयात पथ हटाने में असमर्थ", "unable_to_delete_shared_link": "साझा लिंक हटाने में असमर्थ", "unable_to_delete_user": "उपयोगकर्ता को हटाने में असमर्थ", "unable_to_download_files": "फ़ाइलें डाउनलोड करने में असमर्थ", "unable_to_edit_exclusion_pattern": "बहिष्करण पैटर्न संपादित करने में असमर्थ", - "unable_to_edit_import_path": "आयात पथ संपादित करने में असमर्थ", "unable_to_empty_trash": "कचरा खाली करने में असमर्थ", "unable_to_enter_fullscreen": "फ़ुलस्क्रीन दर्ज करने में असमर्थ", "unable_to_exit_fullscreen": "फ़ुलस्क्रीन से बाहर निकलने में असमर्थ", @@ -1083,7 +1082,7 @@ "external": "बाहरी", "external_libraries": "बाहरी पुस्तकालय", "external_network": "बाहरी नेटवर्क", - "external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom", + "external_network_sheet_info": "जब पसंदीदा वाई-फाई नेटवर्क पर नहीं होगा, तो ऐप नीचे दिए गए यूआरएल में से पहले के माध्यम से सर्वर से कनेक्ट होगा, ऊपर से नीचे तक शुरू करते हुए", "face_unassigned": "सौंपे नहीं गए", "failed": "विफल हुआ", "failed_to_authenticate": "प्रमाणित करने में विफल", @@ -1095,56 +1094,118 @@ "favorites": "पसंदीदा", "favorites_page_no_favorites": "कोई पसंदीदा एसेट नहीं मिले", "feature_photo_updated": "फ़ीचर फ़ोटो अपडेट किया गया", + "features": "विशेषताएँ", + "features_in_development": "विकास में सुविधाएँ", + "features_setting_description": "ऐप सुविधाओं का प्रबंधन करें", "file_name": "फ़ाइल का नाम", "file_name_or_extension": "फ़ाइल का नाम या एक्सटेंशन", + "file_size": "फ़ाइल का साइज़", "filename": "फ़ाइल का नाम", "filetype": "फाइल का प्रकार", "filter": "फ़िल्टर", "filter_people": "लोगों को फ़िल्टर करें", + "filter_places": "स्थानों को फ़िल्टर करें", "find_them_fast": "खोज के साथ नाम से उन्हें तेजी से ढूंढें", + "first": "पहला", "fix_incorrect_match": "ग़लत मिलान ठीक करें", + "folder": "फ़ोल्डर", + "folder_not_found": "फ़ोल्डर नहीं मिला", + "folders": "फ़ोल्डर", + "folders_feature_description": "फ़ाइल सिस्टम पर फ़ोटो और वीडियो के लिए फ़ोल्डर दृश्य ब्राउज़ करना", + "forgot_pin_code_question": "अपना पिन भूल गए?", "forward": "आगे", + "gcast_enabled": "गूगल कास्ट", + "gcast_enabled_description": "यह सुविधा काम करने के लिए गूगल से बाह्य संसाधन लोड करती है।", "general": "सामान्य", + "geolocation_instruction_location": "किसी परिसंपत्ति के स्थान का उपयोग करने के लिए GPS निर्देशांक वाली परिसंपत्ति पर क्लिक करें, या सीधे मानचित्र से कोई स्थान चुनें", "get_help": "मदद लें", + "get_wifiname_error": "वाई-फ़ाई नाम नहीं मिल सका। सुनिश्चित करें कि आपने आवश्यक अनुमतियाँ दे दी हैं और वाई-फ़ाई नेटवर्क से कनेक्ट हैं", "getting_started": "शुरू करना", "go_back": "वापस जाओ", + "go_to_folder": "फ़ोल्डर पर जाएँ", "go_to_search": "खोज पर जाएँ", + "gps": "GPS", + "gps_missing": "कोई जीपीएस नहीं", + "grant_permission": "अनुमति प्रदान करें", "group_albums_by": "इनके द्वारा समूह एल्बम..।", + "group_country": "देश के अनुसार समूह", "group_no": "कोई समूहीकरण नहीं", "group_owner": "स्वामी द्वारा समूह", + "group_places_by": "स्थानों को समूहबद्ध करें..।", "group_year": "वर्ष के अनुसार समूह", + "haptic_feedback_switch": "स्पर्श प्रतिक्रिया सक्षम करें", + "haptic_feedback_title": "हैप्टिक राय", "has_quota": "कोटा है", - "header_settings_add_header_tip": "Header डालें", + "hash_asset": "हैश परिसंपत्ति", + "hashed_assets": "हैश की गई संपत्तियां", + "hashing": "हैशिंग", + "header_settings_add_header_tip": "हेडर जोड़ें", + "header_settings_field_validator_msg": "मान रिक्त नहीं हो सकता", + "header_settings_header_name_input": "हेडर का नाम", + "header_settings_header_value_input": "हेडर मान", + "headers_settings_tile_title": "कस्टम प्रॉक्सी हेडर", + "hi_user": "नमस्ते {name} ({email})", "hide_all_people": "सभी लोगों को छुपाएं", "hide_gallery": "गैलरी छिपाएँ", + "hide_named_person": "व्यक्ति को छिपाएँ {name}", "hide_password": "पासवर्ड छिपाएं", "hide_person": "व्यक्ति छिपाएँ", "hide_unnamed_people": "अनाम लोगों को छुपाएं", - "home_page_add_to_album_success": "{added} एसेट्स को एल्बम {album} में डाल दिया", + "home_page_add_to_album_conflicts": "{added} संपत्तियां एल्बम {album} में जोड़ी गईं. {failed} संपत्तियां पहले से ही एल्बम में हैं।", + "home_page_add_to_album_err_local": "अभी तक एल्बम में स्थानीय संपत्तियां नहीं जोड़ी जा सकीं, छोड़ दिया गया", + "home_page_add_to_album_success": "एल्बम {album} में {added} संपत्तियां जोड़ी गईं।", "home_page_album_err_partner": "अभी पार्टनर एसेट्स को एल्बम में डाल नहीं सकते, स्किप कर रहे हैं", + "home_page_archive_err_local": "स्थानीय संपत्तियों को अभी संग्रहीत नहीं किया जा सकता, छोड़ा जा रहा है", "home_page_archive_err_partner": "पार्टनर एसेट्स को आर्काइव नहीं कर सकते, स्किप कर रहे हैं", + "home_page_building_timeline": "समयरेखा का निर्माण", "home_page_delete_err_partner": "पार्टनर एसेट्स को डिलीट नहीं कर सकते, स्किप कर रहे हैं", + "home_page_delete_remote_err_local": "दूरस्थ चयन को हटाने, छोड़ने में स्थानीय संपत्तियाँ", + "home_page_favorite_err_local": "स्थानीय संपत्तियों को अभी तक पसंदीदा नहीं बनाया जा सका, छोड़ा जा रहा है", "home_page_favorite_err_partner": "अब तक पार्टनर एसेट्स को फेवरेट नहीं कर सकते, स्किप कर रहे हैं", "home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).", + "home_page_locked_error_local": "स्थानीय संपत्तियों को लॉक किए गए फ़ोल्डर में नहीं ले जाया जा सकता, छोड़ा जा सकता है", + "home_page_locked_error_partner": "साझेदार संपत्तियों को लॉक किए गए फ़ोल्डर में नहीं ले जाया जा सकता, छोड़ें", "home_page_share_err_local": "लोकल एसेट्स को लिंक के जरिए शेयर नहीं कर सकते, स्किप कर रहे हैं", + "home_page_upload_err_limit": "एक समय में अधिकतम 30 संपत्तियां ही अपलोड की जा सकती हैं, छोड़कर", "host": "मेज़बान", "hour": "घंटा", + "hours": "घंटे", + "id": "पहचान", + "idle": "निष्क्रिय", "ignore_icloud_photos": "आइक्लाउड फ़ोटो को अनदेखा करें", "ignore_icloud_photos_description": "आइक्लाउड पर स्टोर की गई फ़ोटोज़ इमिच सर्वर पर अपलोड नहीं की जाएंगी", "image": "छवि", + "image_alt_text_date": "{isVideo, select, true {Video} other {Image}} {date} को लिया गया", + "image_alt_text_date_1_person": "{isVideo, select, true {Video} other {Image}} {person1} के साथ {date} को लिया गया", + "image_alt_text_date_2_people": "{isVideo, select, true {Video} other {Image}} {person1} और {person2} के साथ {date} को लिया गया", + "image_alt_text_date_3_people": "{isVideo, select, true {Video} other {Image}} {person1}, {person2}, और {person3} के साथ {date} को लिया गया", + "image_alt_text_date_4_or_more_people": "{isVideo, select, true {Video} other {Image}} {person1}, {person2}, other {additionalCount, number} अन्य लोगों के साथ {date} को लिया गया", + "image_alt_text_date_place": "{isVideo, select, true {Video} other {Image}} {city}, {country} में {date} को लिया गया", + "image_alt_text_date_place_1_person": "{isVideo, select, true {Video} other {Image}} {city}, {country} में {person1} के साथ {date} को लिया गया", + "image_alt_text_date_place_2_people": "{isVideo, select, true {Video} other {Image}} {city}, {country} में {person1} और {person2} के साथ {date} को लिया गया", + "image_alt_text_date_place_3_people": "{isVideo, select, true {Video} other {Image}} {city}, {country} में {person1}, {person2}, और {person3} के साथ {date} को लिया गया", + "image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Video} other {Image}} {city}, {country} में {person1}, {person2}, और {additionalCount, number} अन्य लोगों के साथ {date} को लिया गया", "image_saved_successfully": "इमेज सहेज दी गई", + "image_viewer_page_state_provider_download_started": "डाउनलोड शुरू", + "image_viewer_page_state_provider_download_success": "डाउनलोड सफल", + "image_viewer_page_state_provider_share_error": "साझा करने में त्रुटि", "immich_logo": "Immich लोगो", "immich_web_interface": "इमिच वेब इंटरफ़ेस", "import_from_json": "JSON से आयात करें", "import_path": "आयात पथ", + "in_albums": "{count, plural, one {# album} other {# albums}} में", "in_archive": "पुरालेख में", + "in_year": "{year} में", + "in_year_selector": "में", "include_archived": "संग्रहीत शामिल करें", "include_shared_albums": "साझा किए गए एल्बम शामिल करें", "include_shared_partner_assets": "साझा भागीदार संपत्तियां शामिल करें", "individual_share": "व्यक्तिगत हिस्सेदारी", + "individual_shares": "व्यक्तिगत शेयर", "info": "जानकारी", "interval": { "day_at_onepm": "हर दिन दोपहर 1 बजे", + "hours": "हर {hours, plural, one {hour} other {{hours, number} hours}}", "night_at_midnight": "हर रात आधी रात को", "night_at_twoam": "हर रात 2 बजे" }, @@ -1152,41 +1213,118 @@ "invalid_date_format": "अमान्य तारीख़ प्रारूप", "invite_people": "लोगो को निमंत्रण भेजो", "invite_to_album": "एल्बम के लिए आमंत्रित करें", + "ios_debug_info_fetch_ran_at": "फ़ेच रन {dateTime}", + "ios_debug_info_last_sync_at": "अंतिम सिंक {dateTime}", + "ios_debug_info_no_processes_queued": "कोई पृष्ठभूमि प्रक्रिया कतारबद्ध नहीं है", + "ios_debug_info_no_sync_yet": "अभी तक कोई पृष्ठभूमि समन्वयन कार्य नहीं चलाया गया है", + "ios_debug_info_processes_queued": "{count, plural, one {{count} background process queued} other {{count} background processes queued}}", + "ios_debug_info_processing_ran_at": "प्रसंस्करण {dateTime} पर चला", + "items_count": "{count, plural, one {# item} other {# items}}", "jobs": "नौकरियां", "keep": "रखना", "keep_all": "सभी रखना", + "keep_this_delete_others": "इसे रखें, अन्य को हटाएँ", + "kept_this_deleted_others": "इस संपत्ति को रखा गया और {count, plural, one {# asset} other {# assets}} को हटा दिया गया", "keyboard_shortcuts": "कुंजीपटल अल्प मार्ग", "language": "भाषा", + "language_no_results_subtitle": "अपने खोज शब्द को समायोजित करने का प्रयास करें", + "language_no_results_title": "कोई भाषा नहीं मिली", + "language_search_hint": "भाषाएं खोजें..।", "language_setting_description": "अपनी पसंदीदा भाषा चुनें", + "large_files": "बड़ी फ़ाइलें", + "last": "अंतिम", + "last_months": "{count, plural, one {Last month} other {Last # months}}", "last_seen": "अंतिम बार देखा गया", "latest_version": "नवीनतम संस्करण", "latitude": "अक्षांश", "leave": "छुट्टी", + "leave_album": "एल्बम छोड़ें", + "lens_model": "लेंस मॉडल", "let_others_respond": "दूसरों को जवाब देने दें", "level": "स्तर", "library": "पुस्तकालय", "library_options": "पुस्तकालय विकल्प", + "library_page_device_albums": "डिवाइस पर एल्बम", + "library_page_new_album": "नया एल्बम", + "library_page_sort_asset_count": "परिसंपत्तियों की संख्या", + "library_page_sort_created": "सृजित दिनांक", + "library_page_sort_last_modified": "अंतिम संशोधन", + "library_page_sort_title": "एल्बम का शीर्षक", + "licenses": "लाइसेंस", "light": "रोशनी", + "like": "पसंद", "like_deleted": "जैसे हटा दिया गया", + "link_motion_video": "लिंक मोशन वीडियो", "link_to_oauth": "OAuth से लिंक करें", "linked_oauth_account": "लिंक किया गया OAuth खाता", "list": "सूची", "loading": "लोड हो रहा है", "loading_search_results_failed": "खोज परिणाम लोड करना विफल रहा", - "location_permission_content": "In order to use the auto-switching feature, Immich needs precise location permission so it can read the current WiFi network's name", + "local": "स्थानीय", + "local_asset_cast_failed": "सर्वर पर अपलोड न की गई संपत्ति को कास्ट करने में असमर्थ", + "local_assets": "स्थानीय संपत्तियाँ", + "local_media_summary": "स्थानीय मीडिया सारांश", + "local_network": "स्थानीय नेटवर्क", + "local_network_sheet_info": "निर्दिष्ट वाई-फाई नेटवर्क का उपयोग करते समय ऐप इस URL के माध्यम से सर्वर से कनेक्ट होगा", + "location": "स्थान", + "location_permission": "स्थान की अनुमति", + "location_permission_content": "ऑटो-स्विचिंग सुविधा का उपयोग करने के लिए,Immich को सटीक स्थान अनुमति की आवश्यकता होती है ताकि वह वर्तमान वाई-फाई नेटवर्क का नाम पढ़ सके", + "location_picker_choose_on_map": "मानचित्र पर चुनें", + "location_picker_latitude_error": "मान्य अक्षांश दर्ज करें", + "location_picker_latitude_hint": "अपना अक्षांश यहां दर्ज करें", + "location_picker_longitude_error": "एक मान्य देशांतर दर्ज करें", + "location_picker_longitude_hint": "अपना देशांतर यहाँ दर्ज करें", + "lock": "ताला", + "locked_folder": "लॉक किया गया फ़ोल्डर", + "log_detail_title": "लॉग विवरण", "log_out": "लॉग आउट", "log_out_all_devices": "सभी डिवाइस लॉग आउट करें", + "logged_in_as": "{user} के रूप में लॉग इन किया गया", "logged_out_all_devices": "सभी डिवाइस लॉग आउट कर दिए गए", "logged_out_device": "लॉग आउट डिवाइस", "login": "लॉग इन करें", + "login_disabled": "लॉगिन अक्षम कर दिया गया है", + "login_form_api_exception": "API अपवाद. कृपया सर्वर URL जाँचें और पुनः प्रयास करें।", + "login_form_back_button_text": "पीछे", + "login_form_email_hint": "youremail@email.com", + "login_form_endpoint_hint": "http://आपका-सर्वर-आईपी:पोर्ट", + "login_form_endpoint_url": "सर्वर एंडपॉइंट URL", + "login_form_err_http": "कृपया http:// या https:// निर्दिष्ट करें", + "login_form_err_invalid_email": "अमान्य ईमेल", + "login_form_err_invalid_url": "असामान्य यूआरएल", + "login_form_err_leading_whitespace": "अग्रणी रिक्त स्थान", + "login_form_err_trailing_whitespace": "अनुगामी रिक्त स्थान", + "login_form_failed_get_oauth_server_config": "OAuth का उपयोग करते समय त्रुटि लॉगिंग, सर्वर URL की जाँच करें", + "login_form_failed_get_oauth_server_disable": "इस सर्वर पर OAuth सुविधा उपलब्ध नहीं है", + "login_form_failed_login": "लॉग इन करते समय त्रुटि हुई, सर्वर URL, ईमेल और पासवर्ड जांचें", + "login_form_handshake_exception": "सर्वर में एक हैंडशेक अपवाद था। यदि आप स्व-हस्ताक्षरित प्रमाणपत्र का उपयोग कर रहे हैं, तो सेटिंग्स में स्व-हस्ताक्षरित प्रमाणपत्र समर्थन सक्षम करें।", + "login_form_password_hint": "पासवर्ड", + "login_form_save_login": "लॉग इन रहें", + "login_form_server_empty": "सर्वर URL दर्ज करें।", + "login_form_server_error": "सर्वर से कनेक्ट नहीं कर सका।", "login_has_been_disabled": "लॉगिन अक्षम कर दिया गया है।", + "login_password_changed_error": "आपका पासवर्ड अपडेट करते समय एक त्रुटि हुई", + "login_password_changed_success": "पासवर्ड सफलतापूर्वक अद्यतन", "logout_all_device_confirmation": "क्या आप वाकई सभी डिवाइस से लॉग आउट करना चाहते हैं?", "logout_this_device_confirmation": "क्या आप वाकई इस डिवाइस को लॉग आउट करना चाहते हैं?", + "logs": "लॉग्स", "longitude": "देशान्तर", "look": "देखना", "loop_videos": "लूप वीडियो", "loop_videos_description": "विवरण व्यूअर में किसी वीडियो को स्वचालित रूप से लूप करने में सक्षम करें।", + "main_branch_warning": "आप विकास संस्करण का उपयोग कर रहे हैं; हम दृढ़ता से रिलीज़ संस्करण का उपयोग करने की अनुशंसा करते हैं!", + "main_menu": "मेनू चलाएँ", + "maintenance_description": "Immich को मेंटेनेंस मोड में डाल दिया गया है।", + "maintenance_end": "रखरखाव मोड समाप्त करें", + "maintenance_end_error": "मेंटेनेंस मोड खत्म नहीं हो सका।", + "maintenance_logged_in_as": "अभी {user} के तौर पर लॉग इन हैं", + "maintenance_title": "अस्थाई रूप से अनुपलब्ध", "make": "बनाना", + "manage_geolocation": "स्थान प्रबंधित करें", + "manage_media_access_rationale": "यह अनुमति परिसंपत्तियों को कूड़ेदान में ले जाने तथा वहां से उन्हें वापस लाने के उचित प्रबंधन के लिए आवश्यक है।", + "manage_media_access_settings": "खुली सेटिंग", + "manage_media_access_subtitle": "Immich ऐप को मीडिया फ़ाइलों को प्रबंधित करने और स्थानांतरित करने की अनुमति दें।", + "manage_media_access_title": "मीडिया प्रबंधन पहुँच", "manage_shared_links": "साझा किए गए लिंक का प्रबंधन करें", "manage_sharing_with_partners": "साझेदारों के साथ साझाकरण प्रबंधित करें", "manage_the_app_settings": "ऐप सेटिंग प्रबंधित करें", @@ -1195,34 +1333,92 @@ "manage_your_devices": "अपने लॉग-इन डिवाइस प्रबंधित करें", "manage_your_oauth_connection": "अपना OAuth कनेक्शन प्रबंधित करें", "map": "नक्शा", + "map_assets_in_bounds": "{count, plural, =0 {No photos in this area} one {# photo} other {# photos}}", + "map_cannot_get_user_location": "उपयोगकर्ता का स्थान प्राप्त नहीं किया जा सका", + "map_location_dialog_yes": "हाँ", + "map_location_picker_page_use_location": "इस स्थान का उपयोग करें", + "map_location_service_disabled_content": "आपके वर्तमान स्थान की संपत्तियाँ प्रदर्शित करने के लिए स्थान सेवा सक्षम होनी चाहिए। क्या आप इसे अभी सक्षम करना चाहते हैं?", + "map_location_service_disabled_title": "स्थान सेवा अक्षम", + "map_marker_for_images": "{city}, {country} में ली गई छवियों के लिए मानचित्र मार्कर", "map_marker_with_image": "छवि के साथ मानचित्र मार्कर", + "map_no_location_permission_content": "आपके वर्तमान स्थान से संपत्तियाँ प्रदर्शित करने के लिए स्थान अनुमति आवश्यक है। क्या आप इसे अभी अनुमति देना चाहते हैं?", + "map_no_location_permission_title": "स्थान की अनुमति अस्वीकृत", "map_settings": "मानचित्र सेटिंग", + "map_settings_dark_mode": "डार्क मोड", + "map_settings_date_range_option_day": "पिछले 24 घंटे", + "map_settings_date_range_option_days": "पिछले {days} दिन", + "map_settings_date_range_option_year": "पिछले एक साल", + "map_settings_date_range_option_years": "पिछले {years} वर्ष", + "map_settings_dialog_title": "मानचित्र सेटिंग्स", + "map_settings_include_show_archived": "संग्रहीत शामिल करें", + "map_settings_include_show_partners": "भागीदारों को शामिल करें", + "map_settings_only_show_favorites": "केवल पसंदीदा दिखाएँ", + "map_settings_theme_settings": "मानचित्र थीम", + "map_zoom_to_see_photos": "फ़ोटो देखने के लिए ज़ूम आउट करें", + "mark_all_as_read": "सभी को पढ़ा हुआ मार्क करें", + "mark_as_read": "पढ़े हुए का चिह्न", + "marked_all_as_read": "सभी को पढ़ा हुआ चिह्नित किया गया", "matches": "माचिस", + "matching_assets": "मिलान संपत्तियां", "media_type": "मीडिया प्रकार", "memories": "यादें", + "memories_all_caught_up": "सारी जानकारी प्राप्त", + "memories_check_back_tomorrow": "अधिक यादों के लिए कल पुनः आइए", "memories_setting_description": "आप अपनी यादों में जो देखते हैं उसे प्रबंधित करें", + "memories_start_over": "प्रारंभ करें", + "memories_swipe_to_close": "बंद करने के लिए ऊपर स्वाइप करें", "memory": "याद", + "memory_lane_title": "स्मृति लेन {title}", "menu": "मेन्यू", "merge": "मर्ज", "merge_people": "लोगों को मिलाओ", "merge_people_limit": "आप एक समय में अधिकतम 5 चेहरों को ही मर्ज कर सकते हैं", "merge_people_prompt": "क्या आप इन लोगों का विलय करना चाहते हैं? यह कार्रवाई अपरिवर्तनीय है।", "merge_people_successfully": "लोगों को सफलतापूर्वक मर्ज करें", + "merged_people_count": "विलयित {count, plural, one {# person} other {# people}}", "minimize": "छोटा करना", "minute": "मिनट", + "minutes": "मिनट", "missing": "गुम", + "mobile_app": "मोबाइल एप्लिकेशन", + "mobile_app_download_onboarding_note": "निम्नलिखित विकल्पों का उपयोग करके साथी मोबाइल ऐप डाउनलोड करें", "model": "मॉडल", "month": "महीना", + "monthly_title_text_date_format": "एमएमएमएम वाई", "more": "अधिक", + "move": "स्थान परिवर्तन", + "move_off_locked_folder": "लॉक किए गए फ़ोल्डर से बाहर ले जाएं", + "move_to": "करने के लिए कदम", + "move_to_lock_folder_action_prompt": "{count} लॉक किए गए फ़ोल्डर में जोड़ा गया", + "move_to_locked_folder": "लॉक किए गए फ़ोल्डर में ले जाएं", + "move_to_locked_folder_confirmation": "ये फ़ोटो और वीडियो सभी एल्बमों से हटा दिए जाएँगे और केवल लॉक किए गए फ़ोल्डर से ही देखे जा सकेंगे", + "moved_to_archive": "{count, plural, one {# asset} other {# assets}} को संग्रह में ले जाया गया", + "moved_to_library": "{count, plural, one {# asset} other {# assets}} को लाइब्रेरी में ले जाया गया", "moved_to_trash": "कूड़ेदान में ले जाया गया", + "multiselect_grid_edit_date_time_err_read_only": "केवल पढ़ने योग्य परिसंपत्ति(यों) की तिथि संपादित नहीं की जा सकती, छोड़ी जा रही है", + "multiselect_grid_edit_gps_err_read_only": "केवल पढ़ने योग्य परिसंपत्ति(यों) का स्थान संपादित नहीं किया जा सकता, छोड़ा जा रहा है", + "mute_memories": "मूक यादें", "my_albums": "मेरे एल्बम", "name": "नाम", "name_or_nickname": "नाम या उपनाम", + "navigate": "नेविगेट", + "navigate_to_time": "समय पर नेविगेट करें", + "network_requirement_photos_upload": "फ़ोटो का बैकअप लेने के लिए सेलुलर डेटा का उपयोग करें", + "network_requirement_videos_upload": "वीडियो का बैकअप लेने के लिए सेलुलर डेटा का उपयोग करें", + "network_requirements": "नेटवर्क आवश्यकताएँ", + "network_requirements_updated": "नेटवर्क आवश्यकताएँ बदली गईं, बैकअप कतार रीसेट की जा रही है", + "networking_settings": "नेटवर्किंग", + "networking_subtitle": "सर्वर एंडपॉइंट सेटिंग्स प्रबंधित करें", "never": "कभी नहीं", "new_album": "नयी एल्बम", "new_api_key": "नई एपीआई कुंजी", + "new_date_range": "नई तिथि सीमा", "new_password": "नया पासवर्ड", "new_person": "नया व्यक्ति", + "new_pin_code": "नया पिन कोड", + "new_pin_code_subtitle": "आप पहली बार लॉक किए गए फ़ोल्डर तक पहुँच रहे हैं। इस पृष्ठ तक सुरक्षित रूप से पहुँचने के लिए एक पिन कोड बनाएँ", + "new_timeline": "नई समयरेखा", + "new_update": "नई अपडेट", "new_user_created": "नया उपयोगकर्ता बनाया गया", "new_version_available": "नया संस्करण उपलब्ध है", "newest_first": "नवीनतम पहले", @@ -1234,44 +1430,87 @@ "no_albums_yet": "ऐसा लगता है कि आपके पास अभी तक कोई एल्बम नहीं है।", "no_archived_assets_message": "फ़ोटो और वीडियो को अपने फ़ोटो दृश्य से छिपाने के लिए उन्हें संग्रहीत करें", "no_assets_message": "अपना पहला फोटो अपलोड करने के लिए क्लिक करें", + "no_assets_to_show": "दिखाने के लिए कोई संपत्ति नहीं", + "no_cast_devices_found": "कोई कास्ट डिवाइस नहीं मिला", + "no_checksum_local": "कोई चेकसम उपलब्ध नहीं है - स्थानीय संपत्तियां प्राप्त नहीं की जा सकतीं", + "no_checksum_remote": "कोई चेकसम उपलब्ध नहीं है - दूरस्थ संपत्ति प्राप्त नहीं की जा सकती", + "no_devices": "कोई अधिकृत उपकरण नहीं", "no_duplicates_found": "कोई नकलची नहीं मिला।", "no_exif_info_available": "कोई एक्सिफ़ जानकारी उपलब्ध नहीं है", "no_explore_results_message": "अपने संग्रह का पता लगाने के लिए और फ़ोटो अपलोड करें।", "no_favorites_message": "अपनी सर्वश्रेष्ठ तस्वीरें और वीडियो तुरंत ढूंढने के लिए पसंदीदा जोड़ें", "no_libraries_message": "अपनी फ़ोटो और वीडियो देखने के लिए एक बाहरी लाइब्रेरी बनाएं", + "no_local_assets_found": "इस चेकसम के साथ कोई स्थानीय संपत्ति नहीं मिली", + "no_locked_photos_message": "लॉक किए गए फ़ोल्डर में मौजूद फ़ोटो और वीडियो छिपे हुए हैं और जब आप अपनी लाइब्रेरी ब्राउज़ या खोजेंगे तो वे दिखाई नहीं देंगे।", "no_name": "कोई नाम नहीं", + "no_notifications": "कोई सूचना नहीं", + "no_people_found": "कोई मेल खाता व्यक्ति नहीं मिला", "no_places": "कोई जगह नहीं", + "no_remote_assets_found": "इस चेकसम के साथ कोई दूरस्थ संपत्ति नहीं मिली", "no_results": "कोई परिणाम नहीं", "no_results_description": "कोई पर्यायवाची या अधिक सामान्य कीवर्ड आज़माएँ", "no_shared_albums_message": "अपने नेटवर्क में लोगों के साथ फ़ोटो और वीडियो साझा करने के लिए एक एल्बम बनाएं", + "no_uploads_in_progress": "कोई अपलोड प्रगति पर नहीं है", + "not_allowed": "अनुमति नहीं", + "not_available": "लागू नहीं", "not_in_any_album": "किसी एलबम में नहीं", + "not_selected": "चयनित नहीं", "note_apply_storage_label_to_previously_uploaded assets": "नोट: पहले अपलोड की गई संपत्तियों पर स्टोरेज लेबल लागू करने के लिए, चलाएँ", "notes": "टिप्पणियाँ", + "nothing_here_yet": "यहाँ अभी तक कुछ नहीं", + "notification_permission_dialog_content": "सूचनाएं सक्षम करने के लिए सेटिंग्स में जाएं और अनुमति दें चुनें।", + "notification_permission_list_tile_content": "अधिसूचनाएं सक्षम करने की अनुमति प्रदान करें।", + "notification_permission_list_tile_enable_button": "सूचनाएं सक्षम करें", + "notification_permission_list_tile_title": "अधिसूचना अनुमति", "notification_toggle_setting_description": "ईमेल सूचनाएं सक्षम करें", "notifications": "सूचनाएं", "notifications_setting_description": "सूचनाएं प्रबंधित करें", + "oauth": "OAuth", + "obtainium_configurator": "ओब्टेनियम विन्यासक", + "obtainium_configurator_instructions": "Immich GitHub रिलीज़ से सीधे Android ऐप इंस्टॉल और अपडेट करने के लिए Obtainium का उपयोग करें। अपना Obtainium कॉन्फ़िगरेशन लिंक बनाने के लिए एक API कुंजी बनाएँ और एक वैरिएंट चुनें", + "ocr": "ओसीआर", + "official_immich_resources": "आधिकारिक Immich संसाधन", "offline": "ऑफलाइन", + "offset": "ओफ़्सेट", "ok": "ठीक है", "oldest_first": "सबसे पुराना पहले", "on_this_device": "इस डिवाइस पर", "onboarding": "ज्ञानप्राप्ति", + "onboarding_locale_description": "अपनी पसंदीदा भाषा चुनें। आप इसे बाद में अपनी सेटिंग में बदल सकते हैं।", + "onboarding_privacy_description": "निम्नलिखित (वैकल्पिक) सुविधाएं बाहरी सेवाओं पर निर्भर करती हैं, और इन्हें सेटिंग्स में किसी भी समय अक्षम किया जा सकता है।", + "onboarding_server_welcome_description": "आइए, कुछ सामान्य सेटिंग्स के साथ आपका इंस्टेंस सेट अप करें।", "onboarding_theme_description": "अपने उदाहरण के लिए एक रंग थीम चुनें।", + "onboarding_user_welcome_description": "चलिए शुरू करते हैं!", + "onboarding_welcome_user": "स्वागत है, {user}", "online": "ऑनलाइन", "only_favorites": "केवल पसंदीदा", + "open": "खुला", + "open_in_map_view": "मानचित्र दृश्य में खोलें", "open_in_openstreetmap": "OpenStreetMap में खोलें", "open_the_search_filters": "खोज फ़िल्टर खोलें", "options": "विकल्प", "or": "या", + "organize_into_albums": "एल्बम में व्यवस्थित करें", + "organize_into_albums_description": "वर्तमान सिंक सेटिंग्स का उपयोग करके मौजूदा फ़ोटो को एल्बम में डालें", "organize_your_library": "अपनी लाइब्रेरी व्यवस्थित करें", "original": "मूल", "other": "अन्य", "other_devices": "अन्य उपकरण", + "other_entities": "अन्य संस्थाएँ", "other_variables": "अन्य चर", "owned": "स्वामित्व", "owner": "मालिक", "partner": "साथी", + "partner_can_access": "{partner} एक्सेस कर सकते हैं", "partner_can_access_assets": "संग्रहीत और हटाए गए को छोड़कर आपके सभी फ़ोटो और वीडियो", "partner_can_access_location": "वह स्थान जहां आपकी तस्वीरें ली गईं थीं", + "partner_list_user_photos": "{user} की तस्वीरें", + "partner_list_view_all": "सभी को देखें", + "partner_page_empty_message": "आपकी तस्वीरें अभी तक किसी भी भागीदार के साथ साझा नहीं की गई हैं।", + "partner_page_no_more_users": "अब और कोई उपयोगकर्ता जोड़ने की आवश्यकता नहीं है", + "partner_page_partner_add_failed": "भागीदार जोड़ने में विफल", + "partner_page_select_partner": "भागीदार चुनें", + "partner_page_shared_to_title": "साझा किया गया", "partner_page_stop_sharing_content": "{partner} will no longer be able to access your photos।", "partner_sharing": "पार्टनर शेयरिंग", "partners": "भागीदारों", @@ -1279,6 +1518,11 @@ "password_does_not_match": "पासवर्ड मैच नहीं कर रहा है", "password_required": "पासवर्ड आवश्यक", "password_reset_success": "पासवर्ड रीसेट सफल", + "past_durations": { + "days": "पिछले {days, plural, one {day} other {# days}}", + "hours": "पिछले {hours, plural, one {hour} other {# hours}}", + "years": "पिछले {years, plural, one {year} other {# years}}" + }, "path": "पथ", "pattern": "नमूना", "pause": "विराम", @@ -1286,37 +1530,81 @@ "paused": "रोके गए", "pending": "लंबित", "people": "लोग", + "people_edits_count": "संपादित {count, plural, one {# person} other {# people}}", + "people_feature_description": "लोगों द्वारा समूहीकृत फ़ोटो और वीडियो ब्राउज़ करना", "people_sidebar_description": "साइडबार में लोगों के लिए एक लिंक प्रदर्शित करें", "permanent_deletion_warning": "स्थायी विलोपन चेतावनी", "permanent_deletion_warning_setting_description": "संपत्तियों को स्थायी रूप से हटाते समय एक चेतावनी दिखाएं", "permanently_delete": "स्थायी रूप से हटाना", + "permanently_delete_assets_count": "{count, plural, one {asset} other {assets}} को स्थायी रूप से हटाएं", + "permanently_delete_assets_prompt": "क्या आप वाकई {count, plural, one {this asset?} other {these # assets?}} को स्थायी रूप से हटाना चाहते हैं? इससे {count, plural, one {it from its} other {them from their}} एल्बम भी हट जाएंगे।", "permanently_deleted_asset": "स्थायी रूप से हटाई गई संपत्ति", + "permanently_deleted_assets_count": "स्थायी रूप से हटा दिया गया {count, plural, one {# asset} other {# assets}}", + "permission": "अनुमति", + "permission_empty": "आपकी अनुमति खाली नहीं होनी चाहिए", "permission_onboarding_back": "वापस", + "permission_onboarding_continue_anyway": "फिर भी जारी रखें", + "permission_onboarding_get_started": "शुरू हो जाओ", + "permission_onboarding_go_to_settings": "सेटिंग्स पर जाएँ", + "permission_onboarding_permission_denied": "अनुमति अस्वीकृत। Immich का उपयोग करने के लिए, सेटिंग में फ़ोटो और वीडियो की अनुमति दें।", + "permission_onboarding_permission_granted": "अनुमति मिल गई! आप तैयार हैं।", + "permission_onboarding_permission_limited": "अनुमति सीमित है। Immich को आपके संपूर्ण गैलरी संग्रह का बैकअप लेने और उसे प्रबंधित करने की अनुमति देने के लिए, सेटिंग में फ़ोटो और वीडियो की अनुमति दें।", + "permission_onboarding_request": "Immich को आपकी तस्वीरें और वीडियो देखने के लिए अनुमति की आवश्यकता है।", "person": "व्यक्ति", + "person_age_months": "{months, plural, one {# month} other {# months}} पुराना", + "person_age_year_months": "1 वर्ष, {months, plural, one {# month} other {# months}} पुराना", + "person_age_years": "{years, plural, other {# years}} पुराना", + "person_birthdate": "{date} को जन्मे", + "person_hidden": "{name}{hidden, select, true { (hidden)} other {}}", "photo_shared_all_users": "ऐसा लगता है कि आपने अपनी तस्वीरें सभी उपयोगकर्ताओं के साथ साझा कीं या आपके पास साझा करने के लिए कोई उपयोगकर्ता नहीं है।", "photos": "तस्वीरें", "photos_and_videos": "तस्वीरें और वीडियो", + "photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}", "photos_from_previous_years": "पिछले वर्षों की तस्वीरें", "pick_a_location": "एक स्थान चुनें", + "pick_custom_range": "कस्टम रेंज", + "pick_date_range": "दिनांक सीमा चुनें", + "pin_code_changed_successfully": "पिन कोड सफलतापूर्वक बदला गया", + "pin_code_reset_successfully": "पिन कोड सफलतापूर्वक रीसेट किया गया", + "pin_code_setup_successfully": "पिन कोड सफलतापूर्वक सेट किया गया", + "pin_verification": "पिन कोड सत्यापन", "place": "जगह", "places": "स्थानों", + "places_count": "{count, plural, one {{count, number} Place} other {{count, number} Places}}", "play": "खेल", "play_memories": "यादें खेलें", "play_motion_photo": "मोशन फ़ोटो चलाएं", "play_or_pause_video": "वीडियो चलाएं या रोकें", + "play_original_video": "मूल वीडियो चलाएँ", + "play_original_video_setting_description": "ट्रांसकोड किए गए वीडियो के बजाय मूल वीडियो के प्लेबैक को प्राथमिकता दें। यदि मूल एसेट संगत नहीं है, तो हो सकता है कि वह ठीक से प्लेबैक न हो।", + "play_transcoded_video": "ट्रांसकोडेड वीडियो चलाएं", + "please_auth_to_access": "कृपया पहुँच के लिए प्रमाणित करें", "port": "पत्तन", + "preferences_settings_subtitle": "ऐप की प्राथमिकताएँ प्रबंधित करें", + "preferences_settings_title": "प्राथमिकताएँ", + "preparing": "तैयारी", "preset": "प्रीसेट", "preview": "पूर्व दर्शन", "previous": "पहले का", "previous_memory": "पिछली स्मृति", - "previous_or_next_photo": "पिछला या अगला फ़ोटो", + "previous_or_next_day": "दिन आगे/पीछे", + "previous_or_next_month": "महीना आगे/पीछे", + "previous_or_next_photo": "फ़ोटो आगे/पीछे", + "previous_or_next_year": "वर्ष आगे/पीछे", "primary": "प्राथमिक", + "privacy": "गोपनीयता", + "profile": "प्रोफ़ाइल", + "profile_drawer_app_logs": "लॉग्स", + "profile_drawer_client_server_up_to_date": "क्लाइंट और सर्वर अद्यतित हैं", "profile_drawer_github": "गिटहब", + "profile_drawer_readonly_mode": "केवल-पठन मोड सक्षम है। बाहर निकलने के लिए उपयोगकर्ता अवतार आइकन को देर तक दबाएँ।", + "profile_image_of_user": "{user} की प्रोफ़ाइल छवि", "profile_picture_set": "प्रोफ़ाइल चित्र सेट।", "public_album": "सार्वजनिक एल्बम", "public_share": "सार्वजनिक शेयर", "purchase_account_info": "समर्थक", "purchase_activated_subtitle": "इमिच और ओपन-सोर्स सॉफ़्टवेयर का समर्थन करने के लिए धन्यवाद", + "purchase_activated_time": "{date} को सक्रिय किया गया", "purchase_activated_title": "आपकी कुंजी सफलतापूर्वक सक्रिय कर दी गई है", "purchase_button_activate": "सक्रिय", "purchase_button_buy": "खरीदना", @@ -1334,7 +1622,7 @@ "purchase_lifetime_description": "जीवन भर की खरीदारी", "purchase_option_title": "खरीद विकल्प", "purchase_panel_info_1": "इमिच को बनाने में बहुत समय और प्रयास लगता है, और हमारे पास इसे जितना संभव हो सके उतना अच्छा बनाने के लिए पूर्णकालिक इंजीनियर इस पर काम कर रहे हैं।", - "purchase_panel_info_2": "चूंकि हम पेवॉल नहीं जोड़ने के लिए प्रतिबद्ध हैं, इसलिए यह खरीदारी आपको इमिच में कोई अतिरिक्त सुविधाएं नहीं देगी।", + "purchase_panel_info_2": "चूँकि हम पेवॉल नहीं जोड़ने के लिए प्रतिबद्ध हैं, इसलिए इस खरीदारी से आपको Immich में कोई अतिरिक्त सुविधाएँ नहीं मिलेंगी। Immich के निरंतर विकास में सहयोग के लिए हम आप जैसे उपयोगकर्ताओं पर निर्भर हैं।", "purchase_panel_title": "परियोजना का समर्थन करें", "purchase_per_server": "प्रति सर्वर", "purchase_per_user": "प्रति उपयोगकर्ता", @@ -1346,33 +1634,67 @@ "purchase_server_description_2": "समर्थक स्थिति", "purchase_server_title": "सर्वर", "purchase_settings_server_activated": "सर्वर उत्पाद कुंजी व्यवस्थापक द्वारा प्रबंधित की जाती है", + "query_asset_id": "क्वेरी एसेट आईडी", + "queue_status": "कतारबद्ध {count}/{total}", + "rating": "स्टार रेटिंग", + "rating_clear": "स्पष्ट रेटिंग", + "rating_count": "{count, plural, one {# star} other {# stars}}", + "rating_description": "जानकारी पैनल में EXIF रेटिंग प्रदर्शित करें", "reaction_options": "प्रतिक्रिया विकल्प", "read_changelog": "चेंजलॉग पढ़ें", + "readonly_mode_disabled": "केवल-पढ़ने के लिए मोड अक्षम", + "readonly_mode_enabled": "केवल-पढ़ने के लिए मोड सक्षम", + "ready_for_upload": "अपलोड के लिए तैयार", "reassign": "पुनः असाइन", + "reassigned_assets_to_existing_person": "{count, plural, one {# asset} other {# assets}} को {name, select, null {an existing person} other {{name}}} को फिर से असाइन किया गया", + "reassigned_assets_to_new_person": "{count, plural, one {# asset} other {# assets}} को एक नए व्यक्ति को फिर से असाइन किया गया", "reassing_hint": "चयनित संपत्तियों को किसी मौजूदा व्यक्ति को सौंपें", "recent": "हाल ही का", + "recent-albums": "हाल के एल्बम", "recent_searches": "हाल की खोजें", "recently_added": "हाल ही में डाला गया", "recently_added_page_title": "हाल ही में डाला गया", + "recently_taken": "हाल ही में लिया गया", + "recently_taken_page_title": "हाल ही में लिया गया", "refresh": "ताज़ा करना", "refresh_encoded_videos": "एन्कोडेड वीडियो ताज़ा करें", + "refresh_faces": "चेहरे ताज़ा करें", "refresh_metadata": "मेटाडेटा ताज़ा करें", "refresh_thumbnails": "थंबनेल ताज़ा करें", "refreshed": "ताज़ा किया", "refreshes_every_file": "प्रत्येक फ़ाइल को ताज़ा करता है", "refreshing_encoded_video": "ताज़ा किया जा रहा एन्कोडेड वीडियो", + "refreshing_faces": "ताज़ा चेहरे", "refreshing_metadata": "ताज़ा मेटाडेटा", "regenerating_thumbnails": "पुनर्जीवित थंबनेल", + "remote": "रिमोट", + "remote_assets": "दूरस्थ संपत्तियाँ", + "remote_media_summary": "रिमोट मीडिया सारांश", "remove": "निकालना", + "remove_assets_album_confirmation": "क्या आप वाकई एल्बम से {count, plural, one {# asset} other {# assets}} हटाना चाहते हैं?", + "remove_assets_shared_link_confirmation": "क्या आप वाकई इस शेयर्ड लिंक से {count, plural, one {# asset} other {# assets}} हटाना चाहते हैं?", "remove_assets_title": "संपत्तियाँ हटाएँ?", "remove_custom_date_range": "कस्टम दिनांक सीमा हटाएँ", "remove_deleted_assets": "ऑफ़लाइन फ़ाइलें हटाएँ", "remove_from_album": "एल्बम से हटाएँ", + "remove_from_album_action_prompt": "एल्बम से {count} हटा दिया गया", "remove_from_favorites": "पसंदीदा से निकालें", + "remove_from_lock_folder_action_prompt": "लॉक किए गए फ़ोल्डर से {count} हटा दिया गया", + "remove_from_locked_folder": "लॉक किए गए फ़ोल्डर से निकालें", + "remove_from_locked_folder_confirmation": "क्या आप वाकई इन फ़ोटो और वीडियो को लॉक किए गए फ़ोल्डर से बाहर ले जाना चाहते हैं? वे आपकी लाइब्रेरी में दिखाई देंगे।", "remove_from_shared_link": "साझा लिंक से हटाएँ", + "remove_memory": "मेमोरी हटाएँ", + "remove_photo_from_memory": "इस मेमोरी से फ़ोटो हटाएँ", + "remove_tag": "टैग हटाएँ", + "remove_url": "URL हटाएँ", "remove_user": "उपयोगकर्ता को हटाएँ", + "removed_api_key": "हटाई गई API कुंजी: {name}", "removed_from_archive": "संग्रह से हटा दिया गया", "removed_from_favorites": "पसंदीदा से हटाया गया", + "removed_from_favorites_count": "पसंदीदा से {count, plural, other {Removed #}}", + "removed_memory": "हटाई गई मेमोरी", + "removed_photo_from_memory": "मेमोरी से फ़ोटो हटा दी गई", + "removed_tagged_assets": "{count, plural, one {# asset} other {# assets}} से टैग हटाया गया", "rename": "नाम बदलें", "repair": "मरम्मत", "repair_no_results_message": "ट्रैक न की गई और गुम फ़ाइलें यहां दिखाई देंगी", @@ -1380,64 +1702,113 @@ "repository": "कोष", "require_password": "पासवर्ड की आवश्यकता है", "require_user_to_change_password_on_first_login": "उपयोगकर्ता को पहले लॉगिन पर पासवर्ड बदलने की आवश्यकता है", + "rescan": "पुन: स्कैन", "reset": "रीसेट", "reset_password": "पासवर्ड रीसेट", "reset_people_visibility": "लोगों की दृश्यता रीसेट करें", + "reset_pin_code": "पिन कोड रीसेट करें", + "reset_pin_code_description": "अगर आप अपना PIN कोड भूल गए हैं, तो आप इसे रीसेट करने के लिए सर्वर एडमिनिस्ट्रेटर से संपर्क कर सकते हैं", + "reset_pin_code_success": "पिन कोड सफलतापूर्वक रीसेट किया गया", + "reset_pin_code_with_password": "आप हमेशा अपने पासवर्ड से अपना पिन कोड रीसेट कर सकते हैं", + "reset_sqlite": "SQLite डेटाबेस रीसेट करें", + "reset_sqlite_confirmation": "क्या आप वाकई SQLite डेटाबेस को रीसेट करना चाहते हैं? डेटा को फिर से सिंक करने के लिए आपको लॉग आउट करके फिर से लॉग इन करना होगा", + "reset_sqlite_success": "SQLite डेटाबेस को सफलतापूर्वक रीसेट करें", "reset_to_default": "वितथ पर ले जाएं", + "resolution": "संकल्प", "resolve_duplicates": "डुप्लिकेट का समाधान करें", "resolved_all_duplicates": "सभी डुप्लिकेट का समाधान किया गया", "restore": "पुनर्स्थापित करना", "restore_all": "सभी बहाल करो", + "restore_trash_action_prompt": "{count} ट्रैश से पुनर्स्थापित किया गया", "restore_user": "उपयोगकर्ता को पुनर्स्थापित करें", "restored_asset": "पुनर्स्थापित संपत्ति", "resume": "फिर शुरू करना", + "resume_paused_jobs": "रिज्यूमे {count, plural, one {# paused job} other {# paused jobs}}", "retry_upload": "पुनः अपलोड करने का प्रयास करें", "review_duplicates": "डुप्लिकेट की समीक्षा करें", + "review_large_files": "बड़ी फ़ाइलों की समीक्षा करें", "role": "भूमिका", "role_editor": "संपादक", "role_viewer": "दर्शक", + "running": "चल रहा है", "save": "बचाना", "save_to_gallery": "गैलरी में सहेजें", + "saved": "सहेजा गया", "saved_api_key": "सहेजी गई एपीआई कुंजी", "saved_profile": "प्रोफ़ाइल सहेजी गई", "saved_settings": "सहेजी गई सेटिंग्स", "say_something": "कुछ कहें", + "scaffold_body_error_occurred": "त्रुटि हुई", "scan_all_libraries": "सभी पुस्तकालयों को स्कैन करें", + "scan_library": "स्कैन", "scan_settings": "सेटिंग्स स्कैन करें", "scanning_for_album": "एल्बम के लिए स्कैन किया जा रहा है..।", "search": "खोज", "search_albums": "एल्बम खोजें", "search_by_context": "संदर्भ के आधार पर खोजें", + "search_by_description": "विवरण के अनुसार खोजें", + "search_by_description_example": "सापा में हाइकिंग का दिन", "search_by_filename": "फ़ाइल नाम या एक्सटेंशन के आधार पर खोजें", "search_by_filename_example": "यानी IMG_1234.JPG या PNG", + "search_by_ocr": "OCR द्वारा खोजें", + "search_by_ocr_example": "लट्टे", + "search_camera_lens_model": "लेंस मॉडल खोजें..।", "search_camera_make": "कैमरा निर्माण खोजें..।", "search_camera_model": "कैमरा मॉडल खोजें..।", "search_city": "शहर खोजें..।", "search_country": "देश खोजें..।", + "search_filter_apply": "फ़िल्टर लागू करें", "search_filter_camera_title": "कैमरा प्रकार चुनें", "search_filter_date": "तारीख़", "search_filter_date_interval": "{start} से {end} तक", "search_filter_date_title": "तारीख़ की सीमा चुनें", + "search_filter_display_option_not_in_album": "एल्बम में नहीं", "search_filter_display_options": "प्रदर्शन विकल्प", + "search_filter_filename": "फ़ाइल नाम से खोजें", "search_filter_location": "स्थान", "search_filter_location_title": "स्थान चुनें", "search_filter_media_type": "मीडिया प्रकार", "search_filter_media_type_title": "मीडिया प्रकार चुनें", + "search_filter_ocr": "OCR द्वारा खोजें", "search_filter_people_title": "लोगों का चयन करें", + "search_for": "निम्न को खोजें", "search_for_existing_person": "मौजूदा व्यक्ति को खोजें", + "search_no_more_result": "कोई और परिणाम नहीं", "search_no_people": "कोई लोग नहीं", + "search_no_people_named": "\"{name}\" नाम के कोई लोग नहीं हैं", + "search_no_result": "कोई रिज़ल्ट नहीं मिला, कोई दूसरा सर्च टर्म या कॉम्बिनेशन ट्राई करें", + "search_options": "खोज विकल्प", + "search_page_categories": "श्रेणियाँ", + "search_page_motion_photos": "मोशन फ़ोटो", + "search_page_no_objects": "कोई ऑब्जेक्ट जानकारी उपलब्ध नहीं है", + "search_page_no_places": "कोई जगह की जानकारी उपलब्ध नहीं है", + "search_page_screenshots": "स्क्रीनशॉट", + "search_page_search_photos_videos": "अपनी फ़ोटो और वीडियो खोजें", + "search_page_selfies": "सेल्फ़ीज़", + "search_page_things": "चीज़ें", + "search_page_view_all_button": "सभी को देखें", + "search_page_your_activity": "आपकी गतिविधि", + "search_page_your_map": "आपका नक्शा", "search_people": "लोगों को खोजें", "search_places": "स्थान खोजें", + "search_rating": "रेटिंग के हिसाब से खोजें..।", + "search_result_page_new_search_hint": "नई खोज", + "search_settings": "खोज सेटिंग्स", "search_state": "स्थिति खोजें..।", + "search_suggestion_list_smart_search_hint_1": "स्मार्ट सर्च डिफ़ॉल्ट रूप से चालू रहता है, मेटाडेटा खोजने के लिए सिंटैक्स का इस्तेमाल करें ", + "search_suggestion_list_smart_search_hint_2": "m:आपका-खोज-शब्द", + "search_tags": "टैग खोजें..।", "search_timezone": "समयक्षेत्र खोजें..।", "search_type": "तलाश की विधि", "search_your_photos": "अपनी फ़ोटो खोजें", "searching_locales": "स्थान खोजे जा रहे हैं..।", "second": "दूसरा", "see_all_people": "सभी लोगों को देखें", + "select": "चुनना", "select_album_cover": "एल्बम कवर चुनें", "select_all": "सबका चयन करें", "select_all_duplicates": "सभी डुप्लिकेट का चयन करें", + "select_all_in": "{group} में सभी का चयन करें", "select_avatar_color": "अवतार रंग चुनें", "select_face": "चेहरा चुनें", "select_featured_photo": "चुनिंदा फ़ोटो चुनें", @@ -1445,44 +1816,128 @@ "select_keep_all": "सभी रखें का चयन करें", "select_library_owner": "लाइब्रेरी स्वामी का चयन करें", "select_new_face": "नया चेहरा चुनें", + "select_person_to_tag": "टैग करने के लिए किसी व्यक्ति का चयन करें", "select_photos": "फ़ोटो चुनें", "select_trash_all": "ट्रैश ऑल का चयन करें", + "select_user_for_sharing_page_err_album": "एल्बम बनाने में विफल", "selected": "चयनित", + "selected_count": "{count, plural, other {# selected}}", + "selected_gps_coordinates": "चयनित GPS निर्देशांक", "send_message": "मेसेज भेजें", "send_welcome_email": "स्वागत ईमेल भेजें", + "server_endpoint": "सर्वर एंडपॉइंट", + "server_info_box_app_version": "एप्लिकेशन वेरीज़न", "server_info_box_server_url": "सर्वर URL", "server_offline": "सर्वर ऑफ़लाइन", "server_online": "सर्वर ऑनलाइन", + "server_privacy": "सर्वर गोपनीयता", + "server_restarting_description": "यह पेज कुछ देर में रिफ्रेश हो जाएगा।", + "server_restarting_title": "सर्वर पुनः प्रारंभ हो रहा है", "server_stats": "सर्वर आँकड़े", + "server_update_available": "सर्वर अपडेट उपलब्ध है", "server_version": "सर्वर संस्करण", "set": "तय करना", "set_as_album_cover": "एल्बम कवर के रूप में सेट करें", + "set_as_featured_photo": "फ़ीचर्ड फ़ोटो के तौर पर सेट करें", "set_as_profile_picture": "प्रोफाइल चित्र के रूप में सेट", "set_date_of_birth": "जन्मतिथि निर्धारित करें", "set_profile_picture": "प्रोफ़ाइल चित्र सेट करें", "set_slideshow_to_fullscreen": "स्लाइड शो को फ़ुलस्क्रीन पर सेट करें", + "set_stack_primary_asset": "प्राथमिक संपत्ति के रूप में सेट करें", + "setting_image_viewer_help": "डिटेल व्यूअर पहले छोटा थंबनेल लोड करता है, फिर मीडियम-साइज़ प्रीव्यू लोड करता है (अगर इनेबल है), और आखिर में ओरिजिनल लोड करता है (अगर इनेबल है)।", + "setting_image_viewer_original_subtitle": "ओरिजिनल फुल-रिज़ॉल्यूशन इमेज (बड़ी!) लोड करने के लिए इनेबल करें। डेटा का इस्तेमाल कम करने के लिए डिसेबल करें (नेटवर्क और डिवाइस कैश दोनों)।", + "setting_image_viewer_original_title": "मूल छवि लोड करें", + "setting_image_viewer_preview_subtitle": "मीडियम-रिज़ॉल्यूशन इमेज लोड करने के लिए चालू करें। ओरिजिनल इमेज को सीधे लोड करने या सिर्फ़ थंबनेल इस्तेमाल करने के लिए बंद करें।", + "setting_image_viewer_preview_title": "पूर्वावलोकन छवि लोड करें", + "setting_image_viewer_title": "इमेजिस", + "setting_languages_apply": "आवेदन करना", + "setting_languages_subtitle": "ऐप की भाषा बदलें", + "setting_notifications_notify_failures_grace_period": "बैकग्राउंड बैकअप फेलियर की सूचना दें: {duration}", + "setting_notifications_notify_hours": "{count} घंटे", + "setting_notifications_notify_immediately": "तुरंत", + "setting_notifications_notify_minutes": "{count} मिनट", + "setting_notifications_notify_never": "कभी नहीं", + "setting_notifications_notify_seconds": "{count} सेकंड", + "setting_notifications_single_progress_subtitle": "हर एसेट के लिए अपलोड प्रोग्रेस की पूरी जानकारी", + "setting_notifications_single_progress_title": "बैकग्राउंड बैकअप डिटेल प्रोग्रेस दिखाएँ", + "setting_notifications_subtitle": "अपनी नोटिफ़िकेशन प्राथमिकताएँ समायोजित करें", + "setting_notifications_total_progress_subtitle": "ओवरऑल अपलोड प्रोग्रेस (हो गया/टोटल एसेट्स)", + "setting_notifications_total_progress_title": "बैकग्राउंड बैकअप की कुल प्रोग्रेस दिखाएँ", + "setting_video_viewer_auto_play_subtitle": "वीडियो खुलने पर अपने आप चलना शुरू हो जाता है", + "setting_video_viewer_auto_play_title": "ऑटो प्ले वीडियो", + "setting_video_viewer_looping_title": "पाशन", + "setting_video_viewer_original_video_subtitle": "सर्वर से वीडियो स्ट्रीम करते समय, ट्रांसकोड उपलब्ध होने पर भी ओरिजिनल वीडियो चलाएं। इससे बफरिंग हो सकती है। इस सेटिंग के बावजूद, स्थानीय रूप से उपलब्ध वीडियो ओरिजिनल क्वालिटी में चलाए जाते हैं।", + "setting_video_viewer_original_video_title": "मूल वीडियो को बलपूर्वक", "settings": "समायोजन", + "settings_require_restart": "इस सेटिंग को लागू करने के लिए कृपया Immich को रीस्टार्ट करें", "settings_saved": "सेटिंग्स को सहेजा गया", + "setup_pin_code": "पिन कोड सेट करें", "share": "शेयर करना", + "share_action_prompt": "साझा {count} संपत्तियाँ", "share_add_photos": "फ़ोटो डालें", + "share_assets_selected": "{count} चयनित", + "share_dialog_preparing": "तैयारी..।", + "share_link": "लिंक शेयर करें", "shared": "साझा", "shared_album_activities_input_disable": "कॉमेंट डिजेबल्ड है", "shared_album_activity_remove_content": "क्या आप इस गतिविधि को हटाना चाहते हैं?", "shared_album_activity_remove_title": "गतिविधि हटाएं", + "shared_album_section_people_action_error": "एल्बम से हटाने/छोड़ने में त्रुटि", + "shared_album_section_people_action_leave": "उपयोगकर्ता को एल्बम से हटाएँ", + "shared_album_section_people_action_remove_user": "उपयोगकर्ता को एल्बम से हटाएँ", + "shared_album_section_people_title": "लोग", "shared_by": "द्वारा साझा", + "shared_by_user": "{user} द्वारा साझा किया गया", "shared_by_you": "आपके द्वारा साझा किया गया", + "shared_from_partner": "{partner} से फ़ोटो", + "shared_intent_upload_button_progress_text": "{current} / {total} अपलोड किया गया", "shared_link_app_bar_title": "साझा किए गए लिंक", + "shared_link_clipboard_copied_massage": "क्लिपबोर्ड पर कॉपी किया गया", + "shared_link_clipboard_text": "लिंक: {link}\nपासवर्ड: {password}", + "shared_link_create_error": "शेयर्ड लिंक बनाते समय एरर आया", + "shared_link_custom_url_description": "कस्टम URL से इस शेयर्ड लिंक को एक्सेस करें", "shared_link_edit_description_hint": "शेयर विवरण दर्ज करें", + "shared_link_edit_expire_after_option_day": "1 दिन", + "shared_link_edit_expire_after_option_days": "{count} दिन", + "shared_link_edit_expire_after_option_hour": "1 घंटा", + "shared_link_edit_expire_after_option_hours": "{count} घंटे", + "shared_link_edit_expire_after_option_minute": "1 मिनट", + "shared_link_edit_expire_after_option_minutes": "{count} मिनट", + "shared_link_edit_expire_after_option_months": "{count} महीने", + "shared_link_edit_expire_after_option_year": "{count} वर्ष", "shared_link_edit_password_hint": "शेयर पासवर्ड दर्ज करें", "shared_link_edit_submit_button": "अपडेट लिंक", + "shared_link_error_server_url_fetch": "सर्वर URL नहीं मिल रहा है", + "shared_link_expires_day": "{count} दिन में समाप्त हो रहा है", + "shared_link_expires_days": "{count} दिनों में समाप्त हो जाएगा", + "shared_link_expires_hour": "{count} घंटे में समाप्त हो जाएगा", + "shared_link_expires_hours": "{count} घंटे में समाप्त हो जाएगा", + "shared_link_expires_minute": "{count} मिनट में समाप्त हो रहा है", + "shared_link_expires_minutes": "{count} मिनट में समाप्त हो जाएगा", + "shared_link_expires_never": "समाप्त ∞", + "shared_link_expires_second": "{count} सेकंड में समाप्त हो रहा है", + "shared_link_expires_seconds": "{count} सेकंड में समाप्त हो जाएगा", + "shared_link_individual_shared": "व्यक्तिगत साझा", + "shared_link_info_chip_metadata": "EXIF", "shared_link_manage_links": "साझा किए गए लिंक का प्रबंधन करें", + "shared_link_options": "साझा लिंक विकल्प", + "shared_link_password_description": "इस शेयर किए गए लिंक को एक्सेस करने के लिए पासवर्ड ज़रूरी है", "shared_links": "साझा किए गए लिंक", + "shared_links_description": "लिंक के साथ फ़ोटो और वीडियो शेयर करें", + "shared_photos_and_videos_count": "{assetCount, plural, other {# shared photos & videos.}}", "shared_with_me": "मेरे साथ साझा किया गया", + "shared_with_partner": "{partner} के साथ शेयर किया गया", "sharing": "शेयरिंग", "sharing_enter_password": "कृपया इस पृष्ठ को देखने के लिए पासवर्ड दर्ज करें।", + "sharing_page_album": "साझा एल्बम", + "sharing_page_description": "अपने नेटवर्क में लोगों के साथ फ़ोटो और वीडियो शेयर करने के लिए शेयर्ड एल्बम बनाएं।", + "sharing_page_empty_list": "खाली सूची", "sharing_sidebar_description": "साइडबार में शेयरिंग के लिए एक लिंक प्रदर्शित करें", + "sharing_silver_appbar_create_shared_album": "नया साझा एल्बम", + "sharing_silver_appbar_share_partner": "पार्टनर के साथ शेयर करें", "shift_to_permanent_delete": "संपत्ति को स्थायी रूप से हटाने के लिए ⇧ दबाएँ", "show_album_options": "एल्बम विकल्प दिखाएँ", + "show_albums": "एल्बम दिखाएँ", "show_all_people": "सभी लोगों को दिखाओ", "show_and_hide_people": "लोगों को दिखाएँ और छिपाएँ", "show_file_location": "फ़ाइल स्थान दिखाएँ", @@ -1497,133 +1952,245 @@ "show_person_options": "व्यक्ति विकल्प दिखाएँ", "show_progress_bar": "प्रगति पट्टी दिखाएँ", "show_search_options": "खोज विकल्प दिखाएँ", + "show_shared_links": "साझा लिंक दिखाएँ", + "show_slideshow_transition": "स्लाइड शो ट्रांज़िशन दिखाएँ", "show_supporter_badge": "समर्थक बिल्ला", "show_supporter_badge_description": "समर्थक बैज दिखाएँ", + "show_text_search_menu": "टेक्स्ट खोज मेनू दिखाएँ", "shuffle": "मिश्रण", + "sidebar": "साइड बार", + "sidebar_display_description": "साइडबार में व्यू का लिंक दिखाएं", "sign_out": "साइन आउट", "sign_up": "साइन अप करें", "size": "आकार", "skip_to_content": "इसे छोड़कर सामग्री पर बढ़ने के लिए", + "skip_to_folders": "फ़ोल्डरों पर जाएं", + "skip_to_tags": "टैग पर जाएं", "slideshow": "स्लाइड शो", "slideshow_settings": "स्लाइड शो सेटिंग्स", "sort_albums_by": "एल्बम को क्रमबद्ध करें..।", "sort_created": "बनाया गया दिनांक", "sort_items": "मदों की संख्या", "sort_modified": "डेटा संशोधित", + "sort_newest": "नवीनतम फोटो", "sort_oldest": "सबसे पुरानी तस्वीर", + "sort_people_by_similarity": "लोगों को समानता के आधार पर छाँटें", "sort_recent": "सबसे ताज़ा फ़ोटो", "sort_title": "शीर्षक", "source": "स्रोत", "stack": "ढेर", + "stack_action_prompt": "{count} स्टैक्ड", + "stack_duplicates": "डुप्लिकेट स्टैक करें", + "stack_select_one_photo": "स्टैक के लिए एक मुख्य फ़ोटो चुनें", "stack_selected_photos": "चयनित फ़ोटो को ढेर करें", + "stacked_assets_count": "स्टैक्ड {count, plural, one {# asset} other {# assets}}", "stacktrace": "स्टैक ट्रेस", "start": "शुरू", "start_date": "आरंभ करने की तिथि", + "start_date_before_end_date": "आरंभ तिथि समाप्ति तिथि से पहले होनी चाहिए", "state": "राज्य", "status": "स्थिति", + "stop_casting": "कास्टिंग बंद करो", "stop_motion_photo": "स्टॉप मोशन फोटो", "stop_photo_sharing": "अपनी तस्वीरें साझा करना बंद करें?", + "stop_photo_sharing_description": "{partner} अब आपकी फ़ोटो एक्सेस नहीं कर पाएगा।", "stop_sharing_photos_with_user": "इस उपयोगकर्ता के साथ अपनी तस्वीरें साझा करना बंद करें", "storage": "स्टोरेज की जगह", "storage_label": "भंडारण लेबल", + "storage_quota": "भंडारण कोटा", + "storage_usage": "{used} में से {available} इस्तेमाल किया हुआ", "submit": "जमा करना", + "success": "सफलता", "suggestions": "सुझाव", "sunrise_on_the_beach": "समुद्र तट पर सूर्योदय", + "support": "सहायता", + "support_and_feedback": "समर्थन और प्रतिक्रिया", + "support_third_party_description": "आपका Immich इंस्टॉलेशन किसी थर्ड-पार्टी ने पैकेज किया था। आपको जो दिक्कतें आ रही हैं, वे उस पैकेज की वजह से हो सकती हैं, इसलिए कृपया नीचे दिए गए लिंक का इस्तेमाल करके सबसे पहले उनके साथ अपनी दिक्कतें बताएं।", "swap_merge_direction": "मर्ज दिशा स्वैप करें", "sync": "साथ-साथ करना", "sync_albums": "एल्बम्स सिंक करें", "sync_albums_manual_subtitle": "चुने हुए बैकअप एल्बम्स में सभी अपलोड की गई वीडियो और फ़ोटो सिंक करें", + "sync_local": "स्थानीय सिंक करें", + "sync_remote": "सिंक रिमोट", + "sync_status": "सिंक स्थिति", + "sync_status_subtitle": "सिंक सिस्टम देखें और मैनेज करें", "sync_upload_album_setting_subtitle": "अपनी फ़ोटो और वीडियो बनाएँ और उन्हें इमिच पर चुने हुए एल्बम्स में अपलोड करें", + "tag": "टैग", + "tag_assets": "टैग संपत्तियाँ", + "tag_created": "बनाया गया टैग: {tag}", + "tag_feature_description": "लॉजिकल टैग टॉपिक के हिसाब से ग्रुप किए गए फ़ोटो और वीडियो ब्राउज़ करना", + "tag_not_found_question": "टैग नहीं मिल रहा है? नया टैग बनाएं.", + "tag_people": "लोगों को टैग करें", + "tag_updated": "अपडेट किया गया टैग: {tag}", + "tagged_assets": "टैग किया गया {count, plural, one {# asset} other {# assets}}", + "tags": "टैग्स", + "tap_to_run_job": "जॉब चलाने के लिए टैप करें", "template": "खाका", "theme": "विषय", "theme_selection": "थीम चयन", "theme_selection_description": "आपके ब्राउज़र की सिस्टम प्राथमिकता के आधार पर थीम को स्वचालित रूप से प्रकाश या अंधेरे पर सेट करें", + "theme_setting_asset_list_storage_indicator_title": "एसेट टाइल्स पर स्टोरेज इंडिकेटर दिखाएं", + "theme_setting_asset_list_tiles_per_row_title": "प्रति पंक्ति एसेट की संख्या ({count})", "theme_setting_colorful_interface_subtitle": "प्राथमिक रंग को पृष्ठभूमि सतहों पर लागू करें", "theme_setting_colorful_interface_title": "रंगीन इंटरफ़ेस", + "theme_setting_image_viewer_quality_subtitle": "डिटेल इमेज व्यूअर की क्वालिटी एडजस्ट करें", + "theme_setting_image_viewer_quality_title": "छवि दर्शक गुणवत्ता", "theme_setting_primary_color_subtitle": "प्राथमिक क्रियाओं और उच्चारणों के लिए एक रंग चुनें", "theme_setting_primary_color_title": "प्राथमिक रंग", "theme_setting_system_primary_color_title": "सिस्टम रंग का उपयोग करें", + "theme_setting_system_theme_switch": "ऑटोमैटिक (सिस्टम सेटिंग फ़ॉलो करें)", + "theme_setting_theme_subtitle": "ऐप की थीम सेटिंग चुनें", + "theme_setting_three_stage_loading_subtitle": "थ्री-स्टेज लोडिंग से लोडिंग परफॉर्मेंस बढ़ सकती है लेकिन इससे नेटवर्क लोड काफी बढ़ जाता है", + "theme_setting_three_stage_loading_title": "तीन-चरण लोडिंग सक्षम करें", "they_will_be_merged_together": "इन्हें एक साथ मिला दिया जाएगा", + "third_party_resources": "तृतीय-पक्ष संसाधन", + "time": "समय", "time_based_memories": "समय आधारित यादें", + "time_based_memories_duration": "हर इमेज दिखाने में लगने वाला सेकंड।", + "timeline": "समयरेखा", "timezone": "समय क्षेत्र", "to_archive": "पुरालेख", "to_change_password": "पासवर्ड बदलें", "to_favorite": "पसंदीदा", "to_login": "लॉग इन करें", + "to_multi_select": "बहु-चयन करने के लिए", + "to_parent": "माता-पिता के पास जाएँ", + "to_select": "चयन करने के लिए", "to_trash": "कचरा", "toggle_settings": "सेटिंग्स टॉगल करें", + "total": "कुल", "total_usage": "कुल उपयोग", "trash": "कचरा", + "trash_action_prompt": "{count} को ट्रैश में ले जाया गया", "trash_all": "सब कचरा", + "trash_count": "कचरा {count, number}", "trash_delete_asset": "संपत्ति को ट्रैश/डिलीट करें", "trash_emptied": "कचरा खाली कर दिया", "trash_no_results_message": "ट्रैश की गई फ़ोटो और वीडियो यहां दिखाई देंगे।", + "trash_page_delete_all": "सभी हटा दो", "trash_page_empty_trash_dialog_content": "क्या आप अपनी कूड़ेदान संपत्तियों को खाली करना चाहते हैं? इन आइटमों को Immich से स्थायी रूप से हटा दिया जाएगा", + "trash_page_info": "ट्रैश किए गए आइटम {days} दिनों के बाद हमेशा के लिए डिलीट कर दिए जाएंगे", + "trash_page_no_assets": "कोई ट्रैश की गई संपत्ति नहीं", "trash_page_restore_all": "सभी को पुनः स्थानांतरित करें", "trash_page_select_assets_btn": "संपत्तियों को चयन करें", + "trash_page_title": "कचरा ({count})", + "trashed_items_will_be_permanently_deleted_after": "ट्रैश किए गए आइटम {days, plural, one {# day} other {# days}} के बाद स्थायी रूप से हटा दिए जाएंगे।", + "troubleshoot": "समस्याओं का निवारण", "type": "प्रकार", + "unable_to_change_pin_code": "पिन कोड बदलने में असमर्थ", + "unable_to_check_version": "ऐप या सर्वर वर्शन चेक नहीं कर पा रहे हैं", + "unable_to_setup_pin_code": "पिन कोड सेट करने में असमर्थ", "unarchive": "संग्रह से निकालें", + "unarchive_action_prompt": "{count} आर्काइव से हटा दिया गया", + "unarchived_count": "{count, plural, other {Unarchived #}}", + "undo": "पूर्ववत", "unfavorite": "नापसंद करें", + "unfavorite_action_prompt": "{count} को पसंदीदा से हटा दिया गया", "unhide_person": "व्यक्ति को उजागर करें", "unknown": "अज्ञात", + "unknown_country": "अज्ञात देश", "unknown_year": "अज्ञात वर्ष", "unlimited": "असीमित", + "unlink_motion_video": "मोशन वीडियो को अनलिंक करें", "unlink_oauth": "OAuth को अनलिंक करें", "unlinked_oauth_account": "OAuth खाता अनलिंक किया गया", + "unmute_memories": "यादें अनम्यूट करें", "unnamed_album": "अनाम एल्बम", + "unnamed_album_delete_confirmation": "क्या आप वाकई इस एल्बम को डिलीट करना चाहते हैं?", "unnamed_share": "अनाम साझा करें", "unsaved_change": "सहेजा न गया परिवर्तन", "unselect_all": "सभी को अचयनित करें", "unselect_all_duplicates": "सभी डुप्लिकेट को अचयनित करें", + "unselect_all_in": "{group} में सभी का चयन रद्द करें", "unstack": "स्टैक रद्द करें", + "unstack_action_prompt": "{count} अनस्टैक्ड", + "unstacked_assets_count": "अन-स्टैक्ड {count, plural, one {# asset} other {# assets}}", + "untagged": "टैग नहीं किए गए", "up_next": "अब अगला", + "update_location_action_prompt": "{count} चुने गए एसेट की लोकेशन अपडेट करें:", + "updated_at": "अपडेट किया गया", "updated_password": "अद्यतन पासवर्ड", "upload": "डालना", + "upload_action_prompt": "अपलोड के लिए {count} कतार में", "upload_concurrency": "समवर्ती अपलोड करें", + "upload_details": "विवरण अपलोड करें", + "upload_dialog_info": "क्या आप चुने हुए एसेट का सर्वर पर बैकअप लेना चाहते हैं?", + "upload_dialog_title": "संपत्ति अपलोड करें", + "upload_errors": "अपलोड {count, plural, one {# error} other {# errors}} के साथ पूरा हुआ, नए अपलोड एसेट देखने के लिए पेज को रिफ्रेश करें।", + "upload_finished": "अपलोड समाप्त", + "upload_progress": "शेष {remaining, number} - संसाधित {processed, number}/{total, number}", + "upload_skipped_duplicates": "छोड़ा गया {count, plural, one {# duplicate asset} other {# duplicate assets}}", "upload_status_duplicates": "डुप्लिकेट", "upload_status_errors": "त्रुटियाँ", "upload_status_uploaded": "अपलोड किए गए", "upload_success": "अपलोड सफल रहा, नई अपलोड संपत्तियां देखने के लिए पेज को रीफ्रेश करें।", + "upload_to_immich": "Immich पर अपलोड करें ({count})", + "uploading": "अपलोड हो रहा है", + "uploading_media": "मीडिया अपलोड करना", "url": "यूआरएल", "usage": "प्रयोग", + "use_biometric": "बायोमेट्रिक का उपयोग करें", + "use_current_connection": "वर्तमान कनेक्शन का उपयोग करें", "use_custom_date_range": "इसके बजाय कस्टम दिनांक सीमा का उपयोग करें", "user": "उपयोगकर्ता", + "user_has_been_deleted": "इस यूज़र को हटा दिया गया है।", "user_id": "उपयोगकर्ता पहचान", + "user_liked": "{user} ने पसंद किया {type, select, photo {this photo} video {this video} asset {this asset} other {it}}", + "user_pin_code_settings": "पिन कोड", + "user_pin_code_settings_description": "अपना पिन कोड प्रबंधित करें", + "user_privacy": "उपयोगकर्ता गोपनीयता", "user_purchase_settings": "खरीदना", "user_purchase_settings_description": "अपनी खरीदारी प्रबंधित करें", + "user_role_set": "{user} को {role} के तौर पर सेट करें", "user_usage_detail": "उपयोगकर्ता उपयोग विवरण", + "user_usage_stats": "खाता उपयोग के आँकड़े", "user_usage_stats_description": "खाता उपयोग सांख्यिकी देखें", "username": "उपयोगकर्ता नाम", "users": "उपयोगकर्ताओं", + "users_added_to_album_count": "एल्बम में {count, plural, one {# user} other {# users}} जोड़े गए", "utilities": "उपयोगिताओं", "validate": "मान्य", + "validate_endpoint_error": "क्रुपया मान्य यूआरएल दर्ज करें", "variables": "चर", "version": "संस्करण", "version_announcement_closing": "आपका मित्र, एलेक्स", - "version_announcement_message": "नमस्कार मित्र, एप्लिकेशन का एक नया संस्करण है, कृपया अपना समय निकालकर इसे देखें रिलीज नोट्स और अपना सुनिश्चित करें docker-compose.yml, और .env किसी भी गलत कॉन्फ़िगरेशन को रोकने के लिए सेटअप अद्यतित है, खासकर यदि आप वॉचटावर या किसी भी तंत्र का उपयोग करते हैं जो आपके एप्लिकेशन को स्वचालित रूप से अपडेट करने का प्रबंधन करता है।", + "version_announcement_message": "नमस्ते! Immich का नया वर्शन उपलब्ध है। कृपया रिलीज़ नोट्स पढ़ने के लिए कुछ समय निकालें ताकि यह पक्का हो सके कि आपका सेटअप अप-टू-डेट है ताकि कोई भी गलत कॉन्फ़िगरेशन न हो, खासकर अगर आप WatchTower या कोई ऐसा मैकेनिज़्म इस्तेमाल करते हैं जो आपके Immich इंस्टेंस को ऑटोमैटिकली अपडेट करता है।", + "version_history": "संस्करण इतिहास", + "version_history_item": "{version} को {date} पर इंस्टॉल किया गया", "video": "वीडियो", "video_hover_setting": "होवर पर वीडियो थंबनेल चलाएं", "video_hover_setting_description": "जब माउस आइटम पर घूम रहा हो तो वीडियो थंबनेल चलाएं।", "videos": "वीडियो", + "videos_count": "{count, plural, one {# Video} other {# Videos}}", "view": "देखना", "view_album": "एल्बम देखें", "view_all": "सभी को देखें", "view_all_users": "सभी उपयोगकर्ताओं को देखें", + "view_details": "विवरण देखें", "view_in_timeline": "टाइमलाइन में देखें", + "view_link": "लिंक देखें", "view_links": "लिंक देखें", + "view_name": "देखना", "view_next_asset": "अगली संपत्ति देखें", "view_previous_asset": "पिछली संपत्ति देखें", + "view_qr_code": "QR कोड देखें", + "view_similar_photos": "समान फ़ोटो देखें", "view_stack": "ढेर देखें", + "view_user": "उपयोगकर्ता देखें", "viewer_remove_from_stack": "स्टैक से हटाएं", "viewer_stack_use_as_main_asset": "मुख्य संपत्ति के रूप में उपयोग करें", "viewer_unstack": "स्टैक रद्द करें", + "visibility_changed": "{count, plural, one {# person} other {# people}} के लिए विज़िबिलिटी बदली गई", "waiting": "इंतज़ार में", "warning": "चेतावनी", "week": "सप्ताह", "welcome": "स्वागत", - "welcome_to_immich": "इमिच में आपका स्वागत है", - "wifi_name": "WiFi Name", + "welcome_to_immich": "Immich में आपका स्वागत है", + "wifi_name": "वाई-फाई का नाम", + "workflow": "कार्यप्रवाह", + "wrong_pin_code": "गलत पिन कोड", "year": "वर्ष", + "years_ago": "{years, plural, one {# year} other {# years}} पहले", "yes": "हाँ", "you_dont_have_any_shared_links": "आपके पास कोई साझा लिंक नहीं है", "your_wifi_name": "आपके वाईफाई का नाम", diff --git a/i18n/hr.json b/i18n/hr.json index a900ebac2a..3dfed04233 100644 --- a/i18n/hr.json +++ b/i18n/hr.json @@ -1,5 +1,5 @@ { - "about": "O", + "about": "Pojedinosti", "account": "Račun", "account_settings": "Postavke računa", "acknowledge": "Potvrdi", @@ -17,7 +17,6 @@ "add_birthday": "Dodaj rođendan", "add_endpoint": "Dodaj krajnju točku", "add_exclusion_pattern": "Dodaj uzorak izuzimanja", - "add_import_path": "Dodaj putanju uvoza", "add_location": "Dodaj lokaciju", "add_more_users": "Dodaj još korisnika", "add_partner": "Dodaj partnera", @@ -76,7 +75,7 @@ "exclusion_pattern_description": "Uzorci izuzimanja omogućuju vam da ignorirate datoteke i mape prilikom skeniranja svoje biblioteke. Ovo je korisno ako imate mape koje sadrže datoteke koje ne želite uvesti, kao što su RAW datoteke.", "external_library_management": "Upravljanje vanjskom bibliotekom", "face_detection": "Detekcija lica", - "face_detection_description": "Detektirajte lica u stavkama pomoću strojnog učenja. Za videozapise se uzima u obzir samo sličica. \"Osvježi\" (ponovno) obrađuje sve stavke. \"Poništi\" dodatno briše sve trenutne podatke o licu. \"Nedostaje\" stavlja u red čekanja stavke koje još nisu obrađene. Detektirana lica bit će stavljena u red čekanja za Prepoznavanje lica nakon što se dovrši Detekcija lica, grupirajući ih u postojeće ili nove osobe.", + "face_detection_description": "Detektirajte lica u stavkama pomoću strojnog učenja. Za videozapise se uzima u obzir samo sličica. \"Osvježi\" (ponovno) obrađuje sve stavke. \"Poništi\" dodatno briše sve trenutne podatke o licu. \"Nedostaje\" stavlja u red čekanja stavke koje još nisu obrađene. Detektirana lica bit će stavljena u red čekanja za prepoznavanje lica nakon što se dovrši detekcija lica, grupirajući ih u postojeće ili nove osobe.", "facial_recognition_job_description": "Grupirajte otkrivena lica u osobe. Ovaj korak se izvršava nakon što je Detekcija lica dovršena. \"Resetiraj\" (ponovno) grupira sva lica. \"Nedostaje\" stavlja u red lica kojima nije dodijeljena osoba.", "failed_job_command": "Naredba {command} nije uspjela za posao: {job}", "force_delete_user_warning": "UPOZORENJE: Ovo će odmah ukloniti korisnika i sve pripadajuće stavke. Ovo se ne može poništiti i datoteke se ne mogu vratiti.", @@ -109,18 +108,17 @@ "job_settings_description": "Upravljajte istovremenošću poslova", "job_status": "Status posla", "jobs_delayed": "{jobCount, plural, other {# odgođenih}}", - "jobs_failed": "{jobCount, plural, other {# failed}}", + "jobs_failed": "{jobCount, plural, one {# neuspješan} few {# neuspješna} other {# neuspješnih}}", "library_created": "Stvorena biblioteka: {library}", "library_deleted": "Biblioteka izbrisana", - "library_import_path_description": "Navedite mapu za uvoz. Ova će se mapa, uključujući podmape, skenirati u potrazi za slikama i videozapisima.", - "library_scanning": "Periodično Skeniranje", + "library_scanning": "Periodično skeniranje", "library_scanning_description": "Konfigurirajte periodično skeniranje biblioteke", "library_scanning_enable_description": "Omogući periodično skeniranje biblioteke", - "library_settings": "Externa biblioteka", + "library_settings": "Vanjska biblioteka", "library_settings_description": "Upravljajte postavkama vanjske biblioteke", "library_tasks_description": "Skeniraj vanjske biblioteke za nove i/ili promijenjene stavke", "library_watching_enable_description": "Pratite vanjske biblioteke za promjena datoteke", - "library_watching_settings": "Gledanje biblioteke (EKSPERIMENTALNO)", + "library_watching_settings": "Gledanje biblioteke [EKSPERIMENTALNO]", "library_watching_settings_description": "Automatsko praćenje promijenjenih datoteke", "logging_enable_description": "Omogući zapisivanje", "logging_level_description": "Kada je omogućeno, koju razinu zapisivanja koristiti.", @@ -131,7 +129,7 @@ "machine_learning_availability_checks_interval_description": "Interval u milisekundama između provjera dostupnosti", "machine_learning_clip_model": "CLIP model", "machine_learning_clip_model_description": "Naziv CLIP modela navedenog ovdje. Imajte na umu da morate ponovno pokrenuti posao 'Pametno Pretraživanje' za sve slike nakon promjene modela.", - "machine_learning_duplicate_detection": "Detekcija Duplikata", + "machine_learning_duplicate_detection": "Detekcija duplikata", "machine_learning_duplicate_detection_enabled": "Omogući detekciju duplikata", "machine_learning_duplicate_detection_enabled_description": "Ako je onemogućeno, potpuno identične stavke i dalje će biti deduplicirane.", "machine_learning_duplicate_detection_setting_description": "Upotrijebite CLIP ugradnje da biste pronašli vjerojatne duplikate", @@ -162,16 +160,16 @@ "manage_log_settings": "Upravljanje postavkama zapisivanje", "map_dark_style": "Tamni stil", "map_enable_description": "Omogući značajke karte", - "map_gps_settings": "Postavke Karte i GPS-a", - "map_gps_settings_description": "Upravljajte Postavkama Karte i GPS-a (Obrnuto Geokodiranje)", + "map_gps_settings": "Postavke karte i GPS-a", + "map_gps_settings_description": "Upravljajte postavkama karte i GPS-a (obrnutog geokodiranja)", "map_implications": "Značajka karte se oslanja na vanjsku uslugu pločica (tiles.immich.cloud)", "map_light_style": "Svijetli stil", - "map_manage_reverse_geocoding_settings": "Upravljajte postavkama Obrnutog Geokodiranja", + "map_manage_reverse_geocoding_settings": "Upravljajte postavkama Obrnutog geokodiranja", "map_reverse_geocoding": "Obrnuto Geokodiranje", "map_reverse_geocoding_enable_description": "Omogući obrnuto geokodiranje", - "map_reverse_geocoding_settings": "Postavke Obrnuto Geokodiranje", + "map_reverse_geocoding_settings": "Postavke Obrnutog geokodiranja", "map_settings": "Karta", - "map_settings_description": "Upravljanje postavkama karte", + "map_settings_description": "Upravljajte postavkama karte", "map_style_description": "URL na style.json temu karte", "memory_cleanup_job": "Čišćenje memorije", "memory_generate_job": "Generiranje memorije", @@ -179,7 +177,7 @@ "metadata_extraction_job_description": "Izdvojite metapodatke iz svake stavke, kao što su GPS, lica i rezolucija", "metadata_faces_import_setting": "Omogući uvoz lica", "metadata_faces_import_setting_description": "Uvezite lica iz EXIF podataka slike i sidecar datoteka", - "metadata_settings": "Postavke Metapodataka", + "metadata_settings": "Postavke metapodataka", "metadata_settings_description": "Upravljanje postavkama metapodataka", "migration_job": "Migracija", "migration_job_description": "Premjestite sličice za stavke i lica u najnoviju strukturu mapa", @@ -199,7 +197,7 @@ "nightly_tasks_sync_quota_usage_setting_description": "Ažuriraj korisničku kvotu za pohranu na temelju trenutne potrošnje", "no_paths_added": "Nema dodanih putanja", "no_pattern_added": "Nije dodan uzorak", - "note_apply_storage_label_previous_assets": "Napomena: Da biste primijenili Oznaku pohrane na prethodno prenesene stavke, pokrenite", + "note_apply_storage_label_previous_assets": "Napomena: Da biste primijenili oznaku pohrane na prethodno prenesene stavke, pokrenite", "note_cannot_be_changed_later": "NAPOMENA: Ovo se ne može promijeniti kasnije!", "notification_email_from_address": "Od adrese", "notification_email_from_address_description": "E-mail adresa pošiljatelja, na primjer: \"Immich Photo Server \". Obavezno koristite adresu s koje vam je dopušteno slanje e-pošte.", @@ -217,7 +215,7 @@ "notification_email_test_email_sent": "Testna e-poruka poslana je na {email}. Provjerite svoju pristiglu poštu.", "notification_email_username_description": "Korisničko ime koje se koristi pri autentifikaciji s poslužiteljem e-pošte", "notification_enable_email_notifications": "Omogući obavijesti putem e-pošte", - "notification_settings": "Postavke Obavijesti", + "notification_settings": "Postavke obavijesti", "notification_settings_description": "Upravljanje postavkama obavijesti, uključujući e-poštu", "oauth_auto_launch": "Automatsko pokretanje", "oauth_auto_launch_description": "Automatski pokrenite OAuth prijavu nakon navigacije na stranicu za prijavu", @@ -239,7 +237,7 @@ "oauth_storage_quota_claim": "Zahtjev za kvotom pohrane", "oauth_storage_quota_claim_description": "Automatski postavite korisničku kvotu pohrane na vrijednost ovog zahtjeva.", "oauth_storage_quota_default": "Zadana kvota pohrane (GiB)", - "oauth_storage_quota_default_description": "Kvota u GiB koja će se koristiti kada nema zahtjeva", + "oauth_storage_quota_default_description": "Kvota u GiB koja će se koristiti kada nema zahtjeva.", "oauth_timeout": "Istek vremena zahtjeva", "oauth_timeout_description": "Istek vremena zahtjeva je u milisekundama", "password_enable_description": "Prijava s email adresom i zaporkom", @@ -268,7 +266,7 @@ "sidecar_job": "Sidecar metapodaci", "sidecar_job_description": "Otkrijte ili sinkronizirajte sidecar metapodatke iz datotečnog sustava", "slideshow_duration_description": "Broj sekundi za prikaz svake slike", - "smart_search_job_description": "Pokrenite strojno učenje na stavkama za korištenje Pametnog pretraživanja", + "smart_search_job_description": "Pokrenite strojno učenje na stavkama za korištenje pametnog pretraživanja", "storage_template_date_time_description": "Vremenska oznaka stvaranja stavke koristi se za informacije o datumu i vremenu", "storage_template_date_time_sample": "Vrijeme uzorka {date}", "storage_template_enable_description": "Omogući mehanizam predloška za pohranu", @@ -276,7 +274,7 @@ "storage_template_hash_verification_enabled_description": "Omogućuje hash provjeru, nemojte je onemogućiti osim ako niste sigurni u implikacije", "storage_template_migration": "Migracija predloška za pohranu", "storage_template_migration_description": "Primijenite trenutni {template} na prethodno prenesene stavke", - "storage_template_migration_info": "Predložak za pohranu pretvorit će sve datotečne nastavke u mala slova. Promjene predloška primijenit će se samo na nove stavke. Da biste retroaktivno primijenili predložak na prethodno prenesene stavke, pokrenite {job}.", + "storage_template_migration_info": "Predložak za pohranu pretvorit će sve datotečne nastavke u mala slova. Promjene predloška primijenit će se samo na nove stavke. Da biste retroaktivno primijenili predložak na prethodno prenesene stavke, pokrenite {job}.", "storage_template_migration_job": "Posao Migracije Predloška Pohrane", "storage_template_more_details": "Za više pojedinosti o ovoj značajci pogledajte Predložak pohrane i njegove implikacije", "storage_template_onboarding_description_v2": "Kada je omogućena, ova će značajka automatski organizira datoteke prema predlošku koji je definirao korisnik. Za više informacija pogledajte dokumentaciju.", @@ -284,13 +282,13 @@ "storage_template_settings": "Predložak pohrane", "storage_template_settings_description": "Upravljajte strukturom mape i nazivom datoteke učitane stavke", "storage_template_user_label": "{label} je korisnička oznaka za pohranu", - "system_settings": "Postavke Sustava", + "system_settings": "Postavke sustava", "tag_cleanup_job": "Čišćenje oznaka", "template_email_available_tags": "Možete koristiti sljedeće varijable u vašem predlošku:{tags}", "template_email_if_empty": "Ukoliko je predložak prazan, koristit će se zadana e-mail adresa.", "template_email_invite_album": "Predložak za pozivnicu u album", "template_email_preview": "Pregled", - "template_email_settings": "E-mail Predlošci", + "template_email_settings": "E-mail predlošci", "template_email_update_album": "Ažuriraj Album Predložak", "template_email_welcome": "Predložak e-maila dobrodošlice", "template_settings": "Predložak Obavijesti", @@ -323,20 +321,20 @@ "transcoding_constant_rate_factor": "Faktor konstantne stope (-crf)", "transcoding_constant_rate_factor_description": "Razina kvalitete videa. Uobičajene vrijednosti su 23 za H.264, 28 za HEVC, 31 za VP9 i 35 za AV1. Niže je bolje, ali stvara veće datoteke.", "transcoding_disabled_description": "Nemojte transkodirati nijedan videozapis, može prekinuti reprodukciju na nekim klijentima", - "transcoding_encoding_options": "Opcije Kodiranja", + "transcoding_encoding_options": "Opcije kodiranja", "transcoding_encoding_options_description": "Postavi kodeke, rezoluciju, kvalitetu i druge opcije za kodirane videje", - "transcoding_hardware_acceleration": "Hardversko Ubrzanje", + "transcoding_hardware_acceleration": "Hardversko ubrzanje", "transcoding_hardware_acceleration_description": "Eksperimentalno: brže transkodiranje, ali može smanjiti kvalitetu pri istoj brzini prijenosa", "transcoding_hardware_decoding": "Hardversko dekodiranje", "transcoding_hardware_decoding_setting_description": "Odnosi se samo na NVENC, QSV i RKMPP. Omogućuje ubrzanje s kraja na kraj umjesto samo ubrzavanja kodiranja. Možda neće raditi na svim videozapisima.", "transcoding_max_b_frames": "Maksimalni B-frameovi", "transcoding_max_b_frames_description": "Više vrijednosti poboljšavaju učinkovitost kompresije, ali usporavaju kodiranje. Možda nije kompatibilan s hardverskim ubrzanjem na starijim uređajima. 0 onemogućuje B-frameove, dok -1 automatski postavlja ovu vrijednost.", "transcoding_max_bitrate": "Maksimalne brzina prijenosa (bitrate)", - "transcoding_max_bitrate_description": "Postavljanje maksimalne brzine prijenosa može učiniti veličine datoteka predvidljivijima uz manji trošak za kvalitetu. Pri 720p, tipične vrijednosti su 2600 kbit/s za VP9 ili HEVC ili 4500 kbit/s za H.264. Onemogućeno ako je postavljeno na 0.", + "transcoding_max_bitrate_description": "Postavljanje maksimalne brzine prijenosa može učiniti veličine datoteka predvidljivijima uz manji gubitak kvalitete. Pri 720p, tipične vrijednosti su 2600 kbit/s za VP9 ili HEVC, te 4500 kbit/s za H.264. Onemogućeno ako je postavljeno na 0. Kada nije navedena mjerna jedinica, pretpostavlja se k (za kbit/s); stoga su 5000, 5000k i 5M (za Mbit/s) ekvivalentni.", "transcoding_max_keyframe_interval": "Maksimalni interval ključnih sličica", "transcoding_max_keyframe_interval_description": "Postavlja maksimalnu udaljenost slika između ključnih kadrova. Niže vrijednosti pogoršavaju učinkovitost kompresije, ali poboljšavaju vrijeme traženja i mogu poboljšati kvalitetu u scenama s brzim kretanjem. 0 automatski postavlja ovu vrijednost.", "transcoding_optimal_description": "Videozapisi koji su veći od ciljne rezolucije ili nisu u prihvatljivom formatu", - "transcoding_policy": "Politika Transkodiranja", + "transcoding_policy": "Pravila transkodiranja", "transcoding_policy_description": "Postavi kada će video biti transkodiran", "transcoding_preferred_hardware_device": "Preferirani hardverski uređaj", "transcoding_preferred_hardware_device_description": "Odnosi se samo na VAAPI i QSV. Postavlja dri node koji se koristi za hardversko transkodiranje.", @@ -345,12 +343,12 @@ "transcoding_reference_frames": "Referentne slike", "transcoding_reference_frames_description": "Broj slika za referencu prilikom komprimiranja određene slike. Više vrijednosti poboljšavaju učinkovitost kompresije, ali usporavaju kodiranje. 0 automatski postavlja ovu vrijednost.", "transcoding_required_description": "Samo videozapisi koji nisu u prihvaćenom formatu", - "transcoding_settings": "Postavke Video Transkodiranja", + "transcoding_settings": "Postavke video transkodiranja", "transcoding_settings_description": "Upravljaj koji videozapisi će se transkodirati i kako ih obraditi", "transcoding_target_resolution": "Ciljana rezolucija", "transcoding_target_resolution_description": "Veće razlučivosti mogu sačuvati više detalja, ali trebaju dulje za kodiranje, imaju veće veličine datoteka i mogu smanjiti odziv aplikacije.", "transcoding_temporal_aq": "Vremenski AQ", - "transcoding_temporal_aq_description": "Odnosi se samo na NVENC. Povećava kvalitetu scena s puno detalja i malo pokreta. Možda nije kompatibilan sa starijim uređajima.", + "transcoding_temporal_aq_description": "Odnosi se samo na NVENC. Vremenska adaptivna kvantizacija povećava kvalitetu scena s mnogim detaljima i malo kretanja. Možda nije kompatibilno sa starijim uređajima.", "transcoding_threads": "Sljedovi (Threads)", "transcoding_threads_description": "Više vrijednosti dovode do bržeg kodiranja, ali ostavljaju manje prostora poslužitelju za obradu drugih zadataka dok je aktivan. Ova vrijednost ne smije biti veća od broja CPU jezgri. Maksimalno povećava iskorištenje ako je postavljeno na 0.", "transcoding_tone_mapping": "Tonsko preslikavanje", @@ -361,10 +359,10 @@ "transcoding_two_pass_encoding_setting_description": "Transkodiranje u dva prolaza za proizvodnju bolje kodiranih videozapisa. Kada je omogućena maksimalna brzina prijenosa (potrebna za rad s H.264 i HEVC), ovaj način rada koristi raspon brzine prijenosa na temelju maksimalne brzine prijenosa i zanemaruje CRF. Za VP9, CRF se može koristiti ako je maksimalna brzina prijenosa onemogućena.", "transcoding_video_codec": "Video kodek", "transcoding_video_codec_description": "VP9 ima visoku učinkovitost i web-kompatibilnost, ali treba dulje za transkodiranje. HEVC ima sličnu izvedbu, ali ima slabiju web kompatibilnost. H.264 široko je kompatibilan i brzo se transkodira, ali proizvodi mnogo veće datoteke. AV1 je najučinkovitiji kodek, ali nema podršku na starijim uređajima.", - "trash_enabled_description": "Omogućite značajke Smeća", + "trash_enabled_description": "Omogući značajke smeća", "trash_number_of_days": "Broj dana", "trash_number_of_days_description": "Broj dana za čuvanje stavki u smeću prije njihovog trajnog uklanjanja", - "trash_settings": "Postavke Smeća", + "trash_settings": "Postavke smeća", "trash_settings_description": "Upravljanje postavkama smeća", "unlink_all_oauth_accounts": "Odspoji sve OAuth račune", "unlink_all_oauth_accounts_description": "Zapamtite da odspojite sve OAuth račune prije prelaska na novog pružatelja usluge.", @@ -400,12 +398,12 @@ "advanced_settings_log_level_title": "Razina zapisivanja: {level}", "advanced_settings_prefer_remote_subtitle": "Neki uređaji sporo učitavaju sličice s lokalnih stavki. Aktivirajte ovu postavku kako biste umjesto toga učitali slike s udaljenih izvora.", "advanced_settings_prefer_remote_title": "Preferiraj udaljene slike", - "advanced_settings_proxy_headers_subtitle": "Definirajte zaglavlja posrednika koja Immich treba slati sa svakim mrežnim zahtjevom.", - "advanced_settings_proxy_headers_title": "Proxy zaglavlja", - "advanced_settings_readonly_mode_subtitle": "Omogućuje read-only mod u kojem je moguće samo pregledavanje fotografija, radnje poput odabira više fotografija, dijeljenje, proiciranje i brisanje svih fotografija su onemogućene. Upali/ugasi read-only mod preko korisnickog avatara na glavnom ekranu.", + "advanced_settings_proxy_headers_subtitle": "Definirajte proxy zaglavlja koja Immich treba poslati sa svakim mrežnim zahtjevom", + "advanced_settings_proxy_headers_title": "Prilagođeni proxy zaglavlja [EKSPERIMENTALNO]", + "advanced_settings_readonly_mode_subtitle": "Omogućuje način rada za čitanje u kojem se fotografije mogu samo pregledavati, a stvari poput odabira više slika, dijeljenja, emitiranja i brisanja su onemogućene. Omogući/onemogući način rada za čitanje putem korisničkog avatara s glavnog zaslona", "advanced_settings_readonly_mode_title": "Read-only mod", "advanced_settings_self_signed_ssl_subtitle": "Preskoči provjeru SSL certifikata za krajnju točku poslužitelja. Potrebno za samo-potpisane certifikate.", - "advanced_settings_self_signed_ssl_title": "Dopusti samo-potpisane SSL certifikate", + "advanced_settings_self_signed_ssl_title": "Dopusti samopotpisane SSL certifikate [EKSPERIMENTALNO]", "advanced_settings_sync_remote_deletions_subtitle": "Automatski izbriši ili obnovi stavku na ovom uređaju kada se ta radnja izvrši na webu", "advanced_settings_sync_remote_deletions_title": "Sinkroniziraj udaljena brisanja [EKSPERIMENTALNO]", "advanced_settings_tile_subtitle": "Postavke za napredne korisnike", @@ -453,7 +451,7 @@ "albums_on_device_count": "Albumi na uređaju ({count})", "all": "Sve", "all_albums": "Svi albumi", - "all_people": "Svi ljudi", + "all_people": "Sve osobe", "all_videos": "Svi videi", "allow_dark_mode": "Dozvoli tamni način", "allow_edits": "Dozvoli izmjene", @@ -464,7 +462,7 @@ "api_key": "API Ključ", "api_key_description": "Ova će vrijednost biti prikazana samo jednom. Obavezno ju kopirajte prije zatvaranja prozora.", "api_key_empty": "Naziv vašeg API ključa ne smije biti prazan", - "api_keys": "API Ključevi", + "api_keys": "API ključevi", "app_architecture_variant": "Varijanta(Arhitektura)", "app_bar_signout_dialog_content": "Jeste li sigurni da se želite odjaviti?", "app_bar_signout_dialog_ok": "Da", @@ -473,6 +471,7 @@ "app_settings": "Postavke aplikacije", "app_update_available": "Ažuriranje aplikacije je dostupno", "appears_in": "Pojavljuje se u", + "apply_count": "Primijeni ({count, number})", "archive": "Arhiva", "archive_action_prompt": "{count} dodano u arhivu", "archive_or_unarchive_photo": "Arhivirajte ili dearhivirajte fotografiju", @@ -481,7 +480,7 @@ "archive_size": "Veličina arhive", "archive_size_description": "Konfigurirajte veličinu arhive za preuzimanja (u GiB)", "archived": "Arhivirano", - "archived_count": "{count, plural, other {Archived #}}", + "archived_count": "{count, plural, one {Arhivirana #} few {Arhivirane #} other {Arhivirano #}}", "are_these_the_same_person": "Je li ovo ista osoba?", "are_you_sure_to_do_this": "Jeste li sigurni da to želite učiniti?", "asset_action_delete_err_read_only": "Nije moguće izbrisati stavke samo za čitanje, preskakanje", @@ -518,22 +517,22 @@ "assets_cannot_be_added_to_album_count": "{count, plural, one {Stavka se ne može} other {Stavke se ne mogu}} dodati u album", "assets_cannot_be_added_to_albums": "{count, plural, one {Stavka se ne može} few {Stavke se ne mogu} other {Stavki se ne može}} dodati ni u jedan album", "assets_count": "{count, plural, one {# stavka} few {# stavke} other {# stavki}}", - "assets_deleted_permanently": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}}", + "assets_deleted_permanently": "{count, plural, one {# stavka trajno izbrisana} few {# stavke trajno izbrisane} other {# stavki trajno izbrisano}}", "assets_deleted_permanently_from_server": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}} s Immich servera", "assets_downloaded_failed": "{count, plural, one {Preuzeta # datoteka – {error} datoteka nije uspjela} few {Preuzete # datoteke - {error} datoteke nisu uspjele} other {Preuzeto # datoteka – {error} datoteke nisu uspjele}}", "assets_downloaded_successfully": "{count, plural, one {Uspješno preuzeta # datoteka} few {Uspješno preuzete # datoteke} other {Uspješno preueto # datoteka}}", "assets_moved_to_trash_count": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavk premještenoi}} u smeće", "assets_permanently_deleted_count": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}}", "assets_removed_count": "{count, plural, one {Uklonjena # stavka} few {Uklonjene # stavke} other {Uklonjeno # stavki}}", - "assets_removed_permanently_from_device": "{count} resurs(i) trajno uklonjen(i) s vašeg uređaja", - "assets_restore_confirmation": "Jeste li sigurni da želite obnoviti sve svoje resurse bačene u otpad? Ne možete poništiti ovu radnju! Imajte na umu da se bilo koji izvanmrežni resursi ne mogu obnoviti na ovaj način.", - "assets_restored_count": "Vraćeno {count, plural, one {# asset} other {# assets}}", - "assets_restored_successfully": "{count} resurs(i) uspješno obnovljen(i)", - "assets_trashed": "{count} resurs(i) premješten(i) u smeće", - "assets_trashed_count": "Bačeno u smeće {count, plural, one {# asset} other {# assets}}", - "assets_trashed_from_server": "{count} resurs(i) premješten(i) u smeće s Immich poslužitelja", - "assets_were_part_of_album_count": "{count, plural, one {Asset was} other {Assets were}} već dio albuma", - "assets_were_part_of_albums_count": "{count, plural, one {Datoteka je već bila dio albuma} few {Datoteke su već bile dio albuma} other {Datoteka je već bila dio albuma}}", + "assets_removed_permanently_from_device": "{count, plural, one {# stavka trajno uklonjena} few {# stavke trajno uklonjene} other {# stavki trajno uklonjeno}} s vašeg uređaja", + "assets_restore_confirmation": "Jeste li sigurni da želite vratiti sve svoje izbrisane stavke? Ovu radnju ne možete poništiti! Imajte na umu da se na ovaj način ne mogu vratiti izvanmrežne stavke.", + "assets_restored_count": "{count, plural, one {Vraćena # stavka} few {Vraćene # stavke} other {Vraćeno # stavki}}", + "assets_restored_successfully": "{count, plural, one {# stavka uspješno obnovljena} few {# stavke uspješno obnovljene} other {# stavki uspješno obnovljeno}}", + "assets_trashed": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće", + "assets_trashed_count": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće", + "assets_trashed_from_server": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće s Immich poslužitelja", + "assets_were_part_of_album_count": "{count, plural, one {Stavka je već bila} other {Stavke su već bile}} dio albuma", + "assets_were_part_of_albums_count": "{count, plural, one {Stavka je već bila} other {Stavke su već bile}} dio albuma", "authorized_devices": "Ovlašteni uređaji", "automatic_endpoint_switching_subtitle": "Povežite se lokalno preko naznačene Wi-Fi mreže kada je dostupna i koristite alternativne veze na drugim lokacijama", "automatic_endpoint_switching_title": "Automatsko prebacivanje URL-a", @@ -545,17 +544,18 @@ "backup": "Sigurnosna kopija", "backup_album_selection_page_albums_device": "Albumi na uređaju ({count})", "backup_album_selection_page_albums_tap": "Dodirnite za uključivanje, dvostruki dodir za isključivanje", - "backup_album_selection_page_assets_scatter": "Resursi mogu biti raspoređeni u više albuma. Stoga, albumi mogu biti uključeni ili isključeni tijekom procesa sigurnosnog kopiranja.", + "backup_album_selection_page_assets_scatter": "Stavke se mogu raspršiti po više albuma. Stoga se albumi mogu uključiti ili isključiti tijekom postupka sigurnosnog kopiranja.", "backup_album_selection_page_select_albums": "Odabrani albumi", "backup_album_selection_page_selection_info": "Informacije o odabiru", - "backup_album_selection_page_total_assets": "Ukupan broj jedinstvenih resursa", + "backup_album_selection_page_total_assets": "Ukupan broj jedinstvenih stavki", "backup_all": "Sve", - "backup_background_service_backup_failed_message": "Neuspješno sigurnosno kopiranje resursa. Pokušavam ponovo…", + "backup_background_service_backup_failed_message": "Neuspješno sigurnosno kopiranje stavki. Ponovno pokušavanje…", + "backup_background_service_complete_notification": "Sigurnosno kopiranje stavki dovršeno", "backup_background_service_connection_failed_message": "Neuspješno povezivanje s poslužiteljem. Pokušavam ponovo…", "backup_background_service_current_upload_notification": "Šaljem {filename}", - "backup_background_service_default_notification": "Provjera novih resursa…", + "backup_background_service_default_notification": "Provjera novih stavki…", "backup_background_service_error_title": "Pogreška pri sigurnosnom kopiranju", - "backup_background_service_in_progress_notification": "Sigurnosno kopiranje vaših resursa…", + "backup_background_service_in_progress_notification": "Sigurnosno kopiranje vaših stavki…", "backup_background_service_upload_failure_notification": "Neuspješno slanje {filename}", "backup_controller_page_albums": "Sigurnosno kopiranje albuma", "backup_controller_page_background_app_refresh_disabled_content": "Omogućite osvježavanje aplikacije u pozadini u Postavke > Opće Postavke > Osvježavanje Aplikacija u Pozadini kako biste koristili sigurnosno kopiranje u pozadini.", @@ -567,8 +567,8 @@ "backup_controller_page_background_battery_info_title": "Optimizacije baterije", "backup_controller_page_background_charging": "Samo tijekom punjenja", "backup_controller_page_background_configure_error": "Neuspješno konfiguriranje pozadinske usluge", - "backup_controller_page_background_delay": "Odgođeno sigurnosno kopiranje novih resursa: {duration}", - "backup_controller_page_background_description": "Uključite pozadinsku uslugu kako biste automatski sigurnosno kopirali nove resurse bez potrebe za otvaranjem aplikacije", + "backup_controller_page_background_delay": "Odgoda sigurnosnog kopiranja novih stavki: {duration}", + "backup_controller_page_background_description": "Uključite pozadinsku uslugu za automatsko sigurnosno kopiranje svih novih stavki bez potrebe za otvaranjem aplikacije", "backup_controller_page_background_is_off": "Automatsko sigurnosno kopiranje u pozadini je isključeno", "backup_controller_page_background_is_on": "Automatsko sigurnosno kopiranje u pozadini je uključeno", "backup_controller_page_background_turn_off": "Isključite pozadinsku uslugu", @@ -578,7 +578,7 @@ "backup_controller_page_backup_selected": "Odabrani: ", "backup_controller_page_backup_sub": "Sigurnosno kopirane fotografije i videozapisi", "backup_controller_page_created": "Kreirano: {date}", - "backup_controller_page_desc_backup": "Uključite sigurnosno kopiranje u prvom planu kako biste automatski prenijeli nove resurse na poslužitelj prilikom otvaranja aplikacije.", + "backup_controller_page_desc_backup": "Uključite sigurnosno kopiranje u prvom planu kako biste automatski prenijeli nove stavke na poslužitelj prilikom otvaranja aplikacije.", "backup_controller_page_excluded": "Izuzeto: ", "backup_controller_page_failed": "Neuspješno ({count})", "backup_controller_page_filename": "Naziv datoteke: {filename} [{size}]", @@ -598,7 +598,7 @@ "backup_controller_page_turn_on": "Uključite sigurnosno kopiranje u prvom planu", "backup_controller_page_uploading_file_info": "Slanje informacija o datoteci", "backup_err_only_album": "Nije moguće ukloniti jedini album", - "backup_info_card_assets": "resursi", + "backup_info_card_assets": "stavke", "backup_manual_cancelled": "Otkazano", "backup_manual_in_progress": "Slanje već u tijeku. Pokšuajte nakon nekog vremena", "backup_manual_success": "Uspijeh", @@ -618,15 +618,15 @@ "bugs_and_feature_requests": "Bugovi i zahtjevi za značajke", "build": "Sagradi (Build)", "build_image": "Sagradi (Build) Image", - "bulk_delete_duplicates_confirmation": "Jeste li sigurni da želite skupno izbrisati {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će zadržati najveće sredstvo svake grupe i trajno izbrisati sve druge duplikate. Ne možete poništiti ovu radnju!", + "bulk_delete_duplicates_confirmation": "Jeste li sigurni da želite skupno izbrisati {count, plural, one {# dupliciranu stavku} few {# duplicirane stavke} other {# dupliciranih stavki}}? Ovo će zadržati najveću stavku svake grupe i trajno izbrisati sve druge duplikate. Ne možete poništiti ovu radnju!", "bulk_keep_duplicates_confirmation": "Jeste li sigurni da želite zadržati {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će riješiti sve duplicirane grupe bez brisanja ičega.", - "bulk_trash_duplicates_confirmation": "Jeste li sigurni da želite na veliko baciti u smeće {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će zadržati najveće sredstvo svake grupe i baciti sve ostale duplikate u smeće.", + "bulk_trash_duplicates_confirmation": "Jeste li sigurni da želite skupno u smeće premjestiti {count, plural, one {# dupliciranu stavku} few {# duplicirane stavke} other {# dupliciranih stavki}}? Ovo će zadržati najveću stavku svake grupe i premjestiti sve ostale duplikate u smeće.", "buy": "Kupi Immich", "cache_settings_clear_cache_button": "Očisti predmemoriju", "cache_settings_clear_cache_button_title": "Briše predmemoriju aplikacije. Ovo će značajno utjecati na performanse aplikacije dok se predmemorija ponovno ne izgradi.", "cache_settings_duplicated_assets_clear_button": "OČISTI", - "cache_settings_duplicated_assets_subtitle": "Fotografije i videozapisi koje je aplikacija ignorira", - "cache_settings_duplicated_assets_title": "Duplicirani resursi ({count})", + "cache_settings_duplicated_assets_subtitle": "Fotografije i videozapisi koje aplikacija ignorira", + "cache_settings_duplicated_assets_title": "Duplicirane stavke ({count})", "cache_settings_statistics_album": "Sličice biblioteke", "cache_settings_statistics_full": "Pune slike", "cache_settings_statistics_shared": "Sličice dijeljenih albuma", @@ -683,8 +683,8 @@ "client_cert_import_success_msg": "Klijentski certifikat je uvezen", "client_cert_invalid_msg": "Neispravna datoteka certifikata ili pogrešna lozinka", "client_cert_remove_msg": "Klijentski certifikat je uklonjen", - "client_cert_subtitle": "Podržava samo PKCS12 (.p12, .pfx) format. Uvoz/uklanjanje certifikata moguće je samo prije prijave", - "client_cert_title": "SSL klijentski certifikat", + "client_cert_subtitle": "Podržava samo PKCS12 (.p12, .pfx) format. Uvoz/uklanjanje certifikata dostupno je samo prije prijave", + "client_cert_title": "SSL klijentski certifikat [EKSPERIMENTALNO]", "clockwise": "U smjeru kazaljke na satu", "close": "Zatvori", "collapse": "Sažmi", @@ -699,9 +699,9 @@ "completed": "Dovršeno", "confirm": "Potvrdi", "confirm_admin_password": "Potvrdite lozinku administratora", - "confirm_delete_face": "Jeste li sigurni da želite izbrisati lice {name} iz resursa?", + "confirm_delete_face": "Jeste li sigurni da želite izbrisati lice {name} iz stavke?", "confirm_delete_shared_link": "Jeste li sigurni da želite izbrisati ovu zajedničku vezu?", - "confirm_keep_this_delete_others": "Sva druga sredstva u nizu bit će izbrisana osim ovog sredstva. Jeste li sigurni da želite nastaviti?", + "confirm_keep_this_delete_others": "Sve druge stavke u stogu bit će izbrisane osim ove stavke. Jeste li sigurni da želite nastaviti?", "confirm_new_pin_code": "Potvrdi novi PIN kod", "confirm_password": "Potvrdite lozinku", "confirm_tag_face": "Želite li označiti ovo lice kao {name}?", @@ -717,7 +717,7 @@ "control_bottom_app_bar_edit_location": "Uredi lokaciju", "control_bottom_app_bar_edit_time": "Uredi datum i vrijeme", "control_bottom_app_bar_share_link": "Podijeli poveznicu", - "control_bottom_app_bar_share_to": "Podijeli s...", + "control_bottom_app_bar_share_to": "Dijeli s", "control_bottom_app_bar_trash_from_immich": "Premjesti u smeće", "copied_image_to_clipboard": "Slika je kopirana u međuspremnik.", "copied_to_clipboard": "Kopirano u međuspremnik!", @@ -740,7 +740,7 @@ "create_link_to_share_description": "Dopusti svakome s vezom da vidi odabrane fotografije", "create_new": "KREIRAJ NOVO", "create_new_person": "Stvorite novu osobu", - "create_new_person_hint": "Dodijelite odabrana sredstva novoj osobi", + "create_new_person_hint": "Dodijelite odabrane stavke novoj osobi", "create_new_user": "Kreiraj novog korisnika", "create_shared_album_page_share_add_assets": "DODAJ STAVKE", "create_shared_album_page_share_select_photos": "Odaberi fotografije", @@ -778,7 +778,7 @@ "default_locale": "Zadana lokalizacija", "default_locale_description": "Oblikujte datume i brojeve na temelju jezika preglednika", "delete": "Izbriši", - "delete_action_confirmation_message": "Jeste li sigurni da želite izbrisati ovaj sadržaj? Ova radnja će premjestiti sadržaj u smeće na poslužitelju i upitat će vas želite li ga izbrisati i lokalno", + "delete_action_confirmation_message": "Jeste li sigurni da želite izbrisati ovu stavku? Ova radnja će premjestiti stavku u smeće poslužitelja i pitati vas želite li ju izbrisati lokalno", "delete_action_prompt": "{count} izbrisano", "delete_album": "Izbriši album", "delete_api_key_prompt": "Jeste li sigurni da želite izbrisati ovaj API ključ?", @@ -805,7 +805,7 @@ "delete_tag_confirmation_prompt": "Jeste li sigurni da želite izbrisati oznaku {tagName}?", "delete_user": "Izbriši korisnika", "deleted_shared_link": "Izbrisana dijeljena poveznica", - "deletes_missing_assets": "Briše sredstva koja nedostaju s diska", + "deletes_missing_assets": "Briše stavke koje nedostaju na disku", "description": "Opis", "description_input_hint_text": "Dodaj opis...", "description_input_submit_error": "Pogreška pri ažuriranju opisa, provjerite zapisnik za više detalja", @@ -822,12 +822,12 @@ "display_options": "Mogućnosti prikaza", "display_order": "Redoslijed prikaza", "display_original_photos": "Prikaz originalnih fotografija", - "display_original_photos_setting_description": "Radije prikažite izvornu fotografiju kada gledate materijal umjesto sličica kada je izvorni materijal kompatibilan s webom. To može rezultirati sporijim brzinama prikaza fotografija.", + "display_original_photos_setting_description": "Radije prikažite izvornu fotografiju kada gledate stavku umjesto sličica kada je izvorna stavka kompatibilna s webom. To može rezultirati sporijim brzinama prikaza fotografija.", "do_not_show_again": "Ne prikazuj više ovu poruku", "documentation": "Dokumentacija", "done": "Gotovo", "download": "Preuzmi", - "download_action_prompt": "Preuzimanje {count} sadržaja", + "download_action_prompt": "Preuzimanje {count, plural, one {# stavke} few {# stavke} other {# stavki}}", "download_canceled": "Preuzimanje otkazano", "download_complete": "Preuzimanje završeno", "download_enqueue": "Preuzimanje dodano u red", @@ -839,13 +839,13 @@ "download_notfound": "Preuzimanje nije pronađeno", "download_paused": "Preuzimanje pauzirano", "download_settings": "Preuzmi", - "download_settings_description": "Upravljajte postavkama koje se odnose na preuzimanje sredstava", + "download_settings_description": "Upravljajte postavkama vezanim uz preuzimanje stavki", "download_started": "Preuzimanje započeto", "download_sucess": "Preuzimanje uspješno", "download_sucess_android": "Medij je preuzet u DCIM/Immich", "download_waiting_to_retry": "Čeka se ponovni pokušaj", "downloading": "Preuzimanje", - "downloading_asset_filename": "Preuzimanje materijala {filename}", + "downloading_asset_filename": "Preuzimanje stavke {filename}", "downloading_media": "Preuzimanje medija", "drop_files_to_upload": "Ispustite datoteke bilo gdje za prijenos", "duplicates": "Duplikati", @@ -864,8 +864,6 @@ "edit_description_prompt": "Molimo odaberite novi opis:", "edit_exclusion_pattern": "Uredi uzorak izuzimanja", "edit_faces": "Uređivanje lica", - "edit_import_path": "Uredi put uvoza", - "edit_import_paths": "Uredi Uvozne Putanje", "edit_key": "Ključ za uređivanje", "edit_link": "Uredi poveznicu", "edit_location": "Uredi lokaciju", @@ -885,7 +883,7 @@ "email_notifications": "Obavijesti putem e-maila", "empty_folder": "Ova mapa je prazna", "empty_trash": "Isprazni smeće", - "empty_trash_confirmation": "Jeste li sigurni da želite isprazniti smeće? Time će se iz Immicha trajno ukloniti sva sredstva u otpadu.\nNe možete poništiti ovu radnju!", + "empty_trash_confirmation": "Jeste li sigurni da želite isprazniti smeće? Time će se iz Immicha trajno ukloniti sve stavke u smeću.\nNe možete poništiti ovu radnju!", "enable": "Omogući", "enable_backup": "Omogući sigurnosnu kopiju", "enable_biometric_auth_description": "Unesite svoj PIN kod za omogućavanje biometrijske autentikacije", @@ -903,57 +901,55 @@ "error_tag_face_bounding_box": "Pogreška pri označavanju lica – nije moguće dohvatiti koordinate granica (bounding box)", "error_title": "Greška - Nešto je pošlo krivo", "errors": { - "cannot_navigate_next_asset": "Nije moguće prijeći na sljedeći materijal", - "cannot_navigate_previous_asset": "Nije moguće prijeći na prethodni materijal", + "cannot_navigate_next_asset": "Nije moguće prijeći na sljedeću stavku", + "cannot_navigate_previous_asset": "Nije moguće prijeći na prethodnu stavku", "cant_apply_changes": "Nije moguće primijeniti promjene", "cant_change_activity": "Nije moguće {enabled, select, true {onemogućiti} other {omogućiti}} aktivnost", - "cant_change_asset_favorite": "Nije moguće promijeniti favorita za sredstvo", - "cant_change_metadata_assets_count": "Nije moguće promijeniti metapodatke {count, plural, one {# asset} other {# assets}}", + "cant_change_asset_favorite": "Nije moguće promijeniti favorita za stavku", + "cant_change_metadata_assets_count": "Nije moguće promijeniti metapodatke {count, plural, one {# stavke} few {# stavke} other {# stavki}}", "cant_get_faces": "Ne mogu dobiti lica", "cant_get_number_of_comments": "Ne mogu dobiti broj komentara", "cant_search_people": "Ne mogu pretraživati ljude", "cant_search_places": "Ne mogu pretraživati mjesta", - "error_adding_assets_to_album": "Pogreška pri dodavanju materijala u album", + "error_adding_assets_to_album": "Pogreška pri dodavanju stavki u album", "error_adding_users_to_album": "Pogreška pri dodavanju korisnika u album", "error_deleting_shared_user": "Pogreška pri brisanju dijeljenog korisnika", "error_downloading": "Pogreška pri preuzimanju {filename}", "error_hiding_buy_button": "Pogreška pri skrivanju gumba za kupnju", - "error_removing_assets_from_album": "Pogreška prilikom uklanjanja materijala iz albuma, provjerite konzolu za više pojedinosti", - "error_selecting_all_assets": "Pogreška pri odabiru svih sredstava", + "error_removing_assets_from_album": "Pogreška prilikom uklanjanja stavki iz albuma, provjerite konzolu za više detalja", + "error_selecting_all_assets": "Pogreška pri odabiru svih stavki", "exclusion_pattern_already_exists": "Ovaj uzorak izuzimanja već postoji.", "failed_to_create_album": "Izrada albuma nije uspjela", "failed_to_create_shared_link": "Stvaranje dijeljene veze nije uspjelo", "failed_to_edit_shared_link": "Nije uspjelo uređivanje dijeljene poveznice", - "failed_to_get_people": "Dohvaćanje ljudi nije uspjelo", - "failed_to_keep_this_delete_others": "Zadržavanje ovog sredstva i brisanje ostalih sredstava nije uspjelo", - "failed_to_load_asset": "Učitavanje sredstva nije uspjelo", - "failed_to_load_assets": "Učitavanje sredstava nije uspjelo", + "failed_to_get_people": "Dohvaćanje osoba nije uspjelo", + "failed_to_keep_this_delete_others": "Zadržavanje ove stavke i brisanje ostalih stavki nije uspjelo", + "failed_to_load_asset": "Učitavanje stavke nije uspjelo", + "failed_to_load_assets": "Učitavanje stavki nije uspjelo", "failed_to_load_notifications": "Neuspješno učitavanje obavijesti", - "failed_to_load_people": "Učitavanje ljudi nije uspjelo", + "failed_to_load_people": "Učitavanje osoba nije uspjelo", "failed_to_remove_product_key": "Uklanjanje ključa proizvoda nije uspjelo", "failed_to_reset_pin_code": "Neuspješno resetiranje PIN koda", - "failed_to_stack_assets": "Slaganje sredstava nije uspjelo", - "failed_to_unstack_assets": "Nije uspjelo uklanjanje snopa sredstava", + "failed_to_stack_assets": "Slaganje stavki nije uspjelo", + "failed_to_unstack_assets": "Razdvajanje stavki nije uspjelo", "failed_to_update_notification_status": "Neuspješno ažuriranje statusa obavijesti", - "import_path_already_exists": "Ovaj uvozni put već postoji.", "incorrect_email_or_password": "Netočna adresa e-pošte ili lozinka", "paths_validation_failed": "{paths, plural, one {# putanja nije prošla} other {# putanje nisu prošle}} provjeru valjanosti", "profile_picture_transparent_pixels": "Profilne slike ne smiju imati prozirne piksele. Povećajte i/ili pomaknite sliku.", "quota_higher_than_disk_size": "Postavili ste kvotu veću od veličine diska", "something_went_wrong": "Nešto je pošlo po zlu", "unable_to_add_album_users": "Nije moguće dodati korisnike u album", - "unable_to_add_assets_to_shared_link": "Nije moguće dodati sredstva na dijeljenu poveznicu", + "unable_to_add_assets_to_shared_link": "Nije moguće dodati stavke u dijeljenu vezu", "unable_to_add_comment": "Nije moguće dodati komentar", "unable_to_add_exclusion_pattern": "Nije moguće dodati uzorak izuzimanja", - "unable_to_add_import_path": "Nije moguće dodati putanju uvoza", "unable_to_add_partners": "Nije moguće dodati partnere", - "unable_to_add_remove_archive": "Nije moguće {archived, select, true {ukloniti resurs iz} other {dodati resurs u}} arhivu", + "unable_to_add_remove_archive": "Nije moguće {archived, select, true {ukloniti stavku iz} other {dodati stavku u}} arhivu", "unable_to_add_remove_favorites": "Nije moguće {favorite, select, true {add asset to} other {remove asset from}} favorite", "unable_to_archive_unarchive": "Nije moguće {archived, select, true {arhivirati} other {dearhivirati}}", "unable_to_change_album_user_role": "Nije moguće promijeniti ulogu korisnika albuma", "unable_to_change_date": "Nije moguće promijeniti datum", "unable_to_change_description": "Nije moguće promijeniti opis", - "unable_to_change_favorite": "Nije moguće promijeniti favorita za sredstvo", + "unable_to_change_favorite": "Nije moguće promijeniti favorita za stavku", "unable_to_change_location": "Nije moguće promijeniti lokaciju", "unable_to_change_password": "Nije moguće promijeniti lozinku", "unable_to_change_visibility": "Nije moguće promijeniti vidljivost za {count, plural, one {# osobu} other {# osobe}}", @@ -965,15 +961,13 @@ "unable_to_create_library": "Nije moguće stvoriti biblioteku", "unable_to_create_user": "Nije moguće stvoriti korisnika", "unable_to_delete_album": "Nije moguće izbrisati album", - "unable_to_delete_asset": "Nije moguće izbrisati sredstvo", - "unable_to_delete_assets": "Pogreška pri brisanju sredstava", + "unable_to_delete_asset": "Nije moguće izbrisati stavku", + "unable_to_delete_assets": "Pogreška pri brisanju stavki", "unable_to_delete_exclusion_pattern": "Nije moguće izbrisati uzorak izuzimanja", - "unable_to_delete_import_path": "Nije moguće izbrisati put uvoza", "unable_to_delete_shared_link": "Nije moguće izbrisati dijeljenu poveznicu", "unable_to_delete_user": "Nije moguće izbrisati korisnika", "unable_to_download_files": "Nije moguće preuzeti datoteke", "unable_to_edit_exclusion_pattern": "Nije moguće urediti uzorak izuzimanja", - "unable_to_edit_import_path": "Nije moguće urediti put uvoza", "unable_to_empty_trash": "Nije moguće isprazniti otpad", "unable_to_enter_fullscreen": "Nije moguće otvoriti cijeli zaslon", "unable_to_exit_fullscreen": "Nije moguće izaći iz cijelog zaslona", @@ -986,19 +980,19 @@ "unable_to_log_out_device": "Nije moguće odjaviti uređaj", "unable_to_login_with_oauth": "Nije moguće prijaviti se pomoću OAutha", "unable_to_play_video": "Nije moguće reproducirati video", - "unable_to_reassign_assets_existing_person": "Nije moguće ponovno dodijeliti imovinu na {name, select, null {postojeću osobu} other {{name}}}", - "unable_to_reassign_assets_new_person": "Nije moguće ponovno dodijeliti imovinu novoj osobi", + "unable_to_reassign_assets_existing_person": "Nije moguće ponovno dodijeliti stavke {name, select, null {postojećoj osobi} other {{name}}}", + "unable_to_reassign_assets_new_person": "Nije moguće ponovno dodijeliti stavke novoj osobi", "unable_to_refresh_user": "Nije moguće osvježiti korisnika", "unable_to_remove_album_users": "Nije moguće ukloniti korisnike iz albuma", "unable_to_remove_api_key": "Nije moguće ukloniti API ključ", - "unable_to_remove_assets_from_shared_link": "Nije moguće ukloniti sredstva iz dijeljene poveznice", + "unable_to_remove_assets_from_shared_link": "Nije moguće ukloniti stavke iz dijeljene veze", "unable_to_remove_library": "Nije moguće ukloniti biblioteku", "unable_to_remove_partner": "Nije moguće ukloniti partnera", "unable_to_remove_reaction": "Nije moguće ukloniti reakciju", "unable_to_reset_password": "Nije moguće ponovno postaviti lozinku", "unable_to_reset_pin_code": "Nije moguće poništiti PIN kod", "unable_to_resolve_duplicate": "Nije moguće razriješiti duplikat", - "unable_to_restore_assets": "Nije moguće vratiti imovinu", + "unable_to_restore_assets": "Nije moguće vratiti stavke", "unable_to_restore_trash": "Nije moguće vratiti otpad", "unable_to_restore_user": "Nije moguće vratiti korisnika", "unable_to_save_album": "Nije moguće spremiti album", @@ -1012,7 +1006,7 @@ "unable_to_set_feature_photo": "Nije moguće postaviti istaknutu fotografiju", "unable_to_set_profile_picture": "Nije moguće postaviti profilnu sliku", "unable_to_submit_job": "Nije moguće poslati posao", - "unable_to_trash_asset": "Nije moguće baciti sredstvo u smeće", + "unable_to_trash_asset": "Nije moguće premjestiti stavku u smeće", "unable_to_unlink_account": "Nije moguće prekinuti vezu računa", "unable_to_unlink_motion_video": "Nije moguće prekinuti vezu videozapisa pokreta", "unable_to_update_album_cover": "Nije moguće ažurirati omot albuma", @@ -1054,13 +1048,13 @@ "face_unassigned": "Nedodijeljeno", "failed": "Neuspješno", "failed_to_authenticate": "Neuspješna autentikacija", - "failed_to_load_assets": "Neuspjelo učitavanje stavki", + "failed_to_load_assets": "Učitavanje stavki nije uspjelo", "failed_to_load_folder": "Neuspjelo učitavanje mape", "favorite": "Omiljeno", "favorite_action_prompt": "{count} dodano u Omiljeno", "favorite_or_unfavorite_photo": "Omiljena ili neomiljena fotografija", "favorites": "Omiljene", - "favorites_page_no_favorites": "Nema pronađenih omiljenih stavki", + "favorites_page_no_favorites": "Nema pronađenih favorita", "feature_photo_updated": "Istaknuta fotografija ažurirana", "features": "Značajke", "features_setting_description": "Upravljajte značajkama aplikacije", @@ -1081,8 +1075,9 @@ "forgot_pin_code_question": "Zaboravili ste svoj PIN?", "forward": "Naprijed", "gcast_enabled": "Google Cast", - "gcast_enabled_description": "Ova značajka učitava vanjske resurse s Googlea kako bi radila.", + "gcast_enabled_description": "Ova značajka učitava vanjske stavke s Googlea kako bi radila.", "general": "Općenito", + "geolocation_instruction_location": "Kliknite na stavku s GPS koordinatama da biste koristili njezinu lokaciju ili odaberite lokaciju izravno s karte", "get_help": "Potražite pomoć", "get_wifiname_error": "Nije moguće dohvatiti naziv Wi-Fi mreže. Provjerite imate li potrebna dopuštenja i jeste li povezani na Wi-Fi mrežu", "getting_started": "Početak Rada", @@ -1099,8 +1094,8 @@ "haptic_feedback_switch": "Omogući haptičku povratnu informaciju", "haptic_feedback_title": "Haptička povratna informacija", "has_quota": "Ima kvotu", - "hash_asset": "Hash sadržaja", - "hashed_assets": "Hashirani sadržaji", + "hash_asset": "Hashiraj stavku", + "hashed_assets": "Hashirane stavke", "hashing": "Hashiranje", "header_settings_add_header_tip": "Dodaj zaglavlje", "header_settings_field_validator_msg": "Vrijednost ne može biti prazna", @@ -1115,21 +1110,21 @@ "hide_person": "Sakrij osobu", "hide_unnamed_people": "Sakrij neimenovane osobe", "home_page_add_to_album_conflicts": "Dodano {added} stavki u album {album}. {failed} stavki je već u albumu.", - "home_page_add_to_album_err_local": "Lokalne stavke još nije moguće dodati u albume, preskačem", + "home_page_add_to_album_err_local": "Lokalne stavke još nije moguće dodati u albume, preskakanje", "home_page_add_to_album_success": "Dodano {added} stavki u album {album}.", - "home_page_album_err_partner": "Još nije moguće dodati partnerske stavke u album, preskačem", - "home_page_archive_err_local": "Lokalne stavke još nije moguće arhivirati, preskačem", - "home_page_archive_err_partner": "Partnerske stavke nije moguće arhivirati, preskačem", + "home_page_album_err_partner": "Još nije moguće dodati partnerove stavke u album, preskakanje", + "home_page_archive_err_local": "Lokalne stavke još nije moguće arhivirati, preskakanje", + "home_page_archive_err_partner": "Partnerove stavke nije moguće arhivirati, preskakanje", "home_page_building_timeline": "Izrada vremenske crte", - "home_page_delete_err_partner": "Nije moguće izbrisati partnerske stavke, preskačem", - "home_page_delete_remote_err_local": "Lokalne stavke su u odabiru za udaljeno brisanje, preskačem", - "home_page_favorite_err_local": "Lokalne stavke još nije moguće označiti kao omiljene, preskačem", - "home_page_favorite_err_partner": "Partnerske stavke još nije moguće označiti kao omiljene, preskačem", + "home_page_delete_err_partner": "Nije moguće izbrisati partnerove stavke, preskakanje", + "home_page_delete_remote_err_local": "Lokalne stavke su u odabiru za udaljeno brisanje, preskakanje", + "home_page_favorite_err_local": "Lokalne stavke još nije moguće označiti kao favorite, preskakanje", + "home_page_favorite_err_partner": "Partnerove stavke još nije moguće označiti kao favorite, preskakanje", "home_page_first_time_notice": "Ako prvi put koristite aplikaciju, svakako odaberite album za sigurnosnu kopiju kako bi vremenska crta mogla prikazati fotografije i videozapise", - "home_page_locked_error_local": "Nije moguće premjestiti lokalne resurse u zaključanu mapu, preskačem", - "home_page_locked_error_partner": "Nije moguće premjestiti partnerske resurse u zaključanu mapu, preskačem", - "home_page_share_err_local": "Lokalne stavke nije moguće dijeliti putem poveznice, preskačem", - "home_page_upload_err_limit": "Moguće je prenijeti najviše 30 stavki odjednom, preskačem", + "home_page_locked_error_local": "Nije moguće premjestiti lokalne stavke u zaključanu mapu, preskakanje", + "home_page_locked_error_partner": "Nije moguće premjestiti partnerove stavke u zaključanu mapu, preskakanje", + "home_page_share_err_local": "Lokalne stavke nije moguće dijeliti putem poveznice, preskakanje", + "home_page_upload_err_limit": "Moguće je prenijeti najviše 30 stavki odjednom, preskakanje", "host": "Domaćin", "hour": "Sat", "hours": "Sati", @@ -1160,7 +1155,7 @@ "in_archive": "U arhivi", "include_archived": "Uključi arhivirano", "include_shared_albums": "Uključi dijeljene albume", - "include_shared_partner_assets": "Uključite zajedničku imovinu partnera", + "include_shared_partner_assets": "Uključi zajedničke stavke partnera", "individual_share": "Pojedinačni udio", "individual_shares": "Pojedinačna dijeljenja", "info": "Informacije", @@ -1185,7 +1180,7 @@ "keep": "Zadrži", "keep_all": "Zadrži Sve", "keep_this_delete_others": "Zadrži ovo, izbriši ostale", - "kept_this_deleted_others": "Zadržana je ova datoteka i izbrisano {count, plural, one {# datoteka} other {# datoteka}}", + "kept_this_deleted_others": "Zadržana je ova stavka i {count, plural, one {izbrisana # datoteka} few {izbrisane # datoteke} other {izbrisano # datoteka}}", "keyboard_shortcuts": "Prečaci tipkovnice", "language": "Jezik", "language_no_results_subtitle": "Pokušajte prilagoditi pojam za pretraživanje", @@ -1206,7 +1201,7 @@ "library_options": "Mogućnosti biblioteke", "library_page_device_albums": "Albumi na uređaju", "library_page_new_album": "Novi album", - "library_page_sort_asset_count": "Broj resursa", + "library_page_sort_asset_count": "Broj stavki", "library_page_sort_created": "Datum kreiranja", "library_page_sort_last_modified": "Zadnja izmjena", "library_page_sort_title": "Naslov albuma", @@ -1221,8 +1216,8 @@ "loading": "Učitavanje", "loading_search_results_failed": "Učitavanje rezultata pretraživanja nije uspjelo", "local": "Lokalno", - "local_asset_cast_failed": "Nije moguće reproducirati sadržaj koji nije prenesen na poslužitelj", - "local_assets": "Lokalni sadržaji", + "local_asset_cast_failed": "Nije moguće emitirati stavku koja nije prenesena na poslužitelj", + "local_assets": "Lokalne stavke", "local_network": "Lokalna mreža", "local_network_sheet_info": "Aplikacija će se povezati s poslužiteljem putem ovog URL-a kada koristi određenu Wi-Fi mrežu", "location_permission": "Dozvola za lokaciju", @@ -1279,7 +1274,7 @@ "manage_your_devices": "Upravljajte uređajima na kojima ste prijavljeni", "manage_your_oauth_connection": "Upravljajte svojom OAuth vezom", "map": "Karta", - "map_assets_in_bounds": "{count, plural, =0 {Nema fotografija na ovom području} one {# fotografija} few {#fotografije} other {# fotografija}}", + "map_assets_in_bounds": "{count, plural, =0 {Nema fotografija na ovom području} one {# fotografija} few {# fotografije} other {# fotografija}}", "map_cannot_get_user_location": "Nije moguće dohvatiti lokaciju korisnika", "map_location_dialog_yes": "Da", "map_location_picker_page_use_location": "Koristi ovu lokaciju", @@ -1305,6 +1300,7 @@ "mark_as_read": "Označi kao pročitano", "marked_all_as_read": "Označeno sve kao pročitano", "matches": "Podudaranja", + "matching_assets": "Odgovarajuće stavke", "media_type": "Vrsta medija", "memories": "Sjećanja", "memories_all_caught_up": "Sve ste pregledali", @@ -1316,10 +1312,10 @@ "memory_lane_title": "Traka sjećanja {title}", "menu": "Izbornik", "merge": "Spoji", - "merge_people": "Spajanje ljudi", + "merge_people": "Spoji osobe", "merge_people_limit": "Možete spojiti najviše 5 lica odjednom", "merge_people_prompt": "Želite li spojiti ove ljude? Ova radnja je nepovratna.", - "merge_people_successfully": "Uspješno spajanje ljudi", + "merge_people_successfully": "Uspješno spajanje osoba", "merged_people_count": "{count, plural, one {# Spojena osoba} other {# Spojene osobe}}", "minimize": "Minimiziraj", "minute": "Minuta", @@ -1334,11 +1330,11 @@ "move_to_lock_folder_action_prompt": "{count} dodano u zaključanu mapu", "move_to_locked_folder": "Premjesti u zaključanu mapu", "move_to_locked_folder_confirmation": "Ove fotografije i videozapis bit će uklonjeni iz svih albuma i bit će vidljivi samo iz zaključane mape", - "moved_to_archive": "Premješteno {count, plural, one {# resurs} other {# resursa}} u arhivu", - "moved_to_library": "Premješteno {count, plural, one {# resurs} other {# resursa}} u biblioteku", + "moved_to_archive": "{count, plural, one {Premještena # stavka} few {Premještene # stavke} other {Premješteno # stavki}} u arhivu", + "moved_to_library": "{count, plural, one {Premještena # stavka} few {Premještene # stavke} other {Premješteno # stavki}} u biblioteku", "moved_to_trash": "Premješteno u smeće", - "multiselect_grid_edit_date_time_err_read_only": "Nije moguće urediti datum stavki samo za čitanje, preskačem", - "multiselect_grid_edit_gps_err_read_only": "Nije moguće urediti lokaciju stavki samo za čitanje, preskačem", + "multiselect_grid_edit_date_time_err_read_only": "Nije moguće urediti datum stavki označenih kao samo za čitanje, preskakanje", + "multiselect_grid_edit_gps_err_read_only": "Nije moguće urediti lokaciju stavki označenih kao samo za čitanje, preskakanje", "mute_memories": "Isključi uspomene", "my_albums": "Moji albumi", "name": "Ime", @@ -1368,23 +1364,27 @@ "no_assets_message": "KLIKNITE DA PRENESETE SVOJU PRVU FOTOGRAFIJU", "no_assets_to_show": "Nema stavki za prikaz", "no_cast_devices_found": "Nisu pronađeni uređaji za reprodukciju", + "no_checksum_local": "Nema dostupnog kontrolnog zbroja - nije moguće dohvatiti lokalne stavke", + "no_checksum_remote": "Nema dostupnog kontrolnog zbroja - nije moguće dohvatiti udaljenu stavku", "no_duplicates_found": "Nisu pronađeni duplikati.", "no_exif_info_available": "Nema dostupnih exif podataka", "no_explore_results_message": "Prenesite više fotografija da istražite svoju zbirku.", "no_favorites_message": "Dodajte favorite kako biste brzo pronašli svoje najbolje slike i videozapise", "no_libraries_message": "Stvorite vanjsku biblioteku za pregled svojih fotografija i videozapisa", + "no_local_assets_found": "Nisu pronađene lokalne stavke s ovim kontrolnim zbrojem", "no_locked_photos_message": "Fotografije i videozapisi u zaključanoj mapi su skriveni i neće se prikazivati dok pregledavate ili pretražujete svoju biblioteku.", "no_name": "Bez imena", "no_notifications": "Nema notifikacija", "no_people_found": "Nema pronađenih odgovarajućih osoba", "no_places": "Nema mjesta", + "no_remote_assets_found": "Nisu pronađene udaljene stavke s ovim kontrolnim zbrojem", "no_results": "Nema rezultata", "no_results_description": "Pokušajte sa sinonimom ili općenitijom ključnom riječi", "no_shared_albums_message": "Stvorite album za dijeljenje fotografija i videozapisa s osobama u svojoj mreži", "no_uploads_in_progress": "Nema aktivnih prijenosa", "not_in_any_album": "Ni u jednom albumu", "not_selected": "Nije odabrano", - "note_apply_storage_label_to_previously_uploaded assets": "Napomena: Da biste primijenili Oznaku za skladištenje na prethodno prenesena sredstva, pokrenite", + "note_apply_storage_label_to_previously_uploaded assets": "Napomena: Da biste primijenili oznaku pohrane na prethodno prenesene stavke, pokrenite", "notes": "Bilješke", "nothing_here_yet": "Ovdje još nema ničega", "notification_permission_dialog_content": "Da biste omogućili obavijesti, idite u Postavke i odaberite dopusti.", @@ -1426,7 +1426,7 @@ "owner": "Vlasnik", "partner": "Partner", "partner_can_access": "{partner} može pristupiti", - "partner_can_access_assets": "Sve vaše fotografije i videi osim onih u arhivi i smeću", + "partner_can_access_assets": "Sve vaše fotografije i videozapisi osim onih u arhivi i smeću", "partner_can_access_location": "Mjesto otkuda je slika otkinuta", "partner_list_user_photos": "{user} fotografije", "partner_list_view_all": "Prikaži sve", @@ -1453,17 +1453,17 @@ "pause_memories": "Pauziraj sjećanja", "paused": "Pauzirano", "pending": "Na čekanju", - "people": "Ljudi", + "people": "Osobe", "people_edits_count": "Izmjenjeno {count, plural, one {# osoba} other {# osobe}}", "people_feature_description": "Pregledavanje fotografija i videozapisa grupiranih po osobama", "people_sidebar_description": "Prikažite poveznicu na Osobe na bočnoj traci", "permanent_deletion_warning": "Upozorenje za nepovratno brisanje", - "permanent_deletion_warning_setting_description": "Prikaži upozorenje prilikom trajnog brisanja sredstava", + "permanent_deletion_warning_setting_description": "Prikaži upozorenje prilikom trajnog brisanja stavki", "permanently_delete": "Nepovratno obriši", "permanently_delete_assets_count": "Trajno izbriši {count, plural, one {datoteku} other {datoteke}}", - "permanently_delete_assets_prompt": "Da li ste sigurni da želite trajni izbrisati {count, plural, one {ovu datoteku?} other {ove # datoteke?}}Ovo će ih također ukloniti {count, plural, one {iz njihovog} other {iz njihovih}} albuma.", - "permanently_deleted_asset": "Trajno izbrisano sredstvo", - "permanently_deleted_assets_count": "Trajno izbrisano {count, plural, one {# datoteka} other {# datoteke}}", + "permanently_delete_assets_prompt": "Jeste li sigurni da želite trajno izbrisati {count, plural, one {ovu stavku?} other {ove # stavke?}} Ovo će {count, plural, one {ju također ukloniti iz njezinog} other {ih također ukloniti iz njihovih}} albuma.", + "permanently_deleted_asset": "Trajno izbrisana stavka", + "permanently_deleted_assets_count": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbisano # stavki}}", "permission": "Dozvola", "permission_empty": "Vaša dozvola ne smije biti prazna", "permission_onboarding_back": "Natrag", @@ -1497,6 +1497,7 @@ "play_memories": "Pokreni sjećanja", "play_motion_photo": "Reproduciraj Pokretnu fotografiju", "play_or_pause_video": "Reproducirajte ili pauzirajte video", + "play_original_video_setting_description": "Preferirajte reprodukciju originalnih videozapisa umjesto transkodiranih videozapisa. Ako originalna stavka nije kompatibilna, možda se neće ispravno reproducirati.", "please_auth_to_access": "Molimo autentificirajte se za pristup", "port": "Port", "preferences_settings_subtitle": "Upravljajte postavkama aplikacije", @@ -1551,6 +1552,7 @@ "purchase_server_description_2": "Status podupiratelja", "purchase_server_title": "Poslužitelj (Server)", "purchase_settings_server_activated": "Ključem proizvoda poslužitelja upravlja administrator", + "query_asset_id": "Ispitaj ID stavke", "queue_status": "Stavljanje u red {count}/{total}", "rating": "Broj zvjezdica", "rating_clear": "Obriši ocjenu", @@ -1559,9 +1561,9 @@ "reaction_options": "Mogućnosti reakcije", "read_changelog": "Pročitajte Dnevnik promjena", "reassign": "Ponovno dodijeli", - "reassigned_assets_to_existing_person": "Ponovo dodijeljeno{count, plural, one {# datoteka} other {# datoteke}} postojećoj {name, select, null {osobi} other {{name}}}", - "reassigned_assets_to_new_person": "Ponovo dodijeljeno {count, plural, one {# datoteka} other {# datoteke}} novoj osobi", - "reassing_hint": "Dodijelite odabrane datoteke postojećoj osobi", + "reassigned_assets_to_existing_person": "Ponovno dodijeljeno {count, plural, one {# stavka} few {# stavke} other {# stavki}} {name, select, null {postojećoj osobi} other {{name}}}", + "reassigned_assets_to_new_person": "{count, plural, one {# stavka ponovno dodijeljena} few {# stavke ponovno dodijeljene} other {# stavki ponovno dodijeljeno}} novoj osobi", + "reassing_hint": "Dodijelite odabrane stavke postojećoj osobi", "recent": "Nedavno", "recent-albums": "Nedavni albumi", "recent_searches": "Nedavne pretrage", @@ -1581,13 +1583,13 @@ "refreshing_metadata": "Osvježavanje metapodataka", "regenerating_thumbnails": "Obnavljanje sličica", "remote": "Udaljeno", - "remote_assets": "Udaljeni sadržaji", + "remote_assets": "Udaljene stavke", "remove": "Ukloni", - "remove_assets_album_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# datoteku} other {# datoteke}} iz albuma?", - "remove_assets_shared_link_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# datoteku} other {# datoteke}} iz ove dijeljene veze?", - "remove_assets_title": "Ukloniti datoteke?", + "remove_assets_album_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# stavku} few {# stavke} other {# stavki}} iz albuma?", + "remove_assets_shared_link_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# stavku} few {# stavke} other {# stavki}} iz ove dijeljene veze?", + "remove_assets_title": "Ukloniti stavke?", "remove_custom_date_range": "Ukloni prilagođeni datumski raspon", - "remove_deleted_assets": "Ukloni izbrisana sredstva", + "remove_deleted_assets": "Ukloni izbrisane stavke", "remove_from_album": "Ukloni iz albuma", "remove_from_album_action_prompt": "{count} uklonjeno iz albuma", "remove_from_favorites": "Ukloni iz favorita", @@ -1606,7 +1608,7 @@ "removed_from_favorites_count": "{count, plural, other {Uklonjeno #}} iz omiljenih", "removed_memory": "Uklonjena uspomena", "removed_photo_from_memory": "Uklonjena fotografija iz uspomene", - "removed_tagged_assets": "Uklonjena oznaka iz {count, plural, one {# datoteke} other {# datoteka}}", + "removed_tagged_assets": "Uklonjena oznaka iz {count, plural, one {# stavke} few {# stavke} other {# stavki}}", "rename": "Preimenuj", "repair": "Popravi", "repair_no_results_message": "Nepraćene datoteke i datoteke koje nedostaju pojavit će se ovdje", @@ -1617,7 +1619,7 @@ "rescan": "Ponovno skeniraj", "reset": "Resetiraj", "reset_password": "Resetiraj lozinku", - "reset_people_visibility": "Poništi vidljivost ljudi", + "reset_people_visibility": "Poništi vidljivost osoba", "reset_pin_code": "Resetiraj PIN kod", "reset_pin_code_description": "Ako ste zaboravili svoj PIN kod, možete kontaktirati administratora poslužitelja da ga resetira", "reset_pin_code_success": "PIN kod je uspješno resetiran", @@ -1632,7 +1634,7 @@ "restore_all": "Oporavi sve", "restore_trash_action_prompt": "{count} vraćeno iz smeća", "restore_user": "Vrati korisnika", - "restored_asset": "Obnovljena datoteka", + "restored_asset": "Obnovljena stavka", "resume": "Nastavi", "retry_upload": "Ponovi prijenos", "review_duplicates": "Pregledajte duplikate", @@ -1679,7 +1681,7 @@ "search_for": "Traži", "search_for_existing_person": "Potražite postojeću osobu", "search_no_more_result": "Nema više rezultata", - "search_no_people": "Nema ljudi", + "search_no_people": "Nema osoba", "search_no_people_named": "Nema osoba s imenom \"{name}\"", "search_no_result": "Nema rezultata, pokušajte s drugim pojmom za pretraživanje ili kombinacijom", "search_options": "Opcije pretraživanja", @@ -1703,7 +1705,7 @@ "search_suggestion_list_smart_search_hint_1": "Pametna pretraga je omogućena prema zadanim postavkama, za pretraživanje metapodataka koristite sintaksu ", "search_suggestion_list_smart_search_hint_2": "m:vaš-pojam-pretrage", "search_tags": "Traži oznake...", - "search_timezone": "Pretraži vremenske zone", + "search_timezone": "Pretraživanje vremenske zone...", "search_type": "Vrsta pretraživanja", "search_your_photos": "Pretražite svoje fotografije", "searching_locales": "Traženje lokaliteta...", @@ -1744,7 +1746,7 @@ "set_date_of_birth": "Postavi datum rođenja", "set_profile_picture": "Postavi profilnu sliku", "set_slideshow_to_fullscreen": "Postavi prezentaciju na cijeli zaslon", - "set_stack_primary_asset": "Postavi kao glavni sadržaj", + "set_stack_primary_asset": "Postavi kao glavnu stavku", "setting_image_viewer_help": "Preglednik detalja prvo učitava malu sličicu, zatim učitava pregled srednje veličine (ako je omogućen), te na kraju učitava original (ako je omogućen).", "setting_image_viewer_original_subtitle": "Omogućite za učitavanje originalne slike pune rezolucije (velika!). Onemogućite za smanjenje potrošnje podataka (i mrežne i na predmemoriji uređaja).", "setting_image_viewer_original_title": "Učitaj originalnu sliku", @@ -1759,10 +1761,10 @@ "setting_notifications_notify_minutes": "{count} minuta", "setting_notifications_notify_never": "nikad", "setting_notifications_notify_seconds": "{count} sekundi", - "setting_notifications_single_progress_subtitle": "Detaljne informacije o napretku prijenosa po stavci", + "setting_notifications_single_progress_subtitle": "Detaljne informacije o napretku prijenosa po stavki", "setting_notifications_single_progress_title": "Prikaži detaljni napredak sigurnosnog kopiranja u pozadini", "setting_notifications_subtitle": "Prilagodite postavke obavijesti", - "setting_notifications_total_progress_subtitle": "Ukupni napredak prijenosa (završeno/ukupno stavki)", + "setting_notifications_total_progress_subtitle": "Ukupni napredak prijenosa (završeno/ukupan broj stavki)", "setting_notifications_total_progress_title": "Prikaži ukupni napredak sigurnosnog kopiranja u pozadini", "setting_video_viewer_looping_title": "Ponavljanje", "setting_video_viewer_original_video_subtitle": "Prilikom strujanja videozapisa s poslužitelja, reproducirajte original čak i kada je dostupna transkodirana verzija. Može doći do međuspremanja. Videozapisi dostupni lokalno reproduciraju se u originalnoj kvaliteti bez obzira na ovu postavku.", @@ -1772,9 +1774,9 @@ "settings_saved": "Postavke su spremljene", "setup_pin_code": "Postavi PIN kod", "share": "Podijeli", - "share_action_prompt": "Podijeljeno {count} sadržaja", + "share_action_prompt": "{count, plural, one {Podijeljena # stavka} few {Podijeljene # stavke} other {Podijeljeno # stavki}}", "share_add_photos": "Dodaj fotografije", - "share_assets_selected": "{count} odabrano", + "share_assets_selected": "{count, plural, one {# odabran} few {# odabrana} other {# odabrano}}", "share_dialog_preparing": "Priprema...", "share_link": "Podijeli Link", "shared": "Podijeljeno", @@ -1823,7 +1825,7 @@ "shared_link_password_description": "Zahtjevaj loziku za pristup ovom dijeljenom linku", "shared_links": "Dijeljene poveznice", "shared_links_description": "Podijelite fotografije i videozapise putem poveznice", - "shared_photos_and_videos_count": "{assetCount, plural, =1 {# podijeljena fotografija ili videozapis.} few {# podijeljene fotografije i videozapisa.} other {# podijeljenih fotografija i videozapisa.}}", + "shared_photos_and_videos_count": "{assetCount, plural, one {# podijeljena fotografija ili videozapis.} few {# podijeljene fotografije i videozapisa.} other {# podijeljenih fotografija i videozapisa.}}", "shared_with_me": "Podijeljeno sa mnom", "shared_with_partner": "Podijeljeno s {partner}", "sharing": "Dijeljenje", @@ -1881,7 +1883,7 @@ "stack_duplicates": "Složi duplikate", "stack_select_one_photo": "Odaberi jednu glavnu fotografiju za slaganje", "stack_selected_photos": "Složi odabrane fotografije", - "stacked_assets_count": "Složeno {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}", + "stacked_assets_count": "{count, plural, one {Složena # stavka} few {Složene # stavke} other {Složeno # stavki}}", "stacktrace": "Pracenje stoga", "start": "Početak", "start_date": "Datum početka", @@ -1919,7 +1921,7 @@ "tag_not_found_question": "Nije moguće pronaći oznaku? Napravite novu oznaku.", "tag_people": "Označi osobe", "tag_updated": "Ažurirana oznaka: {tag}", - "tagged_assets": "Označena {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}", + "tagged_assets": "{count, plural, =1 {Označena # stavka} few {Označene # stavke} other {Označeno # stavki}}", "tags": "Oznake", "tap_to_run_job": "Dodirnite za pokretanje zadatka", "template": "Predložak", @@ -1961,7 +1963,7 @@ "trash_emptied": "Ispražnjeno smeće", "trash_no_results_message": "Ovdje će se prikazati bačene fotografije i videozapisi.", "trash_page_delete_all": "Izbriši sve", - "trash_page_empty_trash_dialog_content": "Želite li isprazniti svoje stavke u smeću? Ove stavke bit će trajno uklonjene iz Immicha", + "trash_page_empty_trash_dialog_content": "Želite li isprazniti svoje stavke u smeću? Ove stavke će biti trajno uklonjene iz Immicha", "trash_page_info": "Stavke u smeću bit će trajno izbrisane nakon {days} dana", "trash_page_no_assets": "Nema stavki u smeću", "trash_page_restore_all": "Vrati sve", @@ -1995,21 +1997,22 @@ "unselect_all_in": "Poništi odabir svih u {group}", "unstack": "Razdvoji", "unstack_action_prompt": "{count} razloženo", - "unstacked_assets_count": "Razdvojena {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}", + "unstacked_assets_count": "{count, plural, one {Razdvojena # stavka} few {Razvdvojene # stavke} other {Razdvojeno # stavki}}", "untagged": "Bez oznaka", "up_next": "Sljedeće", + "update_location_action_prompt": "Ažuriraj lokaciju ({count, plural, one {# odabrane stavke} few {# odabrane stavke} other {# odabranih stavki}}) s:", "updated_at": "Ažurirano", "updated_password": "Lozinka ažurirana", "upload": "Prijenos", "upload_action_prompt": "{count} u redu za prijenos", "upload_concurrency": "Istovremeni prijenosi", "upload_details": "Detalji prijenosa", - "upload_dialog_info": "Želite li sigurnosno kopirati odabranu stavku(e) na poslužitelj?", + "upload_dialog_info": "Želite li sigurnosno kopirati odabrane stavke na poslužitelj?", "upload_dialog_title": "Prenesi stavku", - "upload_errors": "Prijenos završen s {count, plural, =1 {# greškom} few {# greške} other {# grešaka}}, osvježite stranicu da biste vidjeli nove prenesene stavke.", + "upload_errors": "Prijenos završen s {count, plural, one {# greškom} few {# greške} other {# grešaka}}, osvježite stranicu da biste vidjeli nove prenesene stavke.", "upload_finished": "Prijenos završen", "upload_progress": "Preostalo {remaining, number} - Obrađeno {processed, number}/{total, number}", - "upload_skipped_duplicates": "Preskočena {count, plural, =1 {# duplicirana stavka} few {# duplicirane stavke} other {# dupliciranih stavki}}", + "upload_skipped_duplicates": "Preskočena {count, plural, one {# duplicirana stavka} few {# duplicirane stavke} other {# dupliciranih stavki}}", "upload_status_duplicates": "Duplikati", "upload_status_errors": "Greške", "upload_status_uploaded": "Preneseno", @@ -2025,7 +2028,7 @@ "user": "Korisnik", "user_has_been_deleted": "Ovaj korisnik je izbrisan.", "user_id": "ID korisnika", - "user_liked": "{user} je označio/la sviđa mi se {type, select, photo {ovu fotografiju} video {ovaj videozapis} asset {ovu stavku} other {to}}", + "user_liked": "{user} je lajkao/la {type, select, photo {ovu fotografiju} video {ovaj videozapis} asset {ovu stavku} other {to}}", "user_pin_code_settings": "PIN kod", "user_pin_code_settings_description": "Upravljajte svojim PIN kodom", "user_privacy": "Privatnost korisnika", @@ -2037,7 +2040,7 @@ "user_usage_stats_description": "Pregledajte statistiku korištenja računa", "username": "Korisničko ime", "users": "Korisnici", - "users_added_to_album_count": "Dodan{o/a} {count, plural, one {# korisnik} few {# korisnika} other {# korisnika}} u album", + "users_added_to_album_count": "{count, plural, one {Dodan # korisnik} few {Dodana # korisnika} other {Dodano # korisnika}} u album", "utilities": "Alati", "validate": "Provjeri valjanost", "validate_endpoint_error": "Molimo unesite valjanu URL adresu", diff --git a/i18n/hu.json b/i18n/hu.json index e67ad73041..37cfe562a0 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -17,7 +17,6 @@ "add_birthday": "Születésnap hozzáadása", "add_endpoint": "Végpont megadása", "add_exclusion_pattern": "Kihagyási minta (pattern) hozzáadása", - "add_import_path": "Importálási útvonal hozzáadása", "add_location": "Helyszín megadása", "add_more_users": "További felhasználók hozzáadása", "add_partner": "Partner hozzáadása", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# sikertelen}}", "library_created": "Képtár létrehozva: {library}", "library_deleted": "Képtár törölve", - "library_import_path_description": "Add meg az importálandó mappát. A rendszer ebben a mappában és összes almappájában fog képeket és videókat keresni.", "library_scanning": "Időszakos Átfésülés", "library_scanning_description": "A képtár időszakos átfésülésének beállítása", "library_scanning_enable_description": "Képtár időszakos átfésülésének engedélyezése", @@ -894,8 +892,6 @@ "edit_description_prompt": "Kérlek válassz egy új leírást:", "edit_exclusion_pattern": "Kizárási minta (pattern) módosítása", "edit_faces": "Arcok módosítása", - "edit_import_path": "Importálási útvonal módosítása", - "edit_import_paths": "Importálási Útvonalak Módosítása", "edit_key": "Kulcs módosítása", "edit_link": "Link módosítása", "edit_location": "Hely módosítása", @@ -967,7 +963,6 @@ "failed_to_stack_assets": "Elemek csoportosítása sikertelen", "failed_to_unstack_assets": "Csoportosított elemek szétszedése sikertelen", "failed_to_update_notification_status": "Értesítés státusz frissítése sikertelen", - "import_path_already_exists": "Ez az importálási útvonal már létezik.", "incorrect_email_or_password": "Helytelen email vagy jelszó", "paths_validation_failed": "A(z) {paths, plural, one {# elérési útvonal} other {# elérési útvonal}} érvényesítése sikertelen", "profile_picture_transparent_pixels": "Profilképek nem tartalmazhatnak átlátszó pixeleket. Közelíts rá és/vagy mozgasd a képet.", @@ -977,7 +972,6 @@ "unable_to_add_assets_to_shared_link": "Elemeket megosztott linkhez adása sikertelen", "unable_to_add_comment": "Hozzászólás sikertelen", "unable_to_add_exclusion_pattern": "Kivétel minta (pattern) hozzáadása sikertelen", - "unable_to_add_import_path": "Importálási útvonal hozzáadása sikertelen", "unable_to_add_partners": "Partnerek hozzáadása sikertelen", "unable_to_add_remove_archive": "Az elem {archived, select, true {eltávolítása at Archívumból} other {hozzáadása Archívumhoz}} sikertelen", "unable_to_add_remove_favorites": "Az elem {favorite, select, true {eltávolítása a Kedvencekből} other {hozzáadása a Kedvencekhez}} sikertelen", @@ -1000,12 +994,10 @@ "unable_to_delete_asset": "Elem törlése sikertelen", "unable_to_delete_assets": "Hiba az elemek törlésekor", "unable_to_delete_exclusion_pattern": "Kizárási minta (pattern) törlése sikertelen", - "unable_to_delete_import_path": "Import útvonal törlése sikertelen", "unable_to_delete_shared_link": "Megosztott link törlése sikertelen", "unable_to_delete_user": "Felhasználó törlése sikertelen", "unable_to_download_files": "Fájlok letöltése sikertelen", "unable_to_edit_exclusion_pattern": "Kizárási minta (pattern) módosítása sikertelen", - "unable_to_edit_import_path": "Import útvonal módosítása sikertelen", "unable_to_empty_trash": "Lomtár ürítése sikertelen", "unable_to_enter_fullscreen": "Teljes képernyőre váltás sikertelen", "unable_to_exit_fullscreen": "Kilépés a teljes képernyős módból sikertelen", diff --git a/i18n/id.json b/i18n/id.json index 906a0f8ce0..0bc2e22136 100644 --- a/i18n/id.json +++ b/i18n/id.json @@ -17,7 +17,6 @@ "add_birthday": "Tambahkan Tanggal Lahir", "add_endpoint": "Tambahkan titik akhir", "add_exclusion_pattern": "Tambahkan pola pengecualian", - "add_import_path": "Tambahkan jalur impor", "add_location": "Tambahkan lokasi", "add_more_users": "Tambahkan lebih banyak pengguna", "add_partner": "Tambahkan partner", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# gagal}}", "library_created": "Pustaka dibuat: {library}", "library_deleted": "Pustaka dihapus", - "library_import_path_description": "Tentukan folder untuk diimpor. Folder ini, termasuk subfolder, akan dipindai gambar dan videonya.", "library_scanning": "Pemindaian Berkala", "library_scanning_description": "Atur pemindaian pustaka berkala", "library_scanning_enable_description": "Aktifkan pemindaian pustaka berkala", @@ -159,8 +157,15 @@ "machine_learning_ocr_enabled": "Aktfikan OCR", "machine_learning_ocr_enabled_description": "Jika dinonaktifkan, gambar-gambar tidak akan mengalami pengenalan teks.", "machine_learning_ocr_max_resolution": "Resolusi maksimum", - "machine_learning_settings": "Pengaturan Pembelajaran Mesin", - "machine_learning_settings_description": "Keola fitur dan pengaturan pembelajaran mesin", + "machine_learning_ocr_max_resolution_description": "Pratinjau di atas resolusi ini akan disesuaikan ukurannya sambil mempertahankan aspek rasio. Nilai yang lebih tinggi lebih akurat, tetapi membutuhkan waktu yang lama untuk memproses dan membutuhkan memori lebih banyak.", + "machine_learning_ocr_min_detection_score": "Skor deteksi minimum", + "machine_learning_ocr_min_detection_score_description": "Skor kepercayaan minimum untuk teks yang akan dideteksi berkisar antara 0-1. Nilai yang lebih rendah akan mendeteksi teks yang lebih banyak, tetapi dapat menyebabkan hasil yang positif palsu.", + "machine_learning_ocr_min_recognition_score": "Skor pengenalan minimum", + "machine_learning_ocr_min_score_recognition_description": "Skor kepercayaan minimum untuk teks yang akan dideteksi berkisar antara 0-1. Nilai yang lebih rendah akan mendeteksi teks yang lebih banyak, tetapi dapat menyebabkan hasil yang positif palsu.", + "machine_learning_ocr_model": "Model OCR", + "machine_learning_ocr_model_description": "Model server lebih akurat daripada model mobile, tetapi membutuhkan waktu yang lebih lama untuk memproses dan menggunakan memori yang lebih banyak.", + "machine_learning_settings": "Pengaturan Mesin Pembelajaran", + "machine_learning_settings_description": "Kelola fitur dan pengaturan mesin pembelajaran", "machine_learning_smart_search": "Pencarian Pintar", "machine_learning_smart_search_description": "Cari gambar secara semantik menggunakan penyematan CLIP", "machine_learning_smart_search_enabled": "Aktifkan pencarian pintar", @@ -216,6 +221,8 @@ "notification_email_ignore_certificate_errors_description": "Abaikan eror validasi sertifikat TLS (tidak disarankan)", "notification_email_password_description": "Kata sandi yang digunakan ketika mengautentikasi dengan server surel", "notification_email_port_description": "Porta server surel (mis. 25, 465, atau 587)", + "notification_email_secure": "SMTPS", + "notification_email_secure_description": "Gunakan SMTPS (SMTP melalui TLS)", "notification_email_sent_test_email_button": "Kirim surel uji coba dan simpan", "notification_email_setting_description": "Pengaturan pengiriman notifikasi surel", "notification_email_test_email": "Kirim surel uji coba", @@ -248,6 +255,7 @@ "oauth_storage_quota_default_description": "Kuota dalam GiB akan digunakan jika tidak ada klaim yang diberikan.", "oauth_timeout": "Waktu Permintaan Habis", "oauth_timeout_description": "Waktu habis untuk permintaan dalam milidetik", + "ocr_job_description": "Gunakan mesin pembelajaran untuk mengenali teks di dalam gambar", "password_enable_description": "Masuk dengan surel dan kata sandi", "password_settings": "Log Masuk Kata Sandi", "password_settings_description": "Kelola pengaturan log masuk kata sandi", @@ -471,10 +479,14 @@ "api_key_description": "Nilai ini hanya akan ditampilkan sekali. Pastikan untuk menyalin sebelum menutup jendela ini.", "api_key_empty": "Nama Kunci API Anda seharusnya jangan kosong", "api_keys": "Kunci API", + "app_architecture_variant": "Varian (Arsitektur)", "app_bar_signout_dialog_content": "Apakah kamu yakin ingin keluar akun?", "app_bar_signout_dialog_ok": "Ya", "app_bar_signout_dialog_title": "Keluar akun", + "app_download_links": "Link Download Aplikasi", "app_settings": "Pengaturan Aplikasi", + "app_stores": "App Stores", + "app_update_available": "Pembaruan aplikasi tersedia", "appears_in": "Muncul dalam", "apply_count": "Terapkan ({count, number})", "archive": "Arsip", @@ -558,6 +570,7 @@ "backup_albums_sync": "Sinkronisasi cadangan album", "backup_all": "Semua", "backup_background_service_backup_failed_message": "Gagal mencadangkan aset. Mencoba lagi…", + "backup_background_service_complete_notification": "Pencadangan aset selesai", "backup_background_service_connection_failed_message": "Koneksi ke server gagal. Mencoba ulang…", "backup_background_service_current_upload_notification": "Mengunggah {filename}", "backup_background_service_default_notification": "Memeriksa aset baru…", @@ -667,6 +680,8 @@ "change_password_description": "Ini merupakan pertama kali Anda masuk ke sistem atau ada permintaan untuk mengubah kata sandi Anda. Silakan masukkan kata sandi baru di bawah.", "change_password_form_confirm_password": "Konfirmasi Sandi", "change_password_form_description": "Halo {name},\n\nIni pertama kali anda masuk ke dalam sistem atau terdapat permintaan penggantian kata sandi. Harap masukkan password baru.", + "change_password_form_log_out": "Keluar dari semua perangkat lain", + "change_password_form_log_out_description": "Disarankan untuk keluar dari semua perangkat lain", "change_password_form_new_password": "Sandi Baru", "change_password_form_password_mismatch": "Sandi tidak cocok", "change_password_form_reenter_new_password": "Masukkan Ulang Sandi Baru", @@ -744,6 +759,7 @@ "create": "Buat", "create_album": "Buat album", "create_album_page_untitled": "Tak berjudul", + "create_api_key": "Buat kunci API", "create_library": "Buat Pustaka", "create_link": "Buat tautan", "create_link_to_share": "Buat tautan untuk dibagikan", @@ -773,6 +789,7 @@ "daily_title_text_date_year": "E, dd MMM yyyy", "dark": "Gelap", "dark_theme": "Nyalakan mode gelap", + "date": "Tanggal", "date_after": "Tanggal setelah", "date_and_time": "Tanggal dan Waktu", "date_before": "Tanggal sebelum", @@ -875,8 +892,6 @@ "edit_description_prompt": "Silakan pilih deskripsi baru:", "edit_exclusion_pattern": "Sunting pola pengecualian", "edit_faces": "Sunting wajah", - "edit_import_path": "Sunting jalur pengimporan", - "edit_import_paths": "Sunting Jalur Pengimporan", "edit_key": "Sunting kunci", "edit_link": "Sunting tautan", "edit_location": "Sunting lokasi", @@ -948,7 +963,6 @@ "failed_to_stack_assets": "Gagal menumpuk aset", "failed_to_unstack_assets": "Gagal membatalkan penumpukan aset", "failed_to_update_notification_status": "Gagal membarui status notifikasi", - "import_path_already_exists": "Jalur pengimporan ini sudah ada.", "incorrect_email_or_password": "Surel atau kata sandi tidak benar", "paths_validation_failed": "{paths, plural, one {# jalur} other {# jalur}} gagal validasi", "profile_picture_transparent_pixels": "Foto profil tidak dapat memiliki piksel transparan. Silakan perbesar dan/atau pindah posisi gambar.", @@ -958,7 +972,6 @@ "unable_to_add_assets_to_shared_link": "Tidak dapat menambahkan aset ke tautan terbagi", "unable_to_add_comment": "Tidak dapat menambahkan komentar", "unable_to_add_exclusion_pattern": "Tidak dapat menambahkan pola pengecualian", - "unable_to_add_import_path": "Tidak dapat menambahkan jalur pengimporan", "unable_to_add_partners": "Tidak dapat menambahkan partner", "unable_to_add_remove_archive": "Tidak dapat {archived, select, true {menghapus aset dari} other {menambahkan aset ke}} arsip", "unable_to_add_remove_favorites": "Tidak dapat {favorite, select, true {menambahkan aset ke} other {menghapus aset dari}} favorit", @@ -981,12 +994,10 @@ "unable_to_delete_asset": "Tidak dapat menghapus aset", "unable_to_delete_assets": "Terjadi eror menghapus aset", "unable_to_delete_exclusion_pattern": "Tidak dapat menghapus pola pengecualian", - "unable_to_delete_import_path": "Tidak dapat menghapus jalur pengimporan", "unable_to_delete_shared_link": "Tidak dapat menghapus tautan terbagi", "unable_to_delete_user": "Tidak dapat menghapus pengguna", "unable_to_download_files": "Tidak dapat mengunduh berkas", "unable_to_edit_exclusion_pattern": "Tidak dapat menyunting pola pengecualian", - "unable_to_edit_import_path": "Tidak dapat menyunting jalur pengimporan", "unable_to_empty_trash": "Tidak dapat menghapus sampah", "unable_to_enter_fullscreen": "Tidak dapat memasuki layar penuh", "unable_to_exit_fullscreen": "Tidak dapat keluar dari layar penuh", @@ -1042,6 +1053,7 @@ "exif_bottom_sheet_description_error": "Galat saat memperbaharui deskripsi", "exif_bottom_sheet_details": "RINCIAN", "exif_bottom_sheet_location": "LOKASI", + "exif_bottom_sheet_no_description": "Tidak ada deskripsi", "exif_bottom_sheet_people": "ORANG", "exif_bottom_sheet_person_add_person": "Tambah nama", "exit_slideshow": "Keluar dari Salindia", @@ -1080,6 +1092,7 @@ "features_setting_description": "Kelola fitur aplikasi", "file_name": "Nama berkas", "file_name_or_extension": "Nama berkas atau ekstensi", + "file_size": "Ukuran berkas", "filename": "Nama berkas", "filetype": "Jenis berkas", "filter": "Filter", @@ -1243,6 +1256,7 @@ "local_media_summary": "Ringkasan Media Lokal", "local_network": "Jaringan Lokal", "local_network_sheet_info": "Aplikasi akan terhubung ke server melalui URL ini saat menggunakan jaringan Wi-Fi yang ditentukan", + "location": "Lokasi", "location_permission": "Izin lokasi", "location_permission_content": "Untuk menggunakan fitur pengalihan otomatis, Immich memerlukan izin lokasi yang akurat agar dapat membaca nama jaringan Wi-Fi saat ini", "location_picker_choose_on_map": "Pilih di peta", @@ -1347,6 +1361,8 @@ "minute": "Menit", "minutes": "Menit", "missing": "Hilang", + "mobile_app": "Aplikasi Seluler", + "mobile_app_download_onboarding_note": "Unduh aplikasi seluler pendamping dengan menggunakan opsi berikut", "model": "Model", "month": "Bulan", "monthly_title_text_date_format": "BBBB t", @@ -1365,6 +1381,8 @@ "my_albums": "Album saya", "name": "Nama", "name_or_nickname": "Nama atau nama panggilan", + "navigate": "Navigasi", + "navigate_to_time": "Navigasi ke Waktu", "network_requirement_photos_upload": "Gunakan data seluler untuk cadangkan foto", "network_requirement_videos_upload": "Gunakan data seluler untuk cadangkan video", "network_requirements": "Persyaratan Jaringan", @@ -1374,6 +1392,7 @@ "never": "Tidak pernah", "new_album": "Album baru", "new_api_key": "Kunci API Baru", + "new_date_range": "Rentang tanggal baru", "new_password": "Kata sandi baru", "new_person": "Orang baru", "new_pin_code": "Kode PIN baru", @@ -1424,6 +1443,9 @@ "notifications": "Notifikasi", "notifications_setting_description": "Kelola notifikasi", "oauth": "OAuth", + "obtainium_configurator": "Konfigurator Obtainium", + "obtainium_configurator_instructions": "Gunakan Obtainium untuk menginstal dan memperbarui aplikasi Android secara langsung dari rilis GitHub Immich. Buat kunci API dan pilih varian untuk membuat tautan konfigurasi Obtainium anda", + "ocr": "OCR", "official_immich_resources": "Sumber Daya Immich Resmi", "offline": "Luring", "offset": "Ofset", @@ -1528,6 +1550,9 @@ "play_memories": "Putar kenangan", "play_motion_photo": "Putar Foto Gerak", "play_or_pause_video": "Putar atau jeda video", + "play_original_video": "Putar video asli", + "play_original_video_setting_description": "Lebih menyukai memutar video asli daripada video yang telah dikonversi. Jika aset asli tidak kompatibel, video mungkin tidak dapat diputar dengan benar.", + "play_transcoded_video": "Putar video yang telah dikonversi", "please_auth_to_access": "Silakan autentikasi untuk mengakses", "port": "Porta", "preferences_settings_subtitle": "Kelola preferensi aplikasi", @@ -1664,6 +1689,7 @@ "reset_sqlite_confirmation": "Apakah Anda yakin ingin mengatur ulang basis data SQLite? Setelah tindakan ini, Anda harus keluar lalu masuk kembali untuk melakukan sinkronisasi ulang data", "reset_sqlite_success": "Berhasil mengatur ulang basis data SQLite", "reset_to_default": "Atur ulang ke bawaan", + "resolution": "Resolusi", "resolve_duplicates": "Mengatasi duplikat", "resolved_all_duplicates": "Semua duplikat terselesaikan", "restore": "Pulihkan", @@ -1682,6 +1708,7 @@ "running": "Berjalan", "save": "Simpan", "save_to_gallery": "Simpan ke galeri", + "saved": "Disimpan", "saved_api_key": "Kunci API Tersimpan", "saved_profile": "Profil disimpan", "saved_settings": "Pengaturan disimpan", @@ -1698,6 +1725,9 @@ "search_by_description_example": "Hari mendaki di Sapa", "search_by_filename": "Cari berdasarkan nama berkas atau ekstensi", "search_by_filename_example": "mis. IMG_1234.JPG atau PNG", + "search_by_ocr": "Cari dengan OCR", + "search_by_ocr_example": "Latte", + "search_camera_lens_model": "Pencarian model lensa...", "search_camera_make": "Cari merek kamera...", "search_camera_model": "Cari model kamera...", "search_city": "Cari kota...", @@ -1714,6 +1744,7 @@ "search_filter_location_title": "Pilih Lokasi", "search_filter_media_type": "Tipe Media", "search_filter_media_type_title": "Pilih jenis media", + "search_filter_ocr": "Cari dengan OCR", "search_filter_people_title": "Pilih orang", "search_for": "Cari", "search_for_existing_person": "Cari orang yang sudah ada", @@ -1776,6 +1807,7 @@ "server_online": "Server Daring", "server_privacy": "Privasi server", "server_stats": "Statistik Server", + "server_update_available": "Pembaruan server tersedia", "server_version": "Versi Server", "set": "Atur", "set_as_album_cover": "Atur sebagai kover album", @@ -1804,6 +1836,8 @@ "setting_notifications_subtitle": "Atur setelan notifikasi", "setting_notifications_total_progress_subtitle": "Progres keseluruhan unggahan (selesai/total aset)", "setting_notifications_total_progress_title": "Tampilkan progres total pencadangan latar belakang", + "setting_video_viewer_auto_play_subtitle": "Otomatis memutar video saat dibuka", + "setting_video_viewer_auto_play_title": "Putar video secara otomatis", "setting_video_viewer_looping_title": "Ulangi", "setting_video_viewer_original_video_subtitle": "Ketika melakukan streaming video dari server, sistem akan memutar versi asli meskipun tersedia hasil transkode. Pengaturan ini dapat menyebabkan terjadinya buffering. Video yang tersedia secara lokal akan selalu diputar dalam kualitas asli tanpa terpengaruh oleh pengaturan ini.", "setting_video_viewer_original_video_title": "Paksa video asli", @@ -1983,6 +2017,7 @@ "theme_setting_three_stage_loading_title": "Aktifkan pemuatan tiga tahap", "they_will_be_merged_together": "Mereka akan digabungkan bersama", "third_party_resources": "Sumber Daya Pihak Ketiga", + "time": "Waktu", "time_based_memories": "Kenangan berbasis waktu", "timeline": "Lini masa", "timezone": "Zona waktu", @@ -2015,6 +2050,7 @@ "troubleshoot": "Pemecahan Masalah", "type": "Jenis", "unable_to_change_pin_code": "Tidak dapat mengubah kode PIN", + "unable_to_check_version": "Tidak dapat memeriksa versi aplikasi atau server", "unable_to_setup_pin_code": "Tidak dapat memasang kode PIN", "unarchive": "Keluarkan dari arsip", "unarchive_action_prompt": "Sebanyak {count} item telah dihapus dari Arsip", diff --git a/i18n/is.json b/i18n/is.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/is.json @@ -0,0 +1 @@ +{} diff --git a/i18n/it.json b/i18n/it.json index 0429f92d0b..97f486d951 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -17,7 +17,6 @@ "add_birthday": "Aggiungi compleanno", "add_endpoint": "Aggiungi un endpoint", "add_exclusion_pattern": "Aggiungi un pattern di esclusione", - "add_import_path": "Aggiungi un percorso per l’importazione", "add_location": "Aggiungi posizione", "add_more_users": "Aggiungi altri utenti", "add_partner": "Aggiungi partner", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Attiva/disattiva selezione per {album}", "add_to_albums": "Aggiungi ad album", "add_to_albums_count": "Aggiungi ad album ({count})", + "add_to_bottom_bar": "Aggiungi a", "add_to_shared_album": "Aggiungi ad album condiviso", "add_upload_to_stack": "Aggiungi caricamento allo stack", "add_url": "Aggiungi URL", @@ -76,7 +76,7 @@ "exclusion_pattern_description": "I modelli di esclusione ti permettono di ignorare file e cartelle durante la scansione della tua libreria. Questo è utile se hai cartelle che contengono file che non vuoi importare, come ad esempio, i file RAW.", "external_library_management": "Gestione Librerie Esterne", "face_detection": "Rilevamento Volti", - "face_detection_description": "Rileva i volti presenti negli assets utilizzando il machine learning. Per i video, viene presa in considerazione solo la miniatura. \"Aggiorna\" (ri-)processerà tutti gli assets. \"Reset\" inoltre elimina tutti i dati dei volti correnti. \"Mancanti\" seleziona solo gli assets che non sono ancora stati processati. I volti rilevati verranno selezionati per il riconoscimento facciale dopo che il rilevamento dei volti sarà stato completato, raggruppandoli in persone esistenti e/o nuove.", + "face_detection_description": "Rileva i volti presenti negli asset utilizzando il machine-learning. Per i video, viene presa in considerazione solo la miniatura. Utilizzare \"Ripristina\" per cancellare tutti i volti presenti, \"Ricarica\" per processare di nuovo tutti gli asset, \"Mancanti\" processa solo gli asset che non sono ancora stati processati. I volti rilevati verranno selezionati per il riconoscimento facciale dopo che il rilevamento dei volti sarà stato completato, raggruppandoli in persone esistenti e/o nuove.", "facial_recognition_job_description": "Raggruppa i volti rilevati in persone. Questo processo viene eseguito dopo che il rilevamento volti è stato completato. \"Reset\" (ri-)unisce tutti i volti. \"Mancanti\" processa i volti che non hanno una persona assegnata.", "failed_job_command": "Il comando {command} è fallito per il processo: {job}", "force_delete_user_warning": "ATTENZIONE: Questo rimuoverà immediatamente l'utente e tutti i suoi assets. Non è possibile tornare indietro e i file non potranno essere recuperati.", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, one {# fallito} other {# falliti}}", "library_created": "Creata libreria: {library}", "library_deleted": "Libreria eliminata", - "library_import_path_description": "Specifica una cartella da importare. Questa cartella e le sue sottocartelle, verranno analizzate per cercare immagini e video.", "library_scanning": "Scansione periodica", "library_scanning_description": "Configura la scansione periodica della libreria", "library_scanning_enable_description": "Attiva la scansione periodica della libreria", @@ -173,6 +172,10 @@ "machine_learning_smart_search_enabled": "Attiva ricerca intelligente", "machine_learning_smart_search_enabled_description": "Se disabilitato le immagini non saranno codificate per la ricerca intelligente.", "machine_learning_url_description": "URL del server machine learning. Se sono stati forniti più di un URL, verrà testato un server alla volta finché uno non risponderà, in ordine dal primo all'ultimo. I server che non rispondono saranno temporaneamente ignorati finché non torneranno online.", + "maintenance_settings": "Manutenzione", + "maintenance_settings_description": "Metti Immich in modalità manutenzione.", + "maintenance_start": "Avvia modalità manutenzione", + "maintenance_start_error": "Errore nell'avvio della modalità manutenzione.", "manage_concurrency": "Gestisci Concorrenza", "manage_log_settings": "Gestisci le impostazioni dei log", "map_dark_style": "Tema scuro", @@ -430,6 +433,7 @@ "age_months": "Età {months, plural, one {# mese} other {# mesi}}", "age_year_months": "Età 1 anno, {months, plural, one {# mese} other {# mesi}}", "age_years": "{years, plural, other {Età #}}", + "album": "Album", "album_added": "Album aggiunto", "album_added_notification_setting_description": "Ricevi una notifica email quando sei aggiunto ad un album condiviso", "album_cover_updated": "Copertina dell'album aggiornata", @@ -475,6 +479,7 @@ "allow_edits": "Permetti modifiche", "allow_public_user_to_download": "Permetti agli utenti pubblici di scaricare", "allow_public_user_to_upload": "Permetti agli utenti pubblici di caricare", + "allowed": "Consentito", "alt_text_qr_code": "Immagine QR", "anti_clockwise": "Senso anti-orario", "api_key": "Chiave API", @@ -894,8 +899,6 @@ "edit_description_prompt": "Selezionare una nuova descrizione:", "edit_exclusion_pattern": "Modifica pattern di esclusione", "edit_faces": "Modifica volti", - "edit_import_path": "Modifica percorso di importazione", - "edit_import_paths": "Modifica Percorsi di Importazione", "edit_key": "Modifica chiave", "edit_link": "Modifica link", "edit_location": "Modifica posizione", @@ -967,7 +970,6 @@ "failed_to_stack_assets": "Errore durante il raggruppamento degli assets", "failed_to_unstack_assets": "Errore durante la separazione degli assets", "failed_to_update_notification_status": "Aggiornamento stato notifiche fallito", - "import_path_already_exists": "Questo percorso di importazione già esiste.", "incorrect_email_or_password": "Email o password non corretta", "paths_validation_failed": "{paths, plural, one {# percorso} other {# percorsi}} hanno fallito la validazione", "profile_picture_transparent_pixels": "Le foto profilo non possono avere pixel trasparenti. Riprova ingrandendo e/o muovendo l'immagine.", @@ -977,7 +979,6 @@ "unable_to_add_assets_to_shared_link": "Impossibile aggiungere gli assets al link condiviso", "unable_to_add_comment": "Impossibile aggiungere commento", "unable_to_add_exclusion_pattern": "Impossibile aggiungere pattern di esclusione", - "unable_to_add_import_path": "Impossibile aggiungere percorso di importazione", "unable_to_add_partners": "Impossibile aggiungere compagni", "unable_to_add_remove_archive": "Impossibile {archived, select, true {rimuovere l'asset dall'archivio} other {aggiungere l'asset all'archivio}}", "unable_to_add_remove_favorites": "Impossibile {favorite, select, true {rimuovere l'asset dai} other {aggiungere l'asset ai}} preferiti", @@ -1000,12 +1001,10 @@ "unable_to_delete_asset": "Impossibile cancellare asset", "unable_to_delete_assets": "Errore durante l'eliminazione degli asset", "unable_to_delete_exclusion_pattern": "Impossibile cancellare pattern di esclusione", - "unable_to_delete_import_path": "Impossibile cancellare percorso di importazione", "unable_to_delete_shared_link": "Impossibile cancellare link condiviso", "unable_to_delete_user": "Impossibile cancellare utente", "unable_to_download_files": "Impossibile scaricare i file", "unable_to_edit_exclusion_pattern": "Impossibile modificare pattern di esclusione", - "unable_to_edit_import_path": "Impossibile cambiare percorso di importazione", "unable_to_empty_trash": "Impossibile svuotare il cestino", "unable_to_enter_fullscreen": "Impossibile aprire l'applicazione a schermo intero", "unable_to_exit_fullscreen": "Impossibile uscire dallo schermo intero", @@ -1196,6 +1195,8 @@ "import_path": "Importa percorso", "in_albums": "In {count, plural, one {# album} other {# album}}", "in_archive": "In archivio", + "in_year": "Nel {year}", + "in_year_selector": "Nel", "include_archived": "Includi Archiviati", "include_shared_albums": "Includi album condivisi", "include_shared_partner_assets": "Includi elementi condivisi dai compagni", @@ -1232,6 +1233,7 @@ "language_setting_description": "Seleziona la tua lingua predefinita", "large_files": "File pesanti", "last": "Ultimo", + "last_months": "{count, plural, one {Ultimo mese} other {Ultimi # mesi}}", "last_seen": "Ultimo accesso", "latest_version": "Ultima Versione", "latitude": "Latitudine", @@ -1312,8 +1314,17 @@ "loop_videos_description": "Abilita per riprodurre automaticamente un video in loop nel visualizzatore dei dettagli.", "main_branch_warning": "Stai utilizzando una versione di sviluppo. Ti consigliamo vivamente di utilizzare una versione di rilascio!", "main_menu": "Menu Principale", + "maintenance_description": "Immich è stato posto in modalità manutenzione.", + "maintenance_end": "Termina modalità manutenzione", + "maintenance_end_error": "Errore nel terminare la modalità manutenzione.", + "maintenance_logged_in_as": "Accesso effettuato come {user}", + "maintenance_title": "Temporaneamente non disponibile", "make": "Produttore", "manage_geolocation": "Gestisci posizione", + "manage_media_access_rationale": "Questo permesso è richiesto per gestire correttamente lo spostamento del materiale nel cestino e per recuperarlo da esso.", + "manage_media_access_settings": "Apri impostazioni", + "manage_media_access_subtitle": "Permetti all'app di Immich di gestire e spostare file multimediali.", + "manage_media_access_title": "Accesso alla gestione di contenuti multimediali", "manage_shared_links": "Gestisci link condivisi", "manage_sharing_with_partners": "Gestisci la condivisione con i compagni", "manage_the_app_settings": "Gestisci le impostazioni dell'applicazione", @@ -1377,6 +1388,7 @@ "more": "Di più", "move": "Sposta", "move_off_locked_folder": "Sposta al di fuori della cartella privata", + "move_to": "Sposta in", "move_to_lock_folder_action_prompt": "{count} elementi aggiunti alla cartella sicura", "move_to_locked_folder": "Sposta nella cartella privata", "move_to_locked_folder_confirmation": "Queste foto e video verranno rimossi da tutti gli album, e saranno visibili solo dalla cartella privata", @@ -1406,6 +1418,7 @@ "new_pin_code": "Nuovo codice PIN", "new_pin_code_subtitle": "Questa è la prima volta che accedi alla cartella privata. Crea un codice PIN per accedere in modo sicuro a questa pagina", "new_timeline": "Nuova Timeline", + "new_update": "Nuovo aggiornamento", "new_user_created": "Nuovo utente creato", "new_version_available": "NUOVA VERSIONE DISPONIBILE", "newest_first": "Prima recenti", @@ -1421,6 +1434,7 @@ "no_cast_devices_found": "Nessun dispositivo di trasmissione trovato", "no_checksum_local": "Nessun checksum disponibile: impossibile recuperare gli assets locali", "no_checksum_remote": "Nessun checksum disponibile: impossibile recuperare l'asset remoto", + "no_devices": "Nessun device autorizzato", "no_duplicates_found": "Nessun duplicato trovato.", "no_exif_info_available": "Nessuna informazione exif disponibile", "no_explore_results_message": "Carica più foto per esplorare la tua collezione.", @@ -1437,6 +1451,7 @@ "no_results_description": "Prova ad usare un sinonimo oppure una parola chiave più generica", "no_shared_albums_message": "Crea un album per condividere foto e video con le persone nella tua rete", "no_uploads_in_progress": "Nessun upload in corso", + "not_allowed": "Non permesso", "not_available": "N/A", "not_in_any_album": "In nessun album", "not_selected": "Non selezionato", @@ -1547,6 +1562,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Foto}}", "photos_from_previous_years": "Foto dagli anni scorsi", "pick_a_location": "Scegli una posizione", + "pick_custom_range": "Intervallo personalizzato", + "pick_date_range": "Seleziona un periodo temporale", "pin_code_changed_successfully": "Codice PIN cambiato correttamente", "pin_code_reset_successfully": "Codice PIN resettato con successo", "pin_code_setup_successfully": "Codice PIN impostato correttamente", @@ -1716,6 +1733,7 @@ "running": "In esecuzione", "save": "Salva", "save_to_gallery": "Salva in galleria", + "saved": "Salvato", "saved_api_key": "Chiave API salvata", "saved_profile": "Profilo salvato", "saved_settings": "Impostazioni salvate", @@ -1813,6 +1831,8 @@ "server_offline": "Server Offline", "server_online": "Server Online", "server_privacy": "Privacy del Server", + "server_restarting_description": "Questa pagina si aggiornerà per un momento.", + "server_restarting_title": "Il server si sta riavviando", "server_stats": "Statistiche Server", "server_update_available": "Aggiornamento Server disponibile", "server_version": "Versione Server", @@ -2026,6 +2046,7 @@ "third_party_resources": "Risorse di Terze Parti", "time": "Orario", "time_based_memories": "Ricordi basati sul tempo", + "time_based_memories_duration": "Numero di secondi per visualizzare ciascuna immagine.", "timeline": "Linea temporale", "timezone": "Fuso orario", "to_archive": "Archivio", @@ -2166,6 +2187,7 @@ "welcome": "Benvenuto", "welcome_to_immich": "Benvenuto in Immich", "wifi_name": "Nome rete Wi-Fi", + "workflow": "Flusso di lavoro", "wrong_pin_code": "Codice PIN errato", "year": "Anno", "years_ago": "{years, plural, one {# anno} other {# anni}} fa", diff --git a/i18n/ja.json b/i18n/ja.json index c3e53082e8..1fb9fbbd21 100644 --- a/i18n/ja.json +++ b/i18n/ja.json @@ -17,7 +17,6 @@ "add_birthday": "誕生日を設定", "add_endpoint": "エンドポイントを追加", "add_exclusion_pattern": "除外パターンを追加", - "add_import_path": "インポートパスを追加", "add_location": "場所を追加", "add_more_users": "ユーザーを追加", "add_partner": "パートナーを追加", @@ -33,6 +32,7 @@ "add_to_albums": "アルバムに追加", "add_to_albums_count": "{count}つのアルバムへ追加", "add_to_shared_album": "共有アルバムに追加", + "add_upload_to_stack": "スタックにアップロードを追加", "add_url": "URLを追加", "added_to_archive": "アーカイブにしました", "added_to_favorites": "お気に入りに追加済", @@ -111,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {#件}}の失敗", "library_created": "作成されたライブラリ:{library}", "library_deleted": "ライブラリは削除されました", - "library_import_path_description": "インポートするフォルダを指定します。このフォルダはサブフォルダを含めて、画像と動画のスキャンが行われます。", "library_scanning": "定期スキャン", "library_scanning_description": "ライブラリの定期スキャン設定", "library_scanning_enable_description": "ライブラリ定期スキャンの有効化", @@ -119,7 +118,7 @@ "library_settings_description": "外部ライブラリ設定を管理します", "library_tasks_description": "アセットが追加または変更された外部ライブラリをスキャンする", "library_watching_enable_description": "外部ライブラリのファイル変更を監視", - "library_watching_settings": "ライブラリ監視(実験的)", + "library_watching_settings": "ライブラリ監視(実験的機能)", "library_watching_settings_description": "変更されたファイルを自動的に監視", "logging_enable_description": "ログの有効化", "logging_level_description": "有効な場合に使用されるログ レベル。", @@ -153,6 +152,18 @@ "machine_learning_min_detection_score_description": "顔を検出するための最低信頼スコアを0から1の範囲で設定します。値を低くするとより多くの顔を検出できますが、誤検出の可能性が高くなります。", "machine_learning_min_recognized_faces": "顔認識の最低値", "machine_learning_min_recognized_faces_description": "人物として作成されるために必要な最低認識顔数を設定します。この値を増やすと顔認識の精度が向上しますが、その代わりに顔が人物として認識されない可能性も高くなります。", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "画像内の文字を認識するために機械学習を使用する", + "machine_learning_ocr_enabled": "OCRを有効にする", + "machine_learning_ocr_enabled_description": "無効にすると、画像は文字認識されません.", + "machine_learning_ocr_max_resolution": "最大解像度", + "machine_learning_ocr_max_resolution_description": "この解像度を超えるプレビューは、アスペクト比を維持しながらサイズが変更されます。値を大きくすると精度は向上しますが、処理に時間がかかり、メモリ使用量も増加します。", + "machine_learning_ocr_min_detection_score": "検出スコアの最低値", + "machine_learning_ocr_min_detection_score_description": "検出するテキストの最小信頼度スコアを0から1の範囲で設定します。値が低いほど多くのテキストが検出されますが、誤検出が発生する可能性があります。", + "machine_learning_ocr_min_recognition_score": "認識スコアの最小値", + "machine_learning_ocr_min_score_recognition_description": "検出されたテキストを認識するための最低信頼スコアを0から1の範囲で設定します。。値が低いほど多くのテキストが認識されますが、誤検出が発生する可能性があります。", + "machine_learning_ocr_model": "OCRモデル", + "machine_learning_ocr_model_description": "サーバーモデルはモバイルモデルよりも正確ですが、処理に時間がかかり、メモリも多く使用します。", "machine_learning_settings": "機械学習設定", "machine_learning_settings_description": "機械学習の機能と設定を管理します", "machine_learning_smart_search": "スマートサーチ", @@ -160,6 +171,10 @@ "machine_learning_smart_search_enabled": "スマートサーチを有効にします", "machine_learning_smart_search_enabled_description": "無効にすると、画像はスマートサーチ用にエンコードされません。", "machine_learning_url_description": "機械学習サーバーのURL。複数のURLが設定された場合は1つずつサーバーが正常に応答するまで接続を試みます。応答のないサーバーはオンラインになるまで一時的に無視されます。", + "maintenance_settings": "メンテナンス", + "maintenance_settings_description": "Immichをメンテナンスモードにする。", + "maintenance_start": "メンテナンスモードを開始する", + "maintenance_start_error": "メンテナンスモードの開始に失敗しました。", "manage_concurrency": "同時実行数の管理", "manage_log_settings": "ログ設定を管理します", "map_dark_style": "ダークモード", @@ -210,6 +225,8 @@ "notification_email_ignore_certificate_errors_description": "TLS証明書の検証エラーを無視します(非推奨)", "notification_email_password_description": "メールサーバーでの認証時に使用するパスワードを設定します", "notification_email_port_description": "メールサーバーのポート番号を指定します(例:25, 465, 587)", + "notification_email_secure": "SMTPS", + "notification_email_secure_description": "SMTPSを使用 (SMTP over TLS)", "notification_email_sent_test_email_button": "テストメールを送信して設定を保存", "notification_email_setting_description": "メール通知の送信設定", "notification_email_test_email": "テストメールを送信", @@ -242,6 +259,7 @@ "oauth_storage_quota_default_description": "クレームが提供されていない場合に使用されるクォータをGiB単位で設定します。", "oauth_timeout": "リクエストタイムアウト", "oauth_timeout_description": "リクエストのタイムアウトまでの時間(ms)", + "ocr_job_description": "機械学習を使用して画像内のテキストを認識する", "password_enable_description": "メールアドレスとパスワードでログイン", "password_settings": "パスワード ログイン", "password_settings_description": "パスワード ログイン設定を管理します", @@ -332,7 +350,7 @@ "transcoding_max_b_frames": "最大Bフレーム", "transcoding_max_b_frames_description": "値を高くすると圧縮効率が向上しますが、エンコード速度が遅くなります。古いデバイスのハードウェアアクセラレーションでは対応していない場合があります。\"0\" はBフレームを無効にし、\"-1\" はこの値を自動的に設定します。", "transcoding_max_bitrate": "最大ビットレート", - "transcoding_max_bitrate_description": "最大ビットレートを設定すると、品質にわずかな影響を与えながらも、ファイルサイズを予測しやすくなります。720pの場合、一般的な値は VP9 や HEVC で \"2600 kbit/s\"、H.264 で \"4500 kbit/s\" です。\"0\" に設定すると無効になります。", + "transcoding_max_bitrate_description": "最大ビットレートを設定すると、品質にわずかな影響を与えながらも、ファイルサイズを予測しやすくなります。720pの場合、一般的な値は VP9 や HEVC で \"2600 kbit/s\"、H.264 で \"4500 kbit/s\" です。\"0\" に設定すると無効になります。単位が指定されていない場合、k(kbit/s)が適用されます。したがって5000、5000k、5M(5Mbit/s)は等しい設定値です。", "transcoding_max_keyframe_interval": "最大キーフレーム間隔", "transcoding_max_keyframe_interval_description": "キーフレーム間の最大フレーム間隔を設定します。値を低くすると圧縮効率が悪化しますが、シーク時間が改善され、動きの速いシーンの品質が向上する場合があります。\"0\" に設定すると、この値が自動的に設定されます。", "transcoding_optimal_description": "設定解像度を超える動画、または容認されていない形式の動画", @@ -350,7 +368,7 @@ "transcoding_target_resolution": "解像度", "transcoding_target_resolution_description": "解像度を高くすると細かなディテールを保持できますが、エンコードに時間がかかり、ファイルサイズが大きくなり、アプリの応答性が低下する可能性があります。", "transcoding_temporal_aq": "適応的量子化(Temporal AQ)", - "transcoding_temporal_aq_description": "NVEncにのみ適用されます。高精細で動きの少ないシーンの画質を向上させます。古いデバイスとの互換性はありません。", + "transcoding_temporal_aq_description": "NVEncにのみ適用されます。Temporal AQは高精細で動きの少ないシーンの画質を向上させます。古いデバイスとの互換性はありません。", "transcoding_threads": "スレッド数", "transcoding_threads_description": "値を高くするとエンコード速度が速くなりますが、アクティブな間はサーバーが他のタスクを処理する余裕が少なくなります。この値はCPUのコア数を超えないようにする必要があります。\"0\" に設定すると、最大限利用されます。", "transcoding_tone_mapping": "トーンマッピング", @@ -401,11 +419,11 @@ "advanced_settings_prefer_remote_subtitle": "デバイスによっては、デバイス上にあるサムネイルのロードに非常に時間がかかることがあります。このオプションを有効にする事により、サーバーから直接画像をロードすることが可能です。", "advanced_settings_prefer_remote_title": "リモートを優先する", "advanced_settings_proxy_headers_subtitle": "プロキシヘッダを設定する", - "advanced_settings_proxy_headers_title": "プロキシヘッダ", + "advanced_settings_proxy_headers_title": "カスタムプロキシヘッダ [実験的]", "advanced_settings_readonly_mode_subtitle": "読み取り専用モードを有効にすると、写真の複数選択や、共有、削除、キャスト機能が無効になります。メインスクリーンのユーザーアバターから有効/無効を切り替えられます", "advanced_settings_readonly_mode_title": "読み取り専用モード", "advanced_settings_self_signed_ssl_subtitle": "SSLのチェックをスキップする。自己署名証明書が必要です。", - "advanced_settings_self_signed_ssl_title": "自己署名証明書を許可する", + "advanced_settings_self_signed_ssl_title": "自己署名証明書を許可する [実験的]", "advanced_settings_sync_remote_deletions_subtitle": "Webでこの操作を行った際に、自動的にこのデバイス上から当該アセットを削除または復元する", "advanced_settings_sync_remote_deletions_title": "リモート削除の同期 [試験運用]", "advanced_settings_tile_subtitle": "追加ユーザー設定", @@ -414,6 +432,7 @@ "age_months": "生後 {months,plural, one {#か月} other {#か月}}", "age_year_months": "1歳{months,plural, one {#か月} other {#か月}}", "age_years": "{years,plural, one {#歳} other {#歳}}", + "album": "アルバム", "album_added": "アルバム追加", "album_added_notification_setting_description": "共有アルバムに追加されたときEメール通知を受信する", "album_cover_updated": "アルバムカバー更新", @@ -459,6 +478,7 @@ "allow_edits": "編集を許可", "allow_public_user_to_download": "一般ユーザーによるダウンロードを許可", "allow_public_user_to_upload": "一般ユーザーによるアップロードを許可", + "allowed": "許可されている", "alt_text_qr_code": "QRコード画像", "anti_clockwise": "反時計回り", "api_key": "APIキー", @@ -468,7 +488,10 @@ "app_bar_signout_dialog_content": "サインアウトしますか?", "app_bar_signout_dialog_ok": "はい", "app_bar_signout_dialog_title": "サインアウト", + "app_download_links": "アプリのダウンロードリンク", "app_settings": "アプリ設定", + "app_stores": "アプリストア", + "app_update_available": "アプリのアップデートが利用可能です", "appears_in": "これらに含まれます", "apply_count": "適用 ({count, number})", "archive": "アーカイブ", @@ -538,7 +561,7 @@ "autoplay_slideshow": "スライドショーを自動再生", "back": "戻る", "back_close_deselect": "戻る、閉じる、選択解除", - "background_backup_running_error": "バックグラウンドのバックアップがすでに行われている最中です。そのため、マニュアルでのバックアップを開始することはできません。", + "background_backup_running_error": "バックグラウンドのバックアップがすでに行われている最中です。そのため、マニュアルでのバックアップを開始することはできません", "background_location_permission": "バックグラウンド位置情報アクセス", "background_location_permission_content": "正常にWi-Fiの名前(SSID)を獲得するにはアプリが常に詳細な位置情報にアクセスできる必要があります", "background_options": "バックグラウンドの動作オプション", @@ -552,6 +575,7 @@ "backup_albums_sync": "アルバム同期状態をバックアップ", "backup_all": "すべて", "backup_background_service_backup_failed_message": "アップロードに失敗しました。リトライ中…", + "backup_background_service_complete_notification": "アセットのバックアップが完了しました", "backup_background_service_connection_failed_message": "サーバーに接続できません。リトライ中…", "backup_background_service_current_upload_notification": "{filename}をアップロード中", "backup_background_service_default_notification": "新しい写真を確認中…", @@ -661,6 +685,8 @@ "change_password_description": "これは、初めてのサインインであるか、パスワードの変更要求が行われたかのいずれかです。 新しいパスワードを下に入力してください。", "change_password_form_confirm_password": "確定", "change_password_form_description": "{name}さん こんにちは\n\nサーバーにアクセスするのが初めてか、パスワードリセットのリクエストがされました。新しいパスワードを入力してください。", + "change_password_form_log_out": "他の全てのデバイスからログアウトさせる", + "change_password_form_log_out_description": "他のすべてのデバイスからログアウトすることをお勧めします", "change_password_form_new_password": "新しいパスワード", "change_password_form_password_mismatch": "パスワードが一致しません", "change_password_form_reenter_new_password": "再度パスワードを入力してください", @@ -687,8 +713,8 @@ "client_cert_import_success_msg": "クライアント証明書が導入されました", "client_cert_invalid_msg": "パスワードが間違っているか証明書が無効です", "client_cert_remove_msg": "クライアント証明書が削除されました", - "client_cert_subtitle": "PKCS12 (.p12 .pfx) フォーマットのみ対応されてます。証明書の導入や削除はログイン前のみ行えます", - "client_cert_title": "SSLクライアント証明書", + "client_cert_subtitle": "PKCS12 (.p12 .pfx) フォーマットのみ対応しています。証明書の導入や削除はログイン前のみ行えます", + "client_cert_title": "SSLクライアント証明書 [実験的]", "clockwise": "時計回り", "close": "閉じる", "collapse": "展開", @@ -738,6 +764,7 @@ "create": "作成", "create_album": "アルバムを作成", "create_album_page_untitled": "無題のタイトル", + "create_api_key": "APIキーを作成", "create_library": "ライブラリを作成", "create_link": "リンクを作る", "create_link_to_share": "共有リンクを作る", @@ -767,6 +794,7 @@ "daily_title_text_date_year": "yyyy MM DD, EE", "dark": "ダークモード", "dark_theme": "ダークモード切り替え", + "date": "日付", "date_after": "この日以降", "date_and_time": "日付と時間", "date_before": "この日以前", @@ -869,8 +897,6 @@ "edit_description_prompt": "新しい説明文を選んでください:", "edit_exclusion_pattern": "除外パターンを編集", "edit_faces": "顔を編集", - "edit_import_path": "インポートパスを編集", - "edit_import_paths": "インポートパスを編集", "edit_key": "キーを編集", "edit_link": "リンクを編集する", "edit_location": "位置情報を編集", @@ -942,7 +968,6 @@ "failed_to_stack_assets": "アセットをスタックできませんでした", "failed_to_unstack_assets": "アセットをスタックから解除することができませんでした", "failed_to_update_notification_status": "通知ステータスの更新に失敗しました", - "import_path_already_exists": "このインポートパスは既に存在します。", "incorrect_email_or_password": "メールアドレスまたはパスワードが間違っています", "paths_validation_failed": "{paths, plural, one {#個} other {#個}}のパスの検証に失敗しました", "profile_picture_transparent_pixels": "プロフィール写真には透明ピクセルを含めることはできません。画像を拡大/縮小したり移動してください。", @@ -952,7 +977,6 @@ "unable_to_add_assets_to_shared_link": "アセットを共有リンクに追加できません", "unable_to_add_comment": "コメントを追加できません", "unable_to_add_exclusion_pattern": "除外パターンを追加できません", - "unable_to_add_import_path": "インポートパスを追加できません", "unable_to_add_partners": "パートナーを追加できません", "unable_to_add_remove_archive": "アーカイブ{archived, select, true {からアセットを削除} other {にアセットを追加}}できません", "unable_to_add_remove_favorites": "項目をお気に入り{favorite, select, true {に追加} other {の解除}}できませんでした", @@ -975,12 +999,10 @@ "unable_to_delete_asset": "項目を削除できません", "unable_to_delete_assets": "項目を削除中のエラー", "unable_to_delete_exclusion_pattern": "除外パターンを削除できません", - "unable_to_delete_import_path": "インポートパスを削除できません", "unable_to_delete_shared_link": "共有リンクを削除できません", "unable_to_delete_user": "ユーザーを削除できません", "unable_to_download_files": "ファイルをダウンロードできません", "unable_to_edit_exclusion_pattern": "除外パターンを編集できません", - "unable_to_edit_import_path": "インポートパスを編集できません", "unable_to_empty_trash": "ゴミ箱を空にできません", "unable_to_enter_fullscreen": "フルスクリーンにできません", "unable_to_exit_fullscreen": "フルスクリーンを解除できません", @@ -1036,6 +1058,7 @@ "exif_bottom_sheet_description_error": "説明文をアップデートできませんでした", "exif_bottom_sheet_details": "詳細", "exif_bottom_sheet_location": "撮影場所", + "exif_bottom_sheet_no_description": "説明なし", "exif_bottom_sheet_people": "人物", "exif_bottom_sheet_person_add_person": "名前を追加", "exit_slideshow": "スライドショーを終わる", @@ -1074,6 +1097,7 @@ "features_setting_description": "アプリの機能を管理する", "file_name": "ファイル名", "file_name_or_extension": "ファイル名または拡張子", + "file_size": "ファイルサイズ", "filename": "ファイル名", "filetype": "ファイルタイプ", "filter": "フィルター", @@ -1169,6 +1193,7 @@ "import_path": "インポートパス", "in_albums": "{count, plural, one {#件のアルバム} other {#件のアルバム}}の中", "in_archive": "アーカイブ済み", + "in_year": "{year}年", "include_archived": "アーカイブ済みを含める", "include_shared_albums": "共有アルバムを含める", "include_shared_partner_assets": "パートナーがシェアしたアセットを含める", @@ -1237,6 +1262,7 @@ "local_media_summary": "ローカルメディアのまとめ", "local_network": "ローカルネットワーク", "local_network_sheet_info": "アプリは指定されたWi-Fiに繋がっている時サーバーへの接続を下記のURLで行います", + "location": "位置情報", "location_permission": "位置情報権限", "location_permission_content": "自動URL切り替えを使用するにはWi-Fiの名前(SSID)を取得する必要があり、正常に機能するにはアプリが常に詳細な位置情報にアクセスできる必要があります", "location_picker_choose_on_map": "マップを選択", @@ -1284,8 +1310,16 @@ "loop_videos_description": "有効にすると詳細表示で自動的に動画がループします。", "main_branch_warning": "開発版を使っているようです。リリース版の使用を強く推奨します!", "main_menu": "メインメニュー", + "maintenance_description": "Immich は メンテナンスモード中です。", + "maintenance_end": "メンテナンスモードを終了する", + "maintenance_end_error": "メンテナンスモードの終了に失敗しました。", + "maintenance_logged_in_as": "現在 {user}としてログインしています", + "maintenance_title": "一時的に利用不可能", "make": "メーカー", "manage_geolocation": "位置情報を編集", + "manage_media_access_settings": "設定を開く", + "manage_media_access_subtitle": "Immichアプリにメディアファイルの管理と移動を許可する。", + "manage_media_access_title": "メディア管理アクセス", "manage_shared_links": "共有済みのリンクを管理", "manage_sharing_with_partners": "パートナーとの共有を管理します", "manage_the_app_settings": "アプリの設定を管理します", @@ -1341,12 +1375,15 @@ "minute": "分", "minutes": "分", "missing": "欠落", + "mobile_app": "モバイルアプリ", + "mobile_app_download_onboarding_note": "以下のオプションを使用してコンパニオンモバイルアプリをダウンロードしてください", "model": "モデル", "month": "月", "monthly_title_text_date_format": "yyyy MM", "more": "もっと表示", "move": "移動", "move_off_locked_folder": "鍵付きフォルダーから出す", + "move_to": "移動先は", "move_to_lock_folder_action_prompt": "{count}項目を鍵付きフォルダーに追加しました", "move_to_locked_folder": "鍵付きフォルダーへ移動", "move_to_locked_folder_confirmation": "これらの写真や動画はすべてのアルバムから外され、鍵付きフォルダー内でのみ閲覧可能になります", @@ -1359,6 +1396,7 @@ "my_albums": "私のアルバム", "name": "名前", "name_or_nickname": "名前またはニックネーム", + "navigate": "ナビゲート", "network_requirement_photos_upload": "モバイル通信を使用して写真のバックアップを行う", "network_requirement_videos_upload": "モバイル通信を使用して動画のバックアップを行う", "network_requirements": "ネットワークの要件", @@ -1368,11 +1406,13 @@ "never": "行わない", "new_album": "新たなアルバム", "new_api_key": "新しいAPI キー", + "new_date_range": "新しい日付範囲", "new_password": "新しいパスワード", "new_person": "新しい人物", "new_pin_code": "新しいPINコード", "new_pin_code_subtitle": "鍵付きフォルダーを利用するのが初めてのようです。PINコードを作成してください", "new_timeline": "新たなタイムライン", + "new_update": "新たな更新", "new_user_created": "新しいユーザーが作成されました", "new_version_available": "新しいバージョンが利用可能", "newest_first": "最新順", @@ -1388,6 +1428,7 @@ "no_cast_devices_found": "キャスト先のデバイスが見つかりません", "no_checksum_local": "チェックサムが見つかりません - デバイス上の項目を取得できないようです", "no_checksum_remote": "チェックサムが見つかりません - サーバー上の項目を取得できないようです", + "no_devices": "許可されたデバイスがありません", "no_duplicates_found": "重複は見つかりませんでした。", "no_exif_info_available": "exif情報が利用できません", "no_explore_results_message": "コレクションを探索するにはさらに写真をアップロードしてください。", @@ -1404,6 +1445,7 @@ "no_results_description": "同義語やより一般的なキーワードを試してください", "no_shared_albums_message": "アルバムを作成して写真や動画を共有しましょう", "no_uploads_in_progress": "アップロードは行われていません", + "not_allowed": "許可されていません", "not_available": "適用なし", "not_in_any_album": "どのアルバムにも入っていない", "not_selected": "選択なし", @@ -1418,6 +1460,9 @@ "notifications": "通知", "notifications_setting_description": "通知を管理します", "oauth": "OAuth", + "obtainium_configurator": "Obtainiumの設定", + "obtainium_configurator_instructions": "Obtainiumを使用すると、Immich GitHubのリリースから直接Androidアプリをインストールおよびアップデートできます。APIキーを作成し、バリアントを選択してObtainiumの設定リンクを作成してください", + "ocr": "OCR", "official_immich_resources": "公式Immichリソース", "offline": "オフライン", "offset": "オフセット", @@ -1511,6 +1556,7 @@ "photos_count": "{count, plural, one {{count, number}枚の写真} other {{count, number}枚の写真}}", "photos_from_previous_years": "以前の年の写真", "pick_a_location": "場所を選択", + "pick_date_range": "日付範囲の選択", "pin_code_changed_successfully": "PINコードを変更しました", "pin_code_reset_successfully": "PINコードをリセットしました", "pin_code_setup_successfully": "PINコードをセットアップしました", @@ -1522,6 +1568,9 @@ "play_memories": "メモリーを再生", "play_motion_photo": "モーションビデオを再生", "play_or_pause_video": "動画を再生または一時停止", + "play_original_video": "オリジナルの動画を再生", + "play_original_video_setting_description": "トランスコードされた動画よりも、オリジナルの動画を優先して再生します。オリジナルのアセットが互換性がない場合、正しく再生されない可能性があります。", + "play_transcoded_video": "トランスコード済みの動画を再生する", "please_auth_to_access": "アクセスするには認証が必要です", "port": "ポートレート", "preferences_settings_subtitle": "アプリに関する設定", @@ -1658,6 +1707,7 @@ "reset_sqlite_confirmation": "SQLiteを本当にリセットしますか?データを再び同期するためにログアウトし再ログインをする必要があります", "reset_sqlite_success": "SQLiteデータベースのリセットに成功しました", "reset_to_default": "デフォルトにリセット", + "resolution": "解像度", "resolve_duplicates": "重複を解決する", "resolved_all_duplicates": "全ての重複を解決しました", "restore": "復元", @@ -1676,6 +1726,7 @@ "running": "実行中", "save": "保存", "save_to_gallery": "ギャラリーに保存", + "saved": "保存しました", "saved_api_key": "APIキーを保存しました", "saved_profile": "プロフィールを保存しました", "saved_settings": "設定を保存しました", @@ -1692,6 +1743,9 @@ "search_by_description_example": "サパでハイキングした日", "search_by_filename": "ファイル名もしくは拡張子で検索", "search_by_filename_example": "例: IMG_1234.JPG もしくは PNG", + "search_by_ocr": "OCR検索", + "search_by_ocr_example": "お茶", + "search_camera_lens_model": "レンズモデルで検索…", "search_camera_make": "カメラメーカーを検索…", "search_camera_model": "カメラのモデルを検索…", "search_city": "市町村を検索…", @@ -1708,6 +1762,7 @@ "search_filter_location_title": "場所を選択", "search_filter_media_type": "メディアの種類", "search_filter_media_type_title": "メディアの種類を選択", + "search_filter_ocr": "OCRで検索", "search_filter_people_title": "人物を選択", "search_for": "検索", "search_for_existing_person": "既存の人物を検索", @@ -1769,7 +1824,10 @@ "server_offline": "サーバーがオフラインです", "server_online": "サーバーがオンラインです", "server_privacy": "サーバープライバシー", + "server_restarting_description": "このページはすぐに更新されます。", + "server_restarting_title": "サーバーは再起動しています", "server_stats": "サーバー統計", + "server_update_available": "サーバーのアップデートが利用可能です", "server_version": "サーバーバージョン", "set": "設定", "set_as_album_cover": "アルバムカバーとして設定", @@ -1798,6 +1856,8 @@ "setting_notifications_subtitle": "通知設定を変更する", "setting_notifications_total_progress_subtitle": "アップロードの進行状況 (完了済み/全体枚数)", "setting_notifications_total_progress_title": "全体のバックアップの進行状況を表示", + "setting_video_viewer_auto_play_subtitle": "動画を開くと自動で再生されます", + "setting_video_viewer_auto_play_title": "動画の自動再生", "setting_video_viewer_looping_title": "動画をループする", "setting_video_viewer_original_video_subtitle": "動画をストリーミングする際に、トランスコードされた動画が存在していても、あえてオリジナル画質の動画を再生します。ストリーミングに待ち時間が生じるかもしれません。なお、デバイス上に保存されている動画はこの設定の有無に関わらず、オリジナル画質の動画を再生します。", "setting_video_viewer_original_video_title": "常にオリジナル画質の動画を再生する", @@ -1977,7 +2037,9 @@ "theme_setting_three_stage_loading_title": "三段階読み込みをオンにする", "they_will_be_merged_together": "これらは一緒に統合されます", "third_party_resources": "サードパーティーリソース", + "time": "時刻", "time_based_memories": "過去の思い出", + "time_based_memories_duration": "各写真を表示する秒数。", "timeline": "タイムライン", "timezone": "タイムゾーン", "to_archive": "アーカイブ", @@ -2009,6 +2071,7 @@ "troubleshoot": "トラブルシューティング", "type": "タイプ", "unable_to_change_pin_code": "PINコードを変更できませんでした", + "unable_to_check_version": "アプリまたはサーバーのバージョンをチェックできませんでした", "unable_to_setup_pin_code": "PINコードをセットアップできませんでした", "unarchive": "アーカイブを解除", "unarchive_action_prompt": "{count}項目をアーカイブから除きました", @@ -2117,6 +2180,7 @@ "welcome": "ようこそ", "welcome_to_immich": "Immichにようこそ", "wifi_name": "Wi-Fiの名前(SSID)", + "workflow": "ワークフロー", "wrong_pin_code": "PINコードが間違っています", "year": "年", "years_ago": "{years, plural, one {#年} other {#年}}前", diff --git a/i18n/ka.json b/i18n/ka.json index 063419db11..c756b9b708 100644 --- a/i18n/ka.json +++ b/i18n/ka.json @@ -16,7 +16,6 @@ "add_a_title": "დაასათაურე", "add_birthday": "დაბადების დღის დამატება", "add_exclusion_pattern": "დაამატე გამონაკლისი ნიმუში", - "add_import_path": "დაამატე საიმპორტო მისამართი", "add_location": "დაამატე ადგილი", "add_more_users": "დაამატე მომხმარებლები", "add_partner": "დაამატე პარტნიორი", @@ -73,7 +72,6 @@ "image_thumbnail_title": "მინიატურის პარამეტრები", "library_created": "შეიქმნა ბიბლიოთეკა: {library}", "library_deleted": "ბიბლიოთეკა წაიშალა", - "library_import_path_description": "აირჩიე დასაიმპორტებელი საქაღალდე. ფოტოები და ვიდეოები მოიძებნება ამ საქაღალდესა და მასში არსებულ საქაღალდეებში.", "library_settings": "გარე ბიბლიოთეკა", "library_settings_description": "გარე ბიბლიოთეკების პარამეტრების მართვა", "logging_settings": "ჟურნალი", diff --git a/i18n/km.json b/i18n/km.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/km.json @@ -0,0 +1 @@ +{} diff --git a/i18n/kn.json b/i18n/kn.json index 111c802a1e..6bef39c34c 100644 --- a/i18n/kn.json +++ b/i18n/kn.json @@ -17,7 +17,6 @@ "add_birthday": "ಜನ್ಮದಿನ ಸೇರಿಸಿ", "add_endpoint": "ಎಂಡ್‌ಪಾಯಿಂಟ್ ಸೇರಿಸಿ", "add_exclusion_pattern": "ಹೊರಗಿಡುವಿಕೆ ಮಾದರಿಯನ್ನು ಸೇರಿಸಿ", - "add_import_path": "ಆಮದು ಮಾರ್ಗವನ್ನು ಸೇರಿಸಿ", "add_location": "ಸ್ಥಳ ಸೇರಿಸಿ", "add_more_users": "ಹೆಚ್ಚಿನ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ", "add_partner": "ಪಾಲುದಾರರನ್ನು ಸೇರಿಸಿ", diff --git a/i18n/ko.json b/i18n/ko.json index 8a4094c4b0..782069b939 100644 --- a/i18n/ko.json +++ b/i18n/ko.json @@ -17,7 +17,6 @@ "add_birthday": "생일 추가", "add_endpoint": "엔드포인트 추가", "add_exclusion_pattern": "제외 규칙 추가", - "add_import_path": "가져올 경로 추가", "add_location": "위치 추가", "add_more_users": "다른 사용자 추가", "add_partner": "파트너 추가", @@ -33,7 +32,7 @@ "add_to_albums": "여러 앨범에 추가", "add_to_albums_count": "여러 앨범에 추가 ({count})", "add_to_shared_album": "공유 앨범에 추가", - "add_upload_to_stack": "스택에 업로드 추가", + "add_upload_to_stack": "스택에 항목 업로드", "add_url": "URL 추가", "added_to_archive": "보관함으로 이동되었습니다.", "added_to_favorites": "즐겨찾기에 추가되었습니다.", @@ -63,13 +62,13 @@ "config_set_by_file": "설정이 구성 파일을 통해 관리되고 있습니다.", "confirm_delete_library": "{library} 라이브러리를 삭제하시겠습니까?", "confirm_delete_library_assets": "이 라이브러리를 삭제하시겠습니까? Immich에서 {count, plural, one {항목 #개가} other {항목 #개가}} 삭제되며 되돌릴 수 없습니다. 원본 파일은 디스크에 남아 있습니다.", - "confirm_email_below": "계속하려면 아래에 \"{email}\"을(를) 입력하세요.", + "confirm_email_below": "계속 진행하려면 아래에 \"{email}\" 입력", "confirm_reprocess_all_faces": "모든 얼굴을 다시 처리하시겠습니까? 이름이 지정된 인물도 초기화됩니다.", "confirm_user_password_reset": "{user}님의 비밀번호를 초기화하시겠습니까?", "confirm_user_pin_code_reset": "{user}님의 PIN 코드를 초기화하시겠습니까?", "create_job": "새 작업", "cron_expression": "Cron 표현식", - "cron_expression_description": "Cron 표현식으로 스캔 주기를 설정합니다. 자세한 내용은 다음을 참조하세요, Crontab Guru", + "cron_expression_description": "Cron 표현식으로 스캔 주기를 설정합니다. 자세한 내용은 다음 링크를 확인하세요. Crontab Guru", "cron_expression_presets": "Cron 표현식 프리셋", "disable_login": "로그인 비활성화", "duplicate_detection_job_description": "기계 학습으로 유사한 이미지를 감지합니다. 스마트 검색이 활성화되어 있어야 합니다.", @@ -78,7 +77,7 @@ "face_detection": "얼굴 감지", "face_detection_description": "기계 학습으로 항목에서 얼굴을 감지합니다. 동영상의 경우 섬네일만 분석에 사용됩니다. \"새로고침\"은 모든 항목을 (재)처리하며, \"초기화\"는 현재 모든 얼굴 데이터를 추가로 삭제합니다. \"누락\"은 아직 처리되지 않은 항목을 대기열에 추가합니다. 얼굴 감지가 완료되면 얼굴 인식 단계로 넘어가 기존 인물이나 새로운 인물로 그룹화합니다.", "facial_recognition_job_description": "감지된 얼굴을 인물별로 그룹화합니다. 이 작업은 얼굴 감지 작업이 완료된 후 진행됩니다. \"초기화\"는 모든 얼굴을 다시 그룹화합니다. \"누락\"은 그룹화되지 않은 얼굴을 대기열에 추가합니다.", - "failed_job_command": "{job} 작업에서 {command} 실패", + "failed_job_command": "{job} 작업의 {command} 실패", "force_delete_user_warning": "경고: 이 작업은 해당 사용자의 계정과 모든 항목을 즉시 삭제합니다. 이 작업은 되돌릴 수 없으며 삭제된 파일은 복구할 수 없습니다.", "image_format": "형식", "image_format_description": "WebP는 JPEG보다 파일 크기가 작지만 인코딩 속도가 느립니다.", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {#개}} 실패", "library_created": "{library} 라이브러리를 생성했습니다.", "library_deleted": "라이브러리가 삭제되었습니다.", - "library_import_path_description": "가져올 폴더를 지정하세요. 해당 폴더와 모든 하위 폴더에서 이미지와 동영상을 스캔합니다.", "library_scanning": "주기적인 스캔", "library_scanning_description": "주기적인 라이브러리 스캔을 구성합니다.", "library_scanning_enable_description": "주기적인 라이브러리 스캔 활성화", @@ -158,6 +156,7 @@ "machine_learning_ocr_description": "기계 학습으로 이미지에서 텍스트를 인식합니다.", "machine_learning_ocr_enabled": "OCR 활성화", "machine_learning_ocr_min_detection_score": "최소 신뢰도 점수", + "machine_learning_ocr_model": "OCR 모델", "machine_learning_settings": "기계 학습 설정", "machine_learning_settings_description": "기계 학습 시 사용할 모델과 세부 설정을 관리합니다.", "machine_learning_smart_search": "스마트 검색", @@ -241,7 +240,7 @@ "oauth_settings": "OAuth", "oauth_settings_description": "OAuth 로그인 설정을 관리합니다.", "oauth_settings_more_details": "이 기능에 대한 자세한 내용은 문서를 참조하세요.", - "oauth_storage_label_claim": "스토리지 라벨 클레임", + "oauth_storage_label_claim": "스토리지 레이블 클레임", "oauth_storage_label_claim_description": "클레임의 값을 사용자 스토리지 레이블로 자동 설정합니다.", "oauth_storage_quota_claim": "스토리지 용량 클레임", "oauth_storage_quota_claim_description": "요청한 값을 사용자 스토리지 할당량으로 자동 설정합니다.", @@ -249,6 +248,7 @@ "oauth_storage_quota_default_description": "입력하지 않은 경우 사용할 GiB 단위의 할당량", "oauth_timeout": "요청 타임아웃", "oauth_timeout_description": "요청 타임아웃 (밀리초 단위)", + "ocr_job_description": "기계 학습으로 이미지에서 텍스트를 인식합니다.", "password_enable_description": "이메일과 비밀번호로 로그인", "password_settings": "비밀번호 로그인", "password_settings_description": "비밀번호 로그인 설정을 관리합니다.", @@ -882,8 +882,6 @@ "edit_description_prompt": "새 설명을 입력하세요:", "edit_exclusion_pattern": "제외 규칙 수정", "edit_faces": "얼굴 수정", - "edit_import_path": "가져올 경로 수정", - "edit_import_paths": "가져올 경로 수정", "edit_key": "키 수정", "edit_link": "링크 수정", "edit_location": "위치 변경", @@ -955,7 +953,6 @@ "failed_to_stack_assets": "항목 스택에 실패했습니다.", "failed_to_unstack_assets": "항목 스택 풀기에 실패했습니다.", "failed_to_update_notification_status": "알림 상태 업데이트 실패", - "import_path_already_exists": "이 가져올 경로는 이미 존재합니다.", "incorrect_email_or_password": "잘못된 이메일 또는 비밀번호", "paths_validation_failed": "{paths, plural, one {경로 #개} other {경로 #개}}가 유효성 검사에 실패했습니다.", "profile_picture_transparent_pixels": "프로필 사진에 투명 픽셀을 사용할 수 없습니다. 사진을 확대하거나 이동하세요.", @@ -965,7 +962,6 @@ "unable_to_add_assets_to_shared_link": "항목을 공유 링크에 추가할 수 없습니다.", "unable_to_add_comment": "댓글을 추가할 수 없습니다.", "unable_to_add_exclusion_pattern": "제외 규칙을 추가할 수 없습니다.", - "unable_to_add_import_path": "가져올 경로를 추가할 수 없습니다.", "unable_to_add_partners": "파트너를 추가할 수 없습니다.", "unable_to_add_remove_archive": "{archived, select, true {보관함에서 항목을 제거할} other {보관함으로 항목을 이동할}} 수 없습니다.", "unable_to_add_remove_favorites": "즐겨찾기에 항목을 {favorite, select, true {추가} other {제거}}할 수 없습니다", @@ -988,12 +984,10 @@ "unable_to_delete_asset": "항목을 삭제할 수 없습니다.", "unable_to_delete_assets": "항목 삭제 중 오류 발생", "unable_to_delete_exclusion_pattern": "제외 규칙을 삭제할 수 없습니다.", - "unable_to_delete_import_path": "가져올 경로를 삭제할 수 없습니다.", "unable_to_delete_shared_link": "공유 링크를 삭제할 수 없습니다.", "unable_to_delete_user": "사용자를 삭제할 수 없습니다.", "unable_to_download_files": "파일을 다운로드할 수 없습니다.", "unable_to_edit_exclusion_pattern": "제외 규칙을 수정할 수 없습니다.", - "unable_to_edit_import_path": "가져올 경로를 수정할 수 없습니다.", "unable_to_empty_trash": "휴지통을 비울 수 없습니다.", "unable_to_enter_fullscreen": "전체 화면으로 전환할 수 없습니다.", "unable_to_exit_fullscreen": "전체 화면을 종료할 수 없습니다.", diff --git a/i18n/lt.json b/i18n/lt.json index 56f8333bef..38b86e6bae 100644 --- a/i18n/lt.json +++ b/i18n/lt.json @@ -17,7 +17,6 @@ "add_birthday": "Pridėti gimimo diena", "add_endpoint": "Pridėti galutinį tašką", "add_exclusion_pattern": "Pridėti išimčių šabloną", - "add_import_path": "Pridėti importavimo kelią", "add_location": "Pridėti vietovę", "add_more_users": "Pridėti daugiau naudotojų", "add_partner": "Pridėti partnerį", @@ -28,6 +27,7 @@ "add_to_album": "Pridėti į albumą", "add_to_album_bottom_sheet_added": "Pridėta į {album}", "add_to_album_bottom_sheet_already_exists": "Jau yra albume {album}", + "add_to_album_bottom_sheet_some_local_assets": "Dalis vietinių elementų negalėjo būti pridėti į albumą", "add_to_album_toggle": "Perjungti pažymėjimus albumui {album}", "add_to_albums": "Pridėti į albumus", "add_to_albums_count": "Pridėti į albumus ({count})", @@ -110,7 +110,6 @@ "jobs_failed": "{jobCount, plural, other {# nepavyko}}", "library_created": "Sukurta biblioteka: {library}", "library_deleted": "Biblioteka ištrinta", - "library_import_path_description": "Nurodykite aplanką, kurį norite importuoti. Šiame aplanke, įskaitant poaplankius, bus nuskaityti vaizdai ir vaizdo įrašai.", "library_scanning": "Periodinis skenavimas", "library_scanning_description": "Konfigūruoti periodinį bibliotekos skanavimą", "library_scanning_enable_description": "Įgalinti periodinį bibliotekos skenavimą", @@ -152,6 +151,8 @@ "machine_learning_min_detection_score_description": "Minimalus užtikrintumo balas veido aptikimui nuo 0-1. Mažesnė reikšmė aptiks daugiau veidų tačiau bus ir daugiau klaidingų teigiamų režultatų.", "machine_learning_min_recognized_faces": "Mažiausias atpažintų veidų skaičius", "machine_learning_min_recognized_faces_description": "Mažiausias atpažintų veidų skaičius asmeniui, kurį reikia sukurti. Tai padidinus, veido atpažinimas tampa tikslesnis, bet padidėja tikimybė, kad veidas žmogui nepriskirtas.", + "machine_learning_ocr_description": "Naudoti mašininį mokymąsį, teksto atpažinimui nuotraukose", + "machine_learning_ocr_max_resolution": "Maksimali skiriamoji geba", "machine_learning_settings": "Mašininio mokymosi nustatymai", "machine_learning_settings_description": "Tvarkyti mašininio mokymosi funkcijas ir nustatymus", "machine_learning_smart_search": "Išmanioji paieška", @@ -241,6 +242,7 @@ "oauth_storage_quota_default_description": "Nustatoma appimties kvota GiB kai nėra nurodyta tvirtinime.", "oauth_timeout": "Užklausa viršijo laiko limitą", "oauth_timeout_description": "Laiko limitas užklausoms milisekundėmis", + "ocr_job_description": "Naudoti mašininį mokymąsi teksto atpažinimui nuotraukose", "password_enable_description": "Prisijungti su el. paštu ir slaptažodžiu", "password_settings": "Prisijungimas slaptažodžiu", "password_settings_description": "Tvarkyti prisijungimo slaptažodžiu nustatymus", @@ -865,8 +867,6 @@ "edit_description_prompt": "Prašome pasirinkti naują aprašymą:", "edit_exclusion_pattern": "Redaguoti išimčių šabloną", "edit_faces": "Redaguoti veidus", - "edit_import_path": "Redaguoti importavimo kelią", - "edit_import_paths": "Redaguoti importavimo kelius", "edit_key": "Redaguoti raktą", "edit_link": "Redaguoti nuorodą", "edit_location": "Redaguoti vietovę", @@ -938,7 +938,6 @@ "failed_to_stack_assets": "Nepavyko sugrupuoti elementų", "failed_to_unstack_assets": "Nepavyko išgrupuoti elementų", "failed_to_update_notification_status": "Nepavyko atnaujinti pranešimo statuso", - "import_path_already_exists": "Šis importavimo kelias jau egzistuoja.", "incorrect_email_or_password": "Neteisingas el. pašto adresas arba slaptažodis", "paths_validation_failed": "Nepavyko {paths, plural, one {# kelio} other {# kelių}} patvirtinimas", "profile_picture_transparent_pixels": "Profilio nuotrauka negali turėti permatomų pikselių. Prašome priartinti ir/arba perkelkite nuotrauką.", @@ -948,7 +947,6 @@ "unable_to_add_assets_to_shared_link": "Nepavyko į bendrinimo nuorodą pridėti elementų", "unable_to_add_comment": "Nepavyksta pridėti komentaro", "unable_to_add_exclusion_pattern": "Nepavyksta pridėti išimčių šablono", - "unable_to_add_import_path": "Nepavyksta pridėti importavimo kelio", "unable_to_add_partners": "Nepavyksta pridėti partnerių", "unable_to_add_remove_archive": "Nepavyko {archived, select, true {ištraukti iš} other {pridėti prie}} arcyhvo", "unable_to_add_remove_favorites": "Nepavyko {favorite, select, true {įtraukti elemento į mėgstamiausius} other {pašalinti elemento iš mėgstamiausių}}", @@ -971,12 +969,10 @@ "unable_to_delete_asset": "Nepavyko ištrinti elemento", "unable_to_delete_assets": "Klaida trinant elementus", "unable_to_delete_exclusion_pattern": "Nepavyksta ištrinti išimčių šablono", - "unable_to_delete_import_path": "Nepavyksta ištrinti importavimo kelio", "unable_to_delete_shared_link": "Nepavyko ištrinti bendrinimo nuorodos", "unable_to_delete_user": "Nepavyksta ištrinti naudotojo", "unable_to_download_files": "Nepavyksta atsisiųsti failų", "unable_to_edit_exclusion_pattern": "Nepavyksta redaguoti išimčių šablono", - "unable_to_edit_import_path": "Nepavyksta redaguoti išimčių kelio", "unable_to_empty_trash": "Nepavyko ištrinti šiukšliadėžės", "unable_to_enter_fullscreen": "Nepavyksta pereiti į viso ekrano režimą", "unable_to_exit_fullscreen": "Nepavyksta išeiti iš viso ekrano režimo", @@ -1071,6 +1067,7 @@ "features_setting_description": "Valdyti aplikacijos funkcijas", "file_name": "Failo pavadinimas", "file_name_or_extension": "Failo pavadinimas arba plėtinys", + "file_size": "Failo dydis", "filename": "Failopavadinimas", "filetype": "Failo tipas", "filter": "Filtras", @@ -1338,6 +1335,7 @@ "minute": "Minutė", "minutes": "Minutės", "missing": "Trūkstami", + "mobile_app": "Mobili aplikacija", "model": "Modelis", "month": "Mėnesis", "monthly_title_text_date_format": "MMMM y", @@ -1523,6 +1521,7 @@ "port": "Portas", "preferences_settings_subtitle": "Tvarkyti programos nuostatas", "preferences_settings_title": "Nuostatos", + "preparing": "Ruošiama", "preset": "Šablonas", "preview": "Peržiūra", "previous": "Buvęs", @@ -1578,6 +1577,7 @@ "rating_count": "{count, plural, one {# įvertinimas} few {# įvertinimai} other {# įvertinimų}}", "rating_description": "Rodyti EXIF įvertinimus informacijos skydelyje", "read_changelog": "Skaityti pakeitimų sąrašą", + "ready_for_upload": "Paruošta įkėlimui", "recent-albums": "Naujausi albumai", "recent_searches": "Naujausios paieškos", "recently_added": "Neseniai pridėta", @@ -1599,11 +1599,13 @@ "remove_assets_title": "Pašalinti elementus?", "remove_deleted_assets": "Pašalinti Ištrintus Elemenuts", "remove_from_album": "Pašalinti iš albumo", + "remove_from_album_action_prompt": "{count} pašalinta iš albumo", "remove_from_favorites": "Pašalinti iš mėgstamiausių", "remove_from_lock_folder_action_prompt": "{count} ištraukta iš užrakinto aplanko", "remove_from_locked_folder": "Išimti iš užrakinto aplanko", "remove_from_locked_folder_confirmation": "Ar tikrai norite perkelti šias nuotraukas ir vaizdo įrašus iš užrakinto aplanko? Jie taps matomi jūsų galerijoje.", "remove_from_shared_link": "Pašalinti iš bendrinimo nuorodos", + "remove_tag": "Pašalinti žymę", "remove_user": "Pašalinti naudotoją", "removed_api_key": "Pašalintas API Raktas: {name}", "removed_from_archive": "Pašalinta iš archyvo", diff --git a/i18n/lv.json b/i18n/lv.json index 6ff1c4e4ad..4af37ac5ba 100644 --- a/i18n/lv.json +++ b/i18n/lv.json @@ -17,7 +17,6 @@ "add_birthday": "Pievienot dzimšanas dienu", "add_endpoint": "Pievienot galapunktu", "add_exclusion_pattern": "Pievienot izslēgšanas šablonu", - "add_import_path": "Pievienot importa ceļu", "add_location": "Pievienot lokāciju", "add_more_users": "Pievienot vēl lietotājus", "add_partner": "Pievienot partneri", @@ -110,7 +109,6 @@ "job_status": "Uzdevumu statuss", "library_created": "Izveidoja bibliotēku: {library}", "library_deleted": "Bibliotēka dzēsta", - "library_import_path_description": "Norādi importējamo mapi. Šī mape un tās apakšmapes tiks pārbaudīta, lai atrastu attēlus un videoklipus.", "library_scanning": "Periodiska skenēšana", "library_scanning_description": "Konfigurē periodisku bibliotēku skenēšanu", "library_scanning_enable_description": "Iespējot periodisku bibliotēku skenēšanu", @@ -717,8 +715,6 @@ "edit_description_prompt": "Lūdzu, izvēlies jaunu aprakstu:", "edit_exclusion_pattern": "Labot izslēgšanas šablonu", "edit_faces": "Labot sejas", - "edit_import_path": "Labot importa ceļu", - "edit_import_paths": "Labot importa ceļus", "edit_key": "Labot atslēgu", "edit_link": "Rediģēt saiti", "edit_location": "Rediģēt Atrašanās Vietu", @@ -769,7 +765,6 @@ "failed_to_stack_assets": "Neizdevās apvienot failus kaudzē", "failed_to_unstack_assets": "Neizdevās atcelt failu apvienošanu kaudzē", "failed_to_update_notification_status": "Neizdevās mainīt paziņojuma statusu", - "import_path_already_exists": "Šis importa ceļš jau pastāv.", "incorrect_email_or_password": "Nepareizs e-pasts vai parole", "profile_picture_transparent_pixels": "Profila attēlos nevar būt caurspīdīgi pikseļi. Lūdzu, palielini un/vai pārvieto attēlu.", "something_went_wrong": "Kaut kas nogāja greizi", @@ -1300,6 +1295,7 @@ "role_viewer": "Skatītājs", "save": "Saglabāt", "save_to_gallery": "Saglabāt galerijā", + "saved": "Saglabāts", "saved_api_key": "API atslēga saglabāta", "saved_profile": "Profils saglabāts", "saved_settings": "Iestatījumi saglabāti", diff --git a/i18n/mk.json b/i18n/mk.json index e81694e63e..c866b313fd 100644 --- a/i18n/mk.json +++ b/i18n/mk.json @@ -17,7 +17,6 @@ "add_birthday": "Додади роденден", "add_endpoint": "Додади крајна точка", "add_exclusion_pattern": "Додади шаблон за исклучување", - "add_import_path": "Додади патека за импортирање", "add_location": "Додади локација", "add_more_users": "Додади уште корисници", "add_partner": "Додади партнер", @@ -94,7 +93,6 @@ "job_status": "Статус на задачи", "library_created": "Креирана библиотека: {library}", "library_deleted": "Библиотеката е избришана", - "library_import_path_description": "Предложи папка за внес. Оваа папка, вклучува и под папки, ќе биде скенирана за слики и видеа.", "library_scanning": "Периодично скенирање", "library_scanning_description": "Подеси периодично скениранје на библиотеката", "library_scanning_enable_description": "Овозможи периодично скениранје на библиотеката", diff --git a/i18n/ml.json b/i18n/ml.json index ec9eba2794..8847103508 100644 --- a/i18n/ml.json +++ b/i18n/ml.json @@ -17,7 +17,6 @@ "add_birthday": "ജന്മദിനം ചേർക്കുക", "add_endpoint": "എൻഡ്‌പോയിന്റ് ചേർക്കുക", "add_exclusion_pattern": "ഒഴിവാക്കൽ പാറ്റേൺ ചേർക്കുക", - "add_import_path": "ഇമ്പോർട്ട് പാത്ത് ചേർക്കുക", "add_location": "സ്ഥാനം ചേർക്കുക", "add_more_users": "കൂടുതൽ ഉപയോക്താക്കളെ ചേർക്കുക", "add_partner": "പങ്കാളിയെ ചേർക്കുക", @@ -111,7 +110,6 @@ "jobs_failed": "{jobCount, plural, one {# ജോലി പരാജയപ്പെട്ടു} other {# ജോലികൾ പരാജയപ്പെട്ടു}}", "library_created": "{library} എന്ന ലൈബ്രറി സൃഷ്ടിച്ചു", "library_deleted": "ലൈബ്രറി ഇല്ലാതാക്കി", - "library_import_path_description": "ഇമ്പോർട്ടുചെയ്യാൻ ഒരു ഫോൾഡർ വ്യക്തമാക്കുക. സബ്ഫോൾഡറുകൾ ഉൾപ്പെടെ ഈ ഫോൾഡർ ചിത്രങ്ങൾക്കും വീഡിയോകൾക്കുമായി സ്കാൻ ചെയ്യും.", "library_scanning": "ആനുകാലിക സ്കാനിംഗ്", "library_scanning_description": "ആനുകാലിക ലൈബ്രറി സ്കാനിംഗ് കോൺഫിഗർ ചെയ്യുക", "library_scanning_enable_description": "ആനുകാലിക ലൈബ്രറി സ്കാനിംഗ് പ്രവർത്തനക്ഷമമാക്കുക", @@ -869,8 +867,6 @@ "edit_description_prompt": "ദയവായി ഒരു പുതിയ വിവരണം തിരഞ്ഞെടുക്കുക:", "edit_exclusion_pattern": "ഒഴിവാക്കൽ പാറ്റേൺ എഡിറ്റുചെയ്യുക", "edit_faces": "മുഖങ്ങൾ എഡിറ്റുചെയ്യുക", - "edit_import_path": "ഇമ്പോർട്ട് പാത്ത് എഡിറ്റുചെയ്യുക", - "edit_import_paths": "ഇമ്പോർട്ട് പാത്തുകൾ എഡിറ്റുചെയ്യുക", "edit_key": "കീ എഡിറ്റുചെയ്യുക", "edit_link": "ലിങ്ക് എഡിറ്റുചെയ്യുക", "edit_location": "സ്ഥാനം എഡിറ്റുചെയ്യുക", @@ -942,7 +938,6 @@ "failed_to_stack_assets": "അസറ്റുകൾ സ്റ്റാക്ക് ചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു", "failed_to_unstack_assets": "അസറ്റുകൾ അൺ-സ്റ്റാക്ക് ചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു", "failed_to_update_notification_status": "അറിയിപ്പിന്റെ നില അപ്ഡേറ്റ് ചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു", - "import_path_already_exists": "ഈ ഇമ്പോർട്ട് പാത്ത് ഇതിനകം നിലവിലുണ്ട്.", "incorrect_email_or_password": "തെറ്റായ ഇമെയിൽ അല്ലെങ്കിൽ പാസ്‌വേഡ്", "paths_validation_failed": "{paths, plural, one {# പാത്ത്} other {# പാത്തുകൾ}} സാധൂകരണത്തിൽ പരാജയപ്പെട്ടു", "profile_picture_transparent_pixels": "പ്രൊഫൈൽ ചിത്രങ്ങൾക്ക് സുതാര്യമായ പിക്സലുകൾ ഉണ്ടാകരുത്. ദയവായി സൂം ഇൻ ചെയ്യുക കൂടാതെ/അല്ലെങ്കിൽ ചിത്രം നീക്കുക.", @@ -952,7 +947,6 @@ "unable_to_add_assets_to_shared_link": "പങ്കിട്ട ലിങ്കിലേക്ക് അസറ്റുകൾ ചേർക്കാൻ കഴിയില്ല", "unable_to_add_comment": "അഭിപ്രായം ചേർക്കാൻ കഴിയില്ല", "unable_to_add_exclusion_pattern": "ഒഴിവാക്കൽ പാറ്റേൺ ചേർക്കാൻ കഴിയില്ല", - "unable_to_add_import_path": "ഇമ്പോർട്ട് പാത്ത് ചേർക്കാൻ കഴിയില്ല", "unable_to_add_partners": "പങ്കാളികളെ ചേർക്കാൻ കഴിയില്ല", "unable_to_add_remove_archive": "ആർക്കൈവിൽ {archived, select, true {നിന്ന് അസറ്റ് നീക്കംചെയ്യാൻ} other {ലേക്ക് അസറ്റ് ചേർക്കാൻ}} കഴിയില്ല", "unable_to_add_remove_favorites": "പ്രിയപ്പെട്ടവയിലേക്ക് {favorite, select, true {അസറ്റ് ചേർക്കാൻ} other {നിന്ന് അസറ്റ് നീക്കംചെയ്യാൻ}} കഴിയില്ല", @@ -975,12 +969,10 @@ "unable_to_delete_asset": "അസറ്റ് ഇല്ലാതാക്കാൻ കഴിയില്ല", "unable_to_delete_assets": "അസറ്റുകൾ ഇല്ലാതാക്കുന്നതിൽ പിശക്", "unable_to_delete_exclusion_pattern": "ഒഴിവാക്കൽ പാറ്റേൺ ഇല്ലാതാക്കാൻ കഴിയില്ല", - "unable_to_delete_import_path": "ഇമ്പോർട്ട് പാത്ത് ഇല്ലാതാക്കാൻ കഴിയില്ല", "unable_to_delete_shared_link": "പങ്കിട്ട ലിങ്ക് ഇല്ലാതാക്കാൻ കഴിയില്ല", "unable_to_delete_user": "ഉപയോക്താവിനെ ഇല്ലാതാക്കാൻ കഴിയില്ല", "unable_to_download_files": "ഫയലുകൾ ഡൗൺലോഡ് ചെയ്യാൻ കഴിയില്ല", "unable_to_edit_exclusion_pattern": "ഒഴിവാക്കൽ പാറ്റേൺ എഡിറ്റുചെയ്യാൻ കഴിയില്ല", - "unable_to_edit_import_path": "ഇമ്പോർട്ട് പാത്ത് എഡിറ്റുചെയ്യാൻ കഴിയില്ല", "unable_to_empty_trash": "ട്രാഷ് ശൂന്യമാക്കാൻ കഴിയില്ല", "unable_to_enter_fullscreen": "ഫുൾസ്ക്രീനിൽ പ്രവേശിക്കാൻ കഴിയില്ല", "unable_to_exit_fullscreen": "ഫുൾസ്ക്രീനിൽ നിന്ന് പുറത്തുകടക്കാൻ കഴിയില്ല", diff --git a/i18n/mn.json b/i18n/mn.json index 85092fef0d..62e40274af 100644 --- a/i18n/mn.json +++ b/i18n/mn.json @@ -15,7 +15,6 @@ "add_a_name": "Нэр өгөх", "add_a_title": "Гарчиг оруулах", "add_endpoint": "Endpoint нэмэх", - "add_import_path": "Импортлох зам нэмэх", "add_location": "Байршил оруулах", "add_more_users": "Өөр хэрэглэгчид нэмэх", "add_partner": "Хамтрагч нэмэх", diff --git a/i18n/mr.json b/i18n/mr.json index 54cac4b0dc..8404983db1 100644 --- a/i18n/mr.json +++ b/i18n/mr.json @@ -17,7 +17,6 @@ "add_birthday": "जन्मदिवस नोंदवा", "add_endpoint": "एंडपॉइंट जोडा", "add_exclusion_pattern": "अपवाद नमुना जोडा", - "add_import_path": "आयात मार्ग टाका", "add_location": "स्थळ टाका", "add_more_users": "अधिक वापरकर्ते जोडा", "add_partner": "भागीदार जोडा", @@ -32,7 +31,9 @@ "add_to_album_toggle": "{album} साठी निवड बदला", "add_to_albums": "अल्बममध्ये जोडा", "add_to_albums_count": "अल्बमांमध्ये जोडा ({count})", + "add_to_bottom_bar": "मध्ये जोडा", "add_to_shared_album": "सामायिक संग्रहात टाका", + "add_upload_to_stack": "स्टॅकमध्ये अपलोड जोडा", "add_url": "URL प्रविष्ट करा", "added_to_archive": "संग्रहित केले", "added_to_favorites": "आवडत्या संग्रहात जोडले", @@ -48,7 +49,7 @@ "background_task_job": "पृष्ठभूमि कार्य", "backup_database": "डेटाबेस डंप तयार करा", "backup_database_enable_description": "डेटाबेस डंप सक्षम करा", - "backup_keep_last_amount": "पूर्वीच्या किती प्रतिलिपी ठेवायच्या", + "backup_keep_last_amount": "पूर्वीच्या किती डंप्स ठेवायचे", "backup_onboarding_1_description": "क्लाऊडमध्ये किंवा इतर कोणत्याही भौतिक ठिकाणी ठेवलेली ऑफसाइट प्रत.", "backup_onboarding_2_description": "विविध उपकरणांवर स्थानिक प्रती ठेवली जातात. यामध्ये मुख्य फाइल्स आणि त्यांच्या स्थानिक बॅकअपचा समावेश आहे.", "backup_onboarding_3_description": "मुळ फाइल्ससहित तुमच्या डेटाच्या एकूण प्रत्या. यामध्ये 1 ऑफसाइट प्रत आणि 2 स्थानिक प्रतांचा समावेश आहे.", @@ -56,7 +57,7 @@ "backup_onboarding_footer": "Immich चा बॅकअप कसा घ्यावा याबद्दल अधिक माहितीसाठी, कृपया दस्तऐवजीकरण पाहा.", "backup_onboarding_parts_title": "3-2-1 बॅकअपमध्ये समाविष्ट आहे:", "backup_onboarding_title": "बॅकअप", - "backup_settings": "प्रतिलिपी व्यवस्था", + "backup_settings": "डेटाबेस डंप सेटिंग्ज", "backup_settings_description": "माहिती संचय प्रतिलिपी व्यवस्थापन", "cleared_jobs": "{job}: च्या कार्यवाह्या काढल्या", "config_set_by_file": "संरचना सध्या संरचना खतावणीद्वारे निश्चित केली आहे", @@ -111,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# अयशस्वी}}", "library_created": "संग्रह तयार केला: {library}", "library_deleted": "संग्रह हटवला", - "library_import_path_description": "आयात करण्यासाठी फोल्डर निवडा. हा फोल्डर आणि त्यामधील उपफोल्डर्स प्रतिमा व व्हिडिओंसाठी स्कॅन केले जातील.", "library_scanning": "नियमित स्कॅनिंग", "library_scanning_description": "नियमित लायब्ररी स्कॅनिंग कॉन्फिगर करा", "library_scanning_enable_description": "नियमित लायब्ररी स्कॅनिंग चालू करा", @@ -124,6 +124,13 @@ "logging_enable_description": "लॉगिंग सक्षम करा", "logging_level_description": "सक्षम झाल्यावर वापरण्यासाठी कोणता लॉग स्तर निवडा.", "logging_settings": "लॉगिंग", + "machine_learning_availability_checks": "उपलब्धता तपासणी", + "machine_learning_availability_checks_description": "उपलब्ध मशीन लर्निंग सर्व्हर आपोआप शोधा आणि त्यांना प्राधान्य द्या", + "machine_learning_availability_checks_enabled": "उपलब्धता तपासणी सक्षम करा", + "machine_learning_availability_checks_interval": "तपासणी अंतर", + "machine_learning_availability_checks_interval_description": "उपलब्धता तपासण्यांमधील अंतर (मिलीसेकंदांत)", + "machine_learning_availability_checks_timeout": "विनंती वेळमर्यादा", + "machine_learning_availability_checks_timeout_description": "उपलब्धता तपासणीसाठी वेळमर्यादा (मिलीसेकंदांत)", "machine_learning_clip_model": "CLIP मॉडेल", "machine_learning_clip_model_description": "सूचीबद्ध CLIP मॉडेलचे नाव येथे. मॉडेल बदलल्यावर सर्व प्रतिमांसाठी ‘स्मार्ट शोध’ नोकरी पुन्हा चालवा.", "machine_learning_duplicate_detection": "प्रतिलिपी शोध", @@ -146,6 +153,18 @@ "machine_learning_min_detection_score_description": "चेहरा शोधण्यासाठी किमान आत्मविश्वास गुणांक 0 ते 1 दरम्यान असावा. कमी मूल्ये अधिक चेहरे शोधतील, परंतु खोटे सकारात्मक देखील होऊ शकतात.", "machine_learning_min_recognized_faces": "किमान ओळखलेले चेहरे", "machine_learning_min_recognized_faces_description": "व्यक्ती तयार करण्यासाठी ओळखल्या गेलेल्या चेहर्यांची किमान संख्या. हे वाढवल्यास चेहरा एका व्यक्तीला न जोडला जाण्याची शक्यता कमी होते, परंतु चुकीच्या व्यक्ती एकत्र केल्याचे परिणाम वाढू शकतात.", + "machine_learning_ocr": "ओ.सी.आर", + "machine_learning_ocr_description": "प्रतिमांमधील मजकूर ओळखण्यासाठी मशीन लर्निंग वापरा", + "machine_learning_ocr_enabled": "ओ.सी.आर सक्षम करा", + "machine_learning_ocr_enabled_description": "हे बंद असल्यास, प्रतिमांवर मजकूर ओळख प्रक्रिया होणार नाही.", + "machine_learning_ocr_max_resolution": "कमाल रिझोल्यूशन", + "machine_learning_ocr_max_resolution_description": "या रिझोल्यूशनपेक्षा मोठ्या पूर्वदृश्यांचे आकारगुणोत्तर न बदलता आकार बदलले जातील. जास्त मूल्ये अधिक अचूक असतात, पण प्रक्रिया करण्यास जास्त वेळ घेतात आणि अधिक मेमरी वापरतात.", + "machine_learning_ocr_min_detection_score": "किमान डिटेक्शन स्कोअर", + "machine_learning_ocr_min_detection_score_description": "मजकूर ओळखण्यासाठी ०–१ मधील किमान विश्वास स्कोअर. कमी मूल्यांवर अधिक मजकूर सापडेल, पण चुकीचे सकारात्मक निकाल (false positives) येऊ शकतात.", + "machine_learning_ocr_min_recognition_score": "किमान ओळख स्कोअर", + "machine_learning_ocr_min_score_recognition_description": "ओळखलेला मजकूर अंतिम मानण्यासाठी ०–१ मधील किमान विश्वास स्कोअर. कमी मूल्यांवर अधिक मजकूर ओळखला जाईल, पण चुकीचे सकारात्मक निकाल (false positives) येऊ शकतात.", + "machine_learning_ocr_model": "ओसीआर मॉडेल", + "machine_learning_ocr_model_description": "सर्व्हर मॉडेल मोबाईल मॉडेलपेक्षा अधिक अचूक असतात, पण प्रक्रिया करण्यास जास्त वेळ घेतात आणि अधिक मेमरी वापरतात.", "machine_learning_settings": "मशीन लर्निंग सेटिंग्ज", "machine_learning_settings_description": "मशीन लर्निंग वैशिष्ट्ये आणि सेटिंग्ज व्यवस्थापित करा", "machine_learning_smart_search": "स्मार्ट शोध", @@ -531,8 +550,10 @@ "autoplay_slideshow": "स्वयंचलित स्लाइडशो", "back": "मागे", "back_close_deselect": "मागे किंवा बंद करा / निवड रद्द करा", + "background_backup_running_error": "पार्श्वभूमी बॅकअप सध्या चालू आहे, मॅन्युअल बॅकअप सुरू करू शकत नाही", "background_location_permission": "बॅकग्राउंडमध्ये स्थान परवानगी द्या", "background_location_permission_content": "बॅकग्राउंडमध्ये नेटवर्क स्विच करण्यासाठी Immich ला नेहमी अचूक स्थान माहिती (Wi-Fi नाव) पाहिजे", + "background_options": "पार्श्वभूमी पर्याय", "backup": "बॅकअप", "backup_album_selection_page_albums_device": "उपकरणावरील अल्बम ({count})", "backup_album_selection_page_albums_tap": "समाविष्ट करण्यासाठी एकदाच टॅप करा; वगळण्यासाठी डबल टॅप करा", @@ -540,8 +561,10 @@ "backup_album_selection_page_select_albums": "अल्बम निवडा", "backup_album_selection_page_selection_info": "निवड माहिती", "backup_album_selection_page_total_assets": "एकूण स्वतंत्र फाईल्स", + "backup_albums_sync": "बॅकअप अल्बम समक्रमण", "backup_all": "सर्व", "backup_background_service_backup_failed_message": "बॅकअप अयशस्वी. पुन्हा प्रयत्न करत आहे…", + "backup_background_service_complete_notification": "अॅसेटचा बॅकअप पूर्ण झाला", "backup_background_service_connection_failed_message": "सर्व्हरशी कनेक्ट करण्यात अयशस्वी. पुन्हा प्रयत्न करत आहे…", "backup_background_service_current_upload_notification": "{filename} अपलोड करत आहे", "backup_background_service_default_notification": "नवीन फाईल्स शोधत आहे…", @@ -856,8 +879,6 @@ "edit_description_prompt": "नवीन वर्णन निवडा:", "edit_exclusion_pattern": "वगळा पॅटर्न संपादित करा", "edit_faces": "चेहऱ्यांवर संपादन करा", - "edit_import_path": "आयात मार्ग संपादित करा", - "edit_import_paths": "आयात मार्गे संपादित करा", "edit_key": "की संपादित करा", "edit_link": "लिंक संपादित करा", "edit_location": "स्थान संपादित करा", @@ -925,7 +946,6 @@ "failed_to_stack_assets": "फाईल्स एकत्र करता आल्या नाहीत", "failed_to_unstack_assets": "फाईल्स विभाजित करता आल्या नाहीत", "failed_to_update_notification_status": "सूचना स्थिती अपडेट करण्यात अयशस्वी", - "import_path_already_exists": "हा आयात मार्ग आधीच अस्तित्वात आहे।", "incorrect_email_or_password": "चुकीचा ईमेल किंवा संकेतशब्द", "paths_validation_failed": "{paths, plural, one {एक मार्ग वैध नाही} other {# मार्ग वैध नाहीत}}", "profile_picture_transparent_pixels": "प्रोफाइल चित्रात पारदर्शक पिक्सेल असू शकत नाहीत. कृपया झूम करा किंवा प्रतिमा हलवा.", @@ -934,7 +954,6 @@ "unable_to_add_assets_to_shared_link": "शेअर लिंकमध्ये फाईल्स जोडता आले नाहीत", "unable_to_add_comment": "टिप्पणी जोडता आले नाही", "unable_to_add_exclusion_pattern": "वगळण्याचे पॅटर्न जोडता आले नाही", - "unable_to_add_import_path": "आयात मार्ग जोडता आले नाही", "unable_to_add_partners": "सहयोगी जोडता आले नाहीत", "unable_to_add_remove_archive": "{archived, select, true{अर्काइव्हमधून फाईल काढता आले नाही} other{अर्काइव्हमध्ये फाईल जोडता आले नाही}}", "unable_to_add_remove_favorites": "{favorite, select, true{फाईल आवडत्या मध्ये जोडता आले नाही} other{फाईल आवडत्या मधून काढता आले नाही}}", @@ -957,12 +976,10 @@ "unable_to_delete_asset": "फाईल हटवता आली नाही", "unable_to_delete_assets": "फाईल्स हटवताना त्रुटी", "unable_to_delete_exclusion_pattern": "वगळणी पॅटर्न हटवता आला नाही", - "unable_to_delete_import_path": "आयात मार्ग हटवता आला नाही", "unable_to_delete_shared_link": "शेअर लिंक हटवता आला नाही", "unable_to_delete_user": "वापरकर्ता हटवता आला नाही", "unable_to_download_files": "फाईल्स डाउनलोड करता आल्या नाहीत", "unable_to_edit_exclusion_pattern": "वगळणी पॅटर्न संपादित करता आला नाही", - "unable_to_edit_import_path": "आयात मार्ग संपादित करता आला नाही", "unable_to_empty_trash": "ट्रॅश रिकामा करता आला नाही", "unable_to_enter_fullscreen": "फुलस्क्रीन मोडमध्ये जाऊ शकत नाही", "unable_to_exit_fullscreen": "फुलस्क्रीन मोडमधून बाहेर पडता आला नाही", @@ -1137,6 +1154,284 @@ "image_alt_text_date_4_or_more_people": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {person1}, {person2} आणि आणखी {additionalCount, number} जणांसोबत {date} ला घेतले", "image_alt_text_date_place": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {city}, {country} येथे {date} ला घेतले", "image_alt_text_date_place_1_person": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {city}, {country} येथे {person1} सोबत {date} ला घेतले", + "image_alt_text_date_place_2_people": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {city}, {country} येथे {person1} आणि {person2} सोबत {date} रोजी घेतलेला", + "image_alt_text_date_place_3_people": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {city}, {country} येथे {person1}, {person2} आणि {person3} सोबत {date} रोजी घेतलेला", + "image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {व्हिडिओ} other {फोटो}} {city}, {country} येथे {person1}, {person2} आणि इतर {additionalCount, number} जणांसोबत {date} रोजी घेतलेला", + "image_saved_successfully": "प्रतिमा जतन केली", + "image_viewer_page_state_provider_download_started": "डाउनलोड सुरू झाले", + "image_viewer_page_state_provider_download_success": "डाउनलोड यशस्वी झाले", + "image_viewer_page_state_provider_share_error": "शेअर करताना त्रुटी", + "immich_logo": "Immich लोगो", + "immich_web_interface": "Immich वेब इंटरफेस", + "import_from_json": "JSON मधून आयात करा", + "import_path": "इम्पोर्ट पाथ", + "in_albums": "{count, plural, one {# album} other {# albums}} मध्ये", + "in_archive": "आर्काइव्हमध्ये", + "in_year": "{year} मध्ये", + "in_year_selector": "मध्ये", + "include_archived": "आर्काइव्ह केलेले समाविष्ट करा", + "include_shared_albums": "शेअर्ड अल्बम समाविष्ट करा", + "include_shared_partner_assets": "भागीदाराचे शेअर्ड अॅसेट्स समाविष्ट करा", + "individual_share": "वैयक्तिक शेअर", + "individual_shares": "वैयक्तिक शेअर्स", + "info": "माहिती", + "interval": { + "day_at_onepm": "दररोज दुपारी १ वाजता", + "hours": "दर {hours, plural, one {hour} other {{hours, number} hours}}", + "night_at_midnight": "दररोज मध्यरात्री", + "night_at_twoam": "दररोज रात्री २ वाजता" + }, + "invalid_date": "अवैध तारीख", + "invalid_date_format": "अवैध तारीख स्वरूप", + "invite_people": "लोकांना आमंत्रित करा", + "invite_to_album": "अल्बममध्ये आमंत्रित करा", + "ios_debug_info_fetch_ran_at": "फेच {dateTime} ला चालले", + "ios_debug_info_last_sync_at": "शेवटचे समक्रमण {dateTime} ला", + "ios_debug_info_no_processes_queued": "कोणत्याही पार्श्वभूमी प्रक्रिया प्रतीक्षेत नाहीत", + "ios_debug_info_no_sync_yet": "अजून कोणताही पार्श्वभूमी सिंक जॉब चाललेला नाही", + "ios_debug_info_processes_queued": "{count, plural, one {{count} पार्श्वभूमी प्रक्रिया प्रतीक्षेत} other {{count} पार्श्वभूमी प्रक्रिया प्रतीक्षेत}}", + "ios_debug_info_processing_ran_at": "प्रोसेसिंग {dateTime} ला चालले", + "items_count": "{count, plural, one {# आयटम} other {# आयटम} }", + "jobs": "जॉब्स", + "keep": "ठेवा", + "keep_all": "सगळे ठेवा", + "keep_this_delete_others": "हे ठेवा, इतर हटवा", + "kept_this_deleted_others": "हे अॅसेट ठेवले आणि {count, plural, one {इतर # अॅसेट हटवले} other {इतर # अॅसेट्स हटवले}}", + "keyboard_shortcuts": "कीबोर्ड शॉर्टकट्स", + "language": "भाषा", + "language_no_results_subtitle": "तुमचा शोध शब्द बदलून पाहा", + "language_no_results_title": "कोणतीही भाषा सापडली नाही", + "language_search_hint": "भाषा शोधा...", + "language_setting_description": "आपली पसंतीची भाषा निवडा", + "large_files": "मोठ्या फाईल्स", + "last": "शेवटचे", + "last_months": "{count, plural, one {मागील महिना} other {मागील # महिने}}", + "last_seen": "शेवटचे पाहिले", + "latest_version": "नवीनतम आवृत्ती", + "latitude": "अक्षांश", + "leave": "सोडा", + "leave_album": "अल्बम सोडा", + "lens_model": "लेन्स मॉडेल", + "let_others_respond": "इतरांना प्रतिसाद देऊ द्या", + "level": "पातळी", + "library": "लायब्ररी", + "library_add_folder": "फोल्डर जोडा", + "library_edit_folder": "फोल्डर संपादित करा", + "library_options": "लायब्ररी पर्याय", + "library_page_device_albums": "डिव्हाइसवरील अल्बम्स", + "library_page_new_album": "नवीन अल्बम", + "library_page_sort_asset_count": "अॅसेट्सची संख्या", + "library_page_sort_created": "तयार केलेली तारीख", + "library_page_sort_last_modified": "शेवटचा बदल", + "library_page_sort_title": "अल्बमचे शीर्षक", + "licenses": "परवाने", + "light": "लाइट", + "like": "लाईक", + "like_deleted": "लाईक काढून टाकले", + "link_motion_video": "मोशन व्हिडिओ लिंक करा", + "link_to_oauth": "OAuth शी लिंक करा", + "linked_oauth_account": "लिंक केलेले OAuth खाते", + "list": "यादी", + "loading": "लोड होत आहे", + "loading_search_results_failed": "शोध निकाल लोड करण्यात अयशस्वी", + "local": "स्थानिक", + "local_asset_cast_failed": "सर्व्हरवर अपलोड न केलेले अॅसेट कास्ट करू शकत नाही", + "local_assets": "स्थानिक अॅसेट्स", + "local_media_summary": "स्थानिक मीडियाचा सारांश", + "local_network": "स्थानिक नेटवर्क", + "local_network_sheet_info": "दिलेल्या Wi-Fi नेटवर्कवर असताना अॅप या URL द्वारे सर्व्हरशी जोडेल", + "location": "लोकेशन", + "location_permission": "लोकेशन परवानगी", + "location_permission_content": "ऑटो-स्विचिंग फीचर वापरण्यासाठी Immich ला अचूक लोकेशन परवानगी हवी, म्हणजे ते सध्याच्या Wi-Fi नेटवर्कचे नाव वाचू शकेल", + "location_picker_choose_on_map": "नकाशावर निवडा", + "location_picker_latitude_error": "योग्य अक्षांश भरा", + "location_picker_latitude_hint": "येथे तुमचा अक्षांश भरा", + "location_picker_longitude_error": "योग्य रेखांश भरा", + "location_picker_longitude_hint": "येथे तुमचा रेखांश भरा", + "lock": "लॉक", + "locked_folder": "लॉक केलेला फोल्डर", + "log_detail_title": "लॉग तपशील", + "log_out": "लॉग आऊट", + "log_out_all_devices": "सर्व डिव्हाइसवरून लॉग आऊट करा", + "logged_in_as": "{user} म्हणून लॉग इन", + "logged_out_all_devices": "सर्व डिव्हाइसवरून लॉग आऊट झाले", + "logged_out_device": "डिव्हाइसवरून लॉग आऊट झाले", + "login": "लॉगिन", + "login_disabled": "लॉगिन बंद केले आहे", + "login_form_api_exception": "API अपवाद. कृपया सर्व्हर URL तपासा आणि पुन्हा प्रयत्न करा.", + "login_form_back_button_text": "मागे", + "login_form_email_hint": "youremail@email.com", + "login_form_endpoint_hint": "http://तुमचा-सर्व्हर-IP:पोर्ट", + "login_form_endpoint_url": "सर्व्हर एंडपॉइंट URL", + "login_form_err_http": "कृपया http:// किंवा https:// नमूद करा", + "login_form_err_invalid_email": "अवैध ईमेल", + "login_form_err_invalid_url": "अवैध URL", + "login_form_err_leading_whitespace": "सुरुवातीला स्पेस आहे", + "login_form_err_trailing_whitespace": "शेवटी स्पेस आहे", + "login_form_failed_get_oauth_server_config": "OAuth वापरून लॉगिन करताना त्रुटी, सर्व्हर URL तपासा", + "login_form_failed_get_oauth_server_disable": "या सर्व्हरवर OAuth सुविधा उपलब्ध नाही", + "login_form_failed_login": "लॉगिन करताना त्रुटी, सर्व्हर URL, ईमेल आणि पासवर्ड तपासा", + "login_form_handshake_exception": "सर्व्हरसह handshake exception आली. तुम्ही self-signed प्रमाणपत्र वापरत असाल तर सेटिंग्जमध्ये self-signed प्रमाणपत्र समर्थन सक्षम करा.", + "login_form_password_hint": "पासवर्ड", + "login_form_save_login": "लॉगिन ठेवून द्या", + "login_form_server_empty": "सर्व्हर URL भरा.", + "login_form_server_error": "सर्व्हरशी जोडता आले नाही.", + "login_has_been_disabled": "लॉगिन बंद केले आहे.", + "login_password_changed_error": "तुमचा पासवर्ड अपडेट करताना त्रुटी आली", + "login_password_changed_success": "पासवर्ड यशस्वीपणे अपडेट झाला.", + "logout_all_device_confirmation": "तुम्हाला नक्की सर्व डिव्हाइसवरून लॉग आऊट करायचे आहे का?", + "logout_this_device_confirmation": "तुम्हाला नक्की या डिव्हाइसवरून लॉग आऊट करायचे आहे का?", + "logs": "लॉग्स", + "longitude": "रेखांश", + "look": "लूक", + "loop_videos": "व्हिडिओ लूप करा", + "loop_videos_description": "तपशील दृश्यात व्हिडिओ आपोआप लूप होण्यासाठी हे सक्षम करा.", + "main_branch_warning": "तुम्ही development आवृत्ती वापरत आहात; आम्ही ठामपणे release आवृत्ती वापरण्याची शिफारस करतो!", + "main_menu": "मुख्य मेनू", + "maintenance_description": "Immich ला देखभाल मोड मध्ये ठेवले आहे.", + "maintenance_end": "देखभाल मोड समाप्त करा", + "maintenance_end_error": "देखभाल मोड संपवण्यात अयशस्वी.", + "maintenance_logged_in_as": "सध्या {user} म्हणून लॉग इन आहे", + "maintenance_title": "तात्पुरते उपलब्ध नाही", + "make": "तयार करा", + "manage_geolocation": "लोकेशन व्यवस्थापित करा", + "manage_media_access_rationale": "अॅसेट्स कचऱ्यात हलवणे आणि तिथून परत आणणे योग्य प्रकारे हाताळण्यासाठी ही परवानगी आवश्यक आहे.", + "manage_media_access_settings": "सेटिंग्ज उघडा", + "manage_media_access_subtitle": "Immich अॅपला मीडिया फाइल्स व्यवस्थापित व हलवण्याची परवानगी द्या.", + "manage_media_access_title": "मीडिया मॅनेजमेंट प्रवेश", + "manage_shared_links": "शेअर्ड लिंक व्यवस्थापित करा", + "manage_sharing_with_partners": "पार्टनर्ससोबत शेअरींग व्यवस्थापित करा", + "manage_the_app_settings": "अॅप सेटिंग्ज व्यवस्थापित करा", + "manage_your_account": "तुमचे खाते व्यवस्थापित करा", + "manage_your_api_keys": "तुमच्या API कीज व्यवस्थापित करा", + "manage_your_devices": "तुमची लॉगिन असलेली डिव्हाइसेस व्यवस्थापित करा", + "manage_your_oauth_connection": "तुमचे OAuth कनेक्शन व्यवस्थापित करा", + "map": "नकाशा", + "map_assets_in_bounds": "{count, plural, =0 {या भागात कोणतेही फोटो नाहीत} one {# फोटो} other {# फोटो}}", + "map_cannot_get_user_location": "वापरकर्त्याचे लोकेशन मिळू शकले नाही", + "map_location_dialog_yes": "होय", + "map_location_picker_page_use_location": "हे लोकेशन वापरा", + "map_location_service_disabled_content": "सध्याच्या लोकेशनवरील अॅसेट्स दाखवण्यासाठी लोकेशन सेवा सक्षम असणे आवश्यक आहे. तुम्हाला ती आत्ता सक्षम करायची आहे का?", + "map_location_service_disabled_title": "लोकेशन सेवा बंद आहे", + "map_marker_for_images": "{city}, {country} येथे घेतलेल्या प्रतिमांसाठी नकाशा मार्कर", + "map_marker_with_image": "प्रतिमेसह नकाशा मार्कर", + "map_no_location_permission_content": "सध्याच्या लोकेशनवरील अॅसेट्स दाखवण्यासाठी लोकेशन परवानगी आवश्यक आहे. तुम्हाला ती परवानगी आत्ता द्यायची आहे का?", + "map_no_location_permission_title": "लोकेशन परवानगी नाकारली", + "map_settings": "नकाशा सेटिंग्ज", + "map_settings_dark_mode": "डार्क मोड", + "map_settings_date_range_option_day": "मागील २४ तास", + "map_settings_date_range_option_days": "मागील {days} दिवस", + "map_settings_date_range_option_year": "मागील वर्ष", + "map_settings_date_range_option_years": "मागील {years} वर्षे", + "map_settings_dialog_title": "नकाशा सेटिंग्ज", + "map_settings_include_show_archived": "आर्काइव्ह केलेले समाविष्ट करा", + "map_settings_include_show_partners": "पार्टनर्स समाविष्ट करा", + "map_settings_only_show_favorites": "फक्त आवडते दाखवा", + "map_settings_theme_settings": "नकाशा थीम", + "map_zoom_to_see_photos": "फोटो पाहण्यासाठी झूम आउट करा", + "mark_all_as_read": "सर्व वाचले म्हणून चिन्हांकित करा", + "mark_as_read": "वाचले म्हणून चिन्हांकित करा", + "marked_all_as_read": "सर्व वाचले म्हणून चिन्हांकित केले", + "matches": "जुळणारे", + "matching_assets": "जुळणारे अॅसेट्स", + "media_type": "मीडिया प्रकार", + "memories": "आठवणी", + "memories_all_caught_up": "सगळे पाहून झाले", + "memories_check_back_tomorrow": "आणखी आठवणींसाठी उद्या परत पहा", + "memories_setting_description": "आठवणीत काय दिसेल ते व्यवस्थापित करा", + "memories_start_over": "पुन्हा सुरू करा", + "memories_swipe_to_close": "बंद करण्यासाठी वर स्वाइप करा", + "memory": "आठवण", + "memory_lane_title": "मेमरी लेन {title}", + "menu": "मेनू", + "merge": "मर्ज करा", + "merge_people": "लोक मर्ज करा", + "merge_people_limit": "तुम्ही एकावेळी जास्तीत जास्त ५ चेहरेच मर्ज करू शकता", + "merge_people_prompt": "तुम्हाला हे लोक मर्ज करायचे आहेत का? ही क्रिया परत बदलता येणार नाही.", + "merge_people_successfully": "लोक यशस्वीपणे मर्ज केले", + "merged_people_count": "{count, plural, one {# व्यक्ती मर्ज केली} other {# व्यक्ती मर्ज केल्या}}", + "minimize": "मिनिमाईज करा", + "minute": "मिनिट", + "minutes": "मिनिटे", + "missing": "मिसिंग", + "mobile_app": "मोबाईल अॅप", + "mobile_app_download_onboarding_note": "खाली दिलेल्या पर्यायांचा वापर करून साथीदार मोबाईल अॅप डाउनलोड करा", + "model": "मॉडेल", + "month": "महिना", + "monthly_title_text_date_format": "एमएमएमएम वाई", + "more": "अधिक", + "move": "हलवा", + "move_off_locked_folder": "लॉक फोल्डरच्या बाहेर हलवा", + "move_to": "येथे हलवा", + "move_to_lock_folder_action_prompt": "{count} लॉक फोल्डरमध्ये जोडले", + "move_to_locked_folder": "लॉक फोल्डरमध्ये हलवा", + "move_to_locked_folder_confirmation": "हे फोटो आणि व्हिडिओ सर्व अल्बममधून काढले जातील आणि फक्त लॉक फोल्डरमधूनच दिसतील", + "moved_to_archive": "{count, plural, one {# अॅसेट आर्काइव्हमध्ये हलवला} other {# अॅसेट्स आर्काइव्हमध्ये हलवले}}", + "moved_to_library": "{count, plural, one {# अॅसेट लायब्ररीत हलवला} other {# अॅसेट्स लायब्ररीत हलवले}}", + "moved_to_trash": "कचरापेटीत हलवले", + "multiselect_grid_edit_date_time_err_read_only": "फक्त-वाचन (read-only) अॅसेटची तारीख बदलू शकत नाही, वगळत आहोत", + "multiselect_grid_edit_gps_err_read_only": "फक्त-वाचन (read-only) अॅसेटचे लोकेशन बदलू शकत नाही, वगळत आहोत", + "mute_memories": "आठवणी म्यूट करा", + "my_albums": "माझे अल्बम्स", + "name": "नाव", + "name_or_nickname": "नाव किंवा टोपणनाव", + "navigate": "नेव्हिगेट करा", + "navigate_to_time": "वेळेकडे नेव्हिगेट करा", + "network_requirement_photos_upload": "फोटो बॅकअपसाठी सेल्युलर डेटा वापरा", + "network_requirement_videos_upload": "व्हिडिओ बॅकअपसाठी सेल्युलर डेटा वापरा", + "network_requirements": "नेटवर्क आवश्यकता", + "network_requirements_updated": "नेटवर्क आवश्यकता बदलल्या, बॅकअप क्यू रीसेट करत आहोत", + "networking_settings": "नेटवर्किंग", + "networking_subtitle": "सर्व्हर एंडपॉइंट सेटिंग्ज व्यवस्थापित करा", + "never": "कधीच नाही", + "new_album": "नवीन अल्बम", + "new_api_key": "नवीन API की", + "new_date_range": "नवीन तारीख श्रेणी", + "new_password": "नवीन पासवर्ड", + "new_person": "नवीन व्यक्ती", + "new_pin_code": "नवीन PIN कोड", + "new_pin_code_subtitle": "तुम्ही प्रथमच लॉक फोल्डर उघडत आहात. हे पान सुरक्षितपणे उघडण्यासाठी एक PIN कोड तयार करा", + "new_timeline": "नवीन टाइमलाइन", + "new_update": "नवीन अपडेट", + "new_user_created": "नवीन वापरकर्ता तयार झाला", + "new_version_available": "नवीन आवृत्ती उपलब्ध", + "newest_first": "सर्वात नवी प्रथम", + "next": "पुढे", + "next_memory": "पुढील आठवण", + "no": "नाही", + "no_albums_message": "तुमचे फोटो आणि व्हिडिओ व्यवस्थित करण्यासाठी एक अल्बम तयार करा", + "no_albums_with_name_yet": "या नावाचा अजून कोणताही अल्बम नाही असे दिसते.", + "no_albums_yet": "अजून तुमच्याकडे कोणतेही अल्बम नाहीत असे दिसते.", + "no_archived_assets_message": "तुमच्या फोटो दृश्यातून लपवण्यासाठी फोटो आणि व्हिडिओ आर्काइव्ह करा", + "no_assets_message": "तुमचा पहिला फोटो अपलोड करण्यासाठी क्लिक करा", + "no_assets_to_show": "दाखवण्यासाठी कोणतेही अॅसेट नाहीत", + "no_cast_devices_found": "कोणतेही कास्ट डिव्हाइस सापडले नाही", + "no_checksum_local": "चेकसम उपलब्ध नाही — स्थानिक अॅसेट्स आणू शकत नाही", + "no_checksum_remote": "चेकसम उपलब्ध नाही — रिमोट अॅसेट आणू शकत नाही", + "no_devices": "कोणतीही अधिकृत डिव्हाइसेस नाहीत", + "no_duplicates_found": "कोणतेही डुप्लिकेट्स सापडले नाहीत.", + "no_exif_info_available": "EXIF माहिती उपलब्ध नाही", + "no_explore_results_message": "तुमचा संग्रह एक्सप्लोर करण्यासाठी आणखी फोटो अपलोड करा.", + "no_favorites_message": "तुमचे सर्वोत्तम फोटो आणि व्हिडिओ पटकन शोधण्यासाठी त्यांना आवडत्यांत जोडा", + "no_libraries_message": "तुमचे फोटो आणि व्हिडिओ पाहण्यासाठी बाह्य लायब्ररी तयार करा", + "no_local_assets_found": "या चेकसमसह कोणतेही स्थानिक अॅसेट सापडले नाही", + "no_locked_photos_message": "लॉक फोल्डरमधील फोटो आणि व्हिडिओ लपवलेले आहेत आणि लायब्ररी ब्राउज किंवा शोधताना दिसणार नाहीत.", + "no_name": "नाव नाही", + "no_notifications": "कोणत्याही सूचना नाहीत", + "no_people_found": "जुळणारे कोणतेही लोक सापडले नाहीत", + "no_places": "कोणतीही ठिकाणे नाहीत", + "no_remote_assets_found": "या चेकसमसह कोणतेही रिमोट अॅसेट सापडले नाही", + "no_results": "कोणतेही निकाल नाहीत", + "no_results_description": "समार्थक शब्द किंवा अधिक सर्वसाधारण कीवर्ड वापरून पाहा", + "no_shared_albums_message": "तुमच्या नेटवर्कमधील लोकांशी फोटो आणि व्हिडिओ शेअर करण्यासाठी अल्बम तयार करा", + "no_uploads_in_progress": "कोणतेही अपलोड सुरू नाही", + "not_allowed": "परवानगी नाही", + "not_available": "उपलब्ध नाही", + "not_in_any_album": "कोणत्याही अल्बममध्ये नाही", + "not_selected": "निवडलेले नाही", + "note_apply_storage_label_to_previously_uploaded assets": "नोट: आधी अपलोड केलेल्या अॅसेट्सवर स्टोरेज लेबल लागू करण्यासाठी हा आदेश चालवा", + "notes": "नोट्स", + "nothing_here_yet": "इथे अजून काही नाही", "notification_permission_dialog_content": "सूचना सक्षम करण्यासाठी सेटिंग्जमध्ये जा आणि अनुमती द्या.", "notification_permission_list_tile_content": "सूचना सक्षम करण्यासाठी परवानगी द्या.", "notification_permission_list_tile_enable_button": "सूचना सक्षम करा", diff --git a/i18n/ms.json b/i18n/ms.json index c72b1ff688..0491e3953c 100644 --- a/i18n/ms.json +++ b/i18n/ms.json @@ -17,7 +17,6 @@ "add_birthday": "Tambah hari jadi", "add_endpoint": "Tambah titik akhir", "add_exclusion_pattern": "Tambahkan corak pengecualian", - "add_import_path": "Tambahkan laluan import", "add_location": "Tambah lokasi", "add_more_users": "Tambah user lagi", "add_partner": "Tambah rakan", @@ -105,7 +104,6 @@ "jobs_failed": "{jobCount, plural, other {# gagal}}", "library_created": "Pustaka dicipta: {library}", "library_deleted": "Pustaka dipadamkan", - "library_import_path_description": "Tentukan folder untuk diimport. Folder ini, termasuk subfolder, akan diimbas untuk imej dan video.", "library_scanning": "Pengimbasan Berkala", "library_scanning_description": "Konfigurasikan pengimbasan perpustakaan berkala", "library_scanning_enable_description": "Dayakan pengimbasan perpustakaan berkala", diff --git a/i18n/nb_NO.json b/i18n/nb_NO.json index 071dd27a16..4476f905d3 100644 --- a/i18n/nb_NO.json +++ b/i18n/nb_NO.json @@ -17,7 +17,6 @@ "add_birthday": "Legg til bursdag", "add_endpoint": "API endepunkt", "add_exclusion_pattern": "Legg til ekskluderingsmønster", - "add_import_path": "Legg til importsti", "add_location": "Legg til sted", "add_more_users": "Legg til flere brukere", "add_partner": "Legg til partner", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Avhuking for {album}", "add_to_albums": "Legg til i album", "add_to_albums_count": "Legg til i album ({count})", + "add_to_bottom_bar": "Legg til i", "add_to_shared_album": "Legg til delt album", "add_upload_to_stack": "Legg til opplasting i stakken", "add_url": "Legg til URL", @@ -112,13 +112,15 @@ "jobs_failed": "{jobCount, plural, other {# mislyktes}}", "library_created": "Opprettet bibliotek: {library}", "library_deleted": "Bibliotek slettet", - "library_import_path_description": "Spesifiser en mappe for importering. Denne mappen, inkludert undermapper, vil bli skannet for bilder og videoer.", + "library_details": "Bibliotekdetaljer", + "library_remove_folder_prompt": "Er du sikker på at du vil fjerne denne import-mappen?", "library_scanning": "Periodisk skanning", "library_scanning_description": "Konfigurer periodisk skanning av bibliotek", "library_scanning_enable_description": "Aktiver periodisk skanning av bibliotek", "library_settings": "Eksternt bibliotek", "library_settings_description": "Administrer innstillinger for eksterne bibliotek", "library_tasks_description": "Skann eksterne biblioteker for nye og/eller endrede ressurser", + "library_updated": "Oppdatert bibliotek", "library_watching_enable_description": "Overvåk eksterne bibliotek for filendringer", "library_watching_settings": "Overvåkning av bibliotek [EKSPERIMENTELL]", "library_watching_settings_description": "Se automatisk etter endrede filer", @@ -154,9 +156,9 @@ "machine_learning_min_detection_score_description": "Minimum tillitspoeng for at et ansikt skal bli oppdaget, på en skala fra 0 til 1. Lavere verdier vil oppdage flere ansikter, men kan føre til falske positiver.", "machine_learning_min_recognized_faces": "Minimum antall gjenkjente ansikter", "machine_learning_min_recognized_faces_description": "Det minste antallet gjenkjente ansikter som kreves for å opprette en person. Å øke dette gjør ansiktsgjenkjenning mer presis på bekostning av å øke sjansen for at et ansikt ikke tilordnes til en person.", - "machine_learning_ocr": "OCR", + "machine_learning_ocr": "Tekstgjenkjenning", "machine_learning_ocr_description": "Bruk maskinlæring til å gjenkjenne tekst i bilder", - "machine_learning_ocr_enabled": "Aktiver OCR", + "machine_learning_ocr_enabled": "Aktiver tekstgjenkjenning", "machine_learning_ocr_enabled_description": "Hvis deaktivert, vil ikke bilder bli tekstgjenkjent.", "machine_learning_ocr_max_resolution": "Maksimal oppløsning", "machine_learning_ocr_max_resolution_description": "Forhåndsvisninger over denne oppløsningen vil bli endret i størrelse samtidig som sideforholdet bevares. Høyere verdier er mer nøyaktige, men tar lengre tid å behandle og bruker mer minne.", @@ -164,7 +166,7 @@ "machine_learning_ocr_min_detection_score_description": "Minimum konfidenspoeng for at tekst skal kunne oppdages er fra 0–1. Lavere verdier vil oppdage mer tekst, men kan føre til falske positiver.", "machine_learning_ocr_min_recognition_score": "Minste deteksjonspoengsum", "machine_learning_ocr_min_score_recognition_description": "Minste deteksjonspoengsum for at tekst skal bli gjenkjent fra 0-1. Lavere verdier vil gjenkjenne mer tekst, men kan gi falske positiver.", - "machine_learning_ocr_model": "OCR modell", + "machine_learning_ocr_model": "Tekstgjenkjenningsmodell", "machine_learning_ocr_model_description": "Server modeller er mer nøyaktige enn mobilmodeller, men de bruker lengre tid og mer minne.", "machine_learning_settings": "Innstillinger for maskinlæring", "machine_learning_settings_description": "Administrer maskinlæringsfunksjoner og innstillinger", @@ -173,6 +175,9 @@ "machine_learning_smart_search_enabled": "Aktiver smart søk", "machine_learning_smart_search_enabled_description": "Hvis deaktivert, vil bilder ikke bli enkodet for smart søk.", "machine_learning_url_description": "URL til maskinlærings-serveren. Hvis mer enn en URL er lagt inn, hver server vill bli forsøkt en om gangen frem til en svarer suksessfullt, i rekkefølge fra først til sist. Servere som ikke svarer vil midlertidig bli oversett frem til dem svarer igjen.", + "maintenance_settings": "Vedlikehold", + "maintenance_settings_description": "Sett Immich i vedlikeholds modus.", + "maintenance_start": "Start vedlikeholdsmodus", "manage_concurrency": "Administrer samtidighet", "manage_log_settings": "Administrer logginnstillinger", "map_dark_style": "Mørk stil", @@ -475,6 +480,7 @@ "allow_edits": "Tillat redigering", "allow_public_user_to_download": "Tillat uautentiserte brukere å laste ned", "allow_public_user_to_upload": "Tillat uautentiserte brukere å laste opp", + "allowed": "Tillatt", "alt_text_qr_code": "QR-kodebilde", "anti_clockwise": "Mot klokken", "api_key": "API-nøkkel", @@ -894,8 +900,6 @@ "edit_description_prompt": "Vennligst velg en ny beskrivelse:", "edit_exclusion_pattern": "Rediger utelukkelsesmønster", "edit_faces": "Rediger ansikter", - "edit_import_path": "Rediger importsti", - "edit_import_paths": "Rediger importstier", "edit_key": "Rediger nøkkel", "edit_link": "Endre lenke", "edit_location": "Rediger sted", @@ -967,7 +971,6 @@ "failed_to_stack_assets": "Mislyktes med å stable bilder", "failed_to_unstack_assets": "Mislyktes med å avstable bilder", "failed_to_update_notification_status": "Kunne ikke oppdatere varslingsstatusen", - "import_path_already_exists": "Denne importstien eksisterer allerede.", "incorrect_email_or_password": "Feil epost eller passord", "paths_validation_failed": "{paths, plural, one {# sti} other {# sti}} mislyktes validering", "profile_picture_transparent_pixels": "Profil bilde kan ikke ha gjennomsiktige piksler. Vennligst zoom inn og/eller flytt bilde.", @@ -977,7 +980,6 @@ "unable_to_add_assets_to_shared_link": "Kunne ikke legge til bilder til delt lenke", "unable_to_add_comment": "Kunne ikke legge til kommentar", "unable_to_add_exclusion_pattern": "Kunne ikke legge til eksklusjonsmønster", - "unable_to_add_import_path": "Kunne ikke legge til importsti", "unable_to_add_partners": "Kunne ikke legge til partnere", "unable_to_add_remove_archive": "Kunne ikke {archived, select, true {fjerne element fra} other {flytte element til}} arkivet", "unable_to_add_remove_favorites": "Kunne ikke {favorite, select, true {legge til element til} other {fjerne element fra}} favoritter", @@ -1000,12 +1002,10 @@ "unable_to_delete_asset": "Kunne ikke slette filen", "unable_to_delete_assets": "Feil med å slette bilde", "unable_to_delete_exclusion_pattern": "Kunne ikke slette eksklusjonsmønster", - "unable_to_delete_import_path": "Kunne ikke slette importsti", "unable_to_delete_shared_link": "Kunne ikke slette delt lenke", "unable_to_delete_user": "Kunne ikke slette bruker", "unable_to_download_files": "Kunne ikke laste ned filer", "unable_to_edit_exclusion_pattern": "Kunne ikke redigere eksklusjonsmønster", - "unable_to_edit_import_path": "Kunne ikke redigere importsti", "unable_to_empty_trash": "Kunne ikke Tømme papirkurven", "unable_to_enter_fullscreen": "Kunne ikke gå inn i fullskjerm", "unable_to_exit_fullscreen": "Kunne ikke gå ut fra fullskjerm", @@ -1196,6 +1196,8 @@ "import_path": "Import-sti", "in_albums": "I {count, plural, one {# album} other {# albums}}", "in_archive": "I arkiv", + "in_year": "Om {year}", + "in_year_selector": "Om", "include_archived": "Inkluder arkiverte", "include_shared_albums": "Inkluder delte album", "include_shared_partner_assets": "Inkluder delte partnerfiler", @@ -1232,6 +1234,7 @@ "language_setting_description": "Velg ditt foretrukne språk", "large_files": "Store Filer", "last": "Siste", + "last_months": "{count, plural, one {sist måned} other {siste # måned}}", "last_seen": "Sist sett", "latest_version": "Siste versjon", "latitude": "Breddegrad", @@ -1314,6 +1317,10 @@ "main_menu": "Hovedmeny", "make": "Merke", "manage_geolocation": "Administrer plassering", + "manage_media_access_rationale": "Denne tillatelsen er nødvendig for riktig håndtering av flytting av objekter til papirkurven og gjenoppretting av dem fra den.", + "manage_media_access_settings": "Åpne innstillinger", + "manage_media_access_subtitle": "Tillatt Immich appen å håndtere og flytte mediefiler.", + "manage_media_access_title": "Media håndteringstilgang", "manage_shared_links": "Håndter delte linker", "manage_sharing_with_partners": "Administrer deling med partnere", "manage_the_app_settings": "Administrer appinnstillingene", @@ -1406,6 +1413,7 @@ "new_pin_code": "Ny PIN-kode", "new_pin_code_subtitle": "Dette er første gang du åpner den låste mappen. Lag en PIN-kode for å sikre tilgangen til denne siden", "new_timeline": "Ny tidslinje", + "new_update": "Ny oppdatering", "new_user_created": "Ny bruker opprettet", "new_version_available": "NY VERSJON TILGJENGELIG", "newest_first": "Nyeste først", @@ -1421,6 +1429,7 @@ "no_cast_devices_found": "Ingen caste-enheter oppdaget", "no_checksum_local": "Ingen sjekksum tilgjengelig - Kunne ikke hente lokale elementer", "no_checksum_remote": "Ingen sjekksum tilgjengelig - Kunne ikke hente eksterne elementer", + "no_devices": "Ingen autoriserte enheter", "no_duplicates_found": "Ingen duplikater ble funnet.", "no_exif_info_available": "Ingen EXIF-informasjon tilgjengelig", "no_explore_results_message": "Last opp flere bilder for å utforske samlingen din.", @@ -1437,6 +1446,7 @@ "no_results_description": "Prøv et synonym eller mer generelt søkeord", "no_shared_albums_message": "Opprett et album for å dele bilder og videoer med personer i nettverket ditt", "no_uploads_in_progress": "Ingen opplasting pågår", + "not_allowed": "Ikke tillatt", "not_available": "Ikke tilgjengelig", "not_in_any_album": "Ikke i noe album", "not_selected": "Ikke valgt", @@ -1453,7 +1463,7 @@ "oauth": "OAuth", "obtainium_configurator": "Obtainium konfigurator", "obtainium_configurator_instructions": "Bruk Obtainium for å installere og oppdatere Android appen direkte fra Immich sin Github utgivelse. Opprett en API nøkkel og velg en variant for å lage din Obtainium konfigurasjonslink", - "ocr": "OCR", + "ocr": "Tekstgjenkjenning", "official_immich_resources": "Offisielle Immich-ressurser", "offline": "Frakoblet", "offset": "Forskyving", @@ -1547,6 +1557,8 @@ "photos_count": "{count, plural, one {{count, number} Bilde} other {{count, number} Bilder}}", "photos_from_previous_years": "Bilder fra tidliger år", "pick_a_location": "Velg et sted", + "pick_custom_range": "Tilpasset område", + "pick_date_range": "Velg ett datoområde", "pin_code_changed_successfully": "Endring av PIN kode vellykket", "pin_code_reset_successfully": "Vellykket resatt PIN kode", "pin_code_setup_successfully": "Vellykket oppsett av PIN kode", @@ -1752,7 +1764,7 @@ "search_filter_location_title": "Velg lokasjon", "search_filter_media_type": "Medietype", "search_filter_media_type_title": "Velg medietype", - "search_filter_ocr": "Søk med OCR", + "search_filter_ocr": "Søk etter tekst i bilde", "search_filter_people_title": "Velg mennesker", "search_for": "Søk etter", "search_for_existing_person": "Søk etter eksisterende person", @@ -2027,6 +2039,7 @@ "third_party_resources": "Tredjeparts Ressurser", "time": "Tid", "time_based_memories": "Tidsbaserte minner", + "time_based_memories_duration": "Antall sekunder å vise hvert bilde.", "timeline": "Tidslinje", "timezone": "Tidssone", "to_archive": "Arkiv", diff --git a/i18n/nl.json b/i18n/nl.json index 62be7e4a15..12d99f18da 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -17,7 +17,6 @@ "add_birthday": "Voeg een verjaardag toe", "add_endpoint": "Server toevoegen", "add_exclusion_pattern": "Uitsluitingspatroon toevoegen", - "add_import_path": "Import-pad toevoegen", "add_location": "Locatie toevoegen", "add_more_users": "Meer gebruikers toevoegen", "add_partner": "Partner toevoegen", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Selectie inschakelen voor {album}", "add_to_albums": "Toevoegen aan albums", "add_to_albums_count": "Toevoegen aan albums ({count})", + "add_to_bottom_bar": "Toevoegen aan", "add_to_shared_album": "Aan gedeeld album toevoegen", "add_upload_to_stack": "Voeg upload toe aan stack", "add_url": "URL toevoegen", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# mislukt}}", "library_created": "Bibliotheek aangemaakt: {library}", "library_deleted": "Bibliotheek verwijderd", - "library_import_path_description": "Voer een map in om te importeren. Deze map, inclusief submappen, wordt gescand op afbeeldingen en video's.", + "library_details": "Bibliotheek details", + "library_folder_description": "Kies een map om te importeren. Deze map, waaronder subfolders, zal gescand worden voor afbeeldingen en video's.", + "library_remove_exclusion_pattern_prompt": "Weet je zeker dat je dit uitsluitingspatroon wilt verwijderen?", + "library_remove_folder_prompt": "Weet je zeker dat je deze importeer map wilt verwijderen?", "library_scanning": "Periodiek scannen", "library_scanning_description": "Periodieke bibliotheekscan beheren", "library_scanning_enable_description": "Periodieke bibliotheekscan aanzetten", "library_settings": "Externe bibliotheek", "library_settings_description": "Externe bibliotheekinstellingen beheren", "library_tasks_description": "Scan externe bibliotheken op nieuwe en/of gewijzigde media", + "library_updated": "Bijgewerkte bibliotheek", "library_watching_enable_description": "Externe bibliotheken monitoren op bestandswijzigingen", "library_watching_settings": "Bibliotheek monitoren [EXPERIMENTEEL]", "library_watching_settings_description": "Automatisch gewijzigde bestanden bijhouden", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Slim zoeken inschakelen", "machine_learning_smart_search_enabled_description": "Indien uitgeschakeld, worden afbeeldingen niet verwerkt voor slim zoeken.", "machine_learning_url_description": "De URL van de machine learning server. Als er meer dan één URL is opgegeven, wordt elke server geprobeerd totdat er een succesvol reageert, op volgorde van eerste tot laatste. Servers die geen reactie geven zullen tijdelijk genegeerd worden tot zij terug online komen.", + "maintenance_settings": "Onderhoud", + "maintenance_settings_description": "Zet Immich in onderhouds­modus.", + "maintenance_start": "Onderhouds­modus starten", + "maintenance_start_error": "Onderhouds­modus starten mislukt.", "manage_concurrency": "Beheer gelijktijdigheid", "manage_log_settings": "Beheer logboekinstellingen", "map_dark_style": "Donkere stijl", @@ -430,6 +438,7 @@ "age_months": "Leeftijd {months, plural, one {# maand} other {# maanden}}", "age_year_months": "Leeftijd 1 jaar, {months, plural, one {# maand} other {# maanden}}", "age_years": "{years, plural, other {Leeftijd #}}", + "album": "Album", "album_added": "Album toegevoegd", "album_added_notification_setting_description": "Ontvang een e-mailmelding wanneer je aan een gedeeld album wordt toegevoegd", "album_cover_updated": "Albumomslag is bijgewerkt", @@ -475,6 +484,7 @@ "allow_edits": "Bewerkingen toestaan", "allow_public_user_to_download": "Sta openbare gebruiker toe om te downloaden", "allow_public_user_to_upload": "Sta openbare gebruiker toe om te uploaden", + "allowed": "Toegestaan", "alt_text_qr_code": "QR-codeafbeelding", "anti_clockwise": "Linksom", "api_key": "API-sleutel", @@ -558,7 +568,7 @@ "autoplay_slideshow": "Diavoorstelling automatisch afspelen", "back": "Terug", "back_close_deselect": "Terug, sluiten of deselecteren", - "background_backup_running_error": "Achtergrond backup draait, handmatige backup kan niet worden gestart", + "background_backup_running_error": "Back-up draait op de achtergrond, handmatige back-up kan niet worden gestart", "background_location_permission": "Achtergrond locatie toestemming", "background_location_permission_content": "Om van netwerk te wisselen terwijl de app op de achtergrond draait, heeft Immich *altijd* toegang tot de exacte locatie nodig om de naam van het WiFi-netwerk te kunnen lezen", "background_options": "Achtergrond opties", @@ -639,7 +649,7 @@ "birthdate_set_description": "De geboortedatum wordt gebruikt om de leeftijd van deze persoon op het moment van de foto te berekenen.", "blurred_background": "Vervaagde achtergrond", "bugs_and_feature_requests": "Bugs & functieverzoeken", - "build": "Bouwen", + "build": "Build", "build_image": "Build image", "bulk_delete_duplicates_confirmation": "Weet je zeker dat je {count, plural, one {# dubbel item} other {# dubbele items}} in bulk wilt verwijderen? Dit zal de grootste item van elke groep behouden en alle andere duplicaten permanent verwijderen. Je kunt deze actie niet ongedaan maken!", "bulk_keep_duplicates_confirmation": "Weet je zeker dat je {count, plural, one {# dubbel item} other {# dubbele items}} wilt behouden? Dit zal alle groepen met duplicaten oplossen zonder iets te verwijderen.", @@ -790,7 +800,8 @@ "daily_title_text_date": "E dd MMM", "daily_title_text_date_year": "E dd MMM yyyy", "dark": "Donker", - "dark_theme": "Wissel naar donker thema", + "dark_theme": "Donker thema in- of uitschakelen", + "date": "Datum", "date_after": "Datum na", "date_and_time": "Datum en tijd", "date_before": "Datum voor", @@ -893,8 +904,6 @@ "edit_description_prompt": "Selecteer een nieuwe beschrijving:", "edit_exclusion_pattern": "Uitsluitingspatroon bewerken", "edit_faces": "Gezichten bewerken", - "edit_import_path": "Import-pad bewerken", - "edit_import_paths": "Import-paden bewerken", "edit_key": "Key bewerken", "edit_link": "Link bewerken", "edit_location": "Locatie bewerken", @@ -966,8 +975,8 @@ "failed_to_stack_assets": "Fout bij stapelen van items", "failed_to_unstack_assets": "Fout bij ontstapelen van items", "failed_to_update_notification_status": "Kon notificatiestatus niet updaten", - "import_path_already_exists": "Dit import-pad bestaat al.", "incorrect_email_or_password": "Onjuist e-mailadres of wachtwoord", + "library_folder_already_exists": "Dit importpad bestaat al.", "paths_validation_failed": "validatie van {paths, plural, one {# pad} other {# paden}} mislukt", "profile_picture_transparent_pixels": "Profielfoto's kunnen geen transparante pixels bevatten. Zoom in en/of verplaats de afbeelding.", "quota_higher_than_disk_size": "Je hebt een opslaglimiet ingesteld die hoger is dan de schijfgrootte", @@ -976,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Kan items niet aan gedeelde link toevoegen", "unable_to_add_comment": "Kan geen opmerking toevoegen", "unable_to_add_exclusion_pattern": "Kan geen uitsluitingspatroon toevoegen", - "unable_to_add_import_path": "Kan geen import-pad toevoegen", "unable_to_add_partners": "Kan geen partners toevoegen", "unable_to_add_remove_archive": "Kan items niet {archived, select, true {verwijderen uit} other {toevoegen aan}} archief", "unable_to_add_remove_favorites": "Kan items niet {favorite, select, true {toevoegen aan} other {verwijderen uit}} favorieten", @@ -999,12 +1007,10 @@ "unable_to_delete_asset": "Kan item niet verwijderen", "unable_to_delete_assets": "Fout bij verwijderen items", "unable_to_delete_exclusion_pattern": "Kan uitsluitingspatroon niet verwijderen", - "unable_to_delete_import_path": "Kan import-pad niet verwijderen", "unable_to_delete_shared_link": "Kan gedeelde link niet verwijderen", "unable_to_delete_user": "Kan gebruiker niet verwijderen", "unable_to_download_files": "Kan bestanden niet downloaden", "unable_to_edit_exclusion_pattern": "Kan uitsluitingspatroon niet bewerken", - "unable_to_edit_import_path": "Kan import-pad niet bewerken", "unable_to_empty_trash": "Kan prullenbak niet legen", "unable_to_enter_fullscreen": "Kan volledig scherm niet openen", "unable_to_exit_fullscreen": "Kan volledig scherm niet afsluiten", @@ -1055,6 +1061,7 @@ "unable_to_update_user": "Kan gebruiker niet bijwerken", "unable_to_upload_file": "Kan bestand niet uploaden" }, + "exclusion_pattern": "Uitsluitingspatroon", "exif": "Exif", "exif_bottom_sheet_description": "Beschrijving toevoegen...", "exif_bottom_sheet_description_error": "Fout bij het bijwerken van de beschrijving", @@ -1099,6 +1106,7 @@ "features_setting_description": "Beheer de app functies", "file_name": "Bestandsnaam", "file_name_or_extension": "Bestandsnaam of extensie", + "file_size": "Bestandsgrootte", "filename": "Bestandsnaam", "filetype": "Bestandstype", "filter": "Filter", @@ -1194,6 +1202,8 @@ "import_path": "Import-pad", "in_albums": "In {count, plural, one {# album} other {# albums}}", "in_archive": "In archief", + "in_year": "In {year}", + "in_year_selector": "In", "include_archived": "Toon gearchiveerde", "include_shared_albums": "Toon gedeelde albums", "include_shared_partner_assets": "Toon items van gedeelde partner", @@ -1230,6 +1240,7 @@ "language_setting_description": "Selecteer je voorkeurstaal", "large_files": "Grote bestanden", "last": "Laatste", + "last_months": "{count, plural, one {Vorige maand} other {Laatste # maanden}}", "last_seen": "Laatst gezien", "latest_version": "Nieuwste versie", "latitude": "Breedtegraad", @@ -1239,6 +1250,8 @@ "let_others_respond": "Laat anderen reageren", "level": "Niveau", "library": "Bibliotheek", + "library_add_folder": "Map toevoegen", + "library_edit_folder": "Map bewerken", "library_options": "Bibliotheek opties", "library_page_device_albums": "Albums op apparaat", "library_page_new_album": "Nieuw album", @@ -1262,6 +1275,7 @@ "local_media_summary": "Lokale media samenvatting", "local_network": "Lokaal netwerk", "local_network_sheet_info": "De app maakt verbinding met de server via deze URL wanneer het opgegeven WiFi-netwerk wordt gebruikt", + "location": "Locatie", "location_permission": "Locatietoestemming", "location_permission_content": "Om de functie voor automatische serverwissel te gebruiken, heeft Immich toegang tot de exacte locatie nodig om de naam van het huidige WiFi-netwerk te kunnen bepalen", "location_picker_choose_on_map": "Kies op kaart", @@ -1309,8 +1323,17 @@ "loop_videos_description": "Inschakelen om video's automatisch te herhalen in de detailweergave.", "main_branch_warning": "Je gebruikt een ontwikkelingsversie. We raden je ten zeerste aan een releaseversie te gebruiken!", "main_menu": "Hoofdmenu", + "maintenance_description": "Immich is in de onderhouds­modus gezet.", + "maintenance_end": "Onderhouds­modus beëindigen", + "maintenance_end_error": "Onderhouds­modus beëindigen mislukt.", + "maintenance_logged_in_as": "Momenteel ingelogd als {user}", + "maintenance_title": "Tijdelijk niet beschikbaar", "make": "Merk", "manage_geolocation": "Beheer locatie", + "manage_media_access_rationale": "Deze rechten zijn nodig om items op een goede manier te verwijderen en te verplaatsen.", + "manage_media_access_settings": "Open instellingen", + "manage_media_access_subtitle": "Toestaan dat de Immich app mediabestanden mag beheren en verplaatsen.", + "manage_media_access_title": "Toegang tot mediabeheer", "manage_shared_links": "Beheer gedeelde links", "manage_sharing_with_partners": "Beheer delen met partners", "manage_the_app_settings": "Beheer de appinstellingen", @@ -1374,6 +1397,7 @@ "more": "Meer", "move": "Verplaats", "move_off_locked_folder": "Verplaats uit vergrendelde map", + "move_to": "Verplaatsen naar", "move_to_lock_folder_action_prompt": "{count} item(s) toegevoegd aan de vergrendelde map", "move_to_locked_folder": "Verplaats naar vergrendelde map", "move_to_locked_folder_confirmation": "Deze foto’s en video’s worden uit alle albums verwijderd en zijn alleen te bekijken in de vergrendelde map", @@ -1403,6 +1427,7 @@ "new_pin_code": "Nieuwe pincode", "new_pin_code_subtitle": "Dit is de eerste keer dat u de vergrendelde map opent. Stel een pincode in om deze pagina veilig te openen", "new_timeline": "Nieuwe tijdlijn", + "new_update": "Nieuwe update", "new_user_created": "Nieuwe gebruiker aangemaakt", "new_version_available": "NIEUWE VERSIE BESCHIKBAAR", "newest_first": "Nieuwste eerst", @@ -1418,6 +1443,7 @@ "no_cast_devices_found": "Geen cast-apparaten gevonden", "no_checksum_local": "Geen checksum beschikbaar - kan lokale assets niet ophalen", "no_checksum_remote": "Geen checksum beschikbaar - kan online assets niet ophalen", + "no_devices": "Geen geautoriseerde apparaten", "no_duplicates_found": "Er zijn geen duplicaten gevonden.", "no_exif_info_available": "Geen exif info beschikbaar", "no_explore_results_message": "Upload meer foto's om je verzameling te verkennen.", @@ -1434,6 +1460,7 @@ "no_results_description": "Probeer een synoniem of een algemener zoekwoord", "no_shared_albums_message": "Maak een album om foto's en video's te delen met mensen in je netwerk", "no_uploads_in_progress": "Geen uploads bezig", + "not_allowed": "Niet toegestaan", "not_available": "n.v.t.", "not_in_any_album": "Niet in een album", "not_selected": "Niet geselecteerd", @@ -1544,6 +1571,8 @@ "photos_count": "{count, plural, one {{count, number} foto} other {{count, number} foto's}}", "photos_from_previous_years": "Foto's van voorgaande jaren", "pick_a_location": "Kies een locatie", + "pick_custom_range": "Aangepast bereik", + "pick_date_range": "Selecteer een datumbereik", "pin_code_changed_successfully": "Pincode succesvol gewijzigd", "pin_code_reset_successfully": "Pincode succesvol gereset", "pin_code_setup_successfully": "Pincode succesvol ingesteld", @@ -1694,6 +1723,7 @@ "reset_sqlite_confirmation": "Ben je zeker dat je de SQLite database wilt resetten? Je zal moeten uitloggen om de data opnieuw te synchroniseren", "reset_sqlite_success": "De SQLite database is succesvol gereset", "reset_to_default": "Resetten naar standaard", + "resolution": "Resolutie", "resolve_duplicates": "Duplicaten oplossen", "resolved_all_duplicates": "Alle duplicaten opgelost", "restore": "Herstellen", @@ -1712,6 +1742,7 @@ "running": "Actief", "save": "Opslaan", "save_to_gallery": "Opslaan in galerij", + "saved": "Opgeslagen", "saved_api_key": "API-sleutel opgeslagen", "saved_profile": "Profiel opgeslagen", "saved_settings": "Instellingen opgeslagen", @@ -1809,6 +1840,8 @@ "server_offline": "Server offline", "server_online": "Server online", "server_privacy": "Serverprivacy", + "server_restarting_description": "Deze pagina wordt zometeen ververst.", + "server_restarting_title": "Server is aan het herstarten", "server_stats": "Serverstatistieken", "server_update_available": "Server update is beschikbaar", "server_version": "Serverversie", @@ -2020,7 +2053,9 @@ "theme_setting_three_stage_loading_title": "Laden in drie fasen inschakelen", "they_will_be_merged_together": "Zij zullen worden samengevoegd", "third_party_resources": "Bronnen van derden", + "time": "Tijd", "time_based_memories": "Tijdgebaseerde herinneringen", + "time_based_memories_duration": "Aantal seconden dat elke afbeelding wordt weergegeven.", "timeline": "Tijdlijn", "timezone": "Tijdzone", "to_archive": "Archiveren", @@ -2128,7 +2163,7 @@ "variables": "Variabelen", "version": "Versie", "version_announcement_closing": "Je vriend, Alex", - "version_announcement_message": "Hallo! Er is een nieuwe versie van Immich beschikbaar. Neem even de tijd om de release notes te lezen en zorg ervoor dat je setup up-to-date is om misconfiguraties te voorkomen, vooral als je WatchTower of een andere update-mechanisme gebruikt.", + "version_announcement_message": "Hallo! Er is een nieuwe versie van Immich beschikbaar. Neem even de tijd om de release notes te lezen en zorg ervoor dat je setup up-to-date is om misconfiguraties te voorkomen, vooral als je WatchTower of een ander update-mechanisme gebruikt.", "version_history": "Versiegeschiedenis", "version_history_item": "{version} geïnstalleerd op {date}", "video": "Video", @@ -2161,6 +2196,7 @@ "welcome": "Welkom", "welcome_to_immich": "Welkom bij Immich", "wifi_name": "WiFi-naam", + "workflow": "Workflow", "wrong_pin_code": "Onjuiste pincode", "year": "Jaar", "years_ago": "{years, plural, one {# jaar} other {# jaar}} geleden", diff --git a/i18n/nn.json b/i18n/nn.json index 2cfb31bede..b9a59c8d78 100644 --- a/i18n/nn.json +++ b/i18n/nn.json @@ -17,7 +17,6 @@ "add_birthday": "Legg til ein fødselsdag", "add_endpoint": "Legg til endepunkt", "add_exclusion_pattern": "Legg til unnlatingsmønster", - "add_import_path": "Legg til sti for importering", "add_location": "Legg til stad", "add_more_users": "Legg til fleire brukarar", "add_partner": "Legg til partnar", @@ -109,7 +108,6 @@ "jobs_failed": "{jobCount, plural, other {# mislykkast}}", "library_created": "Opprett bibliotek: {library}", "library_deleted": "Bibliotek sletta", - "library_import_path_description": "Angje ei mappe å importere. Mappa, inkludert undermapper, bli skanna for bilete og videoar.", "library_scanning": "Regelbunden skanning", "library_scanning_description": "Sett opp regelbunden skanning av biblioteket", "library_scanning_enable_description": "Aktiver regelbunden skanning av biblioteket", diff --git a/i18n/pa.json b/i18n/pa.json index 0801a54351..52b1430134 100644 --- a/i18n/pa.json +++ b/i18n/pa.json @@ -15,7 +15,6 @@ "add_birthday": "ਜਨਮਦਿਨ ਸ਼ਾਮਲ ਕਰੋ", "add_endpoint": "ਐਂਡਪੁਆਇੰਟ ਸ਼ਾਮਲ ਕਰੋ", "add_exclusion_pattern": "ਅਲਹਿਦਗੀ ਪੈਟਰਨ ਸ਼ਾਮਲ ਕਰੋ", - "add_import_path": "ਆਯਾਤ ਮਾਰਗ ਸ਼ਾਮਲ ਕਰੋ", "add_location": "ਸਥਾਨ ਸ਼ਾਮਲ ਕਰੋ", "add_more_users": "ਹੋਰ ਉਪਭੋਗਤਾ ਸ਼ਾਮਲ ਕਰੋ" } diff --git a/i18n/pl.json b/i18n/pl.json index 8bbefef148..443b807115 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -17,7 +17,6 @@ "add_birthday": "Dodaj datę urodzin", "add_endpoint": "Dodaj punkt końcowy", "add_exclusion_pattern": "Dodaj wzór wykluczający", - "add_import_path": "Dodaj ścieżkę importu", "add_location": "Dodaj lokalizację", "add_more_users": "Dodaj więcej użytkowników", "add_partner": "Dodaj partnera", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Przełącz wybieranie dla {album}", "add_to_albums": "Dodaj do albumów", "add_to_albums_count": "Dodaj do albumów ({count})", + "add_to_bottom_bar": "Dodaj do", "add_to_shared_album": "Dodaj do udostępnionego albumu", "add_upload_to_stack": "Dodaj przesłane do stosu", "add_url": "Dodaj URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, one {# nieudany} few {# nieudane} other {# nieudanych}}", "library_created": "Utworzono bibliotekę: {library}", "library_deleted": "Biblioteka usunięta", - "library_import_path_description": "Określ folder do załadowania plików. Ten folder, łącznie z podfolderami, zostanie przeskanowany w poszukiwaniu obrazów i filmów.", + "library_details": "Szczegóły biblioteki", + "library_folder_description": "Wskaż folder do zaimportowania. Ten folder, wraz z podfolderami, zostanie przeskanowany w poszukiwaniu obrazów i filmów.", + "library_remove_exclusion_pattern_prompt": "Czy na pewno chcesz usunąć ten szablon wykluczeń?", + "library_remove_folder_prompt": "Czy na pewno chcesz usunąć ten folder importu?", "library_scanning": "Okresowe Skanowanie", "library_scanning_description": "Skonfiguruj okresowe skanowania bibliotek", "library_scanning_enable_description": "Włącz okresowe skanowanie bibliotek", "library_settings": "Zewnętrzne Biblioteki", "library_settings_description": "Zarządzaj ustawieniami zewnętrznych bibliotek", "library_tasks_description": "Wyszukiwanie nowych lub zmienionych pozycji w zewnętrznych bibliotekach", + "library_updated": "Zaktualizowana biblioteka", "library_watching_enable_description": "Przejrzyj zewnętrzne biblioteki w poszukiwaniu zmienionych plików", "library_watching_settings": "Obserwowanie bibliotek [EKSPERYMENTALNE]", "library_watching_settings_description": "Automatycznie obserwuj zmienione pliki", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Włącz inteligentne wyszukiwanie", "machine_learning_smart_search_enabled_description": "Jeżeli wyłączone, obrazy nie będą przygotowywane do inteligentnego wyszukiwania.", "machine_learning_url_description": "URL serwera uczenia maszynowego. Jeżeli podano więcej niż jeden URL, do każdego serwera po kolei będzie wysłane żądanie dopóki chociaż jeden nie odpowie, w kolejności od pierwszego do ostatniego. Serwery które nie odpowiedzą, zostaną tymczasowo ignorowane aż do momentu ich przejścia w stan online.", + "maintenance_settings": "Konserwacja", + "maintenance_settings_description": "Przełącza Immich w tryb konserwacji.", + "maintenance_start": "Uruchom tryb konserwacji", + "maintenance_start_error": "Nie udało się uruchomić trybu konserwacji.", "manage_concurrency": "Zarządzaj współbieżnością zadań", "manage_log_settings": "Zarządzaj ustawieniami logów", "map_dark_style": "Styl ciemny", @@ -430,6 +438,7 @@ "age_months": "Wiek {months, plural, one {# miesiąc} few {# miesiące} many {# miesięcy} other {# miesięcy}}", "age_year_months": "Wiek 1 rok, {months, plural, one {# miesiąc} few {# miesiące} many {# miesięcy} other {# miesięcy}}", "age_years": "{years, plural, other {Wiek #}}", + "album": "Album", "album_added": "Album udostępniony", "album_added_notification_setting_description": "Otrzymaj powiadomienie email, gdy zostanie Ci udostępniony album", "album_cover_updated": "Okładka albumu została zaktualizowana", @@ -475,6 +484,7 @@ "allow_edits": "Pozwól edytować", "allow_public_user_to_download": "Zezwól użytkownikowi publicznemu na pobieranie", "allow_public_user_to_upload": "Zezwól użytkownikowi publicznemu na przesyłanie plików", + "allowed": "Dozwolone", "alt_text_qr_code": "Obrazek kodu QR", "anti_clockwise": "Przeciwnie do ruchu wskazówek zegara", "api_key": "Klucz API", @@ -894,8 +904,6 @@ "edit_description_prompt": "Wybierz nowy opis:", "edit_exclusion_pattern": "Edytuj wzór wykluczający", "edit_faces": "Edytuj twarze", - "edit_import_path": "Edytuj ścieżkę importu", - "edit_import_paths": "Edytuj ścieżki importu", "edit_key": "Edytuj klucz", "edit_link": "Edytuj link", "edit_location": "Edytuj lokalizację", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Nie udało się utworzyć stosu z zasobów", "failed_to_unstack_assets": "Nie udało się rozdzielić zasobów", "failed_to_update_notification_status": "Nie udało się zaktualizować stanu powiadomienia", - "import_path_already_exists": "Ta ścieżka importu już istnieje.", "incorrect_email_or_password": "Nieprawidłowy e-mail lub hasło", + "library_folder_already_exists": "Ta ścieżka importu już istnieje.", "paths_validation_failed": "{paths, plural, one {# ścieżka} few {# ścieżki} other {# ścieżek}}", "profile_picture_transparent_pixels": "Zdjęcia profilowe nie mogą mieć przezroczystych pikseli. Powiększ i/lub przesuń obraz.", "quota_higher_than_disk_size": "Ustawiony przez ciebie limit większy niż rozmiar dysku", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Nie można dodać zasobów do udostępnionego linku", "unable_to_add_comment": "Nie można dodać komentarza", "unable_to_add_exclusion_pattern": "Nie można dodać wzoru wykluczającego", - "unable_to_add_import_path": "Nie można dodać ścieżki importu", "unable_to_add_partners": "Nie można dodać partnerów", "unable_to_add_remove_archive": "Nie można {archived, select, true {usunąć zasobu z} other {dodać zasobu do}} archiwum", "unable_to_add_remove_favorites": "Nie można {favorite, select, true {dodać zasobu do} other {usunąć zasobu z }} ulubionych", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Nie można usunąć zasobu", "unable_to_delete_assets": "Błąd podczas usuwania zasobów", "unable_to_delete_exclusion_pattern": "Nie można usunąć wzoru wykluczającego", - "unable_to_delete_import_path": "Nie można usunąć ścieżki importu", "unable_to_delete_shared_link": "Nie można usunąć udostępnionego linku", "unable_to_delete_user": "Nie można usunąć użytkownika", "unable_to_download_files": "Nie można pobrać plików", "unable_to_edit_exclusion_pattern": "Nie można zmienić wzoru wykluczającego", - "unable_to_edit_import_path": "Nie można edytować ścieżki importu", "unable_to_empty_trash": "Nie można opróżnić kosza", "unable_to_enter_fullscreen": "Nie można przejść na pełny ekran", "unable_to_exit_fullscreen": "Nie można wyjść z pełnego ekranu", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Nie można zmienić użytkownika", "unable_to_upload_file": "Nie można przesłać pliku" }, + "exclusion_pattern": "Szablon wykluczeń", "exif": "Metadane EXIF", "exif_bottom_sheet_description": "Dodaj Opis...", "exif_bottom_sheet_description_error": "Wystąpił błąd podczas aktualizacji opisu", @@ -1196,6 +1202,8 @@ "import_path": "Ścieżka importu", "in_albums": "W {count, plural, one {# albumie} other {# albumach}}", "in_archive": "W archiwum", + "in_year": "W {year}", + "in_year_selector": "W", "include_archived": "Uwzględnij zarchiwizowane", "include_shared_albums": "Uwzględnij udostępnione albumy", "include_shared_partner_assets": "Uwzględnij udostępnione zasoby partnera", @@ -1232,6 +1240,7 @@ "language_setting_description": "Wybierz swój preferowany język", "large_files": "Duże pliki", "last": "Ostatni", + "last_months": "{count, plural, one {Zeszły miesiąc} few {# zeszłe miesiące} other {# zeszłych miesięcy}}", "last_seen": "Ostatnio widziane", "latest_version": "Najnowsza wersja", "latitude": "Szerokość geograficzna", @@ -1241,6 +1250,8 @@ "let_others_respond": "Pozwól innym reagować", "level": "Poziom", "library": "Biblioteka", + "library_add_folder": "Dodaj folder", + "library_edit_folder": "Edytuj folder", "library_options": "Opcje biblioteki", "library_page_device_albums": "Albumy na Urządzeniu", "library_page_new_album": "Nowy album", @@ -1312,8 +1323,17 @@ "loop_videos_description": "Włącz automatyczne odtwarzanie w pętli filmu w widoku szczegółowym.", "main_branch_warning": "Używasz wersji deweloperskiej. Zdecydowanie zalecamy korzystanie z wydanej wersji aplikacji!", "main_menu": "Menu główne", + "maintenance_description": "Immich został przełączony w tryb konserwacji.", + "maintenance_end": "Zakończ tryb konserwacji", + "maintenance_end_error": "Nie udało się zakończyć trybu konserwacji.", + "maintenance_logged_in_as": "Obecnie zalogowano jako {user}", + "maintenance_title": "Tymczasowo niedostępne", "make": "Marka", "manage_geolocation": "Zarządzaj lokalizacją", + "manage_media_access_rationale": "To uprawnienie jest wymagane do prawidłowej obsługi przenoszenia zasobów do kosza i przywracania ich z niego.", + "manage_media_access_settings": "Otwórz ustawienia", + "manage_media_access_subtitle": "Zezwól aplikacji Immich na zarządzanie plikami multimedialnymi i przenoszenie ich.", + "manage_media_access_title": "Dostęp do zarządzania mediami", "manage_shared_links": "Zarządzaj udostępnionymi linkami", "manage_sharing_with_partners": "Zarządzaj dzieleniem z partnerami", "manage_the_app_settings": "Zarządzaj ustawieniami aplikacji", @@ -1377,6 +1397,7 @@ "more": "Więcej", "move": "Przenieś", "move_off_locked_folder": "Przenieś z folderu zablokowanego", + "move_to": "Przenieś do", "move_to_lock_folder_action_prompt": "{count} dodanych do folderu zablokowanego", "move_to_locked_folder": "Przenieś do folderu zablokowanego", "move_to_locked_folder_confirmation": "Te zdjęcia i filmy zostaną usunięte ze wszystkich albumów i będą widzialne tylko w folderze zablokowanym", @@ -1406,6 +1427,7 @@ "new_pin_code": "Nowy kod PIN", "new_pin_code_subtitle": "Jest to pierwszy raz, kiedy wchodzisz do folderu zablokowanego. Utwórz kod PIN, aby bezpiecznie korzystać z tej strony", "new_timeline": "Nowa oś czasu", + "new_update": "Nowa aktualizacja", "new_user_created": "Pomyślnie stworzono nowego użytkownika", "new_version_available": "NOWA WERSJA DOSTĘPNA", "newest_first": "Od najnowszych", @@ -1421,6 +1443,7 @@ "no_cast_devices_found": "Nie znaleziono urządzeń do przesyłania strumieniowego", "no_checksum_local": "Brak sumy kontrolnej - nie można pobrać lokalnych zasobów", "no_checksum_remote": "Brak sumy kontrolnej - nie można pobrać zdalnego zasobu", + "no_devices": "Brak autoryzowanych urządzeń", "no_duplicates_found": "Nie znaleziono duplikatów.", "no_exif_info_available": "Nie znaleziono informacji exif", "no_explore_results_message": "Prześlij więcej zdjęć, aby przeglądać swój zbiór.", @@ -1437,6 +1460,7 @@ "no_results_description": "Spróbuj użyć synonimu lub bardziej ogólnego słowa kluczowego", "no_shared_albums_message": "Stwórz album aby udostępnić zdjęcia i filmy osobom w Twojej sieci", "no_uploads_in_progress": "Brak przesyłań w toku", + "not_allowed": "Niedozwolone", "not_available": "Nie dotyczy", "not_in_any_album": "Bez albumu", "not_selected": "Nie wybrano", @@ -1547,6 +1571,8 @@ "photos_count": "{count, plural, one {{count, number} Zdjęcie} few {{count, number} Zdjęcia} other {{count, number} Zdjęć}}", "photos_from_previous_years": "Zdjęcia z ubiegłych lat", "pick_a_location": "Oznacz lokalizację", + "pick_custom_range": "Zakres niestandardowy", + "pick_date_range": "Wybierz zakres dat", "pin_code_changed_successfully": "Pomyślnie zmieniono kod PIN", "pin_code_reset_successfully": "Pomyślnie zresetowano kod PIN", "pin_code_setup_successfully": "Pomyślnie ustawiono kod PIN", @@ -1767,7 +1793,7 @@ "search_page_no_places": "Brak informacji o miejscu", "search_page_screenshots": "Zrzuty ekranu", "search_page_search_photos_videos": "Wyszukaj swoje zdjęcia i filmy", - "search_page_selfies": "Selfi", + "search_page_selfies": "Selfiki", "search_page_things": "Rzeczy", "search_page_view_all_button": "Pokaż wszystkie", "search_page_your_activity": "Twoja aktywność", @@ -1814,6 +1840,8 @@ "server_offline": "Serwer Offline", "server_online": "Serwer Online", "server_privacy": "Ochrona prywatności serwera", + "server_restarting_description": "Ta strona zostanie za chwilę odświeżona.", + "server_restarting_title": "Trwa ponowne uruchamianie serwera", "server_stats": "Statystyki serwera", "server_update_available": "Dostępna jest aktualizacja serwera", "server_version": "Wersja serwera", @@ -2027,6 +2055,7 @@ "third_party_resources": "Zasoby stron trzecich", "time": "Czas", "time_based_memories": "Wspomnienia oparte na czasie", + "time_based_memories_duration": "Ilość sekund, przez jaką wyświetlane jest poszczególne zdjęcie.", "timeline": "Oś czasu", "timezone": "Strefa czasowa", "to_archive": "Zarchiwizuj", @@ -2167,6 +2196,7 @@ "welcome": "Witaj", "welcome_to_immich": "Witamy w immich", "wifi_name": "Nazwa Wi-Fi", + "workflow": "Przepływ pracy", "wrong_pin_code": "Nieprawidłowy kod PIN", "year": "Rok", "years_ago": "{years, plural, one {# rok} few {# lata} other {# lat}} temu", diff --git a/i18n/pt.json b/i18n/pt.json index 4e04331ad3..512f4dc20b 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -17,7 +17,6 @@ "add_birthday": "Definir aniversário", "add_endpoint": "Adicionar URL", "add_exclusion_pattern": "Adicionar um padrão de exclusão", - "add_import_path": "Adicionar um caminho de importação", "add_location": "Adicionar localização", "add_more_users": "Adicionar mais utilizadores", "add_partner": "Adicionar parceiro", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Alternar seleção para {album}", "add_to_albums": "Adicionar aos álbuns", "add_to_albums_count": "Adicionar aos álbuns ({count})", + "add_to_bottom_bar": "Adicionar a", "add_to_shared_album": "Adicionar ao álbum partilhado", "add_upload_to_stack": "Adicionar carregamento à fila", "add_url": "Adicionar URL", @@ -69,7 +69,7 @@ "confirm_user_pin_code_reset": "Tem a certeza de que quer repor o código PIN de {user}?", "create_job": "Criar tarefa", "cron_expression": "Expressão Cron", - "cron_expression_description": "Definir o intervalo de análise utilizando o formato Cron. Para mais informações, por favor veja o Crontab Guru", + "cron_expression_description": "Definir o intervalo de análise utilizando o formato Cron. Para mais informações, por favor consulte o Crontab Guru", "cron_expression_presets": "Predefinições das expressões Cron", "disable_login": "Desativar inicio de sessão", "duplicate_detection_job_description": "Executa a aprendizagem de máquina em ficheiros para detetar imagens semelhantes. Depende da Pesquisa Inteligente", @@ -90,7 +90,7 @@ "image_prefer_embedded_preview": "Preferir visualização incorporada", "image_prefer_embedded_preview_setting_description": "Utilizar visualizações incorporadas em fotos RAW como entrada para processamento de imagem e quando disponível. Isto pode produzir cores mais precisas para algumas imagens, mas a qualidade da visualização depende da câmara e a imagem pode ter mais artefatos de compressão.", "image_prefer_wide_gamut": "Prefira ampla gama", - "image_prefer_wide_gamut_setting_description": "Utilizar Display P3 para miniaturas. Isso preserva melhor a vibrância das imagens com espaços de cores amplos, mas as imagens podem aparecer de maneira diferente em dispositivos antigos com uma versão antiga do navegador. As imagens sRGB são mantidas como sRGB para evitar mudanças de cores.", + "image_prefer_wide_gamut_setting_description": "Utilizar Display P3 para miniaturas. Isto preserva melhor a vibrância das imagens com espaços de cores amplos, mas as imagens podem aparecer de maneira diferente em dispositivos antigos com uma versão antiga do navegador. As imagens sRGB são mantidas como sRGB para evitar mudanças de cores.", "image_preview_description": "Imagem de tamanho médio sem metadados, utilizada ao visualizar um único ficheiro e pela aprendizagem de máquina", "image_preview_quality_description": "Qualidade de pré-visualização de 1 a 100. Maior é melhor, mas produz ficheiros maiores e pode reduzir a capacidade de resposta da aplicação. Definir um valor demasiado baixo pode afetar a qualidade da aprendizagem de máquina.", "image_preview_title": "Definições de Pré-visualização", @@ -106,19 +106,23 @@ "job_created": "Tarefa criada", "job_not_concurrency_safe": "Esta tarefa não pode ser executada em simultâneo.", "job_settings": "Definições de Tarefas", - "job_settings_description": "Gerir tarefas em simultâneo", + "job_settings_description": "Gerir tarefas executadas em simultâneo", "job_status": "Estado das Tarefas", "jobs_delayed": "{jobCount, plural, one {# adiado} other {# adiados}}", "jobs_failed": "{jobCount, plural, one {# falhou} other {# falharam}}", "library_created": "Criada biblioteca: {library}", "library_deleted": "Biblioteca eliminada", - "library_import_path_description": "Especifique uma pasta para importar. Esta pasta, incluindo sub-pastas, será analisada por imagens e vídeos.", + "library_details": "Detalhes de Biblioteca", + "library_folder_description": "Especifique uma pasta para importar. Esta pasta, incluindo subpastas, será analisada para procurar imagens e vídeos.", + "library_remove_exclusion_pattern_prompt": "Tem a certeza que pretende remover este padrão de exclusão?", + "library_remove_folder_prompt": "Tem a certeza que quer remover esta pasta de importação?", "library_scanning": "Análise periódica", "library_scanning_description": "Configurar a análise periódica da biblioteca", "library_scanning_enable_description": "Ativar análise periódica da biblioteca", "library_settings": "Biblioteca Externa", "library_settings_description": "Gerir definições de biblioteca externa", "library_tasks_description": "Pesquisa bibliotecas externas em busca de itens novos e/ou alterados", + "library_updated": "Biblioteca atualizada", "library_watching_enable_description": "Analisar bibliotecas externas por alterações de ficheiros", "library_watching_settings": "Análise de biblioteca [EXPERIMENTAL]", "library_watching_settings_description": "Analise automaticamente por ficheiros alterados", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Ativar a Pesquisa Inteligente", "machine_learning_smart_search_enabled_description": "Se desativado, as imagens não serão codificadas para Pesquisa Inteligente.", "machine_learning_url_description": "A URL do servidor de aprendizagem de máquina. Se for fornecido mais do que um URL, cada servidor será testado, um a um, até um deles responder com sucesso, por ordem do primeiro ao último. Servidores que não responderem serão temporariamente ignorados até voltarem a estar online.", + "maintenance_settings": "Manutenção", + "maintenance_settings_description": "Colocar o Immich no modo de manutenção.", + "maintenance_start": "Iniciar modo de manutenção", + "maintenance_start_error": "Ocorreu um erro ao iniciar o modo de manutenção.", "manage_concurrency": "Gerir simultaneidade", "manage_log_settings": "Gerir definições de registo", "map_dark_style": "Tema Escuro", @@ -214,7 +222,7 @@ "nightly_tasks_sync_quota_usage_setting_description": "Atualizar quotas de armazenamento de utilizadores, com base na utilização atual", "no_paths_added": "Nenhum caminho adicionado", "no_pattern_added": "Nenhum padrão adicionado", - "note_apply_storage_label_previous_assets": "Observação: Para aplicar o Rótulo de Armazenamento a ficheiros carregados anteriormente, execute o", + "note_apply_storage_label_previous_assets": "Observação: Para aplicar o Rótulo de Armazenamento a ficheiros carregados anteriormente, execute a", "note_cannot_be_changed_later": "NOTA: Isto não pode ser alterado posteriormente!", "notification_email_from_address": "A partir do endereço", "notification_email_from_address_description": "Endereço de e-mail do remetente, por exemplo: \"Servidor de Fotos Immich \". Certifique-se de que utiliza um endereço através do qual pode enviar e-mails.", @@ -285,10 +293,10 @@ "sidecar_job_description": "Descobrir ou sincronizar metadados secundários a partir do sistema de ficheiros", "slideshow_duration_description": "Tempo em segundos para exibir cada imagem", "smart_search_job_description": "Execute a aprendizagem automática em ficheiros para oferecer apoio à Pesquisa Inteligente", - "storage_template_date_time_description": "O registo de data e hora de criação do ficheiro é usado para fornecer essas informações", - "storage_template_date_time_sample": "Exemplo de tempo {date}", + "storage_template_date_time_description": "O registo de data e hora de criação do ficheiro é utilizado para preencher estas informações", + "storage_template_date_time_sample": "Exemplo de data/hora {date}", "storage_template_enable_description": "Ativar mecanismo de modelo de armazenamento", - "storage_template_hash_verification_enabled": "Verificação de hash ativada", + "storage_template_hash_verification_enabled": "Ativar verificação de hash", "storage_template_hash_verification_enabled_description": "Ativa a verificação de hash, não desative esta opção a menos que tenha a certeza das implicações", "storage_template_migration": "Migração de modelo de armazenamento", "storage_template_migration_description": "Aplica o {template} atual para ficheiros previamente carregados", @@ -300,7 +308,7 @@ "storage_template_settings": "Modelo de Armazenamento", "storage_template_settings_description": "Gerir a estrutura de pastas e o nome do ficheiro carregado", "storage_template_user_label": "{label} é o Rótulo do Armazenamento do utilizador", - "system_settings": "Definições de Sistema", + "system_settings": "Definições do Sistema", "tag_cleanup_job": "Limpeza de etiquetas", "template_email_available_tags": "Pode usar as seguintes variáveis no modelo: {tags}", "template_email_if_empty": "Se o modelo estiver em branco, o modelo de e-mail padrão será utilizado.", @@ -430,6 +438,7 @@ "age_months": "Idade {months, plural, one {# mês} other {# meses}}", "age_year_months": "Idade 1 ano, {months, plural, one {# mês} other {# meses}}", "age_years": "{years, plural, one{# ano} other {# anos}}", + "album": "Álbum", "album_added": "Álbum adicionado", "album_added_notification_setting_description": "Receber uma notificação por e-mail quando for adicionado a um álbum partilhado", "album_cover_updated": "Capa do álbum atualizada", @@ -475,6 +484,7 @@ "allow_edits": "Permitir edições", "allow_public_user_to_download": "Permitir que utilizadores públicos façam transferências", "allow_public_user_to_upload": "Permitir que utilizadores públicos façam carregamentos", + "allowed": "Permitido", "alt_text_qr_code": "Imagem do código QR", "anti_clockwise": "Sentido anti-horário", "api_key": "Chave de API", @@ -852,7 +862,7 @@ "display_options": "Opções de exibição", "display_order": "Ordem de exibição", "display_original_photos": "Exibir fotos originais", - "display_original_photos_setting_description": "Preferir a exibição da foto original ao visualizar um ficheiro em vez de miniaturas quando o ficheiro original é compatível com a web. Isso pode diminuir a velocidade de exibição das fotos.", + "display_original_photos_setting_description": "Preferir a exibição da foto original ao visualizar um ficheiro em vez de miniaturas quando o ficheiro original é compatível com a web. Isto pode diminuir a velocidade de exibição das fotos.", "do_not_show_again": "Não mostrar esta mensagem novamente", "documentation": "Documentação", "done": "Feito", @@ -870,13 +880,13 @@ "download_paused": "Pausado", "download_settings": "Transferir", "download_settings_description": "Gerir definições relacionadas com a transferência de ficheiros", - "download_started": "Iniciando", + "download_started": "Descarregamento iniciado", "download_sucess": "Baixado com sucesso", "download_sucess_android": "O ficheiro foi descarregado para a pasta DCIM/Immich", "download_waiting_to_retry": "Tentando novamente", "downloading": "A transferir", "downloading_asset_filename": "A transferir o ficheiro {filename}", - "downloading_media": "Baixando mídia", + "downloading_media": "A descarregar ficheiro", "drop_files_to_upload": "Solte os ficheiros em qualquer lugar para os enviar", "duplicates": "Itens duplicados", "duplicates_description": "Marque cada grupo indicando quais ficheiros, se algum, são duplicados", @@ -894,8 +904,6 @@ "edit_description_prompt": "Por favor selecione uma nova descrição:", "edit_exclusion_pattern": "Editar o padrão de exclusão", "edit_faces": "Editar rostos", - "edit_import_path": "Editar caminho de importação", - "edit_import_paths": "Editar caminhos de importação", "edit_key": "Editar chave", "edit_link": "Editar link", "edit_location": "Editar Localização", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Ocorreu um erro ao empilhar os ficheiros", "failed_to_unstack_assets": "Ocorreu um erro ao desempilhar ficheiros", "failed_to_update_notification_status": "Ocorreu um erro ao atualizar o estado das notificações", - "import_path_already_exists": "Este caminho de importação já existe.", "incorrect_email_or_password": "Email ou palavra-passe incorretos", + "library_folder_already_exists": "Este caminho de importação já existe.", "paths_validation_failed": "Ocorreu um erro na validação de {paths, plural, one {# caminho} other {# caminhos}}", "profile_picture_transparent_pixels": "Imagem de perfil não pode ter pixeis transparentes. Por favor amplie e/ou mova a imagem.", "quota_higher_than_disk_size": "Definiu uma quota maior do que o tamanho do disco", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Não foi possível adicionar os ficheiros ao link partilhado", "unable_to_add_comment": "Não foi possível adicionar o comentário", "unable_to_add_exclusion_pattern": "Não foi possível adicionar o padrão de exclusão", - "unable_to_add_import_path": "Não foi possível adicionar o caminho de importação", "unable_to_add_partners": "Não foi possível adicionar parceiros", "unable_to_add_remove_archive": "Não foi possível {archived, select, true {remover o ficheiro de} other {adicionar o ficheiro}}", "unable_to_add_remove_favorites": "Não foi possível {favorite, select, true {adicionar ficheiro aos} other {remover ficheiro dos}} favoritos", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Não foi possível eliminar o ficheiro", "unable_to_delete_assets": "Erro ao eliminar ficheiros", "unable_to_delete_exclusion_pattern": "Não foi possível eliminar o padrão de exclusão", - "unable_to_delete_import_path": "Não foi possível eliminar o caminho de importação", "unable_to_delete_shared_link": "Não foi possível eliminar o link compartilhado", "unable_to_delete_user": "Não foi possível eliminar o utilizador", "unable_to_download_files": "Não foi possível transferir ficheiros", "unable_to_edit_exclusion_pattern": "Não foi possível editar o padrão de exclusão", - "unable_to_edit_import_path": "Não foi possível editar o caminho de importação", "unable_to_empty_trash": "Não foi possível esvaziar a reciclagem", "unable_to_enter_fullscreen": "Não foi possível entrar em modo de ecrã inteiro", "unable_to_exit_fullscreen": "Não foi possível sair do modo de ecrã inteiro", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Não foi possível atualizar o utilizador", "unable_to_upload_file": "Não foi possível carregar o ficheiro" }, + "exclusion_pattern": "Padrão de exclusão", "exif": "Exif", "exif_bottom_sheet_description": "Adicionar Descrição...", "exif_bottom_sheet_description_error": "Ocorreu um erro ao alterar a descrição", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Navegar na vista de pastas por fotos e vídeos no sistema de ficheiros", "forgot_pin_code_question": "Esqueceu-se do seu PIN?", "forward": "Para a frente", + "full_path": "Caminho completo:{path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Esta funcionalidade requer o carregamento de recursos externos da Google para poder funcionar.", "general": "Geral", @@ -1187,7 +1194,7 @@ "image_alt_text_date_place_3_people": "{isVideo, select, true {Vídeo gravado} other {Foto tirada}} em {city}, {country} com {person1}, {person2}, e {person3} em {date}", "image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Vídeo gravado} other {Foto tirada}} em {city}, {country} com {person1}, {person2}, e outras {additionalCount, number} pessoas em {date}", "image_saved_successfully": "Imagem salva", - "image_viewer_page_state_provider_download_started": "A descarregar ficheiro", + "image_viewer_page_state_provider_download_started": "Descarregamento Iniciado", "image_viewer_page_state_provider_download_success": "Baixado com sucesso", "image_viewer_page_state_provider_share_error": "Erro ao compartilhar", "immich_logo": "Logotipo do Immich", @@ -1196,6 +1203,8 @@ "import_path": "Caminho de importação", "in_albums": "Em {count, plural, one {# álbum} other {# álbuns}}", "in_archive": "Arquivado", + "in_year": "Em {year}", + "in_year_selector": "Em", "include_archived": "Incluir arquivados", "include_shared_albums": "Incluir álbuns partilhados", "include_shared_partner_assets": "Incluir ficheiros partilhados por parceiros", @@ -1232,6 +1241,7 @@ "language_setting_description": "Selecione o seu Idioma preferido", "large_files": "Ficheiros Grandes", "last": "Último", + "last_months": "{count, plural, one {No último mês} other {Nos últimos # meses}}", "last_seen": "Visto pela ultima vez", "latest_version": "Versão mais recente", "latitude": "Latitude", @@ -1241,6 +1251,8 @@ "let_others_respond": "Permitir respostas", "level": "Nível", "library": "Biblioteca", + "library_add_folder": "Adicionar pasta", + "library_edit_folder": "Editar pasta", "library_options": "Opções da biblioteca", "library_page_device_albums": "Álbuns no dispositivo", "library_page_new_album": "Novo álbum", @@ -1284,7 +1296,7 @@ "login_disabled": "Início de sessão desativado", "login_form_api_exception": "Erro de API. Verifique a URL do servidor e tente novamente.", "login_form_back_button_text": "Voltar", - "login_form_email_hint": "seuemail@email.com", + "login_form_email_hint": "oseuemail@email.com", "login_form_endpoint_hint": "http://ip-do-seu-servidor:porta", "login_form_endpoint_url": "URL do servidor", "login_form_err_http": "Por favor especifique http:// ou https://", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Ativar para repetir os vídeos automaticamente durante a exibição.", "main_branch_warning": "Está a usar uma versão de desenvolvimento; recomendamos vivamente que use uma versão de lançamento!", "main_menu": "Menu Principal", + "maintenance_description": "O Immich foi colocado em modo de manutenção.", + "maintenance_end": "Desativar modo de manutenção", + "maintenance_end_error": "Ocorreu um erro ao desativar o modo de manutenção.", + "maintenance_logged_in_as": "Sessão iniciada como {user}", + "maintenance_title": "Temporariamente Indisponível", "make": "Marca", "manage_geolocation": "Gerir localização", + "manage_media_access_rationale": "Esta autorização é necessária para a correta gestão e envio de ficheiros para a reciclagem, e para os restaurar da mesma.", + "manage_media_access_settings": "Abrir definições", + "manage_media_access_subtitle": "Autorizar que aplicação Immich faça a gestão e movimente ficheiros.", + "manage_media_access_title": "Acesso à Gestão de Ficheiros", "manage_shared_links": "Gerir links partilhados", "manage_sharing_with_partners": "Gerir partilha com parceiros", "manage_the_app_settings": "Gerir definições da aplicação", @@ -1377,6 +1398,7 @@ "more": "Mais", "move": "Mover", "move_off_locked_folder": "Mover para fora da pasta trancada", + "move_to": "Mover para", "move_to_lock_folder_action_prompt": "{count} adicionados à pasta trancada", "move_to_locked_folder": "Mover para a pasta trancada", "move_to_locked_folder_confirmation": "Estas fotos e vídeos serão removidas de todos os álbuns, e só serão visíveis na pasta trancada", @@ -1406,6 +1428,7 @@ "new_pin_code": "Novo código PIN", "new_pin_code_subtitle": "Esta é a primeira vez que acede à pasta trancada. Crie um código PIN para aceder a esta página de forma segura", "new_timeline": "Nova Linha do Tempo", + "new_update": "Nova atualização", "new_user_created": "Novo utilizador criado", "new_version_available": "NOVA VERSÃO DISPONÍVEL", "newest_first": "Mais recente primeiro", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "Nenhum dispositivo de transmissão encontrado", "no_checksum_local": "Sem cálculo de verificação disponível - não pode capturar conteúdos locais", "no_checksum_remote": "Soma de verificação (checksum) não disponível - não é possível obter o recurso remoto", + "no_devices": "Nenhum dispositivo autorizado", "no_duplicates_found": "Nenhum item duplicado foi encontrado.", "no_exif_info_available": "Sem informações exif disponíveis", "no_explore_results_message": "Carregue mais fotos para explorar a sua coleção.", "no_favorites_message": "Adicione aos favoritos para encontrar as suas melhores fotos e vídeos rapidamente", "no_libraries_message": "Crie uma biblioteca externa para ver as suas fotos e vídeos", "no_local_assets_found": "Sem cálculo de verificação disponível", + "no_location_set": "Sem localização definida", "no_locked_photos_message": "Fotos e vídeos na pasta trancada estão ocultos e não serão exibidos enquanto explora ou pesquisa na biblioteca.", "no_name": "Sem nome", "no_notifications": "Sem notificações", @@ -1437,6 +1462,7 @@ "no_results_description": "Tente um sinónimo ou uma palavra-chave mais comum", "no_shared_albums_message": "Crie um álbum para partilhar fotos e vídeos com pessoas na sua rede", "no_uploads_in_progress": "Nenhum carregamento em curso", + "not_allowed": "Não permitido", "not_available": "N/A", "not_in_any_album": "Não está em nenhum álbum", "not_selected": "Não selecionado", @@ -1483,7 +1509,7 @@ "other_devices": "Outros dispositivos", "other_entities": "Outras entidades", "other_variables": "Outras variáveis", - "owned": "Seu", + "owned": "Seus", "owner": "Dono", "partner": "Parceiro", "partner_can_access": "{partner} pode aceder", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos de anos anteriores", "pick_a_location": "Selecione uma localização", + "pick_custom_range": "Intervalo personalizado", + "pick_date_range": "Selecione um intervalo de datas", "pin_code_changed_successfully": "Código PIN alterado com sucesso", "pin_code_reset_successfully": "Código PIN reposto com sucesso", "pin_code_setup_successfully": "Código PIN configurado com sucesso", @@ -1734,14 +1762,14 @@ "search_by_filename": "Pesquisar por nome de ficheiro ou extensão", "search_by_filename_example": "por exemplo, IMG_1234.JPG ou PNG", "search_by_ocr": "Pesquisar por OCR", - "search_by_ocr_example": "Latte", + "search_by_ocr_example": "Galão", "search_camera_lens_model": "Pesquisar por modelo de lente...", "search_camera_make": "Pesquisar por marca da câmara...", "search_camera_model": "Pesquisar por modelo da câmara...", "search_city": "Pesquisar cidade...", "search_country": "Pesquisar país...", "search_filter_apply": "Aplicar filtro", - "search_filter_camera_title": "Selecione o tipo de câmera", + "search_filter_camera_title": "Selecione o tipo de câmara", "search_filter_date": "Data", "search_filter_date_interval": "{start} até {end}", "search_filter_date_title": "Selecione a data", @@ -1750,8 +1778,8 @@ "search_filter_filename": "Pesquisar por nome do ficheiro", "search_filter_location": "Localização", "search_filter_location_title": "Selecione a localização", - "search_filter_media_type": "Tipo da mídia", - "search_filter_media_type_title": "Selecione o tipo da mídia", + "search_filter_media_type": "Tipo de ficheiro", + "search_filter_media_type_title": "Selecione o tipo do ficheiro", "search_filter_ocr": "Pesquisar por OCR", "search_filter_people_title": "Selecionar pessoas", "search_for": "Pesquisar por", @@ -1776,7 +1804,7 @@ "search_places": "Pesquisar lugares", "search_rating": "Pesquisar por classificação...", "search_result_page_new_search_hint": "Nova Pesquisa", - "search_settings": "Definições de pesquisa", + "search_settings": "Pesquisar nas Definições", "search_state": "Pesquisar estado/distrito...", "search_suggestion_list_smart_search_hint_1": "A pesquisa inteligente está ativada por omissão. Para pesquisar por metadados, utilize a sintaxe ", "search_suggestion_list_smart_search_hint_2": "m:a-sua-pesquisa", @@ -1814,6 +1842,8 @@ "server_offline": "Servidor Offline", "server_online": "Servidor Online", "server_privacy": "Privacidade do Servidor", + "server_restarting_description": "A página irá atualizar dentro de momentos.", + "server_restarting_title": "O servidor está a reiniciar", "server_stats": "Estado do servidor", "server_update_available": "Está disponível uma atualização do servidor", "server_version": "Versão do servidor", @@ -1906,12 +1936,12 @@ "shared_links": "Links partilhados", "shared_links_description": "Partilhar fotos e videos com um link", "shared_photos_and_videos_count": "{assetCount, plural, other {# Fotos & videos partilhados.}}", - "shared_with_me": "Compartilhado comigo", + "shared_with_me": "Partilhado comigo", "shared_with_partner": "Partilhado com {partner}", "sharing": "Partilha", "sharing_enter_password": "Por favor, insira a palavra-passe para ver esta página.", - "sharing_page_album": "Álbuns compartilhados", - "sharing_page_description": "Crie álbuns compartilhados para compartilhar fotos e vídeos com pessoas da sua rede.", + "sharing_page_album": "Álbuns partilhados", + "sharing_page_description": "Crie álbuns partilhados para partilhar fotos e vídeos com pessoas da sua rede.", "sharing_page_empty_list": "LISTA VAZIA", "sharing_sidebar_description": "Exibe o link para Partilhar na barra lateral", "sharing_silver_appbar_create_shared_album": "Criar álbum partilhado", @@ -1932,7 +1962,7 @@ "show_password": "Mostrar palavra-passe", "show_person_options": "Exibir opções da pessoa", "show_progress_bar": "Exibir barra de progresso", - "show_search_options": "Exibir opções de pesquisa", + "show_search_options": "Mostrar opções de pesquisa", "show_shared_links": "Mostrar links partilhados", "show_slideshow_transition": "Mostrar transições no Modo de Apresentação", "show_supporter_badge": "Emblema de apoiante", @@ -2027,6 +2057,7 @@ "third_party_resources": "Recursos de terceiros", "time": "Hora", "time_based_memories": "Memórias baseadas no tempo", + "time_based_memories_duration": "Número de segundos para exibir cada imagem.", "timeline": "Linha de tempo", "timezone": "Fuso horário", "to_archive": "Arquivar", @@ -2085,7 +2116,7 @@ "unstack": "Desempilhar", "unstack_action_prompt": "{count} desempilhados", "unstacked_assets_count": "Desempilhados {count, plural, one {# ficheiro} other {# ficheiros}}", - "untagged": "Marcador removido", + "untagged": "Sem etiqueta", "up_next": "A seguir", "update_location_action_prompt": "Atualize a localização de {count} ficheiros selecionados com:", "updated_at": "Atualizado a", @@ -2122,7 +2153,7 @@ "user_purchase_settings": "Comprar", "user_purchase_settings_description": "Gerir a sua compra", "user_role_set": "Definir {user} como {role}", - "user_usage_detail": "Detalhes de utilização do utilizador", + "user_usage_detail": "Detalhes de utilização por utilizador", "user_usage_stats": "Estatísticas de utilização de conta", "user_usage_stats_description": "Ver estatísticas de utilização de conta", "username": "Nome de utilizador", @@ -2167,6 +2198,7 @@ "welcome": "Bem-vindo(a)", "welcome_to_immich": "Bem-vindo(a) ao Immich", "wifi_name": "Nome da rede Wi-Fi", + "workflow": "Fluxo de trabalho", "wrong_pin_code": "Código PIN errado", "year": "Ano", "years_ago": "Há {years, plural, one {# ano} other {# anos}}", diff --git a/i18n/pt_BR.json b/i18n/pt_BR.json index 61dd5a7b75..c915344c55 100644 --- a/i18n/pt_BR.json +++ b/i18n/pt_BR.json @@ -17,7 +17,6 @@ "add_birthday": "Definir aniversário", "add_endpoint": "Adicionar URL", "add_exclusion_pattern": "Adicionar padrão de exclusão", - "add_import_path": "Adicionar caminho de importação", "add_location": "Adicionar local", "add_more_users": "Adicionar mais usuários", "add_partner": "Adicionar parceiro", @@ -28,12 +27,13 @@ "add_to_album": "Adicionar ao álbum", "add_to_album_bottom_sheet_added": "Adicionado ao {album}", "add_to_album_bottom_sheet_already_exists": "Já existe em {album}", - "add_to_album_bottom_sheet_some_local_assets": "Alguns arquivos / mídias não puderam ser adicionados ao álbum", + "add_to_album_bottom_sheet_some_local_assets": "Alguns arquivos não puderam ser adicionados ao álbum", "add_to_album_toggle": "Alternar a seleção de {album}", "add_to_albums": "Adicionar aos álbuns", "add_to_albums_count": "Adicionar aos álbuns ({count})", + "add_to_bottom_bar": "Incluir em", "add_to_shared_album": "Adicionar ao álbum compartilhado", - "add_upload_to_stack": "Adicionar upload ao grupo", + "add_upload_to_stack": "Adicionar ao grupo", "add_url": "Adicionar URL", "added_to_archive": "Adicionado ao arquivo", "added_to_favorites": "Adicionado aos favoritos", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, one {# falhou} other {# falharam}}", "library_created": "Criado biblioteca: {library}", "library_deleted": "Biblioteca excluída", - "library_import_path_description": "Especifique uma pasta para importar. Esta pasta, incluindo subpastas, será escaneada em busca de imagens e vídeos.", + "library_details": "Detalhes da biblioteca", + "library_folder_description": "Escolha uma pasta para importar. Esta pasta e todas suas sub pastas serão analisadas em busca de imagens e vídeos.", + "library_remove_exclusion_pattern_prompt": "Tem certeza de que deseja remover esse padrão de exclusão?", + "library_remove_folder_prompt": "Tem certeza de que deseja remover esta pasta de importação?", "library_scanning": "Verificação Periódica", "library_scanning_description": "Configurar verificação periódica da biblioteca", "library_scanning_enable_description": "Habilitar verificação periódica da biblioteca", "library_settings": "Biblioteca Externa", "library_settings_description": "Gerenciar configurações de biblioteca externa", "library_tasks_description": "Verificar se há arquivos novos ou modificados nas bibliotecas externas", + "library_updated": "Biblioteca atualizada", "library_watching_enable_description": "Observe bibliotecas externas para alterações de arquivos", "library_watching_settings": "Observação de biblioteca [EXPERIMENTAL]", "library_watching_settings_description": "Observe automaticamente os arquivos alterados", @@ -155,15 +159,17 @@ "machine_learning_min_recognized_faces": "Mínimo de rostos reconhecidos", "machine_learning_min_recognized_faces_description": "O número mínimo de rostos reconhecidos para uma pessoa ser criada. Aumentar isso torna o Reconhecimento Facial mais preciso, ao custo de aumentar a chance de um rosto não ser atribuído a uma pessoa.", "machine_learning_ocr": "OCR", - "machine_learning_ocr_description": "Usar machine learning para reconhecer textos em imagens", + "machine_learning_ocr_description": "Usar aprendizado de máquina para reconhecer textos em imagens", "machine_learning_ocr_enabled": "Habilitar OCR", - "machine_learning_ocr_enabled_description": "Se desabilitado, imagens não serão submetidas a reconhecimento de texto.", + "machine_learning_ocr_enabled_description": "Se desabilitado, imagens não serão processadas pelo reconhecimento de texto.", "machine_learning_ocr_max_resolution": "Resolução máxima", - "machine_learning_ocr_max_resolution_description": "Prévias acima dessa resolução serão redimensionadas com a preservação da proporção da imagem. Valores maiores são mais precisos, mas levam mais tempo para serem processados e usam mais memória.", + "machine_learning_ocr_max_resolution_description": "Prévias acima dessa resolução serão redimensionadas preservando a proporção da imagem. Valores maiores são mais precisos, mas levam mais tempo para serem processados e usam mais memória.", "machine_learning_ocr_min_detection_score": "Pontuação mínima para detecção", - "machine_learning_ocr_min_detection_score_description": "Pontuação mínima de confiançá para o texto ser detectado de 0 a 1. Valores mais baixos detectarão mais texto mas podem resultar em falsos positivos.", + "machine_learning_ocr_min_detection_score_description": "Pontuação mínima de confiança para o texto ser detectado de 0 a 1. Valores mais baixos detectarão mais texto mas podem resultar em falsos positivos.", "machine_learning_ocr_min_recognition_score": "Pontuação mínima de reconhecimento", "machine_learning_ocr_min_score_recognition_description": "Pontuação mínima de confiança para o texto ser detectado de 0 a 1. Valores mais baixos reconhecerão mais textos mas podem resultar em falsos positivos.", + "machine_learning_ocr_model": "Modelo OCR", + "machine_learning_ocr_model_description": "Os modelos do servidor são mais precisos do que os modelos do dispositivo móvel, mas demoram mais para processar e usam mais memória.", "machine_learning_settings": "Configurações de aprendizado de máquina", "machine_learning_settings_description": "Gerenciar recursos e configurações do aprendizado de máquina", "machine_learning_smart_search": "Pesquisa Inteligente", @@ -171,6 +177,10 @@ "machine_learning_smart_search_enabled": "Habilitar a Pesquisa Inteligente", "machine_learning_smart_search_enabled_description": "Se desativado, as imagens não serão codificadas para pesquisa inteligente.", "machine_learning_url_description": "A URL do servidor de aprendizado de máquina. Se mais de uma URL for fornecida, elas serão tentadas, uma de cada vez e na ordem indicada, até que uma responda com sucesso. Servidores que não responderem serão ignorados temporariamente até voltarem a estar conectados.", + "maintenance_settings": "Manutenção", + "maintenance_settings_description": "Coloque o Immich em modo de manutenção.", + "maintenance_start": "Iniciar modo de manutenção", + "maintenance_start_error": "Ocorreu um erro ao iniciar o modo de manutenção.", "manage_concurrency": "Gerenciar simultaneidade", "manage_log_settings": "Gerenciar configurações de log", "map_dark_style": "Tema Escuro", @@ -255,6 +265,7 @@ "oauth_storage_quota_default_description": "Cota em GiB que será usada caso esta declaração não seja fornecida.", "oauth_timeout": "Tempo Limite de Requisição", "oauth_timeout_description": "Tempo limite para requisições, em milissegundos", + "ocr_job_description": "Usa machine learning para reconhecer texto em imagens", "password_enable_description": "Login com e-mail e senha", "password_settings": "Senha de acesso", "password_settings_description": "Gerenciar configurações de login e senha", @@ -427,6 +438,7 @@ "age_months": "Idade {months, plural, one {# mês} other {# meses}}", "age_year_months": "Idade 1 ano e {months, plural, one {# mês} other {# meses}}", "age_years": "{years, plural, other {Idade #}}", + "album": "Álbum", "album_added": "Álbum adicionado", "album_added_notification_setting_description": "Receba uma notificação por e-mail quando você for adicionado a um álbum compartilhado", "album_cover_updated": "Capa do álbum atualizada", @@ -472,6 +484,7 @@ "allow_edits": "Permitir edições", "allow_public_user_to_download": "Permitir que usuários públicos baixem os arquivos", "allow_public_user_to_upload": "Permitir que usuários públicos enviem novos arquivos", + "allowed": "Permitido", "alt_text_qr_code": "Imagem do código QR", "anti_clockwise": "Anti-horário", "api_key": "Chave de API", @@ -482,10 +495,10 @@ "app_bar_signout_dialog_content": "Tem certeza de que deseja sair?", "app_bar_signout_dialog_ok": "Sim", "app_bar_signout_dialog_title": "Sair", - "app_download_links": "Links de Download de App", + "app_download_links": "Links para baixar o aplicativo", "app_settings": "Configurações do Aplicativo", "app_stores": "Loja de Aplicativos", - "app_update_available": "Atualizações de apps disponíveis", + "app_update_available": "Uma atualização para o aplicativo está disponível", "appears_in": "Aparece em", "apply_count": "Aplicar ({count, number})", "archive": "Arquivar", @@ -493,7 +506,7 @@ "archive_or_unarchive_photo": "Arquivar ou desarquivar foto", "archive_page_no_archived_assets": "Nenhum arquivo encontrado", "archive_page_title": "Arquivados ({count})", - "archive_size": "Tamanho do arquivo", + "archive_size": "Tamanho do arquivamento", "archive_size_description": "Configure o tamanho do arquivo para baixar (em GiB)", "archived": "Arquivado", "archived_count": "{count, plural, one {# Arquivado} other {# Arquivados}}", @@ -558,7 +571,7 @@ "background_backup_running_error": "Não é possível iniciar o backup manual agora pois o backup em segundo plano já está sendo executado", "background_location_permission": "Permissão de localização em segundo plano", "background_location_permission_content": "Para que seja possível trocar o endereço quando estiver executando em segundo plano, o Immich deve *sempre* ter a permissão de localização precisa para que o aplicativo consiga ler o nome da rede Wi-Fi", - "background_options": "Opções de Plano de Fundo", + "background_options": "Opções de segundo plano", "backup": "Backup", "backup_album_selection_page_albums_device": "Álbuns no dispositivo ({count})", "backup_album_selection_page_albums_tap": "Toque para incluir, toque duas vezes para excluir", @@ -569,7 +582,7 @@ "backup_albums_sync": "Backup de sincronização de álbuns", "backup_all": "Todos", "backup_background_service_backup_failed_message": "Falha ao fazer backup. Tentando novamente…", - "backup_background_service_complete_notification": "Backup de ativo completado", + "backup_background_service_complete_notification": "Backup dos arquivos concluído", "backup_background_service_connection_failed_message": "Falha na conexão com o servidor. Tentando novamente…", "backup_background_service_current_upload_notification": "Enviando {filename}", "backup_background_service_default_notification": "Verificando se há novos arquivos…", @@ -679,6 +692,8 @@ "change_password_description": "Esta é a primeira vez que você está acessando o sistema ou foi feita uma solicitação para alterar sua senha. Por favor, insira a nova senha abaixo.", "change_password_form_confirm_password": "Confirme a senha", "change_password_form_description": "Olá {name},\n\nEsta é a primeira vez que você está acessando o sistema ou foi feita uma solicitação para alterar sua senha. Por favor, insira a nova senha abaixo.", + "change_password_form_log_out": "Desconectar todos os outros dispositivos", + "change_password_form_log_out_description": "É recomendável desconectar todos os outros dispositivos", "change_password_form_new_password": "Nova Senha", "change_password_form_password_mismatch": "As senhas não estão iguais", "change_password_form_reenter_new_password": "Confirme a nova senha", @@ -686,7 +701,7 @@ "change_your_password": "Alterar sua senha", "changed_visibility_successfully": "Visibilidade alterada com sucesso", "charging": "Carregando", - "charging_requirement_mobile_backup": "Backups em plano de fundo requerem que o dispositivo esteja sendo carregado", + "charging_requirement_mobile_backup": "Backups em segundo plano requerem que o dispositivo esteja sendo carregado", "check_corrupt_asset_backup": "Verifique se há backups corrompidos", "check_corrupt_asset_backup_button": "Verificar", "check_corrupt_asset_backup_description": "Execute esta verificação somente em uma rede Wi-Fi e quando o backup de todos os arquivos já estiver concluído. O processo demora alguns minutos.", @@ -786,6 +801,7 @@ "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Escuro", "dark_theme": "Usar tema escuro", + "date": "Data", "date_after": "Data após", "date_and_time": "Data e Hora", "date_before": "Data antes", @@ -888,8 +904,6 @@ "edit_description_prompt": "Por favor selecione uma nova descrição:", "edit_exclusion_pattern": "Editar o padrão de exclusão", "edit_faces": "Editar rostos", - "edit_import_path": "Editar caminho de importação", - "edit_import_paths": "Editar caminhos de importação", "edit_key": "Editar chave", "edit_link": "Editar link", "edit_location": "Editar Localização", @@ -961,8 +975,8 @@ "failed_to_stack_assets": "Falha ao agrupar arquivos", "failed_to_unstack_assets": "Falha ao remover arquivos do grupo", "failed_to_update_notification_status": "Falha ao atualizar o status da notificação", - "import_path_already_exists": "Este caminho de importação já existe.", "incorrect_email_or_password": "E-mail ou senha incorretos", + "library_folder_already_exists": "Este caminho de importação já existe.", "paths_validation_failed": "A validação de {paths, plural, one {# caminho falhou} other {# caminhos falharam}}", "profile_picture_transparent_pixels": "As imagens de perfil não podem ter pixels transparentes. Aumente o zoom e/ou mova a imagem.", "quota_higher_than_disk_size": "Você definiu uma cota maior do que o tamanho do disco", @@ -971,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Não é possível adicionar arquivos ao link compartilhado", "unable_to_add_comment": "Não foi possível adicionar o comentário", "unable_to_add_exclusion_pattern": "Não foi possível adicionar o padrão de exclusão", - "unable_to_add_import_path": "Não foi possível adicionar o caminho de importação", "unable_to_add_partners": "Não foi possível adicionar parceiros", "unable_to_add_remove_archive": "Não é possível {archived, select, true {remove asset from} other {add asset to}} arquivar", "unable_to_add_remove_favorites": "Não foi possível {favorite, select, true {adicionar o arquivo aos} other {remover o arquivo dos}} favoritos", @@ -994,12 +1007,10 @@ "unable_to_delete_asset": "Não foi possível deletar o arquivo", "unable_to_delete_assets": "Erro ao excluir arquivos", "unable_to_delete_exclusion_pattern": "Não foi possível deletar o padrão de exclusão", - "unable_to_delete_import_path": "Não foi possível deletar o caminho de importação", "unable_to_delete_shared_link": "Não foi possível deletar o link compartilhado", "unable_to_delete_user": "Não foi possível deletar o usuário", "unable_to_download_files": "Não foi possível baixar os arquivos", "unable_to_edit_exclusion_pattern": "Não foi possível editar o padrão de exclusão", - "unable_to_edit_import_path": "Não foi possível editar o caminho de importação", "unable_to_empty_trash": "Não foi possível esvaziar a lixeira", "unable_to_enter_fullscreen": "Não foi possível entrar em modo de tela cheia", "unable_to_exit_fullscreen": "Não foi possível sair do modo de tela cheia", @@ -1050,6 +1061,7 @@ "unable_to_update_user": "Não foi possível atualizar o usuário", "unable_to_upload_file": "Não foi possível enviar o arquivo" }, + "exclusion_pattern": "Padrão de exclusão", "exif": "Exif", "exif_bottom_sheet_description": "Adicionar descrição...", "exif_bottom_sheet_description_error": "Erro ao alterar a descrição", @@ -1094,6 +1106,7 @@ "features_setting_description": "Gerenciar as funcionalidades da aplicação", "file_name": "Nome do arquivo", "file_name_or_extension": "Nome do arquivo ou extensão", + "file_size": "Tamanho do arquivo", "filename": "Nome do arquivo", "filetype": "Tipo de arquivo", "filter": "Filtro", @@ -1189,6 +1202,8 @@ "import_path": "Caminho de importação", "in_albums": "Em {count, plural, one {# álbum} other {# álbuns}}", "in_archive": "Arquivado", + "in_year": "Em {year}", + "in_year_selector": "Em", "include_archived": "Incluir arquivados", "include_shared_albums": "Incluir álbuns compartilhados", "include_shared_partner_assets": "Incluir arquivos compartilhados por parceiros", @@ -1225,6 +1240,7 @@ "language_setting_description": "Selecione seu Idioma preferido", "large_files": "Arquivos Grandes", "last": "Último", + "last_months": "{count, plural, one {Last month} other {Last # months}}", "last_seen": "Visto pela ultima vez", "latest_version": "Versão mais recente", "latitude": "Latitude", @@ -1234,6 +1250,8 @@ "let_others_respond": "Permitir respostas", "level": "Nível", "library": "Biblioteca", + "library_add_folder": "Adicionar pasta", + "library_edit_folder": "Editar pasta", "library_options": "Opções da biblioteca", "library_page_device_albums": "Álbuns no Dispositivo", "library_page_new_album": "Novo album", @@ -1257,6 +1275,7 @@ "local_media_summary": "Resumo das mídias locais", "local_network": "Rede local", "local_network_sheet_info": "O aplicativo irá se conectar ao servidor através deste endereço quando estiver na rede Wi-Fi especificada", + "location": "Localização", "location_permission": "Permissão de localização", "location_permission_content": "Para utilizar a função de troca automática de URL é necessário a permissão de localização precisa, para que seja possível ler o nome da rede Wi-Fi", "location_picker_choose_on_map": "Escolha no mapa", @@ -1272,7 +1291,7 @@ "logged_in_as": "Usuário atual: {user}", "logged_out_all_devices": "Saiu de todos os dispositivos", "logged_out_device": "Dispositivo desconectado", - "login": "Iniciar sessão", + "login": "Entrar", "login_disabled": "Login desativado", "login_form_api_exception": "Erro de API. Verifique a URL do servidor e tente novamente.", "login_form_back_button_text": "Voltar", @@ -1297,21 +1316,30 @@ "login_password_changed_success": "Senha atualizada com sucesso", "logout_all_device_confirmation": "Tem certeza de que deseja sair de todos os dispositivos?", "logout_this_device_confirmation": "Tem certeza de que deseja sair deste dispositivo?", - "logs": "Logs", + "logs": "Registros", "longitude": "Longitude", "look": "Estilo", "loop_videos": "Repetir vídeos", "loop_videos_description": "Ative para repetir os vídeos automaticamente durante a exibição.", "main_branch_warning": "Você está utilizando uma versão de desenvolvimento. É fortemente recomendado que utilize uma versão estável!", "main_menu": "Menu Principal", + "maintenance_description": "O Immich foi colocado em modo de manutenção.", + "maintenance_end": "Desativar modo de manutenção", + "maintenance_end_error": "Ocorreu um erro ao desativar o modo de manutenção.", + "maintenance_logged_in_as": "Usuário atual: {user}", + "maintenance_title": "Temporariamente Indisponível", "make": "Marca", "manage_geolocation": "Gerenciar localização", + "manage_media_access_rationale": "Essa permissão é necessária para o correto gerenciamento da movimentação de mídias para a lixeira e para a sua restauração a partir dela.", + "manage_media_access_settings": "Abrir configurações", + "manage_media_access_subtitle": "Permita que o aplicativo Immich gerencie e mova arquivos de mídia.", + "manage_media_access_title": "Acesso para gerenciar mídias", "manage_shared_links": "Gerir links partilhados", "manage_sharing_with_partners": "Gerenciar compartilhamento com parceiros", "manage_the_app_settings": "Gerenciar configurações do app", "manage_your_account": "Gerenciar sua conta", "manage_your_api_keys": "Gerenciar suas Chaves de API", - "manage_your_devices": "Gerenciar seus dispositivos logados", + "manage_your_devices": "Gerenciar seus dispositivos conectados", "manage_your_oauth_connection": "Gerenciar sua conexão OAuth", "map": "Mapa", "map_assets_in_bounds": "{count, plural, =0 {Sem fotos nesta área} one {# foto} other {# fotos}}", @@ -1369,6 +1397,7 @@ "more": "Mais", "move": "Mover", "move_off_locked_folder": "Mover para fora da pasta com senha", + "move_to": "Mover para", "move_to_lock_folder_action_prompt": "{count} adicionados à pasta com senha", "move_to_locked_folder": "Mover para a pasta com senha", "move_to_locked_folder_confirmation": "Estas fotos e vídeos serão removidos de todos os álbuns e somente poderão ser visualizados de dentro da pasta com senha", @@ -1398,6 +1427,7 @@ "new_pin_code": "Novo código PIN", "new_pin_code_subtitle": "Esta é a primeira vez que está acessando a pasta com senha. Crie um código PIN para acessar esta página de forma segura", "new_timeline": "Nova Linha do Tempo", + "new_update": "Nova atualização", "new_user_created": "Novo usuário criado", "new_version_available": "NOVA VERSÃO DISPONÍVEL", "newest_first": "Mais recente primeiro", @@ -1413,6 +1443,7 @@ "no_cast_devices_found": "Nenhum dispositivo encontrado", "no_checksum_local": "Nenhum checksum disponível - não foi possível carregar os arquivos locais", "no_checksum_remote": "Nenhum checksum disponível - não foi possível carregar os arquivos remotos", + "no_devices": "Nenhum dispostivio autorizado", "no_duplicates_found": "Nenhuma duplicidade foi encontrada.", "no_exif_info_available": "Sem informações exif disponíveis", "no_explore_results_message": "Envie mais fotos para explorar sua coleção.", @@ -1429,6 +1460,7 @@ "no_results_description": "Tente um sinônimo ou uma palavra-chave mais geral", "no_shared_albums_message": "Crie um álbum para compartilhar fotos e vídeos com pessoas em sua rede", "no_uploads_in_progress": "Nenhum envio em progresso", + "not_allowed": "Não permitido", "not_available": "N/A", "not_in_any_album": "Fora de álbum", "not_selected": "Não selecionado", @@ -1445,6 +1477,7 @@ "oauth": "OAuth", "obtainium_configurator": "Configurador Obtainium", "obtainium_configurator_instructions": "Use o Obtainium para instalar e atualizar o aplicativo Android diretamente do lançamento do Immich no GitHub. Crie uma chave API e selecione a variante para criar o seu link de configuração Obtainium", + "ocr": "OCR", "official_immich_resources": "Recursos oficiais do Immich", "offline": "Desconectado", "offset": "Deslocamento", @@ -1538,6 +1571,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}", "photos_from_previous_years": "Fotos de anos anteriores", "pick_a_location": "Selecione uma localização", + "pick_custom_range": "Intervalo customizado", + "pick_date_range": "Selecione o intervalo de datas", "pin_code_changed_successfully": "Código PIN alterado com sucesso", "pin_code_reset_successfully": "Código PIN redefinido com sucesso", "pin_code_setup_successfully": "Código PIN criado com sucesso", @@ -1568,7 +1603,7 @@ "primary": "Primário", "privacy": "Privacidade", "profile": "Perfil", - "profile_drawer_app_logs": "Logs", + "profile_drawer_app_logs": "Registros", "profile_drawer_client_server_up_to_date": "Cliente e Servidor estão atualizados", "profile_drawer_github": "GitHub", "profile_drawer_readonly_mode": "Modo apenas leitura habilidato. Dê um toque prolongado na foto do usuário para sair deste modo.", @@ -1618,7 +1653,7 @@ "read_changelog": "Ler Novidades", "readonly_mode_disabled": "Modo apenas visualização desativado", "readonly_mode_enabled": "Modo apenas visualização ativado", - "ready_for_upload": "Pronto para upload", + "ready_for_upload": "Pronto para enviar", "reassign": "Reatribuir", "reassigned_assets_to_existing_person": "{count, plural, one {# arquivo reatribuído} other {# arquivos reatribuídos}} a {name, select, null {uma pessoa} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {# arquivo reatribuído} other {# arquivos reatribuídos}} a uma nova pessoa", @@ -1688,6 +1723,7 @@ "reset_sqlite_confirmation": "Realmente deseja redefinir o banco de dados SQLite? Será necessário sair e entrar em sua conta novamente para ressincronizar os dados", "reset_sqlite_success": "Banco de dados SQLite redefinido com sucesso", "reset_to_default": "Redefinir para a configuração padrão", + "resolution": "Resolução", "resolve_duplicates": "Resolver duplicatas", "resolved_all_duplicates": "Todas duplicidades resolvidas", "restore": "Restaurar", @@ -1706,6 +1742,7 @@ "running": "Executando", "save": "Salvar", "save_to_gallery": "Salvar na galeria", + "saved": "Salvo", "saved_api_key": "Chave de API salva", "saved_profile": "Perfil Salvo", "saved_settings": "Configurações salvas", @@ -1722,6 +1759,8 @@ "search_by_description_example": "Dia de caminhada no Ibirapuera", "search_by_filename": "Pesquisa por nome de arquivo ou extensão", "search_by_filename_example": "Por exemplo, IMG_1234.JPG ou PNG", + "search_by_ocr": "Buscar por OCR", + "search_by_ocr_example": "Café com leite", "search_camera_lens_model": "Buscar por modelo de lente...", "search_camera_make": "Pesquisar câmeras da marca...", "search_camera_model": "Pesquisar câmera do modelo...", @@ -1739,6 +1778,7 @@ "search_filter_location_title": "Selecione a localização", "search_filter_media_type": "Tipo de mídia", "search_filter_media_type_title": "Selecione o tipo de mídia", + "search_filter_ocr": "Buscar por OCR", "search_filter_people_title": "Selecione pessoas", "search_for": "Pesquisar por", "search_for_existing_person": "Pesquisar por pessoas", @@ -1762,7 +1802,7 @@ "search_places": "Pesquisar lugares", "search_rating": "Pesquisar por classificação...", "search_result_page_new_search_hint": "Nova pesquisa", - "search_settings": "Configurações de pesquisa", + "search_settings": "Pesquisar nas Configurações", "search_state": "Pesquisar estado...", "search_suggestion_list_smart_search_hint_1": "A pesquisa inteligente é utilizada por padrão, para pesquisar por metadados, use a sintaxe ", "search_suggestion_list_smart_search_hint_2": "m:seu-termo-de-pesquisa", @@ -1800,6 +1840,8 @@ "server_offline": "Servidor Indisponível", "server_online": "Servidor Disponível", "server_privacy": "Privacidade do servidor", + "server_restarting_description": "Esta página será atualizada em breve.", + "server_restarting_title": "O servidor está reiniciando", "server_stats": "Status do servidor", "server_update_available": "Uma atualização para o servidor está disponível", "server_version": "Versão do servidor", @@ -2011,7 +2053,9 @@ "theme_setting_three_stage_loading_title": "Ative o carregamento em três estágios", "they_will_be_merged_together": "Eles serão mesclados", "third_party_resources": "Recursos de terceiros", + "time": "Hora", "time_based_memories": "Memórias baseadas no tempo", + "time_based_memories_duration": "Número de segundos para exibir cada imagem.", "timeline": "Linha do tempo", "timezone": "Fuso horário", "to_archive": "Arquivar", @@ -2152,6 +2196,7 @@ "welcome": "Bem-vindo(a)", "welcome_to_immich": "Bem-vindo(a) ao Immich", "wifi_name": "Nome do Wi-Fi", + "workflow": "Automação", "wrong_pin_code": "Código PIN incorreto", "year": "Ano", "years_ago": "{years, plural, one {# ano} other {# anos}} atrás", diff --git a/i18n/ro.json b/i18n/ro.json index 3d08b27d75..fc53f3caac 100644 --- a/i18n/ro.json +++ b/i18n/ro.json @@ -17,7 +17,6 @@ "add_birthday": "Adaugă zi de naștere", "add_endpoint": "Adaugă punct final", "add_exclusion_pattern": "Adăugă un model de excludere", - "add_import_path": "Adaugă o cale de import", "add_location": "Adaugă locație", "add_more_users": "Adaugă mai mulți utilizatori", "add_partner": "Adaugă partener", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# eșuat}}", "library_created": "Librărie creată: {library}", "library_deleted": "Bibliotecă ștearsă", - "library_import_path_description": "Specificați un folder pentru a îl importa. Acest folder, inclusiv sub-folderele, vor fi scanate pentru imagini și videoclipuri.", "library_scanning": "Scanare periodică", "library_scanning_description": "Configurează scanarea periodică pentru bibliotecă", "library_scanning_enable_description": "Activează scanarea periodică pentru bibliotecă", @@ -348,7 +346,7 @@ "transcoding_max_b_frames": "Număr maxim de cadre B", "transcoding_max_b_frames_description": "Valorile mai mari îmbunătățesc eficiența compresiei, dar încetinesc codarea. Este posibil să nu fie compatibile cu accelerarea hardware pe dispozitivele mai vechi. 0 dezactivează cadrele B, în timp ce -1 setează această valoare automat.", "transcoding_max_bitrate": "Rata de biți maximă", - "transcoding_max_bitrate_description": "Setarea unei rate maxime de biți poate face dimensiunile fișierelor mai previzibile, cu un cost minor asupra calității. La 720p, valorile tipice sunt 2600 kbit/s pentru VP9 sau HEVC, sau 4500 kbit/s pentru H.264. Dezactivat dacă este setat la 0.", + "transcoding_max_bitrate_description": "Setarea unei rate maxime de biți poate face dimensiunile fișierelor mai previzibile, cu un cost minor asupra calității. La 720p, valorile tipice sunt 2600 kbit/s pentru VP9 sau HEVC, sau 4500 kbit/s pentru H.264. Dezactivat dacă este setat la 0. Cand o unitate nu este specificata, k (pentru kbit/s) este asumat.In acest caz 5000,5000k si 5M (pentru Mbit/s) sunt echivalente.", "transcoding_max_keyframe_interval": "Interval maxim între cadre cheie", "transcoding_max_keyframe_interval_description": "Setează distanța maximă între cadrele cheie. Valorile mai mici reduc eficiența compresiei, dar îmbunătățesc timpii de căutare și pot îmbunătăți calitatea în scenele cu mișcare rapidă. 0 setează această valoare automat.", "transcoding_optimal_description": "Videoclipuri cu rezoluție mai mare decât cea țintă sau care nu sunt într-un format acceptat", @@ -366,7 +364,7 @@ "transcoding_target_resolution": "Rezoluția țintă", "transcoding_target_resolution_description": "Rezoluțiile mai mari pot păstra mai multe detalii, dar necesită mai mult timp pentru codare, au dimensiuni mai mari ale fișierelor și pot reduce răspunsul aplicației.", "transcoding_temporal_aq": "AQ temporal", - "transcoding_temporal_aq_description": "Se aplică doar la NVENC. Îmbunătățește calitatea scenelor cu detalii mari și mișcare redusă. Poate să nu fie compatibil cu dispozitivele mai vechi.", + "transcoding_temporal_aq_description": "Se aplică doar la NVENC.Cuantificarea adaptivă temporală imbunătățește calitatea scenelor cu detalii mari și mișcare redusă. Poate să nu fie compatibil cu dispozitivele mai vechi.", "transcoding_threads": "Fire", "transcoding_threads_description": "Valorile mai mari conduc la o codare mai rapidă, dar lasă mai puțin spațiu serverului pentru a procesa alte sarcini în timp ce este activ. Această valoare nu ar trebui să fie mai mare decât numărul de nuclee CPU. Maximizați utilizarea dacă este setat la 0.", "transcoding_tone_mapping": "Mapare tonuri", @@ -417,11 +415,11 @@ "advanced_settings_prefer_remote_subtitle": "Unele dispozitive încarcă extrem de lent miniaturile din resursele locale. Activați această setare pentru a încărca imagini la distanță.", "advanced_settings_prefer_remote_title": "Preferă fotografii la distanță", "advanced_settings_proxy_headers_subtitle": "Definește antetele proxy pe care Immich ar trebui să le trimită cu fiecare solicitare de rețea", - "advanced_settings_proxy_headers_title": "Headere proxy personalizate", + "advanced_settings_proxy_headers_title": "Headere proxy personalizate [EXPERIMENTAL]", "advanced_settings_readonly_mode_subtitle": "Activează modul doar-citire, în care fotografiile pot fi doar vizualizate, iar acțiuni precum selectarea mai multor imagini, partajarea, redarea pe alt dispozitiv sau ștergerea sunt dezactivate. Activează/Dezactivează modul doar-citire din avatarul utilizatorului de pe ecranul principal", "advanced_settings_readonly_mode_title": "Mod doar citire", "advanced_settings_self_signed_ssl_subtitle": "Omite verificare certificate SSL pentru distinația server-ului, necesar pentru certificate auto-semnate.", - "advanced_settings_self_signed_ssl_title": "Permite certificate SSL auto-semnate", + "advanced_settings_self_signed_ssl_title": "Permite certificate SSL auto-semnate [EXPERIMENTAL]", "advanced_settings_sync_remote_deletions_subtitle": "Ștergeți sau restaurați automat un element de pe acest dispozitiv atunci când acțiunea este efectuată pe web", "advanced_settings_sync_remote_deletions_title": "Sincronizează stergerile efectuate la distanță [EXPERIMENTAL]", "advanced_settings_tile_subtitle": "Setări avansate pentru utilizator", @@ -475,6 +473,7 @@ "allow_edits": "Permite editări", "allow_public_user_to_download": "Permite utilizatorului public să descarce", "allow_public_user_to_upload": "Permite utilizatorului public să încarce", + "allowed": "Permis", "alt_text_qr_code": "Cod QR", "anti_clockwise": "În sens invers acelor de ceasornic", "api_key": "Cheie API", @@ -488,7 +487,7 @@ "app_download_links": "Linkuri de descărcare în aplicație", "app_settings": "Setări aplicație", "app_stores": "Magazine de aplicații", - "app_update_available": "Este disponibilă o actualizare a aplicației", + "app_update_available": "Actualizarea aplicației disponibilă", "appears_in": "Apare în", "apply_count": "Aplică ({count, number})", "archive": "Arhivă", @@ -711,7 +710,7 @@ "client_cert_invalid_msg": "Fisier cu certificat invalid sau parola este greșită", "client_cert_remove_msg": "Certificatul de client este șters", "client_cert_subtitle": "Este suportat doar formatul PKCS12 (.p12, .pfx). Importul/ștergerea certificatului este disponibil(ă) doar înainte de autentificare", - "client_cert_title": "Certificat SSL pentru client", + "client_cert_title": "Certificat SSL pentru client [EXPERIMENTAL]", "clockwise": "În sensul acelor de ceas", "close": "Închideți", "collapse": "Restrângeți", @@ -894,8 +893,6 @@ "edit_description_prompt": "Vă rugăm să selectați o descriere nouă:", "edit_exclusion_pattern": "Editarea modelului de excludere", "edit_faces": "Editare fețe", - "edit_import_path": "Editare cale de import", - "edit_import_paths": "Editare căi de import", "edit_key": "Tastă de editare", "edit_link": "Editare link", "edit_location": "Editare locație", @@ -967,7 +964,6 @@ "failed_to_stack_assets": "Eșec la combinarea resurselor", "failed_to_unstack_assets": "Eșec la desfășurarea resurselor", "failed_to_update_notification_status": "Nu s-a putut actualiza starea notificării", - "import_path_already_exists": "Această cale de import există deja.", "incorrect_email_or_password": "E-mail sau parolă incorect/ă", "paths_validation_failed": "{paths, plural, one {# cale} other {# căi}} nu a trecut validarea", "profile_picture_transparent_pixels": "Pozele de profil nu pot avea pixeli transparenți. Te rugăm să mărești imaginea și/sau să o muți.", @@ -977,7 +973,6 @@ "unable_to_add_assets_to_shared_link": "Imposibil de adăugat resurse la link-ul partajat", "unable_to_add_comment": "Imposibil de adăugat comentariu", "unable_to_add_exclusion_pattern": "Nu se poate adăuga modelul de excludere", - "unable_to_add_import_path": "Imposibil de adăugat calea de import", "unable_to_add_partners": "Nu se pot adăuga parteneri", "unable_to_add_remove_archive": "Nu se poate {archived, select, true {îndepărta resursa din} other {adăuga resursa în}} arhivă", "unable_to_add_remove_favorites": "Nu se poate {favorite, select, true {adăuga resursa în} other {îndepărta resursa din}} favorite", @@ -1000,12 +995,10 @@ "unable_to_delete_asset": "Nu poate fi ștearsă resursa", "unable_to_delete_assets": "Eroare la ștergerea resurselor", "unable_to_delete_exclusion_pattern": "Nu se poate șterge modelul de excludere", - "unable_to_delete_import_path": "Nu se poate șterge calea de import", "unable_to_delete_shared_link": "Nu se poate șterge linkul partajat", "unable_to_delete_user": "Nu se poate șterge userul", "unable_to_download_files": "Nu se pot descărca fișierele", "unable_to_edit_exclusion_pattern": "Nu se poate edita modelul de excludere", - "unable_to_edit_import_path": "Nu se poate edita calea de import", "unable_to_empty_trash": "Nu se poate goli coșul de gunoi", "unable_to_enter_fullscreen": "Nu se poate accesa ecranul complet", "unable_to_exit_fullscreen": "Imposibil de părăsit ecranul complet", @@ -1140,7 +1133,7 @@ "hash_asset": "Hash-ul resursei", "hashed_assets": "Resurse hashed", "hashing": "Generare hash", - "header_settings_add_header_tip": "Adăugați antet", + "header_settings_add_header_tip": "Adăugați header", "header_settings_field_validator_msg": "Valoarea nu poate fi goală", "header_settings_header_name_input": "Numele antetului", "header_settings_header_value_input": "Valoarea antetului", @@ -1389,8 +1382,8 @@ "my_albums": "Albumele mele", "name": "Nume", "name_or_nickname": "Nume sau poreclǎ", - "navigate": "Navighează/Navigare", - "navigate_to_time": "Mergi la Timp", + "navigate": "Navighează", + "navigate_to_time": "Navigheaza la Timp", "network_requirement_photos_upload": "Utilizați datele mobile pentru a face copii de rezervă ale fotografiilor", "network_requirement_videos_upload": "Utilizați datele mobile pentru a face copii de rezervă ale videoclipurilor", "network_requirements": "Cerințe privind rețeaua", diff --git a/i18n/ru.json b/i18n/ru.json index 52cd3adbc3..f6a342b735 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -17,7 +17,6 @@ "add_birthday": "Указать дату рождения", "add_endpoint": "Добавить адрес", "add_exclusion_pattern": "Добавить шаблон исключения", - "add_import_path": "Добавить путь импорта", "add_location": "Добавить местоположение", "add_more_users": "Добавить ещё пользователей", "add_partner": "Добавить партнёра", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Переключить выделение для альбома {album}", "add_to_albums": "Добавить в альбомы", "add_to_albums_count": "Добавить в альбомы ({count})", + "add_to_bottom_bar": "Добавить в", "add_to_shared_album": "Добавить в общий альбом", "add_upload_to_stack": "Загрузить и добавить в группу", "add_url": "Добавить URL", @@ -52,7 +52,7 @@ "backup_keep_last_amount": "Количество хранимых резервных копий базы данных", "backup_onboarding_1_description": "хранение дополнительной внешней копии в облаке или другом физическом месте.", "backup_onboarding_2_description": "хранение основных файлов и их локальной копии на двух разных типах носителей.", - "backup_onboarding_3_description": "создание трёх копий данных, включая исходные файлы. 2 локальных копии и 1 внешнюю.", + "backup_onboarding_3_description": "создание трёх копий данных, включая исходные файлы: 2 локальных копии и 1 внешнюю.", "backup_onboarding_description": "Для надёжной защиты рекомендуется использовать стратегию резервирования данных 3-2-1. Делайте копии как загруженных фотографий и видео, так и базы данных Immich.", "backup_onboarding_footer": "Дополнительная информация по резервному копированию Immich доступна в документации.", "backup_onboarding_parts_title": "Стратегия 3-2-1 подразумевает:", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# не удалось выполнить}}", "library_created": "Создана новая библиотека: {library}", "library_deleted": "Библиотека удалена", - "library_import_path_description": "Укажите папку для импорта. Эта папка и все вложенные будут просканированы на наличие фото и видео.", + "library_details": "Параметры библиотеки", + "library_folder_description": "Укажите путь к папке для импорта. Эта папка, включая подпапки, будет просканирована на наличие фото и видео.", + "library_remove_exclusion_pattern_prompt": "Удалить этот шаблон исключения?", + "library_remove_folder_prompt": "Удалить эту папку из списка?", "library_scanning": "Периодическое сканирование", "library_scanning_description": "Настроить периодическое сканирование библиотеки", "library_scanning_enable_description": "Включить периодическое сканирование библиотеки", "library_settings": "Внешняя библиотека", "library_settings_description": "Управление внешними библиотеками", "library_tasks_description": "Сканирование внешних библиотек на наличие новых и/или изменённых объектов", + "library_updated": "Библиотека обновлена", "library_watching_enable_description": "Отслеживать изменения файлов во внешних библиотеках", "library_watching_settings": "[ЭКСПЕРИМЕНТАЛЬНО] Слежение за библиотекой", "library_watching_settings_description": "Автоматически следить за изменениями файлов", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Включить интеллектуальный поиск", "machine_learning_smart_search_enabled_description": "При отключении этой функции изображения не будут кодироваться для интеллектуального поиска.", "machine_learning_url_description": "URL-адрес сервера машинного обучения. Если указано несколько, запросы будут отправляться по очереди на каждый, пока от одного из них не будет получен успешный ответ. Серверы, которые не отвечают, будут временно игнорироваться до тех пор, пока не станут снова доступны.", + "maintenance_settings": "Обслуживание", + "maintenance_settings_description": "Перевод сервера Immich в режим обслуживания.", + "maintenance_start": "Включить режим обслуживания", + "maintenance_start_error": "Не удалось перейти в режим обслуживания.", "manage_concurrency": "Управление параллельностью", "manage_log_settings": "Управление настройками журнала", "map_dark_style": "Тёмный стиль", @@ -266,7 +274,7 @@ "quota_size_gib": "Размер квоты (GiB)", "refreshing_all_libraries": "Обновление всех библиотек", "registration": "Регистрация администратора", - "registration_description": "Первый зарегистрированный пользователь будет назначен администратором. В дальнейшем этой учетной записи будет доступно создание дополнительных пользователей и управление сервером.", + "registration_description": "Первый зарегистрированный пользователь будет назначен администратором. Он сможет управлять сервером и создавать дополнительных пользователей.", "require_password_change_on_login": "Требовать смену пароля при первом входе", "reset_settings_to_default": "Сброс настроек до значений по умолчанию", "reset_settings_to_recent_saved": "Не сохранённые изменения сброшены к последним сохраненным значениям", @@ -283,7 +291,7 @@ "server_welcome_message_description": "Сообщение, которое будет отображаться на странице входа.", "sidecar_job": "Метаданные из sidecar-файлов", "sidecar_job_description": "Обнаруживает и синхронизирует метаданные из sidecar-файлов", - "slideshow_duration_description": "Количество секунд для отображения каждого изображения", + "slideshow_duration_description": "Длительность показа слайдов в секундах", "smart_search_job_description": "Распознает содержимое медиафайлов для умного поиска", "storage_template_date_time_description": "В качестве даты используется информация о времени съёмки из данных объекта", "storage_template_date_time_sample": "Дата для примера: {date}", @@ -295,7 +303,7 @@ "storage_template_migration_info": "Расширения файлов всегда будут сохраняться в нижнем регистре. Изменения в шаблоне будут применяться только к новым объектам. Чтобы применить шаблон к ранее загруженным объектам, запустите {job}.", "storage_template_migration_job": "Задача по применению шаблона хранилища", "storage_template_more_details": "Для получения дополнительной информации об этой функции обратитесь к разделам документации Шаблон хранилища и Структура хранения файлов", - "storage_template_onboarding_description_v2": "Если эта функция включена, она автоматически организует файлы на основе заданного пользователем шаблона. Для получения дополнительной информации обратитесь к документации.", + "storage_template_onboarding_description_v2": "При включении этой функции файлы будут автоматически переименовываться и распределяться по папкам на основании заданного шаблона. Дополнительная информация доступна в документации.", "storage_template_path_length": "Примерный предел длины пути: {length, number}/{limit, number}", "storage_template_settings": "Шаблон хранилища", "storage_template_settings_description": "Управление структурой папок и именами загруженных файлов", @@ -430,6 +438,7 @@ "age_months": "{months, plural, one {# месяц} many {# месяцев} other {# месяца}}", "age_year_months": "1 год {months, plural, one {# месяц} many {# месяцев} other {# месяца}}", "age_years": "{years, plural, one {# год} many {# лет} other {# года}}", + "album": "Альбом", "album_added": "Альбом добавлен", "album_added_notification_setting_description": "Получать уведомление по электронной почте, когда вам предоставили доступ в общий альбом", "album_cover_updated": "Обложка альбома обновлена", @@ -475,6 +484,7 @@ "allow_edits": "Разрешить редактирование", "allow_public_user_to_download": "Разрешить скачивание", "allow_public_user_to_upload": "Разрешить добавление файлов", + "allowed": "Разрешено", "alt_text_qr_code": "QR-код", "anti_clockwise": "Против часовой", "api_key": "API ключ", @@ -485,7 +495,7 @@ "app_bar_signout_dialog_content": "Вы уверены, что хотите выйти?", "app_bar_signout_dialog_ok": "Да", "app_bar_signout_dialog_title": "Выйти", - "app_download_links": "Ссылки на загрузку мобильного приложения", + "app_download_links": "Ссылки для загрузки мобильного приложения", "app_settings": "Параметры приложения", "app_stores": "Магазины приложений", "app_update_available": "Доступна новая версия приложения", @@ -555,7 +565,7 @@ "authorized_devices": "Авторизованные устройства", "automatic_endpoint_switching_subtitle": "Подключаться локально по выбранной сети и использовать альтернативные адреса в ином случае", "automatic_endpoint_switching_title": "Автоматическая смена URL", - "autoplay_slideshow": "Автовоспроизведение слайдшоу", + "autoplay_slideshow": "Автовоспроизведение", "back": "Назад", "back_close_deselect": "Назад, закрыть или отменить выбор", "background_backup_running_error": "Выполняется фоновое резервное копирование, запуск вручную пока невозможен", @@ -725,7 +735,7 @@ "common_create_new_album": "Создать новый альбом", "completed": "Завершено", "confirm": "Подтвердить", - "confirm_admin_password": "Подтвердите пароль администратора", + "confirm_admin_password": "Подтверждение пароля администратора", "confirm_delete_face": "Удалить лицо человека {name} из этого объекта?", "confirm_delete_shared_link": "Вы действительно хотите удалить эту публичную ссылку?", "confirm_keep_this_delete_others": "Все объекты в группе кроме текущего будут удалены. Продолжить?", @@ -735,7 +745,7 @@ "confirm_tag_face_unnamed": "Хотите отметить этого человека?", "connected_device": "Подключенное устройство", "connected_to": "Подключено к", - "contain": "Вместить", + "contain": "Вписать", "context": "Контекст", "continue": "Продолжить", "control_bottom_app_bar_create_new_album": "Создать альбом", @@ -756,7 +766,7 @@ "copy_password": "Скопировать пароль", "copy_to_clipboard": "Скопировать в буфер обмена", "country": "Страна", - "cover": "Обложка", + "cover": "Обрезать", "covers": "Обложки", "create": "Создать", "create_album": "Создать альбом", @@ -894,8 +904,6 @@ "edit_description_prompt": "Укажите новое описание:", "edit_exclusion_pattern": "Редактирование шаблона исключения", "edit_faces": "Редактирование лиц", - "edit_import_path": "Изменить путь импорта", - "edit_import_paths": "Изменить путь импорта", "edit_key": "Изменить ключ", "edit_link": "Изменить ссылку", "edit_location": "Изменить местоположение", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Не удалось сгруппировать объекты", "failed_to_unstack_assets": "Не удалось разгруппировать объекты", "failed_to_update_notification_status": "Не удалось обновить статус уведомления", - "import_path_already_exists": "Этот путь импорта уже существует.", "incorrect_email_or_password": "Неверный адрес электронной почты или пароль", + "library_folder_already_exists": "Такая папка уже есть в списке.", "paths_validation_failed": "{paths, plural, one {# путь не прошёл} many {# путей не прошли} other {# пути не прошли}} проверку", "profile_picture_transparent_pixels": "Фотография профиля не должна содержать прозрачных пикселей. Попробуйте увеличить и/или переместить изображение.", "quota_higher_than_disk_size": "Вы установили квоту, превышающую размер диска", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Не удалось добавить объекты к публичной ссылке", "unable_to_add_comment": "Не удалось добавить комментарий", "unable_to_add_exclusion_pattern": "Не удалось добавить шаблон исключения", - "unable_to_add_import_path": "Не удалось добавить путь импорта", "unable_to_add_partners": "Не удалось добавить партнёров", "unable_to_add_remove_archive": "Не удалось {archived, select, true {удалить объект из архива} other {добавить объект в архив}}", "unable_to_add_remove_favorites": "Не удалось {favorite, select, true {добавить объект в избранное} other {удалить объект из избранного}}", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Не удалось удалить объект", "unable_to_delete_assets": "Ошибка при удалении объектов", "unable_to_delete_exclusion_pattern": "Не удалось удалить шаблон исключения", - "unable_to_delete_import_path": "Не удалось удалить путь импорта", "unable_to_delete_shared_link": "Не удалось удалить публичную ссылку", "unable_to_delete_user": "Не удалось удалить пользователя", "unable_to_download_files": "Не удалось скачать файлы", "unable_to_edit_exclusion_pattern": "Не удалось отредактировать шаблон исключения", - "unable_to_edit_import_path": "Не удалось отредактировать путь импорта", "unable_to_empty_trash": "Не удалось очистить корзину", "unable_to_enter_fullscreen": "Не удалось переключиться в полноэкранный режим", "unable_to_exit_fullscreen": "Не удалось выйти из полноэкранного режима", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Не удалось обновить пользователя", "unable_to_upload_file": "Не удалось загрузить файл" }, + "exclusion_pattern": "Шаблоны исключений", "exif": "Exif", "exif_bottom_sheet_description": "Добавить описание...", "exif_bottom_sheet_description_error": "Не удалось обновить описание", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Просмотр папок с фото и видео в файловой системе", "forgot_pin_code_question": "Забыли PIN-код?", "forward": "Вперёд", + "full_path": "Полный путь: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Для работы требуется загрузка внешних ресурсов с серверов Google.", "general": "Общие", @@ -1196,6 +1203,8 @@ "import_path": "Путь импорта", "in_albums": "В {count, plural, one {# альбоме} other {# альбомах}}", "in_archive": "В архиве", + "in_year": "{year} г.", + "in_year_selector": "В", "include_archived": "Отображать архив", "include_shared_albums": "Включать объекты общих альбомов", "include_shared_partner_assets": "Включать объекты партнёров", @@ -1232,6 +1241,7 @@ "language_setting_description": "Выберите предпочитаемый вами язык", "large_files": "Файлы наибольшего размера", "last": "Последний", + "last_months": "{count, plural, one {Последний месяц} many {# последних месяцев} other {# последних месяца}}", "last_seen": "Последний доступ", "latest_version": "Последняя версия", "latitude": "Широта", @@ -1241,6 +1251,8 @@ "let_others_respond": "Разрешить другим пользователям добавлять комментарии и отметки \"нравится\"", "level": "Уровень", "library": "Библиотека", + "library_add_folder": "Добавить папку", + "library_edit_folder": "Изменить путь к папке", "library_options": "Действия с библиотекой", "library_page_device_albums": "Альбомы на устройстве", "library_page_new_album": "Новый альбом", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Включить автоматический повтор видео при просмотре.", "main_branch_warning": "Вы используете версию приложения для разработки. Настоятельно рекомендуется перейти на релизную версию приложения!", "main_menu": "Главное меню", + "maintenance_description": "Сервер Immich переведён в режим обслуживания.", + "maintenance_end": "Отключить режим обслуживания", + "maintenance_end_error": "Не удалось отключить режим обслуживания.", + "maintenance_logged_in_as": "В настоящее время вы вошли в систему как {user}", + "maintenance_title": "Временно недоступно", "make": "Производитель", "manage_geolocation": "Управление местами съёмки", + "manage_media_access_rationale": "Это разрешение необходимо для корректного перемещения объектов в корзину и восстановления их из неё.", + "manage_media_access_settings": "Перейти к настройкам", + "manage_media_access_subtitle": "Разрешите приложению Immich управлять медиафайлами.", + "manage_media_access_title": "Доступ к управлению медиафайлами", "manage_shared_links": "Управление публичными ссылками", "manage_sharing_with_partners": "Функция совместного доступа к фото и видео, позволяющая видеть объекты партнёров, а также предоставлять доступ к своим", "manage_the_app_settings": "Управление настройками приложения", @@ -1377,6 +1398,7 @@ "more": "Дополнительные действия", "move": "Переместить", "move_off_locked_folder": "Убрать из личной папки", + "move_to": "Переместить в", "move_to_lock_folder_action_prompt": "Объекты добавлены в личную папку ({count} шт.)", "move_to_locked_folder": "В личную папку", "move_to_locked_folder_confirmation": "Эти фото и видео будут удалены из всех альбомов и будут доступны только в личной папке", @@ -1406,13 +1428,14 @@ "new_pin_code": "Новый PIN-код", "new_pin_code_subtitle": "Это ваш первый доступ к личной папке. Создайте PIN-код для защищенного доступа к этой странице.", "new_timeline": "Новая лента", + "new_update": "Новое обновление", "new_user_created": "Новый пользователь создан", "new_version_available": "ДОСТУПНА НОВАЯ ВЕРСИЯ", "newest_first": "Сначала новые", "next": "Далее", "next_memory": "Следующее воспоминание", "no": "Нет", - "no_albums_message": "Создайте альбом для систематизации ваших фотографий и видео", + "no_albums_message": "Создавайте альбомы для систематизации ваших фотографий и видео", "no_albums_with_name_yet": "Похоже, у вас пока нет альбомов с таким названием.", "no_albums_yet": "Похоже, у вас пока нет альбомов.", "no_archived_assets_message": "Архивируйте фотографии и видео, чтобы скрыть их при общем просмотре", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "Не найдено устройств для трансляции", "no_checksum_local": "Контрольные суммы отсутствуют - невозможно получить объекты на устройстве", "no_checksum_remote": "Контрольные суммы отсутствуют - невозможно получить объекты с сервера", + "no_devices": "Нет авторизованных устройств", "no_duplicates_found": "Дубликатов не обнаружено.", "no_exif_info_available": "Нет доступной информации exif", "no_explore_results_message": "Загружайте больше фотографий, чтобы наслаждаться вашей коллекцией.", "no_favorites_message": "Добавляйте объекты в избранное, чтобы быстрее находить свои лучшие фото и видео", "no_libraries_message": "Создайте внешнюю библиотеку для просмотра в Immich сторонних фотографий и видео", "no_local_assets_found": "На устройстве не найдено объектов с такой контрольной суммой", + "no_location_set": "Местоположение не установлено", "no_locked_photos_message": "Фото и видео, перемещенные в личную папку, скрыты и не отображаются при просмотре библиотеки.", "no_name": "Нет имени", "no_notifications": "Нет уведомлений", @@ -1434,9 +1459,10 @@ "no_places": "Нет мест", "no_remote_assets_found": "На сервере не найдено объектов с такой контрольной суммой", "no_results": "Нет результатов", - "no_results_description": "Попробуйте использовать синоним или более общее ключевое слово", - "no_shared_albums_message": "Создайте альбом для обмена фотографиями и видеозаписями с людьми в вашей сети", + "no_results_description": "Попробуйте использовать синонимы или более общие слова", + "no_shared_albums_message": "Создавайте альбомы для обмена фотографиями и видеозаписями с людьми в вашей сети", "no_uploads_in_progress": "Нет активных загрузок", + "not_allowed": "Запрещено", "not_available": "Нет данных", "not_in_any_album": "Ни в одном альбоме", "not_selected": "Не выбрано", @@ -1453,7 +1479,7 @@ "oauth": "OAuth", "obtainium_configurator": "Настройка Obtainium", "obtainium_configurator_instructions": "Для установки и обновления Android приложения Immich напрямую из источников на GitHub (минуя магазины приложений) можно использовать Obtainium. Создайте новый API ключ и укажите архитектуру приложения для формирования ссылки для Obtainium.", - "ocr": "OCR", + "ocr": "Текст (OCR)", "official_immich_resources": "Официальные ресурсы Immich", "offline": "Недоступен", "offset": "Смещение", @@ -1461,10 +1487,10 @@ "oldest_first": "Сначала старые", "on_this_device": "На этом устройстве", "onboarding": "Начало работы", - "onboarding_locale_description": "Выберите язык приложения. При необходимости его потом можно будет изменить в настройках.", + "onboarding_locale_description": "Выберите язык приложения (можно позже изменить в настройках).", "onboarding_privacy_description": "Следующие необязательные функции зависят от внешних сервисов и в любое время могут быть отключены в настройках.", - "onboarding_server_welcome_description": "Давайте настроим ваш экземпляр с помощью некоторых общих параметров.", - "onboarding_theme_description": "Выберите тему. Вы также сможете изменить её позже в настройках.", + "onboarding_server_welcome_description": "Давайте начнём с настройки нескольких параметров вашего сервера.", + "onboarding_theme_description": "Выберите тему (можно позже изменить в настройках).", "onboarding_user_welcome_description": "Давайте начнем!", "onboarding_welcome_user": "Добро пожаловать, {user}", "online": "Доступен", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} фото} other {{count, number} фото}}", "photos_from_previous_years": "Фотографии прошлых лет в этот день", "pick_a_location": "Выбрать местоположение", + "pick_custom_range": "Произвольный период", + "pick_date_range": "Выберите период", "pin_code_changed_successfully": "PIN-код успешно изменён", "pin_code_reset_successfully": "PIN-код успешно сброшен", "pin_code_setup_successfully": "PIN-код успешно установлен", @@ -1814,6 +1842,8 @@ "server_offline": "Оффлайн", "server_online": "Сервер в сети", "server_privacy": "Конфиденциальность сервера", + "server_restarting_description": "Страница скоро обновится.", + "server_restarting_title": "Сервер перезапускается", "server_stats": "Статистика сервера", "server_update_available": "Доступна новая версия сервера", "server_version": "Версия сервера", @@ -1931,10 +1961,10 @@ "show_or_hide_info": "Показать или скрыть информацию", "show_password": "Показать пароль", "show_person_options": "Действия с человеком", - "show_progress_bar": "Показать Индикатор Выполнения", + "show_progress_bar": "Отображать индикатор выполнения", "show_search_options": "Показать параметры поиска", "show_shared_links": "Показать публичные ссылки", - "show_slideshow_transition": "Показать слайд-шоу переход", + "show_slideshow_transition": "Плавный переход", "show_supporter_badge": "Значок поддержки", "show_supporter_badge_description": "Показать значок поддержки", "show_text_search_menu": "Показать меню текстового поиска", @@ -2027,6 +2057,7 @@ "third_party_resources": "Сторонние ресурсы", "time": "Время", "time_based_memories": "Воспоминания, основанные на времени", + "time_based_memories_duration": "Длительность показа слайдов в секундах", "timeline": "Временная шкала", "timezone": "Часовой пояс", "to_archive": "В архив", @@ -2167,6 +2198,7 @@ "welcome": "Добро пожаловать", "welcome_to_immich": "Добро пожаловать в Immich", "wifi_name": "Имя сети", + "workflow": "Рабочий процесс", "wrong_pin_code": "Неверный PIN-код", "year": "Год", "years_ago": "{years, plural, one {# год} few {# года} many {# лет} other {# года}} назад", diff --git a/i18n/si.json b/i18n/si.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/si.json @@ -0,0 +1 @@ +{} diff --git a/i18n/sk.json b/i18n/sk.json index 010ee89b3a..5deadabec0 100644 --- a/i18n/sk.json +++ b/i18n/sk.json @@ -17,7 +17,6 @@ "add_birthday": "Pridať narodeniny", "add_endpoint": "Pridať koncový bod", "add_exclusion_pattern": "Pridať vzor vylúčenia", - "add_import_path": "Pridať cestu pre import", "add_location": "Pridať polohu", "add_more_users": "Pridať viac používateľov", "add_partner": "Pridať partnera", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Prepnúť výber pre {album}", "add_to_albums": "Pridať do albumov", "add_to_albums_count": "Pridať do albumov ({count})", + "add_to_bottom_bar": "Pridať do", "add_to_shared_album": "Pridať do zdieľaného albumu", "add_upload_to_stack": "Nahrať a pridať do zoskupených", "add_url": "Pridať URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, one {# neúspešný} few {# neúspešné} other {# neúspešných}}", "library_created": "Vytvorená knižnica: {library}", "library_deleted": "Knižnica bola vymazaná", - "library_import_path_description": "Zvoľte priečinok na importovanie. Tento priečinok vrátane podpriečinkov bude skenovaný pre obrázky a videá.", + "library_details": "Podrobnosti o knižnici", + "library_folder_description": "Určite priečinok, ktorý chcete importovať. Tento priečinok vrátane podpriečinkov bude prehľadaný na prítomnosť obrázkov a videí.", + "library_remove_exclusion_pattern_prompt": "Naozaj chcete odstrániť tento vzor vylúčenia?", + "library_remove_folder_prompt": "Naozaj chcete odstrániť tento importovaný priečinok?", "library_scanning": "Pravidelné skenovanie", "library_scanning_description": "Nastaviť pravidelné skenovanie knižnice", "library_scanning_enable_description": "Zapnúť pravidelné skenovanie knižnice", "library_settings": "Externá knižnica", "library_settings_description": "Spravovať nastavenia externej knižnice", "library_tasks_description": "Vyhľadajte nové alebo zmenené médiá v externých knižniciach", + "library_updated": "Aktualizovaná knižnica", "library_watching_enable_description": "Sledovať externé knižnice pre zmeny v súboroch", "library_watching_settings": "Sledovanie knižnice [EXPERIMENTÁLNE]", "library_watching_settings_description": "Automaticky sledovať zmenené súbory", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Povoliť inteligentné vyhľadávanie", "machine_learning_smart_search_enabled_description": "Ak je vypnuté, obrázky nebudú spracované pre inteligentné vyhľadávanie.", "machine_learning_url_description": "URL adresa servera strojového učenia. Ak je zadaných viacero adries URL, každý server bude testovaný postupne, kým jeden z nich neodpovie úspešne, v poradí od prvého po posledný. Servery, ktoré neodpovedajú, budú dočasne ignorované, kým nebudú opäť online.", + "maintenance_settings": "Údržba", + "maintenance_settings_description": "Prepnúť Immich do režimu údržby.", + "maintenance_start": "Spustiť režim údržby", + "maintenance_start_error": "Nepodarilo sa spustiť režim údržby.", "manage_concurrency": "Spravovať súbežnosť", "manage_log_settings": "Spravovať nastavenia ukladania záznamov", "map_dark_style": "Tmavý štýl", @@ -430,6 +438,7 @@ "age_months": "Vek {months, plural, one {# mesiac} few {# mesiace} other {# mesiacov}}", "age_year_months": "Vek 1 rok, {months, plural, one {# mesiac} few {# mesiace} other {# mesiacov}}", "age_years": "{years, plural, other {Vek #}}", + "album": "Album", "album_added": "Album bol pridaný", "album_added_notification_setting_description": "Obdržať upozornenie emailom, keď vás pridajú do zdieľaného albumu", "album_cover_updated": "Obal albumu aktualizovaný", @@ -475,6 +484,7 @@ "allow_edits": "Povoliť úpravy", "allow_public_user_to_download": "Povoliť verejnému používateľovi stiahnutie", "allow_public_user_to_upload": "Umožniť verejnému používateľovi nahrať", + "allowed": "Povolené", "alt_text_qr_code": "Obrázok QR kódu", "anti_clockwise": "Proti smeru hodinových ručičiek", "api_key": "API Klúč", @@ -894,8 +904,6 @@ "edit_description_prompt": "Vyberte prosím nový popis:", "edit_exclusion_pattern": "Upraviť vzor vylúčenia", "edit_faces": "Upraviť tváre", - "edit_import_path": "Upraviť cestu importu", - "edit_import_paths": "Upraviť cesty importu", "edit_key": "Upraviť kľúč", "edit_link": "Upraviť odkaz", "edit_location": "Upraviť polohu", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Nepodarilo sa zoskupiť položky", "failed_to_unstack_assets": "Nepodarilo sa zrušiť zoskupenie položiek", "failed_to_update_notification_status": "Nepodarilo sa aktualizovať stav oznámenia", - "import_path_already_exists": "Táto cesta importu už existuje.", "incorrect_email_or_password": "Nesprávny e-mail alebo heslo", + "library_folder_already_exists": "Táto cesta importu už existuje.", "paths_validation_failed": "{paths, plural, one {# cesta zlyhala} few {# cesty zlyhali} other {# ciest zlyhalo}} pri validácii", "profile_picture_transparent_pixels": "Profilové obrázky nemôžu mať priehľadné pixely. Prosím priblížte a/alebo posuňte obrázok.", "quota_higher_than_disk_size": "Nastavili ste kvótu vyššiu ako je veľkosť disku", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Nie je možné pridať položky k zdieľanému odkazu", "unable_to_add_comment": "Nie je možné pridať komentár", "unable_to_add_exclusion_pattern": "Nie je možné pridať vzor vylúčenia", - "unable_to_add_import_path": "Nie je možné pridať cestu importu", "unable_to_add_partners": "Nie je možné pridať partnerov", "unable_to_add_remove_archive": "Nie je možné {archived, select, true {odstrániť položku z} other {pridať položku do}} archívu", "unable_to_add_remove_favorites": "Nepodarilo sa {favorite, select, true {pridať položku do} other {odstrániť položku z}} obľúbených", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Nie je možné vymazať položku", "unable_to_delete_assets": "Chyba pri odstraňovaní položiek", "unable_to_delete_exclusion_pattern": "Nie je možné vymazať vylučovací vzor", - "unable_to_delete_import_path": "Nie je možné odstrániť cestu importu", "unable_to_delete_shared_link": "Nie je možné vymazať zdieľaný odkaz", "unable_to_delete_user": "Nie je možné vymazať používateľa", "unable_to_download_files": "Nie je možné stiahnuť súbory", "unable_to_edit_exclusion_pattern": "Nie je možné upraviť vzorec vylúčenia", - "unable_to_edit_import_path": "Nie je možné upraviť cestu importu", "unable_to_empty_trash": "Nie je možné vyprázdniť kôš", "unable_to_enter_fullscreen": "Nie je možné prejsť do režimu celej obrazovky", "unable_to_exit_fullscreen": "Nie je možné opustiť režim celej obrazovky", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Nie je možné aktualizovať používateľa", "unable_to_upload_file": "Nie je možné nahrať súbor" }, + "exclusion_pattern": "Vzor vylúčenia", "exif": "Exif", "exif_bottom_sheet_description": "Pridať popis...", "exif_bottom_sheet_description_error": "Chyba pri aktualizácii popisu", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Prezeranie zobrazenia priečinkov fotografií a videí v systéme súborov", "forgot_pin_code_question": "Zabudli ste svoj PIN kód?", "forward": "Dopredu", + "full_path": "Celá cesta: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Táto funkcia načítava externé zdroje zo spoločnosti Google, aby mohla fungovať.", "general": "Všeobecné", @@ -1196,6 +1203,8 @@ "import_path": "Cesta na import", "in_albums": "V {count, plural, one {# albume} other {# albumoch}}", "in_archive": "V archíve", + "in_year": "V {year}", + "in_year_selector": "V", "include_archived": "Zahrnúť archivované", "include_shared_albums": "Zahrnúť zdieľané albumy", "include_shared_partner_assets": "Vrátane zdieľaných položiek partnera", @@ -1232,6 +1241,7 @@ "language_setting_description": "Vyberte požadovaný jazyk", "large_files": "Veľké súbory", "last": "Posledné", + "last_months": "{count, plural, one {Minulý mesiac} few {Posledné # mesiace} other {Posledných # mesiacov}}", "last_seen": "Naposledy videné", "latest_version": "Najnovšia verzia", "latitude": "Zemepisná šírka", @@ -1241,6 +1251,8 @@ "let_others_respond": "Nechajte ostatných reagovať", "level": "Úroveň", "library": "Knižnica", + "library_add_folder": "Pridať priečinok", + "library_edit_folder": "Upraviť priečinok", "library_options": "Možnosti knižnice", "library_page_device_albums": "Albumy v zariadení", "library_page_new_album": "Nový album", @@ -1312,8 +1324,17 @@ "loop_videos_description": "Povolí prehrávanie videí v slučke v detailnom zobrazení.", "main_branch_warning": "Používate vývojársku verziu; dôrazne odporúčame používať vydané verzie!", "main_menu": "Hlavná ponuka", + "maintenance_description": "Immich bol prepnutý do režimu údržby.", + "maintenance_end": "Ukončiť režim údržby", + "maintenance_end_error": "Nepodarilo sa ukončiť režim údržby.", + "maintenance_logged_in_as": "Aktuálne prihlásený ako {user}", + "maintenance_title": "Dočasne nedostupné", "make": "Výrobca", "manage_geolocation": "Spravovať polohu", + "manage_media_access_rationale": "Toto povolenie je potrebné na správne presúvanie súborov do koša a ich obnovenie z neho.", + "manage_media_access_settings": "Otvoriť nastavenia", + "manage_media_access_subtitle": "Povoliť aplikácii Immich spravovať a presúvať mediálne súbory.", + "manage_media_access_title": "Prístup k správe médií", "manage_shared_links": "Spravovať zdieľané odkazy", "manage_sharing_with_partners": "Spravovať zdieľanie s partnermi", "manage_the_app_settings": "Spravovať nastavenia aplikácie", @@ -1377,6 +1398,7 @@ "more": "Viac", "move": "Presunúť", "move_off_locked_folder": "Presunúť zo zamknutého priečinka", + "move_to": "Presunúť do", "move_to_lock_folder_action_prompt": "{count} pridaných do zamknutého priečinka", "move_to_locked_folder": "Presunúť do zamknutého priečinka", "move_to_locked_folder_confirmation": "Tieto fotografie a videá budú odobrané zo všetkých albumov a bude ich možné zobraziť len v zamknutom priečinku", @@ -1406,6 +1428,7 @@ "new_pin_code": "Nový PIN kód", "new_pin_code_subtitle": "Toto je váš prvý prístup k zamknutému priečinku. Vytvorte si PIN kód na bezpečný prístup k tejto stránke", "new_timeline": "Nová časová os", + "new_update": "Nová aktualizácia", "new_user_created": "Nový používateľ vytvorený", "new_version_available": "JE DOSTUPNÁ NOVÁ VERZIA", "newest_first": "Najprv najnovšie", @@ -1421,12 +1444,14 @@ "no_cast_devices_found": "Nenašli sa žiadne zariadenia na prenos", "no_checksum_local": "Kontrola súčtu nie je k dispozícii – nie je možné načítať lokálne položky", "no_checksum_remote": "Kontrola súčtu nie je k dispozícii – nie je možné načítať vzdialené položky", + "no_devices": "Žiadne autorizované zariadenia", "no_duplicates_found": "Nenašli sa žiadne duplicity.", "no_exif_info_available": "Nie sú dostupné exif údaje", "no_explore_results_message": "Nahrajte viac fotiek na objavovanie vašej zbierky.", "no_favorites_message": "Pridajte si obľúbené, aby ste rýchlo našli svoje najlepšie obrázky a videá", "no_libraries_message": "Vytvorte externú knižnicu na prezeranie fotiek a videí", "no_local_assets_found": "Neboli nájdené žiadne lokálne položky s touto kontrolnou sumou", + "no_location_set": "Nie je nastavená žiadna poloha", "no_locked_photos_message": "Fotografie a videá v zamknutom priečinku sú skryté a nezobrazujú sa pri prehľadávaní alebo vyhľadávaní v knižnici.", "no_name": "Bez mena", "no_notifications": "Žiadne oznámenia", @@ -1437,6 +1462,7 @@ "no_results_description": "Skúste synonymum alebo všeobecnejší výraz", "no_shared_albums_message": "Vytvorte album na zdieľanie fotiek a videí s ľuďmi vo vašej sieti", "no_uploads_in_progress": "Žiadne prebiehajúce nahrávanie", + "not_allowed": "Nepovolené", "not_available": "Nedostupné", "not_in_any_album": "Nie je v žiadnom albume", "not_selected": "Nevybrané", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number} fotka} few {{count, number} fotky} other {{count, number} fotiek}}", "photos_from_previous_years": "Fotky z minulých rokov", "pick_a_location": "Vyberte polohu", + "pick_custom_range": "Vlastný rozsah", + "pick_date_range": "Vybrať rozsah dátumov", "pin_code_changed_successfully": "Úspešne ste zmenili PIN kód", "pin_code_reset_successfully": "Úspešne ste obnovili PIN kód", "pin_code_setup_successfully": "Úspešne ste nastavili PIN kód", @@ -1814,6 +1842,8 @@ "server_offline": "Server je Offline", "server_online": "Server je Online", "server_privacy": "Zásady ochrany osobných údajov servera", + "server_restarting_description": "Táto stránka sa o chvíľu obnoví.", + "server_restarting_title": "Server sa reštartuje", "server_stats": "Štatistiky servera", "server_update_available": "Aktualizácia servera je k dispozícii", "server_version": "Verzia servera", @@ -2027,6 +2057,7 @@ "third_party_resources": "Zdroje tretích strán", "time": "Čas", "time_based_memories": "Časové spomienky", + "time_based_memories_duration": "Počet sekúnd zobrazenia jednotlivých obrázkov.", "timeline": "Časová os", "timezone": "Časové pásmo", "to_archive": "Archivovať", @@ -2167,6 +2198,7 @@ "welcome": "Vitajte", "welcome_to_immich": "Vitajte v Immich", "wifi_name": "Názov Wi-Fi", + "workflow": "Pracovný postup", "wrong_pin_code": "Nesprávny PIN kód", "year": "Rok", "years_ago": "pred {years, plural, one {# rokom} other {# rokmi}}", diff --git a/i18n/sl.json b/i18n/sl.json index 9ae16549f5..5a7887c365 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -17,7 +17,6 @@ "add_birthday": "Dodaj rojstni dan", "add_endpoint": "Dodaj končno točko", "add_exclusion_pattern": "Dodaj vzorec izključitve", - "add_import_path": "Dodaj pot uvoza", "add_location": "Dodaj lokacijo", "add_more_users": "Dodaj več uporabnikov", "add_partner": "Dodaj partnerja", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Preklopi izbiro za {album}", "add_to_albums": "Dodaj v albume", "add_to_albums_count": "Dodaj v albume ({count})", + "add_to_bottom_bar": "Dodaj v", "add_to_shared_album": "Dodaj k deljenemu albumu", "add_upload_to_stack": "Dodaj nalaganje v sklad", "add_url": "Dodaj URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# neuspešni}}", "library_created": "Ustvarjena knjižnica: {library}", "library_deleted": "Knjižnica izbrisana", - "library_import_path_description": "Določi mapo za uvoz. Ta mapa in njene podmape bodo pregledane za slike in video posnetke.", + "library_details": "Podrobnosti o knjižnici", + "library_folder_description": "Določite mapo za uvoz. Ta mapa, vključno s podmapami, bo pregledana za slike in videoposnetke.", + "library_remove_exclusion_pattern_prompt": "Ali ste prepričani, da želite odstraniti ta vzorec izključitve?", + "library_remove_folder_prompt": "Ali ste prepričani, da želite odstraniti to mapo za uvoz?", "library_scanning": "Periodični pregledi", "library_scanning_description": "Nastavi periodični pregled knjižnic", "library_scanning_enable_description": "Omogoči periodični pregled knjižnic", "library_settings": "Zunanja knjižnica", "library_settings_description": "Uredi nastavitve zunanje knjižnice", "library_tasks_description": "Izvedi nalogo knjižnice", + "library_updated": "Posodobljena knjižnica", "library_watching_enable_description": "Opazuj spremembe datotek v zunanji knjižnici", "library_watching_settings": "Opazovanje knjižnice [POSKUSNO]", "library_watching_settings_description": "Samodejno opazuj spremembo datotek", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "Omogoči pametno iskanje", "machine_learning_smart_search_enabled_description": "Če je onemogočeno, slike ne bodo kodirane za pametno iskanje.", "machine_learning_url_description": "URL strežnika za strojno učenje. Če je na voljo več kot en URL, bo vsak strežnik poskusen posamično, dokler se eden ne odzove uspešno, v vrstnem redu od prvega do zadnjega. Strežniki, ki se ne odzovejo, bodo začasno prezrti, dokler se spet ne vzpostavijo.", + "maintenance_settings": "Vzdrževanje", + "maintenance_settings_description": "Preklopite Immich v vzdrževalni način.", + "maintenance_start": "Zaženi način vzdrževanja", + "maintenance_start_error": "Vzdrževalnega načina ni bilo mogoče zagnati.", "manage_concurrency": "Upravljanje sočasnosti", "manage_log_settings": "Upravljanje nastavitev dnevnika", "map_dark_style": "Temni način", @@ -430,6 +438,7 @@ "age_months": "Starost {months, plural, one {# mesec} two {# meseca} few {# mesece} other {# mesecev}}", "age_year_months": "Starost 1 leto, {months, plural, one {# mesec} two {# meseca} few {# mesece} other {# mesecev}}", "age_years": "Starost {years, plural, one {# leto} two {# leti} few {# leta} other {# let}}", + "album": "Album", "album_added": "Album dodan", "album_added_notification_setting_description": "Prejmite e-poštno obvestilo, ko ste dodani v album v skupni rabi", "album_cover_updated": "Naslovnica albuma posodobljena", @@ -475,6 +484,7 @@ "allow_edits": "Dovoli urejanja", "allow_public_user_to_download": "Dovoli javnemu uporabniku prenos", "allow_public_user_to_upload": "Dovolite javnemu uporabniku nalaganje", + "allowed": "Dovoljeno", "alt_text_qr_code": "Slika QR kode", "anti_clockwise": "V nasprotni smeri urinega kazalca", "api_key": "API ključ", @@ -894,8 +904,6 @@ "edit_description_prompt": "Izberite nov opis:", "edit_exclusion_pattern": "Uredi vzorec izključitve", "edit_faces": "Uredi obraze", - "edit_import_path": "Uredi uvozno pot", - "edit_import_paths": "Uredi uvozne poti", "edit_key": "Uredi ključ", "edit_link": "Uredi povezavo", "edit_location": "Uredi lokacijo", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "Zlaganje sredstev ni uspelo", "failed_to_unstack_assets": "Sredstev ni bilo mogoče razložiti", "failed_to_update_notification_status": "Stanja obvestila ni bilo mogoče posodobiti", - "import_path_already_exists": "Ta uvozna pot že obstaja.", "incorrect_email_or_password": "Napačen e-poštni naslov ali geslo", + "library_folder_already_exists": "Ta pot uvoza že obstaja.", "paths_validation_failed": "{paths, plural, one {# pot ni bila uspešno preverjena} two {# poti nista bili uspešno preverjeni} few {# poti niso bile uspešno preverjene} other {# poti ni bilo uspešno preverjenih}}", "profile_picture_transparent_pixels": "Profilne slike ne smejo imeti prosojnih slikovnih pik. Povečajte in/ali premaknite sliko.", "quota_higher_than_disk_size": "Nastavili ste kvoto, ki je višja od velikosti diska", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Povezavi v skupni rabi ni mogoče dodati sredstev", "unable_to_add_comment": "Ni mogoče dodati komentarja", "unable_to_add_exclusion_pattern": "Vzorca izključitve ni mogoče dodati", - "unable_to_add_import_path": "Uvozne poti ni mogoče dodati", "unable_to_add_partners": "Partnerjev ni mogoče dodati", "unable_to_add_remove_archive": "Ni mogoče {archived, select, true {odstraniti sredstva iz} other {ter dodati sredstvo v}} archive", "unable_to_add_remove_favorites": "Ni mogoče {favorite, select, true {dodati sredstva v} other {ter ga odstraniti iz}} priljubljenih", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "Sredstva ni mogoče izbrisati", "unable_to_delete_assets": "Napaka pri brisanju sredstev", "unable_to_delete_exclusion_pattern": "Vzorca izključitve ni mogoče izbrisati", - "unable_to_delete_import_path": "Uvozne poti ni mogoče izbrisati", "unable_to_delete_shared_link": "Povezave v skupni rabi ni mogoče izbrisati", "unable_to_delete_user": "Uporabnika ni mogoče izbrisati", "unable_to_download_files": "Ni mogoče prenesti datotek", "unable_to_edit_exclusion_pattern": "Vzorca izključitve ni mogoče urediti", - "unable_to_edit_import_path": "Uvozne poti ni mogoče urediti", "unable_to_empty_trash": "Smetnjaka ni mogoče izprazniti", "unable_to_enter_fullscreen": "Celozaslonski način ni mogoč", "unable_to_exit_fullscreen": "Ni mogoče zapreti celozaslonskega načina", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "Uporabnika ni mogoče posodobiti", "unable_to_upload_file": "Datoteke ni mogoče naložiti" }, + "exclusion_pattern": "Vzorec izključitve", "exif": "Exif", "exif_bottom_sheet_description": "Dodaj opis..", "exif_bottom_sheet_description_error": "Napaka pri posodabljanju opisa", @@ -1115,6 +1121,7 @@ "folders_feature_description": "Brskanje po pogledu mape za fotografije in videoposnetke v datotečnem sistemu", "forgot_pin_code_question": "Ste pozabili PIN?", "forward": "Naprej", + "full_path": "Celotna pot: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Ta funkcija za delovanje nalaga zunanje vire iz Googla.", "general": "Splošno", @@ -1151,6 +1158,7 @@ "hide_named_person": "Skrij osebo {name}", "hide_password": "Skrij geslo", "hide_person": "Skrij osebo", + "hide_text_recognition": "Skrij prepoznavanje besedila", "hide_unnamed_people": "Skrij osebe brez imen", "home_page_add_to_album_conflicts": "Dodanih {added} sredstev v album {album}. {failed} sredstev je že v albumu.", "home_page_add_to_album_err_local": "Lokalnih sredstev še ni mogoče dodati v albume, preskakujem", @@ -1196,6 +1204,8 @@ "import_path": "Pot uvoza", "in_albums": "V {count, plural, one {# album} two {# albuma} few {# albume} other {# albumov}}", "in_archive": "V arhiv", + "in_year": "V {year}", + "in_year_selector": "V", "include_archived": "Vključi arhivirano", "include_shared_albums": "Vključite skupne albume", "include_shared_partner_assets": "Vključite partnerjeva skupna sredstva", @@ -1232,6 +1242,7 @@ "language_setting_description": "Izberite želeni jezik", "large_files": "Velike datoteke", "last": "Zadnji", + "last_months": "{count, plural, one {Zadnji mesec} two {Zadnja # meseca} few {Zadnje # mesece} other {Zadnjih # mesecev}}", "last_seen": "Nazadnje viden", "latest_version": "Najnovejša različica", "latitude": "Zemljepisna širina", @@ -1241,6 +1252,8 @@ "let_others_respond": "Naj drugi odgovorijo", "level": "Raven", "library": "Knjižnica", + "library_add_folder": "Dodaj mapo", + "library_edit_folder": "Uredi mapo", "library_options": "Možnosti knjižnice", "library_page_device_albums": "Albumi v napravi", "library_page_new_album": "Nov album", @@ -1312,8 +1325,17 @@ "loop_videos_description": "Omogočite samodejno ponavljanje videoposnetka v pregledovalniku podrobnosti.", "main_branch_warning": "Uporabljate razvojno različico; močno priporočamo uporabo izdajne različice!", "main_menu": "Glavni meni", + "maintenance_description": "Immich je bil preklopljen v vzdrževalni način.", + "maintenance_end": "Konec vzdrževalnega načina", + "maintenance_end_error": "Vzdrževalnega načina ni bilo mogoče končati.", + "maintenance_logged_in_as": "Trenutno prijavljen kot {user}", + "maintenance_title": "Trenutno ni na voljo", "make": "Izdelava", "manage_geolocation": "Upravljanje lokacije", + "manage_media_access_rationale": "To dovoljenje je potrebno za pravilno premikanje sredstev v koš in njihovo obnovitev iz njega.", + "manage_media_access_settings": "Odpri nastavitve", + "manage_media_access_subtitle": "Dovolite aplikaciji Immich upravljanje in premikanje medijskih datotek.", + "manage_media_access_title": "Dostop do upravljanja medijev", "manage_shared_links": "Upravljanje povezav v skupni rabi", "manage_sharing_with_partners": "Upravljajte skupno rabo s partnerji", "manage_the_app_settings": "Upravljajte nastavitve aplikacije", @@ -1377,6 +1399,7 @@ "more": "Več", "move": "Premakni", "move_off_locked_folder": "Premakni iz zaklenjene mape", + "move_to": "Premakni v", "move_to_lock_folder_action_prompt": "V zaklenjeno mapo je bilo dodanih {count}", "move_to_locked_folder": "Premakni v zaklenjeno mapo", "move_to_locked_folder_confirmation": "Te fotografije in videoposnetki bodo odstranjeni iz vseh albumov in si jih bo mogoče ogledati le v zaklenjeni mapi", @@ -1406,6 +1429,7 @@ "new_pin_code": "Nova PIN koda", "new_pin_code_subtitle": "To je vaš prvi dostop do zaklenjene mape. Ustvarite PIN kodo za varen dostop do te strani", "new_timeline": "Nova časovnica", + "new_update": "Nova posodobitev", "new_user_created": "Nov uporabnik ustvarjen", "new_version_available": "NA VOLJO JE NOVA RAZLIČICA", "newest_first": "Najprej najnovejše", @@ -1421,12 +1445,14 @@ "no_cast_devices_found": "Naprav za predvajanje ni bilo mogoče najti", "no_checksum_local": "Kontrolna vsota ni na voljo – lokalnih sredstev ni mogoče pridobiti", "no_checksum_remote": "Kontrolna vsota ni na voljo – oddaljenega sredstva ni mogoče pridobiti", + "no_devices": "Ni pooblaščenih naprav", "no_duplicates_found": "Najden ni bil noben dvojnik.", "no_exif_info_available": "Podatki o exif niso na voljo", "no_explore_results_message": "Naložite več fotografij, da raziščete svojo zbirko.", "no_favorites_message": "Dodajte priljubljene, da hitreje najdete svoje najboljše slike in videoposnetke", "no_libraries_message": "Ustvarite zunanjo knjižnico za ogled svojih fotografij in videoposnetkov", "no_local_assets_found": "S to kontrolno vsoto ni bilo najdenih lokalnih sredstev", + "no_location_set": "Lokacija ni nastavljena", "no_locked_photos_message": "Fotografije in videoposnetki v zaklenjeni mapi so skriti in se ne bodo prikazali med brskanjem ali iskanjem po knjižnici.", "no_name": "Brez imena", "no_notifications": "Ni obvestil", @@ -1437,6 +1463,7 @@ "no_results_description": "Poskusite s sinonimom ali bolj splošno ključno besedo", "no_shared_albums_message": "Ustvarite album za skupno rabo fotografij in videoposnetkov z osebami v vašem omrežju", "no_uploads_in_progress": "Ni nalaganj v teku", + "not_allowed": "Ni dovoljeno", "not_available": "Ni na voljo", "not_in_any_album": "Ni v nobenem albumu", "not_selected": "Ni izbrano", @@ -1547,6 +1574,8 @@ "photos_count": "{count, plural, one {{count, number} slika} two {{count, number} sliki} few {{count, number} slike} other {{count, number} slik}}", "photos_from_previous_years": "Fotografije iz prejšnjih let", "pick_a_location": "Izberi lokacijo", + "pick_custom_range": "Obseg po meri", + "pick_date_range": "Izberi datumsko obdobje", "pin_code_changed_successfully": "PIN koda je bila uspešno spremenjena", "pin_code_reset_successfully": "PIN koda je bila uspešno ponastavljena", "pin_code_setup_successfully": "Uspešno nastavljena PIN koda", @@ -1814,6 +1843,8 @@ "server_offline": "Strežnik nima povezave", "server_online": "Strežnik povezan", "server_privacy": "Zasebnost strežnika", + "server_restarting_description": "Ta stran se bo za trenutek osvežila.", + "server_restarting_title": "Strežnik se znova zaganja", "server_stats": "Statistika strežnika", "server_update_available": "Posodobitev strežnika je na voljo", "server_version": "Različica strežnika", @@ -1937,6 +1968,7 @@ "show_slideshow_transition": "Prikaži prehod diaprojekcije", "show_supporter_badge": "Značka podpornika", "show_supporter_badge_description": "Prikaži značko podpornika", + "show_text_recognition": "Prikaži prepoznavanje besedila", "show_text_search_menu": "Prikaži meni za iskanje po besedilu", "shuffle": "Naključno", "sidebar": "Stranska vrstica", @@ -2007,6 +2039,7 @@ "tags": "Oznake", "tap_to_run_job": "Dotaknite se za zagon opravila", "template": "Predloga", + "text_recognition": "Prepoznavanje besedila", "theme": "Tema", "theme_selection": "Izbira teme", "theme_selection_description": "Samodejno nastavi temo na svetlo ali temno glede na sistemske nastavitve brskalnika", @@ -2027,6 +2060,7 @@ "third_party_resources": "Viri tretjih oseb", "time": "Čas", "time_based_memories": "Časovni spomini", + "time_based_memories_duration": "Število sekund za prikaz vsake slike.", "timeline": "Časovnica", "timezone": "Časovni pas", "to_archive": "Arhiv", @@ -2167,6 +2201,7 @@ "welcome": "Dobrodošli", "welcome_to_immich": "Dobrodošli v Immich", "wifi_name": "Wi-Fi ime", + "workflow": "Potek dela", "wrong_pin_code": "Napačna PIN koda", "year": "Leto", "years_ago": "{years, plural, one {# leto} two {# leti} few {# leta} other {# let}} nazaj", diff --git a/i18n/sq.json b/i18n/sq.json index de7c5faa27..cd521122df 100644 --- a/i18n/sq.json +++ b/i18n/sq.json @@ -17,7 +17,6 @@ "add_birthday": "Shto një ditëlindje", "add_endpoint": "Shto një endpoint", "add_exclusion_pattern": "Shto model përjashtimi", - "add_import_path": "Shto vënd importimi", "add_location": "Shto vendndodhje", "add_more_users": "Shto më shumë përdorues", "add_partner": "Shto partner", diff --git a/i18n/sr_Cyrl.json b/i18n/sr_Cyrl.json index 8a14e18de5..8c3f25a3cf 100644 --- a/i18n/sr_Cyrl.json +++ b/i18n/sr_Cyrl.json @@ -17,7 +17,6 @@ "add_birthday": "Додај рођендан", "add_endpoint": "Додај адресу", "add_exclusion_pattern": "Додај образац изузимања", - "add_import_path": "Додај путању увоза", "add_location": "Додај локацију", "add_more_users": "Додај кориснике", "add_partner": "Додај партнера", @@ -107,7 +106,6 @@ "jobs_failed": "{jobCount, plural, one {# неуспешни} few {# неуспешна} other {# неуспешних}}", "library_created": "Направљена библиотека: {library}", "library_deleted": "Библиотека је избрисана", - "library_import_path_description": "Одредите фасциклу за увоз. Ова фасцикла, укључујући подфасцикле, биће скенирана за слике и видео записе.", "library_scanning": "Периодично скенирање", "library_scanning_description": "Конфигуришите периодично скенирање библиотеке", "library_scanning_enable_description": "Омогући периодично скенирање библиотеке", @@ -814,8 +812,6 @@ "edit_description": "Измени опис", "edit_exclusion_pattern": "Измените образац изузимања", "edit_faces": "Уреди лица", - "edit_import_path": "Уреди путању за преузимање", - "edit_import_paths": "Уреди Путање за Преузимање", "edit_key": "Измени кључ", "edit_link": "Уреди везу", "edit_location": "Уреди локацију", @@ -878,7 +874,6 @@ "failed_to_stack_assets": "Слагање датотека није успело", "failed_to_unstack_assets": "Разгруписање датотека није успело", "failed_to_update_notification_status": "Ажурирање статуса обавештења није успело", - "import_path_already_exists": "Ова путања увоза већ постоји.", "incorrect_email_or_password": "Неисправан e-mail или лозинка", "paths_validation_failed": "{paths, plural, one {# путања није прошла} other {# путањe нису прошле}} проверу ваљаности", "profile_picture_transparent_pixels": "Слике профила не могу имати прозирне пикселе. Молимо увећајте и/или померите слику.", @@ -887,7 +882,6 @@ "unable_to_add_assets_to_shared_link": "Није могуће додати датотеке дељеној вези", "unable_to_add_comment": "Није могуће додати коментар", "unable_to_add_exclusion_pattern": "Није могуће додати образац изузимања", - "unable_to_add_import_path": "Није могуће додати путању за увоз", "unable_to_add_partners": "Није могуће додати партнере", "unable_to_add_remove_archive": "Није могуће {archived, select, true {уклонити датотеке из} other {додати датотеке у}} архиву", "unable_to_add_remove_favorites": "Није могуће {favorite, select, true {додати датотеке у} other {уклонити датотеке из}} фаворите", @@ -909,12 +903,10 @@ "unable_to_delete_asset": "Није могуће избрисати датотеке", "unable_to_delete_assets": "Грешка при брисању датотека", "unable_to_delete_exclusion_pattern": "Није могуће избрисати образац изузимања", - "unable_to_delete_import_path": "Није могуће избрисати путању за увоз", "unable_to_delete_shared_link": "Није могуће избрисати дељени link", "unable_to_delete_user": "Није могуће избрисати корисника", "unable_to_download_files": "Није могуће преузети датотеке", "unable_to_edit_exclusion_pattern": "Није могуће изменити образац изузимања", - "unable_to_edit_import_path": "Није могуће изменити путању увоза", "unable_to_empty_trash": "Није могуће испразнити отпад", "unable_to_enter_fullscreen": "Није могуће отворити преко целог екрана", "unable_to_exit_fullscreen": "Није могуће изаћи из целог екрана", diff --git a/i18n/sr_Latn.json b/i18n/sr_Latn.json index aa895cd20c..f17de2c8b1 100644 --- a/i18n/sr_Latn.json +++ b/i18n/sr_Latn.json @@ -17,7 +17,6 @@ "add_birthday": "Dodaj rođendan", "add_endpoint": "Dodajte krajnju tačku", "add_exclusion_pattern": "Dodajte obrazac izuzimanja", - "add_import_path": "Dodaj putanju za preuzimanje", "add_location": "Dodaj lokaciju", "add_more_users": "Dodaj korisnike", "add_partner": "Dodaj partner", @@ -110,7 +109,6 @@ "jobs_failed": "{jobCount, plural, one {# neuspešni} few {# neuspešna} other {# neuspešnih}}", "library_created": "Napravljena biblioteka: {library}", "library_deleted": "Biblioteka je izbrisana", - "library_import_path_description": "Odredite fasciklu za uvoz. Ova fascikla, uključujući podfascikle, biće skenirana za slike i video zapise.", "library_scanning": "Periodično skeniranje", "library_scanning_description": "Konfigurišite periodično skeniranje biblioteke", "library_scanning_enable_description": "Omogućite periodično skeniranje biblioteke", @@ -787,8 +785,6 @@ "edit_date_and_time": "Uredi datum i vreme", "edit_exclusion_pattern": "Izmenite obrazac izuzimanja", "edit_faces": "Uredi lica", - "edit_import_path": "Uredi putanju za preuzimanje", - "edit_import_paths": "Uredi Putanje za Preuzimanje", "edit_key": "Izmeni ključ", "edit_link": "Uredi vezu", "edit_location": "Uredi lokaciju", @@ -851,7 +847,6 @@ "failed_to_stack_assets": "Slaganje datoteka nije uspelo", "failed_to_unstack_assets": "Rasklapanje datoteka nije uspelo", "failed_to_update_notification_status": "Ažuriranje statusa obaveštenja nije uspelo", - "import_path_already_exists": "Ova putanja uvoza već postoji.", "incorrect_email_or_password": "Neispravan e-mail ili lozinka", "paths_validation_failed": "{paths, plural, one {# putanja nije prošla} few {# putanje nisu prošle} other {# putanja nisu prošle}} proveru valjanosti", "profile_picture_transparent_pixels": "Slike profila ne mogu imati prozirne piksele. Molimo uvećajte i/ili pomerite sliku.", @@ -860,7 +855,6 @@ "unable_to_add_assets_to_shared_link": "Nije moguće dodati elemente deljenoj vezi", "unable_to_add_comment": "Nije moguće dodati komentar", "unable_to_add_exclusion_pattern": "Nije moguće dodati obrazac izuzimanja", - "unable_to_add_import_path": "Nije moguće dodati putanju za uvoz", "unable_to_add_partners": "Nije moguće dodati partnere", "unable_to_add_remove_archive": "Nije moguće {archived, select, true {ukloniti datoteke iz} other {dodati datoteke u}} arhivu", "unable_to_add_remove_favorites": "Nije moguće {favorite, select, true {dodati datoteke u} other {ukloniti datoteke iz}} favorite", @@ -882,12 +876,10 @@ "unable_to_delete_asset": "Nije moguće izbrisati datoteke", "unable_to_delete_assets": "Greška pri brisanju datoteka", "unable_to_delete_exclusion_pattern": "Nije moguće izbrisati obrazac izuzimanja", - "unable_to_delete_import_path": "Nije moguće izbrisati putanju za uvoz", "unable_to_delete_shared_link": "Nije moguće izbrisati deljeni link", "unable_to_delete_user": "Nije moguće izbrisati korisnika", "unable_to_download_files": "Nije moguće preuzeti datoteke", "unable_to_edit_exclusion_pattern": "Nije moguće izmeniti obrazac izuzimanja", - "unable_to_edit_import_path": "Nije moguće izmeniti putanju uvoza", "unable_to_empty_trash": "Nije moguće isprazniti otpad", "unable_to_enter_fullscreen": "Nije moguće otvoriti preko celog ekrana", "unable_to_exit_fullscreen": "Nije moguće izaći iz celog ekrana", diff --git a/i18n/sv.json b/i18n/sv.json index d8f45465af..0abe751be5 100644 --- a/i18n/sv.json +++ b/i18n/sv.json @@ -9,7 +9,7 @@ "active": "Aktiva", "activity": "Aktivitet", "activity_changed": "Aktiviteten är {enabled, select, true {aktiverad} other {inaktiverad}}", - "add": "Lägg till", + "add": "Tillägga", "add_a_description": "Lägg till en beskrivning", "add_a_location": "Lägg till en plats", "add_a_name": "Lägg till ett namn", @@ -17,7 +17,6 @@ "add_birthday": "Lägg till födelsedag", "add_endpoint": "Lägg till ändpunkt", "add_exclusion_pattern": "Lägg till uteslutningsmönster", - "add_import_path": "Lägg till importsökväg", "add_location": "Lägg till plats", "add_more_users": "Lägg till fler användare", "add_partner": "Lägg till partner", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Växla val för {album}", "add_to_albums": "Lägg till i album", "add_to_albums_count": "Lägg till i album ({count})", + "add_to_bottom_bar": "Lägg till", "add_to_shared_album": "Lägg till i delat album", "add_upload_to_stack": "Lägg till uppladdning till stack", "add_url": "Lägg till URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# misslyckades}}", "library_created": "Skapat bibliotek: {library}", "library_deleted": "Biblioteket har tagits bort", - "library_import_path_description": "Ange en mapp att importera. Den här mappen, inklusive undermappar, skannas efter bilder och videor.", "library_scanning": "Periodisk skanning", "library_scanning_description": "Konfigurera periodisk biblioteksskanning", "library_scanning_enable_description": "Aktivera periodisk biblioteksskanning", @@ -164,8 +163,8 @@ "machine_learning_ocr_min_detection_score_description": "Lägsta konfidenspoäng för att text ska kunna detekteras är mellan 0 och 1. Lägre värden kommer att detektera mer text men kan resultera i falska positiva resultat.", "machine_learning_ocr_min_recognition_score": "Lägsta igenkänningspoäng", "machine_learning_ocr_min_score_recognition_description": "Lägsta konfidenspoäng för att detekterad text ska kunna identifieras är 0–1. Lägre värden identifierar mer text men kan resultera i falska positiva resultat.", - "machine_learning_ocr_model": "OCR modell", - "machine_learning_ocr_model_description": "Servermodeller är mer exakta än mobilmodeller, men tar längre tid att bearbeta och använder mer minne.", + "machine_learning_ocr_model": "OCR-modell", + "machine_learning_ocr_model_description": "Servermodeller är mer exakta än mobilmodeller men tar längre tid att bearbeta och använder mer minne.", "machine_learning_settings": "Inställningar För Maskininlärning", "machine_learning_settings_description": "Hantera funktioner och inställningar för maskininlärning", "machine_learning_smart_search": "Smart Sökning", @@ -430,6 +429,7 @@ "age_months": "Ålder {months, plural, one {# månad} other {# månader}}", "age_year_months": "Ålder 1 år, {months, plural, one {# månad} other {# månader}}", "age_years": "{years, plural, other {Ålder #}}", + "album": "Album", "album_added": "Albumet har lagts till", "album_added_notification_setting_description": "Få ett e-postmeddelande när du läggs till i ett delat album", "album_cover_updated": "Albumomslaget uppdaterat", @@ -461,7 +461,7 @@ "album_viewer_appbar_share_to": "Dela Till", "album_viewer_page_share_add_users": "Lägg till användare", "album_with_link_access": "Låt alla med länken se foton och personer i det här albumet.", - "albums": "Album", + "albums": "Albumen", "albums_count": "{count, plural, one {{count, number} Album} other {{count, number} Album}}", "albums_default_sort_order": "Standard sorteringsordning för album", "albums_default_sort_order_description": "Standard sorteringsordning för mediefiler vid skapande av nytt album.", @@ -475,6 +475,7 @@ "allow_edits": "Tillåt redigeringar", "allow_public_user_to_download": "Tillåt offentlig användare att ladda ner", "allow_public_user_to_upload": "Tillåt en offentlig användare att ladda upp", + "allowed": "Tillåten", "alt_text_qr_code": "QR-kod", "anti_clockwise": "Moturs", "api_key": "API Nyckel", @@ -894,8 +895,6 @@ "edit_description_prompt": "Vänligen välj en ny beskrivning:", "edit_exclusion_pattern": "Redigera uteslutningsmönster", "edit_faces": "Redigera ansikten", - "edit_import_path": "Redigera importsökvägar", - "edit_import_paths": "Redigera importsökvägar", "edit_key": "Redigera nyckel", "edit_link": "Redigera länk", "edit_location": "Redigera plats", @@ -967,7 +966,6 @@ "failed_to_stack_assets": "Det gick inte att stapla objekt", "failed_to_unstack_assets": "Det gick inte att avstapla objekt", "failed_to_update_notification_status": "Misslyckades med att uppdatera aviseringens status", - "import_path_already_exists": "Denna importsökväg finns redan.", "incorrect_email_or_password": "Felaktig e-postadress eller lösenord", "paths_validation_failed": "{paths, plural, one {# path} other {# paths}} misslyckades valideringen", "profile_picture_transparent_pixels": "Profilbilder kan inte ha genomskinliga pixlar. Zooma in och/eller flytta bilden.", @@ -977,7 +975,6 @@ "unable_to_add_assets_to_shared_link": "Det går inte att lägga till objekt till delad länk", "unable_to_add_comment": "Kunde inte lägga till kommentar", "unable_to_add_exclusion_pattern": "Det gick inte att lägga till uteslutningsmönster", - "unable_to_add_import_path": "Det gick inte att lägga till importsökväg", "unable_to_add_partners": "Kunde inte lägga till partners", "unable_to_add_remove_archive": "Det går inte att {archived, select, true {ta bort objekt från} other {lägga till objekt till}} arkiv", "unable_to_add_remove_favorites": "Det går inte att {favorite, select, true {add asset to} other {remove asset from}} favoriter", @@ -1000,12 +997,10 @@ "unable_to_delete_asset": "Det gick inte att ta bort objekt", "unable_to_delete_assets": "Det gick inte att ta bort objekt", "unable_to_delete_exclusion_pattern": "Det gick inte att ta bort uteslutningsmönster", - "unable_to_delete_import_path": "Det gick inte att ta bort importsökvägen", "unable_to_delete_shared_link": "Det gick inte att ta bort delad länk", "unable_to_delete_user": "Kunde inte ta bort användare", "unable_to_download_files": "Det går inte att ladda ner filer", "unable_to_edit_exclusion_pattern": "Det gick inte att redigera uteslutningsmönster", - "unable_to_edit_import_path": "Det gick inte att redigera importsökvägen", "unable_to_empty_trash": "Kunde inte tömma papperskorgen", "unable_to_enter_fullscreen": "Kunde inte växla till fullskärm", "unable_to_exit_fullscreen": "Kunde inte avsluta fullskärm", @@ -1196,6 +1191,8 @@ "import_path": "Importsökväg", "in_albums": "I {count, plural, one {# album} other {# albums}}", "in_archive": "I arkivet", + "in_year": "I {year}", + "in_year_selector": "In", "include_archived": "Inkludera arkiverade", "include_shared_albums": "Inkludera delade album", "include_shared_partner_assets": "Inkludera delade partners tillgångar", @@ -1232,6 +1229,7 @@ "language_setting_description": "Välj önskat språk", "large_files": "Stora filer", "last": "Sista", + "last_months": "{count, plural, one {Senaste månaden} other {Senaste # månaderna}}", "last_seen": "Senast sedd", "latest_version": "Senaste versionen", "latitude": "Latitud", @@ -1264,8 +1262,8 @@ "local_media_summary": "Sammanfattning av lokala medier", "local_network": "Lokalt nätverk", "local_network_sheet_info": "Appen kommer ansluta till servern via denna URL när det specificerade WiFi-nätverket används", - "location": "Position", - "location_permission": "Plats-rättighet", + "location": "Plats", + "location_permission": "Platsrättighet", "location_permission_content": "För att använda funktionen för automatisk växling behöver Immich behörighet till exakt plats så att appen kan läsa av det aktuella Wi-Fi-nätverkets namn", "location_picker_choose_on_map": "Välj på karta", "location_picker_latitude_error": "Ange en giltig latitud", @@ -1314,6 +1312,10 @@ "main_menu": "Huvudmeny", "make": "Tillverkare", "manage_geolocation": "Hantera plats", + "manage_media_access_rationale": "Denna behörighet krävs för korrekt hantering av att flytta tillgångar till papperskorgen och återställa dem från den.", + "manage_media_access_settings": "Öppna inställningar", + "manage_media_access_subtitle": "Tillåt Immich-appen att hantera och flytta mediefiler.", + "manage_media_access_title": "Åtkomst till mediehantering", "manage_shared_links": "Hantera Delade länkar", "manage_sharing_with_partners": "Hantera delning med partner", "manage_the_app_settings": "Hantera appinställningarna", @@ -1377,6 +1379,7 @@ "more": "Mer", "move": "Flytta", "move_off_locked_folder": "Flytta från låst mapp", + "move_to": "Flytta till", "move_to_lock_folder_action_prompt": "{count} adderades till låst mapp", "move_to_locked_folder": "Flytta till låst mapp", "move_to_locked_folder_confirmation": "Dessa foton och videor kommer tas bort från alla album och går endast se i låsta mappen", @@ -1406,6 +1409,7 @@ "new_pin_code": "Ny PIN-kod", "new_pin_code_subtitle": "Det här är första gången du öppnar den låsta mappen. Skapa en PIN-kod för att säkert få åtkomst till den här sidan", "new_timeline": "Ny tidslinje", + "new_update": "Ny uppdatering", "new_user_created": "Ny användare skapad", "new_version_available": "NY VERSION TILLGÄNGLIG", "newest_first": "Nyast först", @@ -1421,6 +1425,7 @@ "no_cast_devices_found": "Inga Cast-enheter hittades", "no_checksum_local": "Ingen kontrollsumma tillgänglig - kan inte hämta lokala tillgångar", "no_checksum_remote": "Ingen kontrollsumma tillgänglig - kan inte hämta fjärrtillgång", + "no_devices": "Inga auktoriserade enheter", "no_duplicates_found": "Inga dubbletter hittades.", "no_exif_info_available": "EXIF-information ej tillgänglig", "no_explore_results_message": "Ladda upp fler bilder för att utforska din samling.", @@ -1437,6 +1442,7 @@ "no_results_description": "Pröva en synonym eller ett annat mer allmänt sökord", "no_shared_albums_message": "Skapa ett album för att dela bilder och videor med andra personer", "no_uploads_in_progress": "Inga uppladdningar pågår", + "not_allowed": "Inte tillåten", "not_available": "N/A", "not_in_any_album": "Inte i något album", "not_selected": "Ej vald", @@ -1547,6 +1553,8 @@ "photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Foton}}", "photos_from_previous_years": "Foton från tidigare år", "pick_a_location": "Välj en plats", + "pick_custom_range": "Anpassat intervall", + "pick_date_range": "Välj ett datumintervall", "pin_code_changed_successfully": "Lyckades ändra PIN-koden", "pin_code_reset_successfully": "Lyckades återställa PIN-kod", "pin_code_setup_successfully": "Lyckades skapa PIN-kod", @@ -2027,6 +2035,7 @@ "third_party_resources": "Tredjepartsresurser", "time": "Tid", "time_based_memories": "Tidsbaserade minnen", + "time_based_memories_duration": "Antal sekunder att visa varje bild.", "timeline": "Tidslinje", "timezone": "Tidszon", "to_archive": "Arkivera", @@ -2167,6 +2176,7 @@ "welcome": "Välkommen", "welcome_to_immich": "Välkommen till Immich", "wifi_name": "Wi-Fi-namn", + "workflow": "Arbetsflöde", "wrong_pin_code": "Fel pinkod", "year": "År", "years_ago": "{years, plural, one {# år} other {# år}} sedan", diff --git a/i18n/ta.json b/i18n/ta.json index 90a7f8e214..55f674ee79 100644 --- a/i18n/ta.json +++ b/i18n/ta.json @@ -17,7 +17,6 @@ "add_birthday": "பிறந்தநாளைச் சேர்க்கவும்", "add_endpoint": "சேவை நிரலை சேர்", "add_exclusion_pattern": "விலக்கு வடிவத்தைச் சேர்க்கவும்", - "add_import_path": "இறக்குமதி பாதையை (இம்போர்ட் பாத்) சேர்க்கவும்", "add_location": "இடத்தைச் சேர்க்கவும்", "add_more_users": "மேலும் பயனர்களை சேர்க்கவும்", "add_partner": "துணையை சேர்க்கவும்", @@ -112,7 +111,6 @@ "jobs_failed": "{jobCount, plural, other {# தோல்வியுற்றது}}", "library_created": "உருவாக்கப்பட்ட புகைப்பட நூலகம்: {library}", "library_deleted": "புகைப்பட நூலகம் நீக்கப்பட்டது", - "library_import_path_description": "இறக்குமதி செய்ய ஒரு கோப்புறையைக் குறிப்பிடவும். துணைக் கோப்புறைகள் உட்பட இந்தக் கோப்புறை படங்கள் மற்றும் வீடியோக்களுக்காக ஸ்கேன் செய்யப்படும்.", "library_scanning": "அவ்வப்போது ஸ்கேனிங்", "library_scanning_description": "நியமிக்கப்பட்ட புகைப்பட நூலக ஸ்கேனிங்கை அமைக்கவும்", "library_scanning_enable_description": "நியமிக்கப்பட்ட புகைப்பட நூலக ஸ்கேனிங்கை இயக்கு", @@ -475,6 +473,7 @@ "allow_edits": "திருத்தங்களை அனுமதிக்கவும்", "allow_public_user_to_download": "பொது பயனரை பதிவிறக்கம் செய்ய அனுமதிக்கவும்", "allow_public_user_to_upload": "பொது பயனரை பதிவேற்ற அனுமதிக்கவும்", + "allowed": "அனுமதித்த", "alt_text_qr_code": "QR குறியீடு படம்", "anti_clockwise": "கடிகார எதிர்ப்பு", "api_key": "பநிஇ விசை", @@ -894,8 +893,6 @@ "edit_description_prompt": "புதிய விளக்கத்தைத் தேர்ந்தெடுக்கவும்:", "edit_exclusion_pattern": "விலக்கு முறையைத் திருத்தவும்", "edit_faces": "முகங்களைத் திருத்தவும்", - "edit_import_path": "இறக்குமதி பாதையைத் திருத்து", - "edit_import_paths": "இறக்குமதி பாதைகளைத் திருத்தவும்", "edit_key": "திறனைத் திருத்து", "edit_link": "இணைப்பைத் திருத்து", "edit_location": "இருப்பிடத்தைத் திருத்தவும்", @@ -967,7 +964,6 @@ "failed_to_stack_assets": "சொத்துக்களை அடுக்கி வைப்பதில் தோல்வி", "failed_to_unstack_assets": "அன்-ச்டாக் சொத்துக்களில் தோல்வியுற்றது", "failed_to_update_notification_status": "அறிவிப்பு நிலையைப் புதுப்பிக்கத் தவறிவிட்டது", - "import_path_already_exists": "இந்த இறக்குமதி பாதை ஏற்கனவே உள்ளது.", "incorrect_email_or_password": "தவறான மின்னஞ்சல் அல்லது கடவுச்சொல்", "paths_validation_failed": "தோல்வியுற்ற சரிபார்ப்பு {paths, plural, one {# பாதை} other {# பாதைகள்}}", "profile_picture_transparent_pixels": "சுயவிவரப் படங்களுக்கு வெளிப்படையான படப்புள்ளிகள் இருக்க முடியாது. தயவுசெய்து பெரிதாக்கவும்/அல்லது படத்தை நகர்த்தவும்.", @@ -977,7 +973,6 @@ "unable_to_add_assets_to_shared_link": "பகிரப்பட்ட இணைப்புக்கு சொத்துக்களைச் சேர்க்க முடியவில்லை", "unable_to_add_comment": "கருத்து சேர்க்க முடியவில்லை", "unable_to_add_exclusion_pattern": "விலக்கு முறையைச் சேர்க்க முடியவில்லை", - "unable_to_add_import_path": "இறக்குமதி பாதையைச் சேர்க்க முடியவில்லை", "unable_to_add_partners": "கூட்டாளர்களைச் சேர்க்க முடியவில்லை", "unable_to_add_remove_archive": "காப்பகத்தில் {archived, select, true {இருந்து சொத்தை அகற்ற} other {சொத்தைச் சேர்க்க}} முடியவில்லை", "unable_to_add_remove_favorites": "பிடித்தவையில் {favorite, select, true {சொத்தைச் சேர்க்க} other {சொத்தை அகற்ற}} முடியவில்லை", @@ -1000,12 +995,10 @@ "unable_to_delete_asset": "சொத்தை நீக்க முடியவில்லை", "unable_to_delete_assets": "சொத்துக்களை நீக்குவதில் பிழை", "unable_to_delete_exclusion_pattern": "விலக்கு முறையை நீக்க முடியவில்லை", - "unable_to_delete_import_path": "இறக்குமதி பாதையை நீக்க முடியவில்லை", "unable_to_delete_shared_link": "பகிரப்பட்ட இணைப்பை நீக்க முடியவில்லை", "unable_to_delete_user": "பயனரை நீக்க முடியவில்லை", "unable_to_download_files": "கோப்புகளைப் பதிவிறக்க முடியவில்லை", "unable_to_edit_exclusion_pattern": "விலக்கு முறையைத் திருத்த முடியவில்லை", - "unable_to_edit_import_path": "இறக்குமதி பாதையைத் திருத்த முடியவில்லை", "unable_to_empty_trash": "குப்பைகளை வெற்று செய்ய முடியவில்லை", "unable_to_enter_fullscreen": "முழுத் திரையில் நுழைய முடியவில்லை", "unable_to_exit_fullscreen": "முழுத்திரை வெளியேற முடியவில்லை", @@ -1196,6 +1189,8 @@ "import_path": "இறக்குமதி பாதை", "in_albums": "{count, plural, one {# செருகேடு} other {# செருகேடுகள்}} இல்", "in_archive": "காப்பகத்தில்", + "in_year": "{year} இல்", + "in_year_selector": "உள்ளே", "include_archived": "காப்பகப்படுத்தப்பட்டவர்", "include_shared_albums": "பகிரப்பட்ட ஆல்பங்களைச் சேர்க்கவும்", "include_shared_partner_assets": "பகிரப்பட்ட கூட்டாளர் சொத்துக்களைச் சேர்க்கவும்", @@ -1232,6 +1227,7 @@ "language_setting_description": "உங்களுக்கு விருப்பமான மொழியைத் தேர்ந்தெடுக்கவும்", "large_files": "பெரிய கோப்புகள்", "last": "கடைசி", + "last_months": "{count, plural, one {கடந்த மாதம்} other {கடந்த # மாதங்கள்}}", "last_seen": "கடைசியாக பார்த்தேன்", "latest_version": "அண்மைக் கால பதிப்பு", "latitude": "அகலாங்கு", @@ -1314,6 +1310,10 @@ "main_menu": "பட்டியல் விளையாடுங்கள்", "make": "உருவாக்கு", "manage_geolocation": "இருப்பிடத்தை நிர்வகிக்கவும்", + "manage_media_access_rationale": "படங்களை குப்பைக்கு நகர்த்துவதை முறையாகக் கையாளுவதற்கும் அதிலிருந்து அவற்றை மீட்டெடுப்பதற்கும் இந்த அனுமதி தேவை.", + "manage_media_access_settings": "அமைப்புகளைத் திற", + "manage_media_access_subtitle": "இம்மிக் செயலி மீடியா கோப்புகளை நிர்வகிக்கவும் நகர்த்தவும் அனுமதிக்கவும்.", + "manage_media_access_title": "மீடியா மேலாண்மை அணுகல்", "manage_shared_links": "பகிரப்பட்ட இணைப்புகளை நிர்வகிக்கவும்", "manage_sharing_with_partners": "கூட்டாளர்களுடன் பகிர்வை நிர்வகிக்கவும்", "manage_the_app_settings": "பயன்பாட்டு அமைப்புகளை நிர்வகிக்கவும்", @@ -1406,6 +1406,7 @@ "new_pin_code": "புதிய முள் குறியீடு", "new_pin_code_subtitle": "பூட்டப்பட்ட கோப்புறையை அணுக இது உங்கள் முதல் முறையாகும். இந்த பக்கத்தை பாதுகாப்பாக அணுக ஒரு முள் குறியீட்டை உருவாக்கவும்", "new_timeline": "புதிய காலவரிசை", + "new_update": "புதிய புதுப்பிப்பு", "new_user_created": "புதிய பயனர் உருவாக்கப்பட்டது", "new_version_available": "புதிய பதிப்பு கிடைக்கிறது", "newest_first": "புதிய முதல்", @@ -1421,6 +1422,7 @@ "no_cast_devices_found": "நடிகர்கள் சாதனங்கள் எதுவும் கிடைக்கவில்லை", "no_checksum_local": "செக்சம் எதுவும் கிடைக்கவில்லை - உள்ளக சொத்துக்களைப் பெற முடியாது", "no_checksum_remote": "செக்சம் எதுவும் கிடைக்கவில்லை - தொலை சொத்து பெற முடியாது", + "no_devices": "அங்கீகரிக்கப்பட்ட சாதனங்கள் இல்லை", "no_duplicates_found": "நகல்கள் எதுவும் காணப்படவில்லை.", "no_exif_info_available": "EXIF செய்தி எதுவும் கிடைக்கவில்லை", "no_explore_results_message": "உங்கள் தொகுப்பை ஆராய கூடுதல் புகைப்படங்களை பதிவேற்றவும்.", @@ -1437,6 +1439,7 @@ "no_results_description": "ஒரு ஒத்த அல்லது பொதுவான முக்கிய சொல்லை முயற்சிக்கவும்", "no_shared_albums_message": "உங்கள் நெட்வொர்க்கில் உள்ளவர்களுடன் புகைப்படங்களையும் வீடியோக்களையும் பகிர்ந்து கொள்ள ஒரு ஆல்பத்தை உருவாக்கவும்", "no_uploads_in_progress": "பதிவேற்றங்கள் முன்னேற்றத்தில் இல்லை", + "not_allowed": "அனுமதிக்கப்படவில்லை", "not_available": "இதற்கில்லை", "not_in_any_album": "எந்த ஆல்பத்திலும் இல்லை", "not_selected": "தேர்ந்தெடுக்கப்படவில்லை", @@ -1547,6 +1550,8 @@ "photos_count": "{count, plural, one {{count, number} படம்} other {{count, number} படங்கள்}}", "photos_from_previous_years": "முந்தைய ஆண்டுகளின் புகைப்படங்கள்", "pick_a_location": "ஒரு இடத்தைத் தேர்ந்தெடுங்கள்", + "pick_custom_range": "தனிப்பயன் வரம்பு", + "pick_date_range": "தேதி வரம்பைத் தேர்ந்தெடுக்கவும்", "pin_code_changed_successfully": "முள் குறியீட்டை வெற்றிகரமாக மாற்றியது", "pin_code_reset_successfully": "முள் குறியீட்டை வெற்றிகரமாக மீட்டமைக்கவும்", "pin_code_setup_successfully": "முள் குறியீட்டை வெற்றிகரமாக அமைக்கவும்", @@ -2027,6 +2032,7 @@ "third_party_resources": "மூன்றாம் தரப்பு வளங்கள்", "time": "நேரம்", "time_based_memories": "நேர அடிப்படையிலான நினைவுகள்", + "time_based_memories_duration": "ஒவ்வொரு படத்தையும் காண்பிக்க தேவைப்படும் வினாடிகள்.", "timeline": "காலவரிசை", "timezone": "நேர மண்டலம்", "to_archive": "காப்பகம்", diff --git a/i18n/te.json b/i18n/te.json index 3cbe6e36bd..98f722da2b 100644 --- a/i18n/te.json +++ b/i18n/te.json @@ -14,17 +14,20 @@ "add_a_location": "స్థానాన్ని జోడించండి", "add_a_name": "పేరును జోడించండి", "add_a_title": "శీర్షికను జోడించండి", + "add_birthday": "పుట్టినరోజును జోడించండి", + "add_endpoint": "ముగింపు బిందువును జోడించండి", "add_exclusion_pattern": "మినహాయింపు నమూనాను జోడించండి", - "add_import_path": "దిగుమతి మార్గాన్ని జోడించండి", "add_location": "స్థానాన్ని జోడించండి", "add_more_users": "మరింత మంది వినియోగదారులను జోడించండి", "add_partner": "భాగస్వామిని జోడించండి", "add_path": "మార్గాన్ని జోడించండి", "add_photos": "ఫోటోలను జోడించండి", + "add_tag": "ట్యాగ్ జోడించండి", "add_to": "జోడించండి…", "add_to_album": "ఆల్బమ్‌కు జోడించండి", "add_to_album_bottom_sheet_added": "ఆల్బమ్కు జోడించబడింది", "add_to_album_bottom_sheet_already_exists": "ఆల్బమ్‌లో ఇప్పటికే జోడించబడింది", + "add_to_album_bottom_sheet_some_local_assets": "కొన్ని స్థానిక ఆస్తులను ఆల్బమ్‌కు జోడించడం సాధ్యం కాలేదు.", "add_to_shared_album": "భాగస్వామ్య ఆల్బమ్‌కు జోడించండి", "add_url": "URLని జోడించండి", "added_to_archive": "ఆర్కైవ్‌కి జోడించబడింది", @@ -92,7 +95,6 @@ "jobs_failed": "{jobCount, plural, other {# విఫలమైంది}}", "library_created": "లైబ్రరీ సృష్టించబడింది: {library}", "library_deleted": "లైబ్రరీ తొలగించబడింది", - "library_import_path_description": "దిగుమతి చేయడానికి ఫోల్డర్‌ను పేర్కొనండి. సబ్ ఫోల్డర్‌లతో సహా ఈ ఫోల్డర్ చిత్రాలు మరియు వీడియోల కోసం స్కాన్ చేయబడుతుంది.", "library_scanning": "ఆవర్తన స్కానింగ్", "library_scanning_description": "ఆవర్తన లైబ్రరీ స్కానింగ్‌ని కాన్ఫిగర్ చేయండి", "library_scanning_enable_description": "ఆవర్తన లైబ్రరీ స్కానింగ్‌ని ప్రారంభించండి", @@ -563,8 +565,6 @@ "edit_date_and_time": "తేదీ మరియు సమయాన్ని సవరించు", "edit_exclusion_pattern": "మినహాయింపు నమూనాను సవరించు", "edit_faces": "ముఖాలను సవరించు", - "edit_import_path": "దిగుమతి మార్గాన్ని సవరించు", - "edit_import_paths": "దిగుమతి మార్గాలను సవరించు", "edit_key": "కీని సవరించు", "edit_link": "లింక్‌ను సవరించు", "edit_location": "స్థానాన్ని సవరించు", @@ -618,7 +618,6 @@ "failed_to_remove_product_key": "ఉత్పత్తి కీని తీసివేయడంలో విఫలమైంది", "failed_to_stack_assets": "ఆస్తులను పేర్చడంలో విఫలమైంది", "failed_to_unstack_assets": "ఆస్తులను అన్-స్టాక్ చేయడంలో విఫలమైంది", - "import_path_already_exists": "ఈ దిగుమతి మార్గం ఇప్పటికే ఉంది.", "incorrect_email_or_password": "తప్పు ఇమెయిల్ లేదా పాస్‌వర్డ్", "paths_validation_failed": "{paths, plural, one {# path} other {# paths}} ధ్రువీకరణ విఫలమైంది", "profile_picture_transparent_pixels": "ప్రొఫైల్ చిత్రాలలో పారదర్శక పిక్సెల్‌లు ఉండకూడదు. దయచేసి చిత్రాన్ని జూమ్ చేయండి మరియు/లేదా తరలించండి.", @@ -627,7 +626,6 @@ "unable_to_add_assets_to_shared_link": "షేర్ చేసిన లింక్‌కు ఆస్తులను జోడించడం సాధ్యం కాలేదు", "unable_to_add_comment": "వ్యాఖ్యను జోడించడం సాధ్యం కాలేదు", "unable_to_add_exclusion_pattern": "మినహాయింపు నమూనాను జోడించడం సాధ్యం కాలేదు", - "unable_to_add_import_path": "దిగుమతి మార్గాన్ని జోడించడం సాధ్యం కాలేదు", "unable_to_add_partners": "భాగస్వాములను జోడించడం సాధ్యం కాలేదు", "unable_to_add_remove_archive": "ఆర్కైవ్ చేయడం {archived, select, true {remove asset from} other {add asset to}} సాధ్యం కాలేదు", "unable_to_add_remove_favorites": "ఇష్టమైనవిగా {favorite, select, true {add asset to} other {remove asset from}} సాధ్యం కాలేదు", @@ -649,12 +647,10 @@ "unable_to_delete_asset": "ఆస్తిని తొలగించడం సాధ్యం కాలేదు", "unable_to_delete_assets": "ఆస్తులను తొలగించడంలో లోపం ఏర్పడింది", "unable_to_delete_exclusion_pattern": "మినహాయింపు నమూనాను తొలగించడం సాధ్యం కాలేదు", - "unable_to_delete_import_path": "దిగుమతి మార్గాన్ని తొలగించలేకపోయింది", "unable_to_delete_shared_link": "షేర్ చేసిన లింక్‌ను తొలగించడం సాధ్యం కాలేదు", "unable_to_delete_user": "వినియోగదారుని తొలగించడం సాధ్యం కాలేదు", "unable_to_download_files": "ఫైళ్లను డౌన్‌లోడ్ చేయడం సాధ్యం కాలేదు", "unable_to_edit_exclusion_pattern": "మినహాయింపు నమూనాను సవరించడం సాధ్యం కాలేదు", - "unable_to_edit_import_path": "దిగుమతి మార్గాన్ని సవరించడం సాధ్యం కాలేదు", "unable_to_empty_trash": "ట్రాష్‌ను ఖాళీ చేయడం సాధ్యం కాలేదు", "unable_to_enter_fullscreen": "పూర్తి స్క్రీన్‌లోకి ప్రవేశించడం సాధ్యం కాలేదు", "unable_to_exit_fullscreen": "పూర్తి స్క్రీన్ నుండి నిష్క్రమించడం సాధ్యం కాలేదు", diff --git a/i18n/th.json b/i18n/th.json index 759b09363d..9bbb6f706c 100644 --- a/i18n/th.json +++ b/i18n/th.json @@ -17,7 +17,6 @@ "add_birthday": "เพิ่มวันเกิด", "add_endpoint": "เพิ่มปลายทาง", "add_exclusion_pattern": "เพิ่มข้อยกเว้น", - "add_import_path": "เพิ่มเส้นทางนำเข้า", "add_location": "เพิ่มตำแหน่ง", "add_more_users": "เพิ่มผู้ใช้งาน", "add_partner": "เพิ่มคู่หู", @@ -32,6 +31,7 @@ "add_to_albums": "เพิ่มเข้าในอัลบั้ม", "add_to_albums_count": "เพิ่มไปยังอัลบั้ม ({count})", "add_to_shared_album": "เพิ่มไปยังอัลบั้มที่แชร์กัน", + "add_upload_to_stack": "เพิ่มที่อัปโหลดเข้า stack", "add_url": "เพิ่ม URL", "added_to_archive": "เพิ่มไปยังที่จัดเก็บถาวร", "added_to_favorites": "เพิ่มเข้ารายการโปรด", @@ -48,7 +48,12 @@ "backup_database": "สำรองฐานข้อมูล", "backup_database_enable_description": "เปิดใช้งานสำรองฐานข้อมูล", "backup_keep_last_amount": "จำนวนข้อมูลสำรองก่อนหน้าที่ต้องเก็บไว้", + "backup_onboarding_1_description": "สำเนานอกสถานที่บนคลาวด์หรือที่ตั้งอื่น", + "backup_onboarding_2_description": "สำเนาที่อยู่บนเครื่องต่างกัน ซึ่งรวมถึงไฟล์หลักและไฟล์สำรองบนเครื่อง", + "backup_onboarding_3_description": "จำนวนชุดของข้อมูลทั้งหมด รวมถึงไฟล์เดิม ซึ่งรวมถึง 1 ชุดที่ตั้งอยู่คนละถิ่น และสำเนาบนเครื่อง 2 ชุด", + "backup_onboarding_description": "แนะนำให้ใช้ การสำรองข้อมูลแบบ 3-2-1เพื่อปกป้องข้อมูล ควรเก็บสำเนาของรูปภาพ/วิดีโอที่อัปโหลดและฐานข้อมูลของ Immich เพื่อสำรองข้อมูลได้อย่างทั่วถึง", "backup_onboarding_footer": "สำหรับข้อมูลเพิ่มเติมที่เกี่ยวกับการสำรองข้อมูลของ Immich โปรดดูที่ documentation", + "backup_onboarding_parts_title": "การสำรองข้อมูลแบบ 3-2-1 ประกอบไปด้วย:", "backup_onboarding_title": "สำรองข้อมูล", "backup_settings": "ตั้งค่าการสำรองข้อมูล", "backup_settings_description": "จัดการการตั้งค่าการสำรองฐานข้อมูล", @@ -105,19 +110,24 @@ "jobs_failed": "{jobCount, plural, other {# ล้มเหลว}}", "library_created": "สร้างคลังภาพ: {library}", "library_deleted": "คลังภาพถูกลบ", - "library_import_path_description": "ระบุโฟลเดอร์เพื่อนําเข้า โฟลเดอร์นี้และโฟลเดอร์ย่อยจะถูกค้นหาภาพและวิดีโอ.", + "library_details": "รายละเอียดคลังภาพ", + "library_folder_description": "เลือกโฟล์เดอร์เพื่อนำเข้า โฟลเดอร์นี้ รวมถึงโฟลเดอร์ย่อยจะถูกสแกนเพื่อรูปภาพและวิดีโอ", + "library_remove_exclusion_pattern_prompt": "คุณแน่ใจว่าต้องการลบรูปแบบข้อยกเว้นนี้ออกหรือไม่?", + "library_remove_folder_prompt": "คุณแน่ใจว่าต้องการลบโฟล์เดอร์นำเข้านี้หรือไม่?", "library_scanning": "การสแกนเป็นระยะ", "library_scanning_description": "ตั้งค่าการสแกนคลังภาพเป็นระยะ", "library_scanning_enable_description": "เปิดการสแกนคลังภาพเป็นระยะ", "library_settings": "คลังภาพภายนอก", "library_settings_description": "จัดการการตั้งค่าคลังภาพภายนอก", "library_tasks_description": "สแกนคลังภาพภายนอกสำหรับทรัพยากรใหม่และ/หรือที่เปลี่ยนแปลง", + "library_updated": "คลังภาพถูกอัปเดต", "library_watching_enable_description": "ดูคลังภาพภายนอกสำหรับการเปลี่ยนแปลงของไฟล์", - "library_watching_settings": "การดูคลังภาพภายนอก (ฟีเจอร์ทดลอง)", + "library_watching_settings": "การดูคลังภาพ [ฟีเจอร์ทดลอง]", "library_watching_settings_description": "หาไฟล์ที่เปลี่ยนแปลงโดยอัตโนมัติ", "logging_enable_description": "เปิดการบันทึก", "logging_level_description": "เมื่อเปิดใช้งาน ใช้ระดับการบันทึกอะไร", "logging_settings": "การบันทึก", + "machine_learning_availability_checks_description": "ตรวจจับและเลือกใช้เซิร์ฟเวอร์ machine learning โดยอัตโนมัติ", "machine_learning_clip_model": "โมเดล Clip", "machine_learning_clip_model_description": "ชื่อของโมเดล CLIP ที่ระบุตรงนี้ โปรดทราบว่าจำเป็นต้องดำเนินงาน 'ค้นหาอัจฉริยะ' ใหม่สำหรับทุกรูปเมื่อเปลี่ยนโมเดล", "machine_learning_duplicate_detection": "ตรวจจับการซ้ำกัน", @@ -140,6 +150,15 @@ "machine_learning_min_detection_score_description": "ค่าความมั่นใจในการตรวจจับใบหน้า จาก 0-1 ค่ายิ่งต่ำจะยิ่งตรวจจับใบหน้ามากขึ้น แต่อาจมีผลผิดพลาด", "machine_learning_min_recognized_faces": "จดจำใบหน้าขั้นต่ำ", "machine_learning_min_recognized_faces_description": "จำนวนใบหน้าขั้นต่ำที่จะสร้างคนขึ้นมา การเพิ่มค่านี้จะทำให้การจดจำใบหน้าแม่นยำกว่าแต่เพิ่มโอกาสที่ใบหน้าจะไม่ถูกมอบหมายให้กับบุคคล", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "ใช้ machine learning ตรวจจับข้อความในภาพ", + "machine_learning_ocr_enabled": "เปิดใช้งาน OCR", + "machine_learning_ocr_enabled_description": "ถ้าปิด ภาพจะไม่ถูกนำเข้ากระบวนการตรวจจับข้อความ", + "machine_learning_ocr_max_resolution": "ความละเอียดสูงสุด", + "machine_learning_ocr_max_resolution_description": "Preview ที่มีความละเอียดสูงกว่าค่านี้จะถูกปรับขนาดโดยคงอัตราส่วนของภาพไว้ ค่าที่สูงจะทำให้มีความแม่นยำมากขึ้นแต่จะใช้เวลาประมวลผลและหน่วยความจำมากขึ้น", + "machine_learning_ocr_min_detection_score": "คะแนนการตรวจจับต่ำสุด", + "machine_learning_ocr_min_detection_score_description": "คะแนนการตรวจจับต่ำสุดที่ข้อความจะถูกตรวจจับ ค่าระหว่าง 0-1 ค่าที่ต่ำจะทำให้ข้อความถูกตรวจจับมากขึ้นแต่อาจทำให้ผลบวกปลอมมากขึ้น", + "machine_learning_ocr_model": "โมเดล OCR", "machine_learning_settings": "การตั้งค่า machine learning", "machine_learning_settings_description": "จัดการการตั้งค่า machine learning", "machine_learning_smart_search": "การค้นหาอัจฉริยะ", @@ -799,8 +818,6 @@ "edit_description_prompt": "โปรดเลื่อกคำอธิบายใหม่", "edit_exclusion_pattern": "แก้ไขข้อยกเว้น", "edit_faces": "แก้ไขหน้า", - "edit_import_path": "แก้ไขพาธนําเข้า", - "edit_import_paths": "แก้ไขพาธนําเข้า", "edit_key": "แก้ไขกุญแจ", "edit_link": "แก้ไขลิงก์", "edit_location": "แก้ไขตำแหน่ง", @@ -867,7 +884,6 @@ "failed_to_stack_assets": "Failed to stack assets", "failed_to_unstack_assets": "Failed to un-stack assets", "failed_to_update_notification_status": "อัพเดทสถานะการแจ้งเตือนไม่สำเร็จ", - "import_path_already_exists": "พาธนำเข้านี้มีอยู่แล้ว", "incorrect_email_or_password": "อีเมลหรือรหัสผ่านไม่ถูกต้อง", "paths_validation_failed": "การตรวจสอบ {paths, plural, one {# path} other {# paths}} ล้มเหลว", "profile_picture_transparent_pixels": "รูปโปรไฟล์ไม่สามารถมีพิกเซลโปร่งใสได้ โปรดซูมเข้าและ/หรือย้ายรูปภาพ", @@ -876,7 +892,6 @@ "unable_to_add_assets_to_shared_link": "ไม่สามารถเพิ่มลงในลิงก์ที่แชร์ได้", "unable_to_add_comment": "ไม่สามารถเพิ่มความเห็นได้", "unable_to_add_exclusion_pattern": "ไม่สามารถเพิ่มรูปแบบข้อยกเว้นได้", - "unable_to_add_import_path": "ไม่สามารถเพิ่มเส้นทางนำเข้าได้", "unable_to_add_partners": "ไม่สามารถเพิ่มคู่หูได้", "unable_to_add_remove_archive": "ไม่สามารถจัดเก็บรายการ {archived, select, true {remove asset from} other {add asset to}} ไปยังการจัดเก็บถาวรได้", "unable_to_add_remove_favorites": "ไม่สามารถทำรายการ {favorite, select, true {add asset to} other {remove asset from}} เข้ารายการโปรดได้", @@ -899,12 +914,10 @@ "unable_to_delete_asset": "ไม่สามารถลบสื่อได้", "unable_to_delete_assets": "เกิดผิดพลาดในการลบ", "unable_to_delete_exclusion_pattern": "ไม่สามารถลบรูปแบบที่ยกเว้น", - "unable_to_delete_import_path": "ไม่สามารถลบเส้นทางนำเข้าได้", "unable_to_delete_shared_link": "ไม่สามารถลบลิงก์ที่แชร์ได้", "unable_to_delete_user": "ไม่สามารถลบผู้ใช้ได้", "unable_to_download_files": "ไม่สามารถดาวน์โหลดไฟล์ได้", "unable_to_edit_exclusion_pattern": "ไม่สามารถแก้ไขรูปแบบยกเว้นได้", - "unable_to_edit_import_path": "ไม่สามารถแก้ไขเส้นทางนำเข้าได้", "unable_to_empty_trash": "ไม่สามารถลบถังขยะได้", "unable_to_enter_fullscreen": "ไม่สามารถเปิดเต็มจอได้", "unable_to_exit_fullscreen": "ไม่สามารถออกโหมดเต็มจอได้", @@ -1082,6 +1095,7 @@ "include_shared_albums": "รวมอัลบั้มที่แชร์กัน", "include_shared_partner_assets": "รวมสื่อที่แชร์กับคู่หู", "individual_share": "แชร์ส่วนตัว", + "individual_shares": "การแชร์เดี่ยว", "info": "ข้อมูล", "interval": { "day_at_onepm": "ทุกวันเวลาบ่ายโมง", @@ -1099,7 +1113,7 @@ "ios_debug_info_no_sync_yet": "ยังไม่มีงานซิงค์รันในพื้นหลัง", "ios_debug_info_processes_queued": "{count} โพรเซสรอคิวในพื้นหลัง", "ios_debug_info_processing_ran_at": "โพรเซสรันเมื่อ {dateTime}", - "items_count": "{count, plural, one {# รายการ} other {#รายการ}}", + "items_count": "{count, plural, one {# รายการ} other {# รายการ}}", "jobs": "งาน", "keep": "เก็บ", "keep_all": "เก็บทั้งหมด", @@ -1111,6 +1125,7 @@ "language_no_results_title": "ไม่พบภาษา", "language_search_hint": "ค้นหาภาษา...", "language_setting_description": "เลือกภาษาที่ต้องการ", + "large_files": "ไฟล์ขนาดใหญ่", "last_seen": "เห็นล่าสุด", "latest_version": "เวอร์ชันล่าสุด", "latitude": "ละติจูด", @@ -1137,7 +1152,7 @@ "local_asset_cast_failed": "ไม่สามารถแคสสื่อที่ไม่ถูกอัพโหลดไปยังเซิร์ฟเวอร์", "local_network": "เครือข่ายระยะใกล้", "local_network_sheet_info": "แอพจะทำการเชื่อมต่อไปยังเซิร์ฟเวอร์ผ่าน URL นี้เมื่อเชื่อต่อกับ Wi-Fi ที่เลือกไว้", - "location_permission": "การอนุญาตตำแหน่ง", + "location_permission": "การอนุญาตเข้าถึงตำแหน่ง", "location_permission_content": "เพื่อใช้ฟีเจอร์การสับโดยอัตโนมัติ Immich ต้องการการอนุญาตเข้าถึงต่ำแหน่งที่แม่นยำเพื่ออ่านชื่อ Wi-Fi ที่เชื่อมต่ออยู่", "location_picker_choose_on_map": "เลือกบนแผนที่", "location_picker_latitude_error": "กรุณาเพิ่มละติจูตที่ถูกต้อง", @@ -1183,6 +1198,7 @@ "main_branch_warning": "คุณกำลังใช้เวอร์ชันการพัฒนา เราขอแนะนำอย่างยิ่งให้ใช้เวอร์ชันเสถียร !", "main_menu": "เมนูหลัก", "make": "สร้าง", + "manage_geolocation": "จัดการตำแหน่ง", "manage_shared_links": "จัดการลิงก์ที่แชร์", "manage_sharing_with_partners": "จัดการการแชร์กับคู่หู", "manage_the_app_settings": "จัดการการตั้งค่าแอป", @@ -1485,6 +1501,7 @@ "resume": "กลับคืน", "retry_upload": "ลองอัปโหลดใหม่", "review_duplicates": "ตรวจสอบรายการที่ซ้ำกัน", + "review_large_files": "ตรวจสอบไฟล์ที่มีขนาดใหญ่", "role": "บทบาท", "role_editor": "เครื่องมือแก้ไข", "role_viewer": "ดู", diff --git a/i18n/tr.json b/i18n/tr.json index 1c1f4c7354..8fb386b9e7 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -17,7 +17,6 @@ "add_birthday": "Doğum günü ekle", "add_endpoint": "Uç nokta ekle", "add_exclusion_pattern": "Hariç tutma deseni ekle", - "add_import_path": "İçe aktarma yolu ekle", "add_location": "Konum ekle", "add_more_users": "Daha fazla kullanıcı ekle", "add_partner": "Ortak ekle", @@ -32,6 +31,7 @@ "add_to_album_toggle": "{album} için seçimi değiştir", "add_to_albums": "Albümlere ekle", "add_to_albums_count": "{count} albümlerine ekle", + "add_to_bottom_bar": "Şuraya ekle", "add_to_shared_album": "Paylaşılan albüme ekle", "add_upload_to_stack": "Yüklemeyi yığına ekle", "add_url": "URL ekle", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# Başarısız}}", "library_created": "Oluşturulan kütüphane : {library}", "library_deleted": "Kütüphane silindi", - "library_import_path_description": "Belirtilecek klasörü içe aktarın. Bu klasör, alt klasörler dahil olmak üzere, görüntüler ve videolar için taranacaktır.", + "library_details": "Kütüphane detayları", + "library_folder_description": "İçe aktarılacak klasörü belirtin. Bu klasör, alt klasörler dahil olmak üzere, resim ve videolar için taranacaktır.", + "library_remove_exclusion_pattern_prompt": "Bu hariç tutma modelini kaldırmak istediğinizden emin misiniz?", + "library_remove_folder_prompt": "Bu içe aktarma klasörünü kaldırmak istediğinizden emin misiniz?", "library_scanning": "Periyodik Tarama", "library_scanning_description": "Periyodik kütüphane taramasını yönet", "library_scanning_enable_description": "Periyodik kütüphane taramasını etkinleştir", "library_settings": "Harici Kütüphane", "library_settings_description": "Harici kütüphane ayarlarını yönet", "library_tasks_description": "Yeni yada değiştirilmiş öğeler için dış kütüphaneleri tara", + "library_updated": "Güncellenmiş kütüphane", "library_watching_enable_description": "Harici kütüphanelerdeki dosya değişikliklerini izle", "library_watching_settings": "Kütüphane izleme [DENEYSEL]", "library_watching_settings_description": "Değişen dosyalar için otomatik olarak izle", @@ -155,15 +159,17 @@ "machine_learning_min_recognized_faces": "Minimum tanınan yüzler", "machine_learning_min_recognized_faces_description": "Kişi oluşturulması için gereken minimum yüzler. Bu değeri yükseltmek yüz tanıma doğruluğunu arttırır fakat yüzün bir kişiye atanmama olasılığını arttırır.", "machine_learning_ocr": "OCR", - "machine_learning_ocr_description": "İmajladaki metinleri tanımak için makine öğrenmesi kullan", - "machine_learning_ocr_enabled": "OCR'ı etkileştir", + "machine_learning_ocr_description": "Resimlerdeki metni tanımak için makine öğrenimini kullan", + "machine_learning_ocr_enabled": "OCR'yi etkinleştir", "machine_learning_ocr_enabled_description": "Devre dışı bırakılırsa, resimler metin tanıma işleminden geçmeyecektir.", "machine_learning_ocr_max_resolution": "En yüksek çözünürlük", "machine_learning_ocr_max_resolution_description": "Bu çözünürlüğün üzerindeki önizlemeler, en-boy oranı korunarak yeniden boyutlandırılacaktır. Daha yüksek değerler daha doğru sonuç verir, ancak işlemesi daha uzun sürer ve daha fazla bellek kullanır.", "machine_learning_ocr_min_detection_score": "En düşük tespit puanı", "machine_learning_ocr_min_detection_score_description": "Metnin tespit edilmesi için minimum güven puanı 0-1 arasındadır. Düşük değerler daha fazla metin tespit eder, ancak yanlış pozitif sonuçlara yol açabilir.", "machine_learning_ocr_min_recognition_score": "Minimum tespit puanı", + "machine_learning_ocr_min_score_recognition_description": "Algılanan metnin tanınması için minimum güven puanı 0-1 arasındadır. Daha düşük değerler daha fazla metni tanır, ancak yanlış pozitif sonuçlara neden olabilir.", "machine_learning_ocr_model": "OCR modeli", + "machine_learning_ocr_model_description": "Sunucu modelleri mobil modellerden daha doğrudur, ancak işlenmesi daha uzun sürer ve daha fazla bellek kullanır.", "machine_learning_settings": "Makine Öğrenmesi ayarları", "machine_learning_settings_description": "Makine öğrenmesi özelliklerini ve ayarlarını yönet", "machine_learning_smart_search": "Akıllı Arama", @@ -171,6 +177,10 @@ "machine_learning_smart_search_enabled": "Akıllı aramayı etkinleştir", "machine_learning_smart_search_enabled_description": "Eğer devre dışı bırakılırsa fotoğraflar akıllı arama için işlenmeyecek.", "machine_learning_url_description": "Makine öğrenimi sunucusunun URL’si. Birden fazla URL sağlanırsa, her sunucu sırayla tek tek denenir ve biri başarılı yanıt verene kadar devam edilir. Yanıt vermeyen sunucular, çevrimiçi duruma gelene kadar geçici olarak yok sayılır.", + "maintenance_settings": "Bakım", + "maintenance_settings_description": "Immich'i bakım moduna alın.", + "maintenance_start": "Bakım modunu başlat", + "maintenance_start_error": "Bakım modu başlatılamadı.", "manage_concurrency": "Aynı anda çalışmayı yönet", "manage_log_settings": "Günlük ayarlarını yönet", "map_dark_style": "Koyu mod", @@ -255,6 +265,7 @@ "oauth_storage_quota_default_description": "Değer (en: OAuth claim) mevcut değilse GiB cinsinden konulacak kota.", "oauth_timeout": "İstek Zaman Aşımı", "oauth_timeout_description": "Milisaniye cinsinden istek zaman aşımı", + "ocr_job_description": "Resimlerdeki metni tanımak için makine öğrenimini kullan", "password_enable_description": "E-posta ve şifre ile giriş yapın", "password_settings": "Şifre ile Giriş", "password_settings_description": "Şifre giriş ayarlarını yönet", @@ -427,6 +438,7 @@ "age_months": "Yaş {months, plural, one {# ay} other {# ay}}", "age_year_months": "1 yaş, {months, plural, one {# ay} other {# ay}}", "age_years": "{years, plural, other {Yaş #}}", + "album": "Albüm", "album_added": "Albüm eklendi", "album_added_notification_setting_description": "Paylaşılan bir albüme eklendiğinizde e-posta bildirimi alın", "album_cover_updated": "Albüm kapağı güncellendi", @@ -472,6 +484,7 @@ "allow_edits": "Düzenlemeye izin ver", "allow_public_user_to_download": "Genel kullanıcının indirmesine aç", "allow_public_user_to_upload": "Genel kullanıcının yüklemesine aç", + "allowed": "İzin verildi", "alt_text_qr_code": "QR kodu görseli", "anti_clockwise": "Saat yönünün tersine", "api_key": "API Anahtarı", @@ -679,6 +692,8 @@ "change_password_description": "Bu sisteme ilk kez giriş yapıyorsunuz veya şifrenizi değiştirmek için bir istekte bulunuldu. Lütfen aşağıya yeni şifrenizi girin.", "change_password_form_confirm_password": "Şifreyi Onayla", "change_password_form_description": "Merhaba {name},\n\nBu sisteme ilk kez giriş yapıyorsunuz veya şifrenizi değiştirmek için bir istekte bulunuldu. Lütfen aşağıya yeni şifrenizi girin.", + "change_password_form_log_out": "Diğer tüm cihazlardan çıkış yap", + "change_password_form_log_out_description": "Diğer tüm cihazlardan çıkış yapmanız önerilir", "change_password_form_new_password": "Yeni Şifre", "change_password_form_password_mismatch": "Şifreler eşleşmiyor", "change_password_form_reenter_new_password": "Yeni Şifreyi Tekrar Giriniz", @@ -889,8 +904,6 @@ "edit_description_prompt": "Lütfen yeni bir açıklama seçin:", "edit_exclusion_pattern": "Hariç tutma desenini düzenle", "edit_faces": "Yüzleri Düzenleyin", - "edit_import_path": "İçe aktarma yolunu düzenleyin", - "edit_import_paths": "İçe Aktarma Yollarını Düzenle", "edit_key": "Anahtarı düzenle", "edit_link": "Bağlantıyı düzenle", "edit_location": "Lokasyonu düzenleyin", @@ -962,8 +975,8 @@ "failed_to_stack_assets": "Öğeler yığınlanamadı", "failed_to_unstack_assets": "Öğelerin yığını kaldırılamadı", "failed_to_update_notification_status": "Bildirim durumu güncellenemedi", - "import_path_already_exists": "Bu içe aktarma yolu halihazırda mevcut.", "incorrect_email_or_password": "Yanlış e-posta veya şifre", + "library_folder_already_exists": "Bu içe aktarma yolu zaten mevcut.", "paths_validation_failed": "{paths, plural, one {# Yol} other {# Yollar}} doğrulanamadı", "profile_picture_transparent_pixels": "Profil resimleri şeffaf piksele sahip olamaz. Lütfen resme yakınlaştırın ve/veya resmi hareket ettirin.", "quota_higher_than_disk_size": "Disk boyutundan daha yüksek bir kota belirlediniz", @@ -972,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Öğeler paylaşılan bağlantıya eklenemiyor", "unable_to_add_comment": "Yorum eklenemiyor", "unable_to_add_exclusion_pattern": "Hariç tutma modeli eklenemiyor", - "unable_to_add_import_path": "İçe aktarma yolu eklenemiyor", "unable_to_add_partners": "Ortaklar eklenemiyor", "unable_to_add_remove_archive": "Arşive {archived, select, true {dosyayı kaldır} other {dosya ekle}} işlemi yapılamıyor", "unable_to_add_remove_favorites": "Favorilere {favorite, select, true {dosya ekle} other {dosyayı kaldır}} işlemi yapılamıyor", @@ -995,12 +1007,10 @@ "unable_to_delete_asset": "Öğe silinemiyor", "unable_to_delete_assets": "Öğeler silinemiyor", "unable_to_delete_exclusion_pattern": "Hariç tutma deseni silinemiyor", - "unable_to_delete_import_path": "İçe aktarma yolu silinemiyor", "unable_to_delete_shared_link": "Paylaşılan bağlantı silinemiyor", "unable_to_delete_user": "Kullanıcı silinemiyor", "unable_to_download_files": "Dosyalar indirilemiyor", "unable_to_edit_exclusion_pattern": "Hariç tutma deseni düzenlenemiyor", - "unable_to_edit_import_path": "İçe aktarma yolu düzenlenemiyor", "unable_to_empty_trash": "Çöp boşaltılamıyor", "unable_to_enter_fullscreen": "Tam ekran yapılamıyor", "unable_to_exit_fullscreen": "Tam ekrandan çıkılamıyor", @@ -1051,6 +1061,7 @@ "unable_to_update_user": "Kullanıcı güncellenemiyor", "unable_to_upload_file": "Dosya yüklenemiyor" }, + "exclusion_pattern": "Hariç tutma modeli", "exif": "EXIF", "exif_bottom_sheet_description": "Açıklama Ekle...", "exif_bottom_sheet_description_error": "Açıklama güncelleme hatası", @@ -1110,6 +1121,7 @@ "folders_feature_description": "Dosya sistemindeki fotoğraf ve videoları klasör görünümüyle keşfedin", "forgot_pin_code_question": "PIN kodunuzu mu unuttunuz?", "forward": "İleri", + "full_path": "Tam yol: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Bu özellik, çalışabilmek için Google'dan harici kaynaklar yükler.", "general": "Genel", @@ -1191,6 +1203,8 @@ "import_path": "İçe aktarma yolu", "in_albums": "{count, plural, one {# Albüm} other {# Albümde}}", "in_archive": "Arşivde", + "in_year": "{year} yılı içinde", + "in_year_selector": "İçinde", "include_archived": "Arşivlenenleri dahil et", "include_shared_albums": "Paylaşılmış albümleri dahil et", "include_shared_partner_assets": "Paylaşılan ortak öğeleri dahil et", @@ -1227,6 +1241,7 @@ "language_setting_description": "Tercih ettiğiniz dili seçiniz", "large_files": "Büyük Dosyalar", "last": "Son", + "last_months": "{count, plural, one {Geçen ay} other {Son # ay}}", "last_seen": "Son görülme", "latest_version": "En Son Sürüm", "latitude": "Enlem", @@ -1236,6 +1251,8 @@ "let_others_respond": "Diğerlerinin yanıt vermesine izin ver", "level": "Seviye", "library": "Kütüphane", + "library_add_folder": "Klasör ekle", + "library_edit_folder": "Klasörü düzenle", "library_options": "Kütüphane ayarları", "library_page_device_albums": "Cihazdaki Albümler", "library_page_new_album": "Yeni albüm", @@ -1259,6 +1276,7 @@ "local_media_summary": "Yerel Medya Özeti", "local_network": "Yerel ağ", "local_network_sheet_info": "Uygulama belirlenmiş Wi-Fi ağını kullanırken bu URL üzerinden sunucuya bağlanacaktır", + "location": "Konum", "location_permission": "Konum izni", "location_permission_content": "Otomatik geçiş özelliğinin çalışabilmesi için Immich'in mevcut Wi-Fi ağının adını bilmesi, bunu sağlamak için de tam konum iznine ihtiyacı vardır", "location_picker_choose_on_map": "Haritada seç", @@ -1301,13 +1319,22 @@ "logout_this_device_confirmation": "Bu cihazda oturum kapatmak istediğinizden emin misiniz?", "logs": "Kayıtlar", "longitude": "Boylam", - "look": "Görünüm", + "look": "Görünüş", "loop_videos": "Videoları döngüye al", "loop_videos_description": "Ayrıntı görünümünde videoların otomatik döngüye alınmasını etkinleştir.", "main_branch_warning": "Geliştirme sürümü kullanıyorsunuz. Yayınlanan bir sürüm kullanmanızı önemle tavsiye ederiz!", "main_menu": "Ana menü", + "maintenance_description": "Immich, bakım moduna alınmıştır.", + "maintenance_end": "Bakım modunu sonlandır", + "maintenance_end_error": "Bakım modu sonlandırılamadı.", + "maintenance_logged_in_as": "Şu anda {user} olarak oturum açılmış durumda", + "maintenance_title": "Geçici Olarak Kullanılamıyor", "make": "Marka", "manage_geolocation": "Konumu yönet", + "manage_media_access_rationale": "Bu izin, öğelerin çöp kutusuna taşınması ve çöp kutusundan geri yüklenmesi için gereklidir.", + "manage_media_access_settings": "Ayarları aç", + "manage_media_access_subtitle": "Immich uygulamasının medya dosyalarını yönetmesine ve taşımasına izin verin.", + "manage_media_access_title": "Medya Yönetimi Erişimi", "manage_shared_links": "Paylaşılan bağlantıları yönet", "manage_sharing_with_partners": "Ortaklarla paylaşımı yönet", "manage_the_app_settings": "Uygulama ayarlarını yönet", @@ -1371,6 +1398,7 @@ "more": "Daha fazla", "move": "Taşı", "move_off_locked_folder": "Kilitli klasörden taşı", + "move_to": "Şuraya taşı", "move_to_lock_folder_action_prompt": "{count} kilitli klasöre eklendi", "move_to_locked_folder": "Kilitli klasöre taşı", "move_to_locked_folder_confirmation": "Bu fotoğraflar ve videolar tüm albümlerden kaldırılacak ve yalnızca kilitli klasörden görüntülenebilecektir", @@ -1400,6 +1428,7 @@ "new_pin_code": "Yeni PIN kodu", "new_pin_code_subtitle": "Kilitli klasöre ilk kez erişiyorsunuz. Bu sayfaya güvenli erişim için bir PIN kodu oluşturun", "new_timeline": "Yeni Zaman Çizelgesi", + "new_update": "Yeni güncelleme", "new_user_created": "Yeni kullanıcı oluşturuldu", "new_version_available": "YENİ SÜRÜM MEVCUT", "newest_first": "Önce en yeniler", @@ -1415,12 +1444,14 @@ "no_cast_devices_found": "Yansıtılacak cihaz bulunamadı", "no_checksum_local": "Sağlama toplamı mevcut değil - yerel varlıkları alamıyor", "no_checksum_remote": "Sağlama toplamı mevcut değil - uzak varlık alınamıyor", + "no_devices": "Yetkili cihaz yok", "no_duplicates_found": "Hiçbir kopya bulunamadı.", "no_exif_info_available": "EXIF bilgisi mevcut değil", "no_explore_results_message": "Koleksiyonunuzu keşfetmek için daha fazla fotoğraf yükleyin.", "no_favorites_message": "En sevdiğiniz fotoğraf ve videoları hızlıca bulmak için favorilere ekleyin", "no_libraries_message": "Fotoğraf ve videolarınızı görmek için bir harici kütüphane oluşturun", "no_local_assets_found": "Bu sağlama toplamı ile yerel varlık bulunamadı", + "no_location_set": "Konum ayarlanmadı", "no_locked_photos_message": "Kilitli klasördeki fotoğraf ve videolar gizlidir; kitaplığınızda gezinirken veya arama yaparken görünmezler.", "no_name": "İsim Yok", "no_notifications": "Bildirim yok", @@ -1431,6 +1462,7 @@ "no_results_description": "Eş anlamlı ya da daha genel anlamlı bir kelime deneyin", "no_shared_albums_message": "Fotoğrafları ve videoları ağınızdaki kişilerle paylaşmak için bir albüm oluşturun", "no_uploads_in_progress": "Yükleme işlemi yok", + "not_allowed": "İzin verilmiyor", "not_available": "YOK", "not_in_any_album": "Hiçbir albümde değil", "not_selected": "Seçilmedi", @@ -1513,7 +1545,7 @@ "people_feature_description": "Kişilere göre gruplanmış fotoğrafları ve videoları inceleyin", "people_sidebar_description": "Yan panelde kişilere hızlı erişim bağlantısı göster", "permanent_deletion_warning": "Kalıcı silme uyarısı", - "permanent_deletion_warning_setting_description": "Nesneleri kalıcı olarak silerken uyarı göster", + "permanent_deletion_warning_setting_description": "Öğeleri kalıcı olarak silerken uyarı göster", "permanently_delete": "Kalıcı olarak sil", "permanently_delete_assets_count": "{count, plural, one {öğe} other {öğe}} kalıcı olarak silindi", "permanently_delete_assets_prompt": "Bu {count, plural, one {öğeyi} other {# öğeleri}} kalıcı olarak silmek istediğinizden emin misiniz? Bu işlem {count, plural, one {bu öğeyi} other {bu öğeleri}} albümlerinizden de kaldırır.", @@ -1541,11 +1573,13 @@ "photos_count": "{count, plural, one {{count, number} fotoğraf} other {{count, number} fotoğraf}}", "photos_from_previous_years": "Önceki yıllardan fotoğraflar", "pick_a_location": "Bir konum seçin", + "pick_custom_range": "Özel aralık", + "pick_date_range": "Bir tarih aralığı seçin", "pin_code_changed_successfully": "PIN kodu başarıyla değiştirildi", "pin_code_reset_successfully": "PIN kodu başarıyla sıfırlandı", "pin_code_setup_successfully": "PIN kodu başarıyla ayarlandı", "pin_verification": "PIN kodu doğrulama", - "place": "Konum", + "place": "Yer", "places": "Konumlar", "places_count": "{count, plural, one {{count, number} yer} other {{count, number} yer}}", "play": "Oynat", @@ -1648,8 +1682,8 @@ "remote_assets": "Uzak Öğeler", "remote_media_summary": "Uzaktan Medya Özeti", "remove": "Kaldır", - "remove_assets_album_confirmation": "{count, plural, one {# öğeyi} other {# öğeleri}} albümden çıkarmak istediğinizden emin misiniz?", - "remove_assets_shared_link_confirmation": "{count, plural, one {# öğeyi} other {# öğeleri}} bu paylaşılan bağlantıdan çıkarmak istediğinizden emin misiniz?", + "remove_assets_album_confirmation": "{count, plural, one {# öğe} other {# öğeler}} albümden çıkarmak istediğinizden emin misiniz?", + "remove_assets_shared_link_confirmation": "{count, plural, one {# öğe} other {# öğeler}} bu paylaşılan bağlantıdan çıkarmak istediğinizden emin misiniz?", "remove_assets_title": "Öğeleri çıkar?", "remove_custom_date_range": "Özel tarih aralığını kaldır", "remove_deleted_assets": "Silinen Öğeleri Kaldır", @@ -1710,6 +1744,7 @@ "running": "Çalışıyor", "save": "Kaydet", "save_to_gallery": "Fotoğraflar'a kaydet", + "saved": "Kaydedildi", "saved_api_key": "API anahtarı kaydedildi", "saved_profile": "Profil kaydedildi", "saved_settings": "Kaydedilen ayarlar", @@ -1726,6 +1761,8 @@ "search_by_description_example": "Sapa'da yürüyüş günü", "search_by_filename": "Dosya adına veya uzantısına göre ara", "search_by_filename_example": "Örn. IMG_1234.JPG veya PNG", + "search_by_ocr": "OCR'ye göre ara", + "search_by_ocr_example": "Sütlü Kahve", "search_camera_lens_model": "Lens modelini ara...", "search_camera_make": "Kamera markasına göre ara...", "search_camera_model": "Kamera modeline göre ara...", @@ -1743,6 +1780,7 @@ "search_filter_location_title": "Konum seç", "search_filter_media_type": "Medya Türü", "search_filter_media_type_title": "Medya türü seç", + "search_filter_ocr": "OCR'ye göre ara", "search_filter_people_title": "Kişi seç", "search_for": "Araştır", "search_for_existing_person": "Mevcut bir kişiyi ara", @@ -1804,6 +1842,8 @@ "server_offline": "Sunucu çevrimdışı", "server_online": "Sunucu çevrimiçi", "server_privacy": "Sunucu Gizliliği", + "server_restarting_description": "Bu sayfa kısa bir süre içinde yenilenecektir.", + "server_restarting_title": "Sunucu yeniden başlatılıyor", "server_stats": "Sunucu istatistikleri", "server_update_available": "Sunucu güncellemesi mevcut", "server_version": "Sunucu Sürümü", @@ -1817,9 +1857,9 @@ "set_stack_primary_asset": "Birincil öğe olarak ayarla", "setting_image_viewer_help": "Görüntüleyici önce küçük resmi gösterir, ardından orta boy önizlemeyi (etkinleştirilmişse) ve son olarak orijinali (etkinleştirilmişse) gösterir.", "setting_image_viewer_original_subtitle": "Orijinal tam çözünürlüklü görüntüyü (büyük!) yüklemek için etkinleştirin. Veri kullanımını azaltmak için devre dışı bırakın (hem ağ hem de cihaz önbelleği).", - "setting_image_viewer_original_title": "Orijinal görüntüyü göster", + "setting_image_viewer_original_title": "Orijinal görüntüyü yükle", "setting_image_viewer_preview_subtitle": "Orta çözünürlüklü bir görüntü göstermek için etkinleştirin. Orijinali doğrudan göstermek veya yalnızca küçük resmi kullanmak için devre dışı bırakın.", - "setting_image_viewer_preview_title": "Önizleme görüntüsü göster", + "setting_image_viewer_preview_title": "Önizleme görüntüsünü yükle", "setting_image_viewer_title": "Resimler", "setting_languages_apply": "Uygula", "setting_languages_subtitle": "Uygulama dilini değiştir", @@ -1830,10 +1870,10 @@ "setting_notifications_notify_never": "hiçbir zaman", "setting_notifications_notify_seconds": "{count} saniye", "setting_notifications_single_progress_subtitle": "Öğe başına ayrıntılı yükleme ilerleme bilgisi", - "setting_notifications_single_progress_title": "Arkaplan yedeklemesi ayrıntılı ilerlemesini göster", + "setting_notifications_single_progress_title": "Arka plan yedeklemesi ayrıntılı ilerlemesini göster", "setting_notifications_subtitle": "Bildirim tercihlerinizi düzenleyin", "setting_notifications_total_progress_subtitle": "Toplam yükleme ilerlemesi (tamamlanan/toplam)", - "setting_notifications_total_progress_title": "Arkaplan yedeklemesi toplam ilerlemesini göster", + "setting_notifications_total_progress_title": "Arka plan yedeklemesi toplam ilerlemesini göster", "setting_video_viewer_auto_play_subtitle": "Videolar açıldığında otomatik olarak oynatmaya başla", "setting_video_viewer_auto_play_title": "Videoları otomatik oynat", "setting_video_viewer_looping_title": "Döngü", @@ -1903,7 +1943,7 @@ "sharing_page_album": "Paylaşılan albümler", "sharing_page_description": "Ağınızdaki kişilerle fotoğraf ve video paylaşmak için paylaşımlı albümler oluşturun.", "sharing_page_empty_list": "LİSTEYİ BOŞALT", - "sharing_sidebar_description": "Yan panelde paylaşılanlara kısa yol göster", + "sharing_sidebar_description": "Yan panelde Paylaşım bağlantısını göster", "sharing_silver_appbar_create_shared_album": "Yeni paylaşılan albüm", "sharing_silver_appbar_share_partner": "Ortakla paylaş", "shift_to_permanent_delete": "Öğeyi kalıcı olarak silmek için ⇧ tuşuna basın", @@ -1915,29 +1955,29 @@ "show_gallery": "Galeriyi göster", "show_hidden_people": "Gizli kişileri göster", "show_in_timeline": "Zaman çizelgesinde göster", - "show_in_timeline_setting_description": "Bu kullanıcının fotoğraf ve videolarını zaman çizelgenizde göster", + "show_in_timeline_setting_description": "Bu kullanıcının fotoğraf ve videolarını zaman çizelgenizde gösterin", "show_keyboard_shortcuts": "Klavye kısayollarını göster", "show_metadata": "Meta verileri göster", - "show_or_hide_info": "Bilgiyi göster veya gizle", + "show_or_hide_info": "Bilgileri göster veya gizle", "show_password": "Şifreyi göster", - "show_person_options": "Kişi ayarlarını göster", - "show_progress_bar": "İlerleme çubuğunu göster", - "show_search_options": "Arama ayarlarını göster", + "show_person_options": "Kişi seçeneklerini göster", + "show_progress_bar": "İlerleme Çubuğunu Göster", + "show_search_options": "Arama seçeneklerini göster", "show_shared_links": "Paylaşılan bağlantıları göster", - "show_slideshow_transition": "Slayt geçişini göster", + "show_slideshow_transition": "Slayt gösterisi geçişini göster", "show_supporter_badge": "Destekçi rozeti", "show_supporter_badge_description": "Destekçi rozetini göster", "show_text_search_menu": "Metin arama menüsünü göster", "shuffle": "Karıştır", "sidebar": "Yan panel", - "sidebar_display_description": "Yan panelde görünüme kısa yol göster", + "sidebar_display_description": "Yan panelde görünüme bir bağlantı göster", "sign_out": "Oturumu Kapat", "sign_up": "Kaydol", "size": "Boyut", "skip_to_content": "İçeriğe atla", "skip_to_folders": "Klasörlere atla", "skip_to_tags": "Etiketlere atla", - "slideshow": "Slayt gösteriisi", + "slideshow": "Slayt gösterisi", "slideshow_settings": "Slayt gösterisi ayarları", "sort_albums_by": "Albümleri sırala...", "sort_created": "Oluşturulma tarihi", @@ -2017,6 +2057,7 @@ "third_party_resources": "Üçüncü taraf kaynaklar", "time": "Zaman", "time_based_memories": "Zaman bazlı anılar", + "time_based_memories_duration": "Her görüntünün gösterileceği saniye sayısı.", "timeline": "Zaman Çizelgesi", "timezone": "Zaman dilimi", "to_archive": "Arşivle", @@ -2132,7 +2173,7 @@ "video_hover_setting_description": "Öğe üzerinde fareyle durulduğunda video küçük resmini oynatır. Bu özellik devre dışıyken, oynatma simgesine fareyle gidilerek oynatma başlatılabilir.", "videos": "Videolar", "videos_count": "{count, plural, one {# video} other {# video}}", - "view": "Görüntüle", + "view": "Görünüm", "view_album": "Albümü görüntüle", "view_all": "Tümünü gör", "view_all_users": "Tüm kullanıcıları görüntüle", @@ -2140,7 +2181,7 @@ "view_in_timeline": "Zaman çizelgesinde görüntüle", "view_link": "Bağlantıyı göster", "view_links": "Bağlantıları göster", - "view_name": "Göster", + "view_name": "Görünüm", "view_next_asset": "Sonraki öğeyi görüntüle", "view_previous_asset": "Önceki öğeyi görüntüle", "view_qr_code": "QR kodu görüntüle", @@ -2157,6 +2198,7 @@ "welcome": "Hoş geldiniz", "welcome_to_immich": "Immich'e hoş geldiniz", "wifi_name": "Wi-Fi Adı", + "workflow": "İş akışı", "wrong_pin_code": "Yanlış PIN kodu", "year": "Yıl", "years_ago": "{years, plural, one {bir yıl} other {# yıl}} önce", diff --git a/i18n/uk.json b/i18n/uk.json index a34e6b8350..3fbdc0daba 100644 --- a/i18n/uk.json +++ b/i18n/uk.json @@ -17,7 +17,6 @@ "add_birthday": "Додати день народження", "add_endpoint": "Додати адресу серверу", "add_exclusion_pattern": "Додати шаблон виключення", - "add_import_path": "Додати шлях імпорту", "add_location": "Додати місцезнаходження", "add_more_users": "Додати користувачів", "add_partner": "Додати партнера", @@ -32,6 +31,7 @@ "add_to_album_toggle": "Перемикання вибору для {album}", "add_to_albums": "Додати до альбомів", "add_to_albums_count": "Додати до альбомів ({count})", + "add_to_bottom_bar": "Додати до", "add_to_shared_album": "Додати у спільний альбом", "add_upload_to_stack": "Додати завантаження до стеку", "add_url": "Додати URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {# не вдалося}}", "library_created": "Створена бібліотека: {library}", "library_deleted": "Бібліотеку видалено", - "library_import_path_description": "Вкажіть папку для імпорту. Цю папку, включно з підпапками, буде проскановано на наявність зображень і відео.", + "library_details": "Деталі бібліотеки", + "library_folder_description": "Вкажіть папку для імпорту. Ця папка, включаючи підпапки, буде просканована на наявність зображень та відео.", + "library_remove_exclusion_pattern_prompt": "Ви впевнені, що хочете видалити цей шаблон виключення?", + "library_remove_folder_prompt": "Ви впевнені, що хочете вилучити цю папку імпорту?", "library_scanning": "Періодичне сканування", "library_scanning_description": "Налаштувати періодичне сканування бібліотеки", "library_scanning_enable_description": "Увімкнути періодичне сканування бібліотеки", "library_settings": "Зовнішня бібліотека", "library_settings_description": "Керування налаштуваннями зовнішніх бібліотек", "library_tasks_description": "Сканувати зовнішні бібліотеки на наявність нових і/або змінених ресурсів", + "library_updated": "Оновлена бібліотека", "library_watching_enable_description": "Слідкуйте за змінами файлів у зовнішніх бібліотеках", "library_watching_settings": "Спостереження за бібліотекою [ЕКСПЕРИМЕНТАЛЬНЕ]", "library_watching_settings_description": "Автоматичне спостереження за зміненими файлами", @@ -154,6 +158,18 @@ "machine_learning_min_detection_score_description": "Мінімальний рівень впевненості для виявлення обличчя від 0 до 1. Нижчі значення дозволять виявляти більше облич, але можуть призводити до помилкових виявлень.", "machine_learning_min_recognized_faces": "Мінімум розпізнаних облич", "machine_learning_min_recognized_faces_description": "Мінімальна кількість розпізнаних облич для створення особи. Збільшення цього параметру робить розпізнавання облич точнішим, але може збільшити ризик того, що обличчя не буде призначено особі.", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "Використовуйте машинне навчання для розпізнавання тексту на зображеннях", + "machine_learning_ocr_enabled": "Увімкнути OCR", + "machine_learning_ocr_enabled_description": "Якщо вимкнено, зображення не розпізнаватимуться за допомогою тексту.", + "machine_learning_ocr_max_resolution": "Максимальна роздільна здатність", + "machine_learning_ocr_max_resolution_description": "Розмір попереднього перегляду з роздільною здатністю вище цієї буде змінено зі збереженням співвідношення сторін. Вищі значення точніші, але обробляються довше та використовують більше пам’яті.", + "machine_learning_ocr_min_detection_score": "Мінімальний бал виявлення", + "machine_learning_ocr_min_detection_score_description": "Мінімальний бал достовірності для виявлення тексту становить від 0 до 1. Нижчі значення дозволять виявити більше тексту, але можуть призвести до хибнопозитивних результатів.", + "machine_learning_ocr_min_recognition_score": "Мінімальний бал розпізнавання", + "machine_learning_ocr_min_score_recognition_description": "Мінімальний бал достовірності для розпізнавання виявленого тексту становить від 0 до 1. Нижчі значення розпізнають більше тексту, але можуть призвести до хибнопозитивних результатів.", + "machine_learning_ocr_model": "Модель OCR", + "machine_learning_ocr_model_description": "Серверні моделі точніші за мобільні, але обробляють дані довше та використовують більше пам'яті.", "machine_learning_settings": "Налаштування машинного навчання", "machine_learning_settings_description": "Управління функціями та налаштуваннями машинного навчання", "machine_learning_smart_search": "Розумний пошук", @@ -161,6 +177,10 @@ "machine_learning_smart_search_enabled": "Увімкнути розумний пошук", "machine_learning_smart_search_enabled_description": "Якщо ця функція вимкнена, зображення не будуть кодуватися для розумного пошуку.", "machine_learning_url_description": "URL сервера машинного навчання. Якщо надано більше одного URL, сервери будуть опитуватися по черзі, поки один з них не відповість успішно, у порядку від першого до останнього. Сервери, які не відповідають, будуть тимчасово ігноруватися, поки не з'являться онлайн.", + "maintenance_settings": "Технічне обслуговування", + "maintenance_settings_description": "Переведіть Immich в режим технічного обслуговування.", + "maintenance_start": "Розпочати режим обслуговування", + "maintenance_start_error": "Не вдалося запустити режим обслуговування.", "manage_concurrency": "Керування паралельністю завдань", "manage_log_settings": "Керування налаштуваннями журналу", "map_dark_style": "Темний стиль", @@ -245,6 +265,7 @@ "oauth_storage_quota_default_description": "Квота в GiB, що використовується, коли налаштування не надано.", "oauth_timeout": "Тайм-аут для запитів", "oauth_timeout_description": "Максимальний час очікування відповіді в мілісекундах", + "ocr_job_description": "Використовуйте машинне навчання для розпізнавання тексту на зображеннях", "password_enable_description": "Увійти за електронною поштою та паролем", "password_settings": "Налаштування входу з паролем", "password_settings_description": "Керування налаштуваннями входу за паролем", @@ -417,6 +438,7 @@ "age_months": "Вік {months, plural, one {# місяць} few {# місяці} many {# місяців} other {# місяців}}", "age_year_months": "Вік 1 рік, {months, plural, one {# місяць} few {# місяці} many {# місяців} other {# місяців}}", "age_years": "{years, plural, other {Вік #}}", + "album": "Альбом", "album_added": "Альбом додано", "album_added_notification_setting_description": "Отримувати повідомлення по електронній пошті, коли вас додають до спільного альбому", "album_cover_updated": "Обкладинка альбому оновлена", @@ -462,6 +484,7 @@ "allow_edits": "Дозволити редагування", "allow_public_user_to_download": "Дозволити публічному користувачеві завантажувати файли", "allow_public_user_to_upload": "Дозволити публічним користувачам завантажувати", + "allowed": "Дозволено", "alt_text_qr_code": "Зображення QR-коду", "anti_clockwise": "Проти годинникової стрілки", "api_key": "Ключ API", @@ -669,6 +692,8 @@ "change_password_description": "Це або перший раз, коли ви увійшли в систему, або було зроблено запит на зміну вашого пароля. Будь ласка, введіть новий пароль нижче.", "change_password_form_confirm_password": "Підтвердити пароль", "change_password_form_description": "Привіт, {name},\n\nЦе або ваш перший вхід у систему, або було надіслано запит на зміну пароля. Будь ласка, введіть новий пароль нижче.", + "change_password_form_log_out": "Вийдіть із системи на всіх інших пристроях", + "change_password_form_log_out_description": "Рекомендується вийти з усіх інших пристроїв", "change_password_form_new_password": "Новий пароль", "change_password_form_password_mismatch": "Паролі не співпадають", "change_password_form_reenter_new_password": "Повторіть новий пароль", @@ -776,6 +801,7 @@ "daily_title_text_date_year": "Е, МММ дд, рррр", "dark": "Темна", "dark_theme": "Увімкнути темну тему", + "date": "Дата", "date_after": "Дата після", "date_and_time": "Дата і час", "date_before": "Дата до", @@ -878,8 +904,6 @@ "edit_description_prompt": "Будь ласка, виберіть новий опис:", "edit_exclusion_pattern": "Редагувати шаблон виключень", "edit_faces": "Редагування облич", - "edit_import_path": "Змінити шлях імпорту", - "edit_import_paths": "Редагувати шлях імпорту", "edit_key": "Змінити ключ", "edit_link": "Редагувати посилання", "edit_location": "Редагувати місцезнаходження", @@ -951,8 +975,8 @@ "failed_to_stack_assets": "Не вдалося згорнути ресурси", "failed_to_unstack_assets": "Не вдалося розгорнути ресурси", "failed_to_update_notification_status": "Не вдалося оновити статус сповіщення", - "import_path_already_exists": "Цей шлях імпорту вже існує.", "incorrect_email_or_password": "Неправильна адреса електронної пошти або пароль", + "library_folder_already_exists": "Цей шлях імпорту вже існує.", "paths_validation_failed": "{paths, plural, one {# шлях} few {# шляхи} many {# шляхів} other {# шляху}} не пройшло перевірку", "profile_picture_transparent_pixels": "Зображення профілю не може містити прозорих пікселів. Будь ласка, збільшіть масштаб та/або перемістіть зображення.", "quota_higher_than_disk_size": "Ви встановили квоту, що перевищує розмір диска", @@ -961,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "Не вдається додати ресурси до спільного посилання", "unable_to_add_comment": "Неможливо додати коментар", "unable_to_add_exclusion_pattern": "Не вдається додати шаблон виключення", - "unable_to_add_import_path": "Не вдається додати шлях до імпорту", "unable_to_add_partners": "Не вдається додати партнерів", "unable_to_add_remove_archive": "Неможливо {archived, select, true {вилучити ресурс із} other {додати ресурс до}} архіву", "unable_to_add_remove_favorites": "Неможливо {favorite, select, true {додати ресурс до} other {вилучити ресурс із}} обраних", @@ -984,12 +1007,10 @@ "unable_to_delete_asset": "Не вдається видалити ресурс", "unable_to_delete_assets": "Помилка видалення ресурсів", "unable_to_delete_exclusion_pattern": "Не вдалося видалити шаблон виключення", - "unable_to_delete_import_path": "Не вдалося видалити шлях імпорту", "unable_to_delete_shared_link": "Не вдалося видалити спільне посилання", "unable_to_delete_user": "Не вдається видалити користувача", "unable_to_download_files": "Неможливо завантажити файли", "unable_to_edit_exclusion_pattern": "Не вдалося редагувати шаблон виключення", - "unable_to_edit_import_path": "Неможливо відредагувати шлях імпорту", "unable_to_empty_trash": "Неможливо очистити кошик", "unable_to_enter_fullscreen": "Неможливо увійти в повноекранний режим", "unable_to_exit_fullscreen": "Неможливо вийти з повноекранного режиму", @@ -1040,6 +1061,7 @@ "unable_to_update_user": "Неможливо оновити дані користувача", "unable_to_upload_file": "Не вдалося завантажити файл" }, + "exclusion_pattern": "Шаблон виключення", "exif": "Exif'", "exif_bottom_sheet_description": "Додати опис...", "exif_bottom_sheet_description_error": "Помилка під час оновлення опису", @@ -1084,6 +1106,7 @@ "features_setting_description": "Керування додатковими можливостями застосунку", "file_name": "Ім'я файлу", "file_name_or_extension": "Ім'я файлу або розширення", + "file_size": "Розмір файлу", "filename": "Ім'я файлу", "filetype": "Тип файлу", "filter": "Фільтр", @@ -1098,6 +1121,7 @@ "folders_feature_description": "Перегляд перегляду папок для фотографій і відео у файловій системі", "forgot_pin_code_question": "Забули свій PIN-код?", "forward": "Переслати", + "full_path": "Повний шлях: {path}", "gcast_enabled": "Google Cast'", "gcast_enabled_description": "Ця функція завантажує зовнішні ресурси з Google для своєї роботи.", "general": "Загальні", @@ -1134,6 +1158,7 @@ "hide_named_person": "Приховати {name}", "hide_password": "Приховати пароль", "hide_person": "Приховати людину", + "hide_text_recognition": "Приховати розпізнавання тексту", "hide_unnamed_people": "Приховати людей без ім'я", "home_page_add_to_album_conflicts": "Додано {added} елементів у альбом {album}. {failed} елементів вже було в альбомі.", "home_page_add_to_album_err_local": "Неможливо додати локальні елементи до альбомів, пропущено", @@ -1179,6 +1204,8 @@ "import_path": "Шлях імпорту", "in_albums": "У {count, plural, one {# альбомі} other {# альбомах}}", "in_archive": "В архіві", + "in_year": "У {year}", + "in_year_selector": "У", "include_archived": "Відображати архів", "include_shared_albums": "Включити спільні альбоми", "include_shared_partner_assets": "Включайте спільні партнерські ресурси", @@ -1215,6 +1242,7 @@ "language_setting_description": "Виберіть мову, якій ви надаєте перевагу", "large_files": "Великі файли", "last": "Останній", + "last_months": "{count, plural, one {Минулого місяця} other {Останні # місяці}}", "last_seen": "Востаннє бачили", "latest_version": "Остання версія", "latitude": "Широта", @@ -1224,6 +1252,8 @@ "let_others_respond": "Дозволити іншим відповідати", "level": "Рівень", "library": "Бібліотека", + "library_add_folder": "Додати папку", + "library_edit_folder": "Редагувати папку", "library_options": "Параметри бібліотеки", "library_page_device_albums": "Альбоми на пристрої", "library_page_new_album": "Новий альбом", @@ -1247,6 +1277,7 @@ "local_media_summary": "Зведення місцевих ЗМІ", "local_network": "Локальна мережа", "local_network_sheet_info": "Застосунок підключатиметься до сервера через цей URL, коли використовується вказана Wi-Fi мережа", + "location": "Розташування", "location_permission": "Дозвіл до місцезнаходження", "location_permission_content": "Щоб перемикати мережі у фоновому режимі, Immich має завжди мати доступ до точної геолокації, щоб зчитувати назву Wi-Fi мережі", "location_picker_choose_on_map": "Обрати на мапі", @@ -1294,8 +1325,17 @@ "loop_videos_description": "Увімкнути циклічне відтворення відео.", "main_branch_warning": "Ви використовуєте версію для розробників; настійно рекомендуємо використовувати релізну версію!", "main_menu": "Головне меню", + "maintenance_description": "Immich переведено в режим технічного обслуговування.", + "maintenance_end": "Завершити режим технічного обслуговування", + "maintenance_end_error": "Не вдалося завершити режим обслуговування.", + "maintenance_logged_in_as": "Наразі ви ввійшли як {user}", + "maintenance_title": "Тимчасово недоступно", "make": "Виробник", "manage_geolocation": "Керувати місцезнаходженням", + "manage_media_access_rationale": "Цей дозвіл потрібен для належного переміщення ресурсів до кошика та їх відновлення з нього.", + "manage_media_access_settings": "Відкрити налаштування", + "manage_media_access_subtitle": "Дозвольте програмі Immich керувати медіафайлами та переміщувати їх.", + "manage_media_access_title": "Доступ до керування медіа", "manage_shared_links": "Керування спільними посиланнями", "manage_sharing_with_partners": "Керуйте спільним використанням з партнерами", "manage_the_app_settings": "Керування налаштуваннями програми", @@ -1359,6 +1399,7 @@ "more": "Більше", "move": "Перемістити", "move_off_locked_folder": "Вийти з особистої папки", + "move_to": "Перемістити до", "move_to_lock_folder_action_prompt": "{count} додано до захищеної теки", "move_to_locked_folder": "Перемістити до особистої папки", "move_to_locked_folder_confirmation": "Ці фото та відео буде видалено зі всіх альбомів і їх можна буде переглядати лише в особистій папці", @@ -1388,6 +1429,7 @@ "new_pin_code": "Новий PIN-код", "new_pin_code_subtitle": "Ви вперше отримуєте доступ до особистої папки. Створіть PIN-код для безпечного доступу до цієї сторінки", "new_timeline": "Нова хронологія", + "new_update": "Нове оновлення", "new_user_created": "Створено нового користувача", "new_version_available": "ДОСТУПНА НОВА ВЕРСІЯ", "newest_first": "Спочатку нові", @@ -1403,12 +1445,14 @@ "no_cast_devices_found": "Пристрої для трансляції не знайдено", "no_checksum_local": "Контрольна сума недоступна – неможливо отримати локальні ресурси", "no_checksum_remote": "Контрольна сума недоступна – неможливо отримати віддалений ресурс", + "no_devices": "Немає авторизованих пристроїв", "no_duplicates_found": "Дублікатів не виявлено.", "no_exif_info_available": "Відсутня інформація про exif", "no_explore_results_message": "Завантажуйте більше фотографій, щоб насолоджуватися вашою колекцією.", "no_favorites_message": "Додавайте улюблені файли, щоб швидко знаходити ваші найкращі зображення та відео", "no_libraries_message": "Створіть зовнішню бібліотеку для перегляду фотографій і відео", "no_local_assets_found": "З цією контрольною сумою не знайдено локальних ресурсів", + "no_location_set": "Місцезнаходження не встановлено", "no_locked_photos_message": "Фото та відео в особистій папці приховані і не відображаються під час перегляду чи пошуку у вашій бібліотеці.", "no_name": "Без імені", "no_notifications": "Немає сповіщень", @@ -1419,6 +1463,7 @@ "no_results_description": "Спробуйте використовувати синонім або більш загальне ключове слово", "no_shared_albums_message": "Створіть альбом, щоб ділитися фотографіями та відео з людьми у вашій мережі", "no_uploads_in_progress": "Немає активних завантажень", + "not_allowed": "Не дозволено", "not_available": "Немає даних", "not_in_any_album": "У жодному альбомі", "not_selected": "Не вибрано", @@ -1435,6 +1480,7 @@ "oauth": "OAuth", "obtainium_configurator": "Конфігуратор Obtainium", "obtainium_configurator_instructions": "Використовуйте Obtainium для встановлення та оновлення програми Android безпосередньо з релізу Immich на GitHub. Створіть ключ API та виберіть варіант, щоб створити посилання на конфігурацію Obtainium", + "ocr": "OCR", "official_immich_resources": "Офіційні ресурси Immich", "offline": "Офлайн", "offset": "Зсув", @@ -1528,6 +1574,8 @@ "photos_count": "{count, plural, one {{count, number} Фотографія} few {{count, number} Фотографії} many {{count, number} Фотографій} other {{count, number} Фотографій}}", "photos_from_previous_years": "Фотографії минулих років у цей день", "pick_a_location": "Виберіть місце розташування", + "pick_custom_range": "Користувацький діапазон", + "pick_date_range": "Виберіть діапазон дат", "pin_code_changed_successfully": "PIN-код успішно змінено", "pin_code_reset_successfully": "PIN-код успішно скинуто", "pin_code_setup_successfully": "PIN-код успішно налаштовано", @@ -1678,6 +1726,7 @@ "reset_sqlite_confirmation": "Ви впевнені, що хочете очистити базу даних SQLite? Після цього потрібно буде вийти з акаунта та увійти знову для повторної синхронізації даних", "reset_sqlite_success": "Базу даних SQLite успішно очищено", "reset_to_default": "Скидання до налаштувань за замовчуванням", + "resolution": "Роздільна Здатність", "resolve_duplicates": "Усунути дублікати", "resolved_all_duplicates": "Усі дублікати усунуто", "restore": "Відновити", @@ -1696,6 +1745,7 @@ "running": "Виконується", "save": "Зберегти", "save_to_gallery": "Зберегти в галерею", + "saved": "Збережено", "saved_api_key": "Збережені ключі API", "saved_profile": "Профіль збережено", "saved_settings": "Налаштування збережено", @@ -1712,6 +1762,8 @@ "search_by_description_example": "Похідний день у Сапі", "search_by_filename": "Пошук за назвою або розширенням файлу", "search_by_filename_example": "Наприклад, IMG_1234.JPG або PNG", + "search_by_ocr": "Пошук за OCR", + "search_by_ocr_example": "Латте", "search_camera_lens_model": "Пошук моделі об’єктива…", "search_camera_make": "Пошук виробника камери...", "search_camera_model": "Пошук моделі камери...", @@ -1729,6 +1781,7 @@ "search_filter_location_title": "Виберіть місцезнаходження", "search_filter_media_type": "Тип медіа", "search_filter_media_type_title": "Виберіть тип медіа", + "search_filter_ocr": "Пошук за OCR", "search_filter_people_title": "Виберіть людей", "search_for": "Шукати для", "search_for_existing_person": "Пошук існуючої особи", @@ -1790,6 +1843,8 @@ "server_offline": "Сервер офлайн", "server_online": "Сервер онлайн", "server_privacy": "Конфіденційність сервера", + "server_restarting_description": "Ця сторінка оновиться миттєво.", + "server_restarting_title": "Сервер перезавантажується", "server_stats": "Статистика сервера", "server_update_available": "Оновлення сервера доступне", "server_version": "Версія сервера", @@ -1913,6 +1968,7 @@ "show_slideshow_transition": "Показати перехід слайд-шоу", "show_supporter_badge": "Значок підтримки", "show_supporter_badge_description": "Показати значок підтримки", + "show_text_recognition": "Показати розпізнавання тексту", "show_text_search_menu": "Показати меню текстового пошуку", "shuffle": "Перемішати", "sidebar": "Бічна панель", @@ -1983,6 +2039,7 @@ "tags": "Теги", "tap_to_run_job": "Торкніться, щоб запустити завдання", "template": "Шаблон", + "text_recognition": "Розпізнавання тексту", "theme": "Тема", "theme_selection": "Вибір теми", "theme_selection_description": "Автоматично встановлювати тему на світлу або темну залежно від системних налаштувань вашого браузера", @@ -2001,7 +2058,9 @@ "theme_setting_three_stage_loading_title": "Увімкнути триетапне завантаження", "they_will_be_merged_together": "Вони будуть об'єднані разом", "third_party_resources": "Ресурси третіх сторін", + "time": "Час", "time_based_memories": "Спогади, що базуються на часі", + "time_based_memories_duration": "Кількість секунд для відображення кожного зображення.", "timeline": "Хронологія", "timezone": "Часовий пояс", "to_archive": "Архів", @@ -2142,6 +2201,7 @@ "welcome": "Ласкаво просимо", "welcome_to_immich": "Ласкаво просимо до Immich", "wifi_name": "Назва Wi-Fi", + "workflow": "Робочий процес", "wrong_pin_code": "Неправильний PIN-код", "year": "Рік", "years_ago": "{years, plural, one {# рік} few {# роки} many {# років} other {# років}} тому", diff --git a/i18n/ur.json b/i18n/ur.json index 357d0b6304..6d6c5232e9 100644 --- a/i18n/ur.json +++ b/i18n/ur.json @@ -17,7 +17,6 @@ "add_birthday": "سالگرہ شامل کریں", "add_endpoint": "اینڈ پوائنٹ درج کریں", "add_exclusion_pattern": "خارج کرنے کا نمونہ شامل کریں", - "add_import_path": "درآمد کا راستہ شامل کریں", "add_location": "جگہ درج کریں", "add_more_users": "مزید صارفین شامل کریں", "add_partner": "ساتھی شامل کریں", diff --git a/i18n/uz.json b/i18n/uz.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/uz.json @@ -0,0 +1 @@ +{} diff --git a/i18n/vi.json b/i18n/vi.json index ad584d7155..00c46a5baf 100644 --- a/i18n/vi.json +++ b/i18n/vi.json @@ -8,7 +8,7 @@ "actions": "hành động", "active": "Đang hoạt động", "activity": "Hoạt động", - "activity_changed": "Hoạt động đã được {enabled, select, true {bật} other {tắt}}", + "activity_changed": "Hoạt động đã được {bật, chọn, bật khác {tắt}}", "add": "Thêm", "add_a_description": "Thêm mô tả", "add_a_location": "Thêm địa điểm", @@ -17,7 +17,6 @@ "add_birthday": "Thêm ngày sinh", "add_endpoint": "Thêm endpoint", "add_exclusion_pattern": "Thêm quy tắc loại trừ", - "add_import_path": "Thêm đường dẫn nhập", "add_location": "Thêm địa điểm", "add_more_users": "Thêm người dùng", "add_partner": "Thêm người thân", @@ -31,6 +30,7 @@ "add_to_album_toggle": "Bật tắt tùy chọn cho {album}", "add_to_albums": "Thêm vào albums", "add_to_albums_count": "Đã thêm {count} vào albums", + "add_to_bottom_bar": "Thêm vào", "add_to_shared_album": "Thêm vào album chia sẻ", "add_url": "Thêm URL", "added_to_archive": "Đã lưu trữ", @@ -48,6 +48,9 @@ "backup_database": "Tạo bản sao lưu CSDL", "backup_database_enable_description": "Bật sao lưu cơ sở dữ liệu", "backup_keep_last_amount": "Số lượng các bản sao lưu CSDL trước đó được giữ lại", + "backup_onboarding_footer": "Để biết thêm thông tin về sao lưu Immich, hãy xem hướng dẫn.", + "backup_onboarding_parts_title": "Phương pháp sao lưu 3-2-1 bao gồm:", + "backup_onboarding_title": "Sao lưu", "backup_settings": "Cài đặt sao lưu cơ sở dữ liệu", "backup_settings_description": "Quản lý cài đặt sao lưu CSDL.", "cleared_jobs": "Đã xoá các tác vụ: {job}", @@ -103,7 +106,6 @@ "jobs_failed": "{jobCount, plural, other {# tác vụ bị thất bại}}", "library_created": "Đã tạo thư viện: {library}", "library_deleted": "Thư viện đã bị xoá", - "library_import_path_description": "Chọn thư mục để nhập. Ứng dụng sẽ quét tất cả hình ảnh và video trong thư mục này bao gồm các thư mục con.", "library_scanning": "Quét định kỳ", "library_scanning_description": "Cấu hình quét thư viện định kỳ", "library_scanning_enable_description": "Bật quét thư viện định kỳ", @@ -116,6 +118,7 @@ "logging_enable_description": "Bật ghi nhật ký", "logging_level_description": "Khi được bật, thiết lập mức ghi nhật ký.", "logging_settings": "Ghi nhật ký", + "machine_learning_availability_checks_description": "Tự động phát hiện và ưu tiên máy chủ học máy khả dụng", "machine_learning_clip_model": "Mô hình CLIP", "machine_learning_clip_model_description": "Tên của mô hình CLIP được liệt kê tại đây. Bạn cần chạy lại tác vụ \"Tìm kiếm thông minh\" cho tất cả hình ảnh sau khi thay đổi mô hình.", "machine_learning_duplicate_detection": "Phát hiện Trùng lặp", @@ -138,6 +141,12 @@ "machine_learning_min_detection_score_description": "Mức điểm tin cậy tối thiểu để phát hiện khuôn mặt, từ 0 đến 1. Giá trị càng thấp, nhiều khuôn mặt sẽ được phát hiện nhưng có thể tăng khả năng phát hiện sai.", "machine_learning_min_recognized_faces": "Số khuôn mặt tối thiểu để nhận dạng", "machine_learning_min_recognized_faces_description": "Số khuôn mặt tối thiểu cần nhận dạng để tạo thành một người. Tăng số lượng này sẽ làm cho Nhận dạng khuôn mặt chính xác hơn, nhưng sẽ tăng khả năng một khuôn mặt không được gán cho người phù hợp.", + "machine_learning_ocr_description": "Dùng học máy để nhận diện chữ trong ảnh", + "machine_learning_ocr_enabled": "Bật OCR", + "machine_learning_ocr_enabled_description": "Nếu tắt, chữ viết trong ảnh sẽ không được nhận diện.", + "machine_learning_ocr_max_resolution": "Độ phân giải tối đa", + "machine_learning_ocr_min_detection_score_description": "Mức điểm tin cậy tối thiểu để phát hiện chữ viết, từ 0 đến 1. Giá trị càng thấp, càng nhiều chữ viết sẽ được phát hiện nhưng có thể tăng khả năng phát hiện sai (dương tính giả).", + "machine_learning_ocr_model": "Mô hình OCR", "machine_learning_settings": "Cài đặt Học máy", "machine_learning_settings_description": "Quản lý các tính năng và cài đặt học máy", "machine_learning_smart_search": "Tìm kiếm Thông minh", @@ -170,6 +179,9 @@ "metadata_settings_description": "Quản lý cài đặt Metadata", "migration_job": "Di chuyển dữ liệu", "migration_job_description": "Di chuyển hình thu nhỏ của các ảnh và khuôn mặt sang cấu trúc thư mục mới", + "nightly_tasks_cluster_faces_setting_description": "Chạy nhận diện khuôn mặt trên những khuôn mặt mới được phát hiện", + "nightly_tasks_settings": "Cài đặt các nhiệm vụ hàng đêm", + "nightly_tasks_settings_description": "Quản lý các nhiệm vụ hàng đêm", "no_paths_added": "Không có đường dẫn nào được thêm vào", "no_pattern_added": "Không có quy tắc nào được thêm vào", "note_apply_storage_label_previous_assets": "Lưu ý: Để áp dụng Nhãn lưu trữ cho nội dung đã tải lên trước đó, hãy chạy", @@ -367,6 +379,7 @@ "advanced_settings_prefer_remote_title": "Ưu tiên ảnh từ máy chủ", "advanced_settings_proxy_headers_subtitle": "Xác định các tiêu đề proxy Immich sẽ gửi kèm mỗi yêu cầu mạng", "advanced_settings_proxy_headers_title": "Tiêu đề proxy", + "advanced_settings_readonly_mode_title": "Chế độ chỉ đọc", "advanced_settings_self_signed_ssl_subtitle": "Bỏ qua xác minh chứng chỉ SSL cho máy chủ cuối. Yêu cầu cho chứng chỉ tự ký.", "advanced_settings_self_signed_ssl_title": "Cho phép chứng chỉ SSL tự ký", "advanced_settings_sync_remote_deletions_subtitle": "Tự động xóa hoặc khôi phục dữ liệu trên thiết bị này khi bạn thao tác trên web", @@ -547,6 +560,7 @@ "backup_controller_page_turn_on": "Bật sao lưu khi mở ứng dụng", "backup_controller_page_uploading_file_info": "Thông tin tệp đang tải lên", "backup_err_only_album": "Không thể xóa album duy nhất", + "backup_error_sync_failed": "Đồng bộ thất bại. Không thể tiến hành sao lưu.", "backup_info_card_assets": "ảnh", "backup_manual_cancelled": "Đã hủy", "backup_manual_in_progress": "Đang tải lên. Vui lòng thử lại sau", @@ -715,6 +729,7 @@ "date_of_birth_saved": "Ngày sinh đã được lưu thành công", "date_range": "Khoảng thời gian", "day": "Ngày", + "days": "Ngày", "deduplicate_all": "Xóa tất cả mục trùng lặp", "deduplication_criteria_1": "Kích thước hình ảnh theo byte", "deduplication_criteria_2": "Số lượng dữ liệu EXIF", @@ -797,8 +812,6 @@ "edit_description_prompt": "Vui lòng chọn một mô tả mới:", "edit_exclusion_pattern": "Chỉnh sửa quy tắc loại trừ", "edit_faces": "Chỉnh sửa khuôn mặt", - "edit_import_path": "Chỉnh sửa đường dẫn nhập", - "edit_import_paths": "Chỉnh sửa các đường dẫn nhập", "edit_key": "Chỉnh sửa khóa", "edit_link": "Chỉnh sửa liên kết", "edit_location": "Chỉnh sửa vị trí", @@ -865,7 +878,6 @@ "failed_to_stack_assets": "Không thể nhóm các ảnh", "failed_to_unstack_assets": "Không thể huỷ xếp nhóm các ảnh", "failed_to_update_notification_status": "Cập nhật trạng thái thông báo thất bại", - "import_path_already_exists": "Đường dẫn nhập này đã tồn tại.", "incorrect_email_or_password": "Email hoặc mật khẩu không chính xác", "paths_validation_failed": "{paths, plural, one {# đường dẫn} other {# đường dẫn}} không hợp lệ", "profile_picture_transparent_pixels": "Ảnh đại diện không thể có điểm ảnh trong suốt. Vui lòng phóng to và/hoặc di chuyển hình ảnh.", @@ -874,7 +886,6 @@ "unable_to_add_assets_to_shared_link": "Không thể thêm ảnh vào liên kết chia sẻ", "unable_to_add_comment": "Không thể thêm bình luận", "unable_to_add_exclusion_pattern": "Không thể thêm quy tắc loại trừ", - "unable_to_add_import_path": "Không thể thêm đường dẫn nhập", "unable_to_add_partners": "Không thể thêm người thân", "unable_to_add_remove_archive": "Không thể {archived, select, true {xóa ảnh khỏi} other {thêm ảnh vào}} Kho lưu trữ", "unable_to_add_remove_favorites": "Không thể {favorite, select, true {thêm ảnh vào} other {xóa ảnh khỏi}} Mục yêu thích", @@ -897,12 +908,10 @@ "unable_to_delete_asset": "Không thể xóa ảnh", "unable_to_delete_assets": "Lỗi khi xóa các ảnh", "unable_to_delete_exclusion_pattern": "Không thể xóa quy tắc loại trừ", - "unable_to_delete_import_path": "Không thể xóa đường dẫn nhập", "unable_to_delete_shared_link": "Không thể xóa liên kết chia sẻ", "unable_to_delete_user": "Không thể xóa người dùng", "unable_to_download_files": "Không thể tải xuống tập tin", "unable_to_edit_exclusion_pattern": "Không thể chỉnh sửa quy tắc loại trừ", - "unable_to_edit_import_path": "Không thể chỉnh sửa đường dẫn nhập", "unable_to_empty_trash": "Không thể dọn sạch thùng rác", "unable_to_enter_fullscreen": "Không thể vào chế độ toàn màn hình", "unable_to_exit_fullscreen": "Không thể thoát chế độ toàn màn hình", @@ -1002,6 +1011,7 @@ "folder_not_found": "Không tìm thấy thư mục", "folders": "Thư mục", "folders_feature_description": "Duyệt ảnh và video theo thư mục trên hệ thống tập tin", + "forgot_pin_code_question": "Quên mã PIN của bạn?", "forward": "Tiến về phía trước", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Tính năng này tải các tài nguyên bên ngoài từ Google để hoạt động.", @@ -1052,6 +1062,7 @@ "home_page_upload_err_limit": "Chỉ có thể tải lên tối đa 30 ảnh cùng một lúc, bỏ qua", "host": "Máy chủ", "hour": "Giờ", + "hours": "Giờ", "id": "ID", "ignore_icloud_photos": "Bỏ qua ảnh iCloud", "ignore_icloud_photos_description": "Ảnh được lưu trữ trên iCloud sẽ không được tải lên máy chủ Immich", @@ -1110,6 +1121,7 @@ "language_no_results_title": "Không tìm thấy ngôn ngữ", "language_search_hint": "Tìm kiếm ngôn ngữ...", "language_setting_description": "Chọn ngôn ngữ ưa thích của bạn", + "large_files": "Tệp lớn", "last_seen": "Lần cuối nhìn thấy", "latest_version": "Phiên bản mới nhất", "latitude": "Vĩ độ", @@ -1118,6 +1130,8 @@ "let_others_respond": "Cho phép bình luận", "level": "Cấp độ", "library": "Thư viện", + "library_add_folder": "Thêm thư mục", + "library_edit_folder": "Sửa thư mục", "library_options": "Tùy chọn thư viện", "library_page_device_albums": "Album trên thiết bị", "library_page_new_album": "Album mới", @@ -1127,6 +1141,7 @@ "library_page_sort_title": "Tiêu đề album", "licenses": "Giấy phép", "light": "Sáng", + "like": "Thích", "like_deleted": "Đã xoá thích", "link_motion_video": "Liên kết video chuyển động", "link_to_oauth": "Liên kết đến OAuth", @@ -1136,6 +1151,7 @@ "loading_search_results_failed": "Tải kết quả tìm kiếm không thành công", "local_network": "Mạng nội bộ", "local_network_sheet_info": "Ứng dụng sẽ kết nối với máy chủ qua URL này khi sử dụng mạng Wi-Fi được chỉ định", + "location": "Địa điểm", "location_permission": "Quyền truy cập vị trí", "location_permission_content": "Để sử dụng tính năng tự động chuyển đổi, Immich cần có quyền vị trí chính xác để có thể đọc tên của mạng Wi-Fi hiện tại", "location_picker_choose_on_map": "Chọn trên bản đồ", @@ -1180,7 +1196,9 @@ "loop_videos_description": "Bật để video tự động lặp lại trong trình xem chi tiết.", "main_branch_warning": "Bạn đang dùng phiên bản đang phát triển; chúng tôi khuyên bạn nên dùng phiên bản phát hành!", "main_menu": "Menu chính", + "maintenance_title": "Tạm thời không khả dụng", "make": "Thương hiệu", + "manage_geolocation": "Quản lý địa điểm", "manage_shared_links": "Quản lý liên kết chia sẻ", "manage_sharing_with_partners": "Quản lý chia sẻ với người thân", "manage_the_app_settings": "Quản lý cài đặt ứng dụng", @@ -1264,6 +1282,7 @@ "new_person": "Người mới", "new_pin_code": "Mã PIN mới", "new_pin_code_subtitle": "Đây là lần đầu bạn vào thư mục Khóa. Hãy tạo mã PIN để truy cập an toàn", + "new_update": "Cập nhật mới", "new_user_created": "Người dùng mới đã được tạo", "new_version_available": "CÓ PHIÊN BẢN MỚI", "newest_first": "Mới nhất trước", @@ -1281,6 +1300,7 @@ "no_explore_results_message": "Tải thêm ảnh lên để khám phá bộ sưu tập của bạn.", "no_favorites_message": "Thêm ảnh yêu thích để nhanh chóng tìm thấy những bức ảnh và video đẹp nhất của bạn", "no_libraries_message": "Tạo một thư viện bên ngoài để xem ảnh và video của bạn", + "no_location_set": "Chưa có địa điểm được đặt", "no_locked_photos_message": "Ảnh và video trong thư mục Khóa sẽ được ẩn đi và không hiển thị khi bạn duyệt hay tìm kiếm trong thư viện.", "no_name": "Không có tên", "no_notifications": "Không có thông báo", @@ -1289,6 +1309,7 @@ "no_results": "Không có kết quả", "no_results_description": "Thử một từ đồng nghĩa hoặc từ khóa tổng quát hơn", "no_shared_albums_message": "Tạo một album để chia sẻ ảnh và video với mọi người trong mạng của bạn", + "not_available": "Thiếu", "not_in_any_album": "Không thuộc album nào", "not_selected": "Không được chọn", "note_apply_storage_label_to_previously_uploaded assets": "Lưu ý: Để áp dụng Nhãn lưu trữ cho các ảnh đã tải lên trước đó, hãy chạy", @@ -1304,6 +1325,7 @@ "oauth": "OAuth", "official_immich_resources": "Tài nguyên chính thức của Immich", "offline": "Ngoại tuyến", + "offset": "Độ lệch", "ok": "Đồng ý", "oldest_first": "Cũ nhất trước", "on_this_device": "Trên máy này", @@ -1516,6 +1538,7 @@ "reset_password": "Đặt lại mật khẩu", "reset_people_visibility": "Đặt lại trạng thái hiển thị của mọi người", "reset_pin_code": "Đặt lại mã PIN", + "reset_pin_code_with_password": "Bạn luôn có thể đặt lại mã PIN của bạn bằng mật khẩu của bạn", "reset_to_default": "Đặt lại về mặc định", "resolve_duplicates": "Xử lý các bản trùng lặp", "resolved_all_duplicates": "Đã xử lý tất cả các bản trùng lặp", @@ -1623,6 +1646,7 @@ "server_offline": "Máy chủ ngoại tuyến", "server_online": "Phiên bản", "server_privacy": "Quyền riêng tư máy chủ", + "server_restarting_title": "Máy chủ đang khởi động lại", "server_stats": "Thống kê máy chủ", "server_version": "Phiên bản máy chủ", "set": "Đặt", @@ -1790,6 +1814,7 @@ "sync": "Đồng bộ", "sync_albums": "Đồng bộ album", "sync_albums_manual_subtitle": "Đồng bộ hóa tất cả video và ảnh đã tải lên vào album sao lưu đã chọn", + "sync_status_subtitle": "Xem và quản lý hệ thống đồng bộ", "sync_upload_album_setting_subtitle": "Tạo và tải lên ảnh và video của bạn vào album đã chọn trên Immich", "tag": "Thẻ", "tag_assets": "Gắn thẻ", @@ -1877,6 +1902,7 @@ "upload_dialog_info": "Bạn có muốn sao lưu những mục đã chọn tới máy chủ không?", "upload_dialog_title": "Tải lên ảnh", "upload_errors": "Tải lên đã hoàn tất với {count, plural, one {# lỗi} other {# lỗi}}, làm mới trang để xem các ảnh mới tải lên.", + "upload_finished": "Đã hoàn tất tải lên", "upload_progress": "Còn lại {remaining, number} - Đã xử lý {processed, number}/{total, number}", "upload_skipped_duplicates": "Đã bỏ qua {count, plural, one {# mục trùng lặp} other {# mục trùng lặp}}", "upload_status_duplicates": "Mục trùng lặp", @@ -1923,6 +1949,7 @@ "view_album": "Xem Album", "view_all": "Xem tất cả", "view_all_users": "Xem tất cả người dùng", + "view_details": "Xem thông tin chi tiết", "view_in_timeline": "Xem trong dòng thời gian", "view_link": "Xem liên kết", "view_links": "Xem các liên kết", @@ -1930,6 +1957,7 @@ "view_next_asset": "Xem ảnh tiếp theo", "view_previous_asset": "Xem ảnh trước đó", "view_qr_code": "Xem mã QR", + "view_similar_photos": "Xem ảnh tương tự", "view_stack": "Xem nhóm ảnh", "view_user": "Xem Người dùng", "viewer_remove_from_stack": "Xoá khỏi nhóm", diff --git a/i18n/yue_Hant.json b/i18n/yue_Hant.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/i18n/yue_Hant.json @@ -0,0 +1 @@ +{} diff --git a/i18n/zh_Hant.json b/i18n/zh_Hant.json index 8baeaec7d8..ca066bedb3 100644 --- a/i18n/zh_Hant.json +++ b/i18n/zh_Hant.json @@ -17,7 +17,6 @@ "add_birthday": "新增生日", "add_endpoint": "新增端點", "add_exclusion_pattern": "加入篩選條件", - "add_import_path": "新增匯入路徑", "add_location": "新增地點", "add_more_users": "新增其他使用者", "add_partner": "新增親朋好友", @@ -32,6 +31,7 @@ "add_to_album_toggle": "選擇相簿{album}", "add_to_albums": "加入相簿", "add_to_albums_count": "將 ({count}) 個項目加入相簿", + "add_to_bottom_bar": "新增到", "add_to_shared_album": "加到共享相簿", "add_upload_to_stack": "新增上傳到堆疊", "add_url": "新增 URL", @@ -112,7 +112,6 @@ "jobs_failed": "{jobCount, plural, other {# 項任務已失敗}}", "library_created": "已建立媒體庫:{library}", "library_deleted": "媒體庫已刪除", - "library_import_path_description": "指定要匯入的資料夾。系統會掃描此資料夾及其子資料夾中的所有影像與影片。", "library_scanning": "定期掃描", "library_scanning_description": "定期媒體庫掃描設定", "library_scanning_enable_description": "啟用媒體庫定期掃描", @@ -156,6 +155,16 @@ "machine_learning_min_recognized_faces_description": "建立新人物所需的最低已辨識臉孔數量。提高此數值可讓臉孔辨識更精確,但同時會增加臉孔未被指派給任何人物的可能性。", "machine_learning_ocr": "文字辨識(OCR)", "machine_learning_ocr_description": "使用機器學習來識別圖片中的文字", + "machine_learning_ocr_enabled": "啟用OCR", + "machine_learning_ocr_enabled_description": "如果禁用,影像將不會進行文字識別。", + "machine_learning_ocr_max_resolution": "最大分辯率", + "machine_learning_ocr_max_resolution_description": "高於此分辯率的預覽將調整大小,同時保持縱橫比。 更高的值更準確,但處理時間更長,佔用更多記憶體。", + "machine_learning_ocr_min_detection_score": "最低檢測分數", + "machine_learning_ocr_min_detection_score_description": "要檢測的文字的最小置信度分數為0-1。 較低的值將檢測到更多的文字,但可能會導致誤報。", + "machine_learning_ocr_min_recognition_score": "最低識別分數", + "machine_learning_ocr_min_score_recognition_description": "檢測到的文字的最小置信度得分為0-1。 較低的值將識別更多的文字,但可能會導致誤報。", + "machine_learning_ocr_model": "OCR模型", + "machine_learning_ocr_model_description": "服務器模型比移動模型更準確,但需要更長的時間來處理和使用更多的記憶體。", "machine_learning_settings": "機器學習設定", "machine_learning_settings_description": "管理機器學習的功能和設定", "machine_learning_smart_search": "智慧搜尋", @@ -163,6 +172,10 @@ "machine_learning_smart_search_enabled": "啟用智慧搜尋", "machine_learning_smart_search_enabled_description": "如果停用,影像將不會被編碼以進行智慧搜尋。", "machine_learning_url_description": "機器學習伺服器的 URL。若提供多個 URL,系統會依序逐一嘗試,直到其中一臺成功回應為止(由前到後)。未回應的伺服器將被暫時忽略,直到其重新上線。", + "maintenance_settings": "維護", + "maintenance_settings_description": "將Immich置於維護模式。", + "maintenance_start": "啟動維護模式", + "maintenance_start_error": "啟動維護模式失敗。", "manage_concurrency": "管理併發", "manage_log_settings": "管理日誌設定", "map_dark_style": "深色樣式", @@ -247,7 +260,7 @@ "oauth_storage_quota_default_description": "未提供宣告時所使用的配額(GiB)。", "oauth_timeout": "請求逾時", "oauth_timeout_description": "請求的逾時時間(毫秒)", - "ocr_job_description": "使用機器學習來識別圖像中的文字", + "ocr_job_description": "使用機器學習來識別圖片中的文字", "password_enable_description": "使用電子郵件和密碼登入", "password_settings": "密碼登入", "password_settings_description": "管理密碼登入設定", @@ -420,6 +433,7 @@ "age_months": "{months, plural, one {# 個月} other {# 個月}}", "age_year_months": "1 歲,{months, plural, one {# 個月} other {# 個月}}", "age_years": "{years, plural, other {# 歲}}", + "album": "相簿", "album_added": "被加入到相簿", "album_added_notification_setting_description": "當我被加入共享相簿時,用電子郵件通知我", "album_cover_updated": "已更新相簿封面", @@ -465,6 +479,7 @@ "allow_edits": "允許編輯", "allow_public_user_to_download": "允許公開使用者下載", "allow_public_user_to_upload": "允許公開使用者上傳", + "allowed": "允許", "alt_text_qr_code": "QR code 圖片", "anti_clockwise": "逆時針", "api_key": "API 金鑰", @@ -672,6 +687,8 @@ "change_password_description": "這是您首次登入系統,或是已收到變更密碼的請求。請在下方輸入新密碼。", "change_password_form_confirm_password": "確認密碼", "change_password_form_description": "您好 {name},\n\n這是您首次登入系統,或是已收到變更密碼的請求。請在下方輸入新密碼。", + "change_password_form_log_out": "註銷所有其他設備", + "change_password_form_log_out_description": "建議退出所有其他設備", "change_password_form_new_password": "新密碼", "change_password_form_password_mismatch": "密碼不一致", "change_password_form_reenter_new_password": "再次輸入新密碼", @@ -779,6 +796,7 @@ "daily_title_text_date_year": "YYYY 年 M 月 D 日 (E)", "dark": "深色", "dark_theme": "切換深色主題", + "date": "日期", "date_after": "起始日期", "date_and_time": "日期與時間", "date_before": "結束日期", @@ -881,8 +899,6 @@ "edit_description_prompt": "請選擇新的描述:", "edit_exclusion_pattern": "編輯排除條件", "edit_faces": "編輯臉孔", - "edit_import_path": "編輯匯入路徑", - "edit_import_paths": "編輯匯入路徑", "edit_key": "編輯金鑰", "edit_link": "編輯連結", "edit_location": "編輯位置", @@ -954,7 +970,6 @@ "failed_to_stack_assets": "無法媒體堆疊", "failed_to_unstack_assets": "解除媒體堆疊失敗", "failed_to_update_notification_status": "無法更新通知狀態", - "import_path_already_exists": "此匯入路徑已存在。", "incorrect_email_or_password": "電子郵件或密碼錯誤", "paths_validation_failed": "{paths, plural, one {# 個路徑} other {# 個路徑}} 驗證失敗", "profile_picture_transparent_pixels": "個人資料圖片不能有透明畫素。請放大並/或移動影像。", @@ -964,7 +979,6 @@ "unable_to_add_assets_to_shared_link": "無法加入媒體到共享連結", "unable_to_add_comment": "無法新增留言", "unable_to_add_exclusion_pattern": "無法新增篩選條件", - "unable_to_add_import_path": "無法新增匯入路徑", "unable_to_add_partners": "無法新增親朋好友", "unable_to_add_remove_archive": "無法{archived, select, true {從封存中移除媒體} other {將檔案加入媒體}}", "unable_to_add_remove_favorites": "無法將媒體{favorite, select, true {加入收藏} other {從收藏中移除}}", @@ -987,12 +1001,10 @@ "unable_to_delete_asset": "無法刪除媒體", "unable_to_delete_assets": "刪除媒體時發生錯誤", "unable_to_delete_exclusion_pattern": "無法刪除篩選條件", - "unable_to_delete_import_path": "無法刪除匯入路徑", "unable_to_delete_shared_link": "刪除共享連結失敗", "unable_to_delete_user": "無法刪除使用者", "unable_to_download_files": "無法下載檔案", "unable_to_edit_exclusion_pattern": "無法編輯篩選條件", - "unable_to_edit_import_path": "無法編輯匯入路徑", "unable_to_empty_trash": "無法清空垃圾桶", "unable_to_enter_fullscreen": "無法進入全螢幕", "unable_to_exit_fullscreen": "無法結束全螢幕", @@ -1087,6 +1099,7 @@ "features_setting_description": "管理應用程式功能", "file_name": "檔案名稱", "file_name_or_extension": "檔案名稱或副檔名", + "file_size": "文件大小", "filename": "檔案名稱", "filetype": "檔案類型", "filter": "濾鏡", @@ -1182,6 +1195,8 @@ "import_path": "匯入路徑", "in_albums": "在 {count, plural, one {# 本相簿} other {# 本相簿}}中", "in_archive": "在封存中", + "in_year": "{year}年", + "in_year_selector": "在", "include_archived": "包含已封存", "include_shared_albums": "包含共享相簿", "include_shared_partner_assets": "包括共享親朋好友的媒體", @@ -1218,6 +1233,7 @@ "language_setting_description": "選擇您的首選語言", "large_files": "大型檔案", "last": "最後一個", + "last_months": "{count, plural, one {上個月} other {最近 # 個月}}", "last_seen": "最後上線", "latest_version": "最新版本", "latitude": "緯度", @@ -1250,6 +1266,7 @@ "local_media_summary": "本機媒體摘要", "local_network": "本機網路", "local_network_sheet_info": "當使用指定的 Wi-Fi 網路時,應用程式將透過此網址連線至伺服器", + "location": "位置", "location_permission": "位置權限", "location_permission_content": "使用自動切換功能,Immich 需要精確位置權限,以取得已連線的 Wi-Fi 網路名稱", "location_picker_choose_on_map": "在地圖上選擇", @@ -1297,8 +1314,17 @@ "loop_videos_description": "啟用後,影片結束會自動重播。", "main_branch_warning": "您現在使用的是開發版本;我們強烈您建議使用正式發行版!", "main_menu": "主選單", + "maintenance_description": "Immich已進入維護模式。", + "maintenance_end": "結束維護模式", + "maintenance_end_error": "未能結束維護模式。", + "maintenance_logged_in_as": "當前以{user}身份登入", + "maintenance_title": "暫時不可用", "make": "製造商", "manage_geolocation": "管理位置", + "manage_media_access_rationale": "正確處理將資產移至垃圾桶並將其從垃圾桶中恢復需要此許可。", + "manage_media_access_settings": "打開設定", + "manage_media_access_subtitle": "允許Immich應用程序管理和移動媒體檔案。", + "manage_media_access_title": "媒體管理訪問", "manage_shared_links": "管理共享連結", "manage_sharing_with_partners": "管理與親朋好友的分享", "manage_the_app_settings": "管理應用程式設定", @@ -1362,6 +1388,7 @@ "more": "更多", "move": "移動", "move_off_locked_folder": "移出鎖定的資料夾", + "move_to": "移動到", "move_to_lock_folder_action_prompt": "{count} 已新增至鎖定的資料夾中", "move_to_locked_folder": "移至鎖定的資料夾", "move_to_locked_folder_confirmation": "這些照片和影片將從所有相簿中移除,並僅可從鎖定的資料夾檢視", @@ -1391,6 +1418,7 @@ "new_pin_code": "新 PIN 碼", "new_pin_code_subtitle": "這是您第一次存取鎖定的資料夾。建立 PIN 碼以安全存取此頁面", "new_timeline": "新時間軸", + "new_update": "新更新", "new_user_created": "已建立新使用者", "new_version_available": "新版本已發布", "newest_first": "最新優先", @@ -1406,6 +1434,7 @@ "no_cast_devices_found": "找不到 Google Cast 裝置", "no_checksum_local": "沒有可用的校驗和 - 無法取得本機資產", "no_checksum_remote": "沒有可用的校驗和 - 無法取得遠端資產", + "no_devices": "無授權設備", "no_duplicates_found": "沒發現重複項目。", "no_exif_info_available": "沒有可用的 Exif 資訊", "no_explore_results_message": "上傳更多照片以利探索。", @@ -1422,6 +1451,7 @@ "no_results_description": "試試同義詞或更通用的關鍵字吧", "no_shared_albums_message": "建立相簿分享照片和影片", "no_uploads_in_progress": "沒有正在上傳的項目", + "not_allowed": "不允許", "not_available": "不適用", "not_in_any_album": "不在任何相簿中", "not_selected": "未選擇", @@ -1438,6 +1468,7 @@ "oauth": "OAuth", "obtainium_configurator": "Obtainium配寘器", "obtainium_configurator_instructions": "使用Obtainium直接從Immich GitHub的版本安裝和更新Android應用程序。 創建一個API金鑰並選擇一個變體來創建您的Obtainium配寘連結", + "ocr": "OCR", "official_immich_resources": "官方 Immich 資源", "offline": "離線", "offset": "移動", @@ -1531,6 +1562,8 @@ "photos_count": "{count, plural, other {{count, number} 張照片}}", "photos_from_previous_years": "往年的照片", "pick_a_location": "選擇位置", + "pick_custom_range": "自定義範圍", + "pick_date_range": "選擇日期範圍", "pin_code_changed_successfully": "變更 PIN 碼成功", "pin_code_reset_successfully": "重設 PIN 碼成功", "pin_code_setup_successfully": "設定 PIN 碼成功", @@ -1681,6 +1714,7 @@ "reset_sqlite_confirmation": "確定要重設 SQLite 資料庫嗎?閣下需登出並重新登入才能重新同步資料", "reset_sqlite_success": "已成功重設 SQLite 資料庫", "reset_to_default": "重設回預設", + "resolution": "分辯率", "resolve_duplicates": "解決重複項", "resolved_all_duplicates": "已解決所有重複項目", "restore": "還原", @@ -1699,6 +1733,7 @@ "running": "執行中", "save": "儲存", "save_to_gallery": "儲存到相簿", + "saved": "已保存", "saved_api_key": "已儲存 API 金鑰", "saved_profile": "已儲存個人資料", "saved_settings": "已儲存設定", @@ -1715,6 +1750,8 @@ "search_by_description_example": "在沙壩的健行之日", "search_by_filename": "以檔名或副檔名搜尋", "search_by_filename_example": "如 IMG_1234.JPG 或 PNG", + "search_by_ocr": "通過OCR蒐索", + "search_by_ocr_example": "拿鐵", "search_camera_lens_model": "蒐索鏡頭型號...", "search_camera_make": "搜尋相機製造商…", "search_camera_model": "搜尋相機型號…", @@ -1732,6 +1769,7 @@ "search_filter_location_title": "選擇位置", "search_filter_media_type": "媒體類型", "search_filter_media_type_title": "選擇媒體類型", + "search_filter_ocr": "通過OCR蒐索", "search_filter_people_title": "選擇人物", "search_for": "搜尋", "search_for_existing_person": "搜尋現有的人物", @@ -1793,6 +1831,8 @@ "server_offline": "伺服器已離線", "server_online": "伺服器已上線", "server_privacy": "伺服器隱私", + "server_restarting_description": "此頁面將立即重繪。", + "server_restarting_title": "服務器正在重新啟動", "server_stats": "伺服器統計", "server_update_available": "服務器更新可用", "server_version": "目前版本", @@ -2004,7 +2044,9 @@ "theme_setting_three_stage_loading_title": "啟用三段式載入", "they_will_be_merged_together": "它們將會被合併在一起", "third_party_resources": "第三方資源", + "time": "時間", "time_based_memories": "依時間回憶", + "time_based_memories_duration": "顯示每張影像的秒數。", "timeline": "時間軸", "timezone": "時區", "to_archive": "封存", @@ -2145,6 +2187,7 @@ "welcome": "歡迎", "welcome_to_immich": "歡迎使用 Immich", "wifi_name": "Wi-Fi 名稱", + "workflow": "工作流程", "wrong_pin_code": "PIN 碼錯誤", "year": "年", "years_ago": "{years, plural, other {# 年}}前", diff --git a/i18n/zh_SIMPLIFIED.json b/i18n/zh_SIMPLIFIED.json index 6d7ea6ae39..f799a803a3 100644 --- a/i18n/zh_SIMPLIFIED.json +++ b/i18n/zh_SIMPLIFIED.json @@ -17,7 +17,6 @@ "add_birthday": "添加生日", "add_endpoint": "添加服务器 URL", "add_exclusion_pattern": "添加排除规则", - "add_import_path": "添加导入路径", "add_location": "添加地点", "add_more_users": "添加更多用户", "add_partner": "添加同伴", @@ -32,6 +31,7 @@ "add_to_album_toggle": "选择相册 {album}", "add_to_albums": "添加到相册", "add_to_albums_count": "添加到相册({count}个)", + "add_to_bottom_bar": "添加到", "add_to_shared_album": "添加到共享相册", "add_upload_to_stack": "上传项目至堆叠", "add_url": "添加 URL", @@ -112,13 +112,17 @@ "jobs_failed": "{jobCount, plural, other {#项失败}}", "library_created": "已创建图库:{library}", "library_deleted": "图库已删除", - "library_import_path_description": "指定一个要导入的文件夹。将扫描此文件夹(包括子文件夹)中的图像和视频。", + "library_details": "图库详情", + "library_folder_description": "指定要导入的文件夹。将对该文件夹(包括子文件夹)进行图像和视频扫描。", + "library_remove_exclusion_pattern_prompt": "您确定要删除此排除规则吗?", + "library_remove_folder_prompt": "您确定要删除此导入文件夹吗?", "library_scanning": "定期扫描", "library_scanning_description": "配置定期扫描图库", "library_scanning_enable_description": "启用定期扫描图库", "library_settings": "外部图库", "library_settings_description": "管理外部图库设置", "library_tasks_description": "扫描外部库,查找新增或修改的项目", + "library_updated": "已更新的图库", "library_watching_enable_description": "监控外部图库文件变化", "library_watching_settings": "监控图库[实验性]", "library_watching_settings_description": "自动监控文件变化", @@ -173,6 +177,10 @@ "machine_learning_smart_search_enabled": "启用智能搜索", "machine_learning_smart_search_enabled_description": "如果禁用,则不会对图像编码以用于智能搜索。", "machine_learning_url_description": "机器学习服务器的 URL。如果提供多个 URL,则将按依次尝试连接每个服务器,直到有一个服务器成功响应为止。不响应的服务器将被暂时忽略,直到它们重新联机。", + "maintenance_settings": "维护模式", + "maintenance_settings_description": "将Immich置于维护模式。", + "maintenance_start": "开启维护模式", + "maintenance_start_error": "开启维护模式失败。", "manage_concurrency": "管理任务并发", "manage_log_settings": "管理日志设置", "map_dark_style": "深色模式", @@ -430,6 +438,7 @@ "age_months": "{months, plural, one {#个月} other {#个月}}", "age_year_months": "1岁{months, plural, one {#个月} other {#个月}}", "age_years": "{years, plural, other {#岁}}", + "album": "相册", "album_added": "被添加到相册", "album_added_notification_setting_description": "当您被添加到共享相册时,接收邮箱通知", "album_cover_updated": "相册封面已更新", @@ -475,6 +484,7 @@ "allow_edits": "允许编辑", "allow_public_user_to_download": "允许所有用户下载", "allow_public_user_to_upload": "允许所有用户上传", + "allowed": "允许", "alt_text_qr_code": "二维码图片", "anti_clockwise": "逆时针", "api_key": "API 密钥", @@ -894,8 +904,6 @@ "edit_description_prompt": "请选择新的描述:", "edit_exclusion_pattern": "编辑排除规则", "edit_faces": "编辑人脸", - "edit_import_path": "编辑导入路径", - "edit_import_paths": "编辑导入路径", "edit_key": "编辑 API 密钥", "edit_link": "编辑链接", "edit_location": "编辑位置", @@ -967,8 +975,8 @@ "failed_to_stack_assets": "无法堆叠项目", "failed_to_unstack_assets": "无法取消堆叠项目", "failed_to_update_notification_status": "更新通知状态失败", - "import_path_already_exists": "此导入路径已存在。", "incorrect_email_or_password": "邮箱或密码错误", + "library_folder_already_exists": "导入路径已存在。", "paths_validation_failed": "{paths, plural, one {#条路径} other {#条路径}} 校验失败", "profile_picture_transparent_pixels": "个人资料图片不可以包含透明像素。请放大或移动此图片。", "quota_higher_than_disk_size": "设置的配额大于磁盘容量", @@ -977,7 +985,6 @@ "unable_to_add_assets_to_shared_link": "无法添加项目到共享链接", "unable_to_add_comment": "无法添加评论", "unable_to_add_exclusion_pattern": "无法添加排除规则", - "unable_to_add_import_path": "无法添加导入路径", "unable_to_add_partners": "无法添加同伴", "unable_to_add_remove_archive": "无法{archived, select, true {从归档中移除} other {添加项目到归档}}", "unable_to_add_remove_favorites": "无法{favorite, select, true {添加项目到收藏} other {从收藏中移除}}", @@ -1000,12 +1007,10 @@ "unable_to_delete_asset": "无法删除项目", "unable_to_delete_assets": "无法删除项目", "unable_to_delete_exclusion_pattern": "无法删除排除规则", - "unable_to_delete_import_path": "无法删除导入路径", "unable_to_delete_shared_link": "无法删除共享链接", "unable_to_delete_user": "无法删除用户", "unable_to_download_files": "无法下载文件", "unable_to_edit_exclusion_pattern": "无法编辑排除规则", - "unable_to_edit_import_path": "无法编辑导入路径", "unable_to_empty_trash": "无法清空回收站", "unable_to_enter_fullscreen": "无法进入全屏", "unable_to_exit_fullscreen": "无法退出全屏", @@ -1056,6 +1061,7 @@ "unable_to_update_user": "无法更新用户", "unable_to_upload_file": "无法上传文件" }, + "exclusion_pattern": "排除规则", "exif": "Exif 信息", "exif_bottom_sheet_description": "添加描述...", "exif_bottom_sheet_description_error": "更新描述时出错", @@ -1115,6 +1121,7 @@ "folders_feature_description": "在文件夹视图中浏览文件系统上的照片和视频", "forgot_pin_code_question": "忘记您的PIN码了?", "forward": "向前", + "full_path": "完整路径:{path}", "gcast_enabled": "Google Cast 投屏", "gcast_enabled_description": "该功能需要加载来自 Google 的外部资源。", "general": "通用", @@ -1196,6 +1203,8 @@ "import_path": "导入路径", "in_albums": "在{count, plural, one {#个相册} other {#个相册}}中", "in_archive": "在归档中", + "in_year": "{year}年", + "in_year_selector": "在", "include_archived": "包括已归档", "include_shared_albums": "包括共享相册", "include_shared_partner_assets": "包括同伴共享项目", @@ -1232,6 +1241,7 @@ "language_setting_description": "选择您的语言偏好", "large_files": "大文件", "last": "最后一个", + "last_months": "{count, plural, one {上个月} other {最近 # 个月}}", "last_seen": "最后上线于", "latest_version": "最新版本", "latitude": "纬度", @@ -1241,6 +1251,8 @@ "let_others_respond": "允许他人回应", "level": "等级", "library": "图库", + "library_add_folder": "添加文件夹", + "library_edit_folder": "编辑文件夹", "library_options": "图库选项", "library_page_device_albums": "设备上的相册", "library_page_new_album": "新建相册", @@ -1312,8 +1324,17 @@ "loop_videos_description": "启用在详细信息中自动循环播放视频。", "main_branch_warning": "您当前使用的是开发版;我们强烈建议您使用正式发行版(release版)!", "main_menu": "主菜单", + "maintenance_description": "Immich已进入维护模式。", + "maintenance_end": "退出维护模式", + "maintenance_end_error": "退出维护模式失败。", + "maintenance_logged_in_as": "当前以{user}身份登录", + "maintenance_title": "暂时不可用", "make": "品牌", "manage_geolocation": "管理坐标位置", + "manage_media_access_rationale": "正确处理将资产移至垃圾桶并将其从垃圾桶中恢复需要此许可。", + "manage_media_access_settings": "打开设置", + "manage_media_access_subtitle": "允许Immich应用程序管理和移动媒体文件。", + "manage_media_access_title": "媒体管理访问", "manage_shared_links": "管理共享链接", "manage_sharing_with_partners": "管理与同伴的共享", "manage_the_app_settings": "管理应用设置", @@ -1377,6 +1398,7 @@ "more": "更多", "move": "移动", "move_off_locked_folder": "移出锁定文件夹", + "move_to": "移动到", "move_to_lock_folder_action_prompt": "已将 {count} 项添加到锁定文件夹", "move_to_locked_folder": "移动到锁定文件夹", "move_to_locked_folder_confirmation": "这些照片和视频将从所有相册中移除,只能在锁定文件夹中查看", @@ -1406,6 +1428,7 @@ "new_pin_code": "新的PIN码", "new_pin_code_subtitle": "这是您第一次访问此锁定文件夹。创建一个PIN码以安全访问此页面", "new_timeline": "切换到新版时间线", + "new_update": "新版本", "new_user_created": "已创建新用户", "new_version_available": "有新版本发布啦", "newest_first": "最新优先", @@ -1421,22 +1444,25 @@ "no_cast_devices_found": "未找到投放设备", "no_checksum_local": "没有可用的校验和-无法获取本地资产", "no_checksum_remote": "没有可用的校验和-无法获取远程资产", + "no_devices": "无授权设备", "no_duplicates_found": "未发现重复项。", "no_exif_info_available": "没有可用的 EXIF 信息", "no_explore_results_message": "上传更多照片来探索。", "no_favorites_message": "添加到收藏夹,快速查找最佳图片和视频", "no_libraries_message": "创建外部图库来查看您的照片和视频", "no_local_assets_found": "未找到具有此校验和的本地资产", + "no_location_set": "未设置地点", "no_locked_photos_message": "锁定文件夹中的照片和视频将被隐藏,不会在您浏览、搜索图库时出现。", "no_name": "未命名", "no_notifications": "没有通知", "no_people_found": "未找到匹配的人物", "no_places": "无位置", "no_remote_assets_found": "未找到具有此校验和的远程资产", - "no_results": "无结果", + "no_results": "无搜索结果", "no_results_description": "尝试使用同义词或更通用的关键词", "no_shared_albums_message": "创建相册以共享照片和视频", "no_uploads_in_progress": "没有正在进行的上传", + "not_allowed": "不允许", "not_available": "不适用", "not_in_any_album": "不在任何相册中", "not_selected": "未选择", @@ -1547,6 +1573,8 @@ "photos_count": "{count, plural, one {{count, number}张照片} other {{count, number}张照片}}", "photos_from_previous_years": "过往的今昔瞬间", "pick_a_location": "选择位置", + "pick_custom_range": "自定义范围", + "pick_date_range": "选择日期范围", "pin_code_changed_successfully": "修改PIN码成功", "pin_code_reset_successfully": "重置PIN码成功", "pin_code_setup_successfully": "设置PIN码成功", @@ -1814,6 +1842,8 @@ "server_offline": "服务器离线", "server_online": "服务器在线", "server_privacy": "服务器隐私", + "server_restarting_description": "此页面将立即刷新。", + "server_restarting_title": "服务器正在重新启动", "server_stats": "服务器状态", "server_update_available": "服务器更新可用", "server_version": "服务器版本", @@ -2027,6 +2057,7 @@ "third_party_resources": "第三方资源", "time": "时间", "time_based_memories": "那年今日", + "time_based_memories_duration": "显示每张图像的秒数。", "timeline": "时间线", "timezone": "时区", "to_archive": "归档", @@ -2167,6 +2198,7 @@ "welcome": "欢迎", "welcome_to_immich": "欢迎使用 Immich", "wifi_name": "Wi-Fi 名称", + "workflow": "流程", "wrong_pin_code": "错误的PIN码", "year": "年", "years_ago": "{years, plural, one {#年} other {#年}}前", diff --git a/machine-learning/Dockerfile b/machine-learning/Dockerfile index 4b8e79b469..6c976d4612 100644 --- a/machine-learning/Dockerfile +++ b/machine-learning/Dockerfile @@ -1,6 +1,6 @@ ARG DEVICE=cpu -FROM python:3.11-bookworm@sha256:fc1f2e357c307c4044133952b203e66a47e7726821a664f603a180a0c5823844 AS builder-cpu +FROM python:3.11-bookworm@sha256:e39286476f84ffedf7c3564b0b74e32c9e1193ec9ca32ee8a11f8c09dbf6aafe AS builder-cpu FROM builder-cpu AS builder-openvino @@ -22,10 +22,10 @@ FROM builder-cpu AS builder-rknn # Warning: 25GiB+ disk space required to pull this image # TODO: find a way to reduce the image size -FROM rocm/dev-ubuntu-22.04:6.4.3-complete@sha256:1f7e92ca7e3a3785680473329ed1091fc99db3e90fcb3a1688f2933e870ed76b AS builder-rocm +FROM rocm/dev-ubuntu-22.04:6.4.3-complete@sha256:6cda50e312f3aac068cea9ec06c560ca1f522ad546bc8b3d2cf06da0fe8e8a76 AS builder-rocm # renovate: datasource=github-releases depName=Microsoft/onnxruntime -ARG ONNXRUNTIME_VERSION="v1.20.1" +ARG ONNXRUNTIME_VERSION="v1.22.1" WORKDIR /code RUN apt-get update && apt-get install -y --no-install-recommends wget git python3.10-venv @@ -68,12 +68,12 @@ RUN if [ "$DEVICE" = "rocm" ]; then \ uv pip install /opt/onnxruntime_rocm-*.whl; \ fi -FROM python:3.11-slim-bookworm@sha256:873f91540d53b36327ed4fb018c9669107a4e2a676719720edb4209c4b15d029 AS prod-cpu +FROM python:3.11-slim-bookworm@sha256:2c5bc243b1cc47985ee4fb768bb0bbd4490481c5d0897a62da31b7f30b7304a7 AS prod-cpu ENV LD_PRELOAD=/usr/lib/libmimalloc.so.2 \ MACHINE_LEARNING_MODEL_ARENA=false -FROM python:3.11-slim-bookworm@sha256:873f91540d53b36327ed4fb018c9669107a4e2a676719720edb4209c4b15d029 AS prod-openvino +FROM python:3.11-slim-bookworm@sha256:2c5bc243b1cc47985ee4fb768bb0bbd4490481c5d0897a62da31b7f30b7304a7 AS prod-openvino RUN apt-get update && \ apt-get install --no-install-recommends -yqq ocl-icd-libopencl1 wget && \ @@ -102,7 +102,7 @@ COPY --from=builder-cuda /usr/local/bin/python3 /usr/local/bin/python3 COPY --from=builder-cuda /usr/local/lib/python3.11 /usr/local/lib/python3.11 COPY --from=builder-cuda /usr/local/lib/libpython3.11.so /usr/local/lib/libpython3.11.so -FROM rocm/dev-ubuntu-22.04:6.4.3-complete@sha256:1f7e92ca7e3a3785680473329ed1091fc99db3e90fcb3a1688f2933e870ed76b AS prod-rocm +FROM rocm/dev-ubuntu-22.04:6.4.3-complete@sha256:6cda50e312f3aac068cea9ec06c560ca1f522ad546bc8b3d2cf06da0fe8e8a76 AS prod-rocm FROM prod-cpu AS prod-armnn diff --git a/machine-learning/immich_ml/models/ocr/detection.py b/machine-learning/immich_ml/models/ocr/detection.py index 4101a5c6f7..d34a51684e 100644 --- a/machine-learning/immich_ml/models/ocr/detection.py +++ b/machine-learning/immich_ml/models/ocr/detection.py @@ -82,6 +82,7 @@ class TextDetector(InferenceModel): ratio = float(self.max_resolution) / img.height else: ratio = float(self.max_resolution) / img.width + ratio = min(ratio, 1.0) resize_h = int(img.height * ratio) resize_w = int(img.width * ratio) diff --git a/machine-learning/patches/0002-target-gfx900-gfx1102.patch b/machine-learning/patches/0002-target-gfx900-gfx1102.patch index fab7a62d8e..11c1ab0367 100644 --- a/machine-learning/patches/0002-target-gfx900-gfx1102.patch +++ b/machine-learning/patches/0002-target-gfx900-gfx1102.patch @@ -1,13 +1,13 @@ diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt -index d90a2a355..bb1a7de12 100644 +index 2714e6f59..a69da76b4 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt -@@ -295,7 +295,7 @@ if (onnxruntime_USE_ROCM) +@@ -338,7 +338,7 @@ if (onnxruntime_USE_ROCM) + if (ROCM_VERSION_DEV VERSION_LESS "6.2") + message(FATAL_ERROR "CMAKE_HIP_ARCHITECTURES is not set when ROCm version < 6.2") + else() +- set(CMAKE_HIP_ARCHITECTURES "gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx940;gfx941;gfx942;gfx1200;gfx1201") ++ set(CMAKE_HIP_ARCHITECTURES "gfx900;gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx1102;gfx940;gfx941;gfx942;gfx1200;gfx1201") + endif() endif() - - if (NOT CMAKE_HIP_ARCHITECTURES) -- set(CMAKE_HIP_ARCHITECTURES "gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx940;gfx941;gfx942;gfx1200;gfx1201") -+ set(CMAKE_HIP_ARCHITECTURES "gfx900;gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx1102;gfx940;gfx941;gfx942;gfx1200;gfx1201") - endif() - - file(GLOB rocm_cmake_components ${onnxruntime_ROCM_HOME}/lib/cmake/*) + diff --git a/machine-learning/pyproject.toml b/machine-learning/pyproject.toml index a93ab1c2af..436dbb7db1 100644 --- a/machine-learning/pyproject.toml +++ b/machine-learning/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "immich-ml" -version = "2.2.3" +version = "2.3.1" description = "" authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }] requires-python = ">=3.10,<4.0" diff --git a/machine-learning/uv.lock b/machine-learning/uv.lock index 919a17d45e..356e954ef4 100644 --- a/machine-learning/uv.lock +++ b/machine-learning/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.10, <4.0" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'darwin'", @@ -23,9 +23,9 @@ resolution-markers = [ name = "aiocache" version = "0.12.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7a/64/b945b8025a9d1e6e2138845f4022165d3b337f55f50984fbc6a4c0a1e355/aiocache-0.12.3.tar.gz", hash = "sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713", size = 132196 } +sdist = { url = "https://files.pythonhosted.org/packages/7a/64/b945b8025a9d1e6e2138845f4022165d3b337f55f50984fbc6a4c0a1e355/aiocache-0.12.3.tar.gz", hash = "sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713", size = 132196, upload-time = "2024-09-25T13:20:23.823Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/d7/15d67e05b235d1ed8c3ce61688fe4d84130e72af1657acadfaac3479f4cf/aiocache-0.12.3-py2.py3-none-any.whl", hash = "sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d", size = 28199 }, + { url = "https://files.pythonhosted.org/packages/37/d7/15d67e05b235d1ed8c3ce61688fe4d84130e72af1657acadfaac3479f4cf/aiocache-0.12.3-py2.py3-none-any.whl", hash = "sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d", size = 28199, upload-time = "2024-09-25T13:20:22.688Z" }, ] [[package]] @@ -41,25 +41,34 @@ dependencies = [ { name = "scipy", version = "1.11.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/14/d6/8dd5b690d28a332a0b2c3179a345808b5d4c7ad5ddc079b7e116098dff35/albumentations-1.3.1.tar.gz", hash = "sha256:a6a38388fe546c568071e8c82f414498e86c9ed03c08b58e7a88b31cf7a244c6", size = 176371 } +sdist = { url = "https://files.pythonhosted.org/packages/14/d6/8dd5b690d28a332a0b2c3179a345808b5d4c7ad5ddc079b7e116098dff35/albumentations-1.3.1.tar.gz", hash = "sha256:a6a38388fe546c568071e8c82f414498e86c9ed03c08b58e7a88b31cf7a244c6", size = 176371, upload-time = "2023-06-10T07:44:32.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/f6/c486cedb4f75147232f32ec4c97026714cfef7c7e247a1f0427bc5489f66/albumentations-1.3.1-py3-none-any.whl", hash = "sha256:6b641d13733181d9ecdc29550e6ad580d1bfa9d25e2213a66940062f25e291bd", size = 125706 }, + { url = "https://files.pythonhosted.org/packages/9b/f6/c486cedb4f75147232f32ec4c97026714cfef7c7e247a1f0427bc5489f66/albumentations-1.3.1-py3-none-any.whl", hash = "sha256:6b641d13733181d9ecdc29550e6ad580d1bfa9d25e2213a66940062f25e291bd", size = 125706, upload-time = "2023-06-10T07:44:30.373Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] name = "antlr4-python3-runtime" version = "4.9.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034 } +sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034, upload-time = "2021-11-06T17:52:23.524Z" } [[package]] name = "anyio" @@ -71,32 +80,32 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f", size = 158770 } +sdist = { url = "https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f", size = 158770, upload-time = "2023-12-16T17:06:57.709Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", size = 85481 }, + { url = "https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", size = 85481, upload-time = "2023-12-16T17:06:55.989Z" }, ] [[package]] name = "backports-asyncio-runner" version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313 }, + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, ] [[package]] name = "bidict" version = "0.23.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9a/6e/026678aa5a830e07cd9498a05d3e7e650a4f56a42f267a53d22bcda1bdc9/bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71", size = 29093 } +sdist = { url = "https://files.pythonhosted.org/packages/9a/6e/026678aa5a830e07cd9498a05d3e7e650a4f56a42f267a53d22bcda1bdc9/bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71", size = 29093, upload-time = "2024-02-18T19:09:05.748Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5", size = 32764 }, + { url = "https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5", size = 32764, upload-time = "2024-02-18T19:09:04.156Z" }, ] [[package]] name = "black" -version = "25.1.0" +version = "25.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -104,116 +113,121 @@ dependencies = [ { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, + { name = "pytokens" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/ad/33adf4708633d047950ff2dfdea2e215d84ac50ef95aff14a614e4b6e9b2/black-25.11.0.tar.gz", hash = "sha256:9a323ac32f5dc75ce7470501b887250be5005a01602e931a15e45593f70f6e08", size = 655669, upload-time = "2025-11-10T01:53:50.558Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419 }, - { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080 }, - { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886 }, - { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404 }, - { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372 }, - { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865 }, - { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699 }, - { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028 }, - { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988 }, - { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985 }, - { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816 }, - { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860 }, - { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673 }, - { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190 }, - { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926 }, - { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613 }, - { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646 }, + { url = "https://files.pythonhosted.org/packages/b3/d2/6caccbc96f9311e8ec3378c296d4f4809429c43a6cd2394e3c390e86816d/black-25.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ec311e22458eec32a807f029b2646f661e6859c3f61bc6d9ffb67958779f392e", size = 1743501, upload-time = "2025-11-10T01:59:06.202Z" }, + { url = "https://files.pythonhosted.org/packages/69/35/b986d57828b3f3dccbf922e2864223197ba32e74c5004264b1c62bc9f04d/black-25.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1032639c90208c15711334d681de2e24821af0575573db2810b0763bcd62e0f0", size = 1597308, upload-time = "2025-11-10T01:57:58.633Z" }, + { url = "https://files.pythonhosted.org/packages/39/8e/8b58ef4b37073f52b64a7b2dd8c9a96c84f45d6f47d878d0aa557e9a2d35/black-25.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c0f7c461df55cf32929b002335883946a4893d759f2df343389c4396f3b6b37", size = 1656194, upload-time = "2025-11-10T01:57:10.909Z" }, + { url = "https://files.pythonhosted.org/packages/8d/30/9c2267a7955ecc545306534ab88923769a979ac20a27cf618d370091e5dd/black-25.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:f9786c24d8e9bd5f20dc7a7f0cdd742644656987f6ea6947629306f937726c03", size = 1347996, upload-time = "2025-11-10T01:57:22.391Z" }, + { url = "https://files.pythonhosted.org/packages/c4/62/d304786b75ab0c530b833a89ce7d997924579fb7484ecd9266394903e394/black-25.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:895571922a35434a9d8ca67ef926da6bc9ad464522a5fe0db99b394ef1c0675a", size = 1727891, upload-time = "2025-11-10T02:01:40.507Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/ffe8a006aa522c9e3f430e7b93568a7b2163f4b3f16e8feb6d8c3552761a/black-25.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb4f4b65d717062191bdec8e4a442539a8ea065e6af1c4f4d36f0cdb5f71e170", size = 1581875, upload-time = "2025-11-10T01:57:51.192Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7c8bda3108d0bb57387ac41b4abb5c08782b26da9f9c4421ef6694dac01a/black-25.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d81a44cbc7e4f73a9d6ae449ec2317ad81512d1e7dce7d57f6333fd6259737bc", size = 1642716, upload-time = "2025-11-10T01:56:51.589Z" }, + { url = "https://files.pythonhosted.org/packages/34/b9/f17dea34eecb7cc2609a89627d480fb6caea7b86190708eaa7eb15ed25e7/black-25.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:7eebd4744dfe92ef1ee349dc532defbf012a88b087bb7ddd688ff59a447b080e", size = 1352904, upload-time = "2025-11-10T01:59:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/7f/12/5c35e600b515f35ffd737da7febdb2ab66bb8c24d88560d5e3ef3d28c3fd/black-25.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:80e7486ad3535636657aa180ad32a7d67d7c273a80e12f1b4bfa0823d54e8fac", size = 1772831, upload-time = "2025-11-10T02:03:47Z" }, + { url = "https://files.pythonhosted.org/packages/1a/75/b3896bec5a2bb9ed2f989a970ea40e7062f8936f95425879bbe162746fe5/black-25.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6cced12b747c4c76bc09b4db057c319d8545307266f41aaee665540bc0e04e96", size = 1608520, upload-time = "2025-11-10T01:58:46.895Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b5/2bfc18330eddbcfb5aab8d2d720663cd410f51b2ed01375f5be3751595b0/black-25.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb2d54a39e0ef021d6c5eef442e10fd71fcb491be6413d083a320ee768329dd", size = 1682719, upload-time = "2025-11-10T01:56:55.24Z" }, + { url = "https://files.pythonhosted.org/packages/96/fb/f7dc2793a22cdf74a72114b5ed77fe3349a2e09ef34565857a2f917abdf2/black-25.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae263af2f496940438e5be1a0c1020e13b09154f3af4df0835ea7f9fe7bfa409", size = 1362684, upload-time = "2025-11-10T01:57:07.639Z" }, + { url = "https://files.pythonhosted.org/packages/ad/47/3378d6a2ddefe18553d1115e36aea98f4a90de53b6a3017ed861ba1bd3bc/black-25.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a1d40348b6621cc20d3d7530a5b8d67e9714906dfd7346338249ad9c6cedf2b", size = 1772446, upload-time = "2025-11-10T02:02:16.181Z" }, + { url = "https://files.pythonhosted.org/packages/ba/4b/0f00bfb3d1f7e05e25bfc7c363f54dc523bb6ba502f98f4ad3acf01ab2e4/black-25.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:51c65d7d60bb25429ea2bf0731c32b2a2442eb4bd3b2afcb47830f0b13e58bfd", size = 1607983, upload-time = "2025-11-10T02:02:52.502Z" }, + { url = "https://files.pythonhosted.org/packages/99/fe/49b0768f8c9ae57eb74cc10a1f87b4c70453551d8ad498959721cc345cb7/black-25.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:936c4dd07669269f40b497440159a221ee435e3fddcf668e0c05244a9be71993", size = 1682481, upload-time = "2025-11-10T01:57:12.35Z" }, + { url = "https://files.pythonhosted.org/packages/55/17/7e10ff1267bfa950cc16f0a411d457cdff79678fbb77a6c73b73a5317904/black-25.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:f42c0ea7f59994490f4dccd64e6b2dd49ac57c7c84f38b8faab50f8759db245c", size = 1363869, upload-time = "2025-11-10T01:58:24.608Z" }, + { url = "https://files.pythonhosted.org/packages/67/c0/cc865ce594d09e4cd4dfca5e11994ebb51604328489f3ca3ae7bb38a7db5/black-25.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:35690a383f22dd3e468c85dc4b915217f87667ad9cce781d7b42678ce63c4170", size = 1771358, upload-time = "2025-11-10T02:03:33.331Z" }, + { url = "https://files.pythonhosted.org/packages/37/77/4297114d9e2fd2fc8ab0ab87192643cd49409eb059e2940391e7d2340e57/black-25.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:dae49ef7369c6caa1a1833fd5efb7c3024bb7e4499bf64833f65ad27791b1545", size = 1612902, upload-time = "2025-11-10T01:59:33.382Z" }, + { url = "https://files.pythonhosted.org/packages/de/63/d45ef97ada84111e330b2b2d45e1dd163e90bd116f00ac55927fb6bf8adb/black-25.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bd4a22a0b37401c8e492e994bce79e614f91b14d9ea911f44f36e262195fdda", size = 1680571, upload-time = "2025-11-10T01:57:04.239Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4b/5604710d61cdff613584028b4cb4607e56e148801ed9b38ee7970799dab6/black-25.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:aa211411e94fdf86519996b7f5f05e71ba34835d8f0c0f03c00a26271da02664", size = 1382599, upload-time = "2025-11-10T01:57:57.427Z" }, + { url = "https://files.pythonhosted.org/packages/00/5d/aed32636ed30a6e7f9efd6ad14e2a0b0d687ae7c8c7ec4e4a557174b895c/black-25.11.0-py3-none-any.whl", hash = "sha256:e3f562da087791e96cefcd9dda058380a442ab322a02e222add53736451f604b", size = 204918, upload-time = "2025-11-10T01:53:48.917Z" }, ] [[package]] name = "blinker" version = "1.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134, upload-time = "2023-11-01T22:06:01.588Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068 }, + { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068, upload-time = "2023-11-01T22:06:00.162Z" }, ] [[package]] name = "brotli" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/c2/f9e977608bdf958650638c3f1e28f85a1b075f075ebbe77db8555463787b/Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", size = 7372270 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/c2/f9e977608bdf958650638c3f1e28f85a1b075f075ebbe77db8555463787b/Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", size = 7372270, upload-time = "2023-09-07T14:05:41.643Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/3a/dbf4fb970c1019a57b5e492e1e0eae745d32e59ba4d6161ab5422b08eefe/Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", size = 873045 }, - { url = "https://files.pythonhosted.org/packages/dd/11/afc14026ea7f44bd6eb9316d800d439d092c8d508752055ce8d03086079a/Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", size = 446218 }, - { url = "https://files.pythonhosted.org/packages/36/83/7545a6e7729db43cb36c4287ae388d6885c85a86dd251768a47015dfde32/Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", size = 2903872 }, - { url = "https://files.pythonhosted.org/packages/32/23/35331c4d9391fcc0f29fd9bec2c76e4b4eeab769afbc4b11dd2e1098fb13/Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", size = 2941254 }, - { url = "https://files.pythonhosted.org/packages/3b/24/1671acb450c902edb64bd765d73603797c6c7280a9ada85a195f6b78c6e5/Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", size = 2857293 }, - { url = "https://files.pythonhosted.org/packages/d5/00/40f760cc27007912b327fe15bf6bfd8eaecbe451687f72a8abc587d503b3/Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", size = 3002385 }, - { url = "https://files.pythonhosted.org/packages/b8/cb/8aaa83f7a4caa131757668c0fb0c4b6384b09ffa77f2fba9570d87ab587d/Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", size = 2911104 }, - { url = "https://files.pythonhosted.org/packages/bc/c4/65456561d89d3c49f46b7fbeb8fe6e449f13bdc8ea7791832c5d476b2faf/Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", size = 2809981 }, - { url = "https://files.pythonhosted.org/packages/05/1b/cf49528437bae28abce5f6e059f0d0be6fecdcc1d3e33e7c54b3ca498425/Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", size = 2935297 }, - { url = "https://files.pythonhosted.org/packages/81/ff/190d4af610680bf0c5a09eb5d1eac6e99c7c8e216440f9c7cfd42b7adab5/Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", size = 2930735 }, - { url = "https://files.pythonhosted.org/packages/80/7d/f1abbc0c98f6e09abd3cad63ec34af17abc4c44f308a7a539010f79aae7a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c", size = 2933107 }, - { url = "https://files.pythonhosted.org/packages/34/ce/5a5020ba48f2b5a4ad1c0522d095ad5847a0be508e7d7569c8630ce25062/Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1", size = 2845400 }, - { url = "https://files.pythonhosted.org/packages/44/89/fa2c4355ab1eecf3994e5a0a7f5492c6ff81dfcb5f9ba7859bd534bb5c1a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2", size = 3031985 }, - { url = "https://files.pythonhosted.org/packages/af/a4/79196b4a1674143d19dca400866b1a4d1a089040df7b93b88ebae81f3447/Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec", size = 2927099 }, - { url = "https://files.pythonhosted.org/packages/e9/54/1c0278556a097f9651e657b873ab08f01b9a9ae4cac128ceb66427d7cd20/Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", size = 333172 }, - { url = "https://files.pythonhosted.org/packages/f7/65/b785722e941193fd8b571afd9edbec2a9b838ddec4375d8af33a50b8dab9/Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", size = 357255 }, - { url = "https://files.pythonhosted.org/packages/96/12/ad41e7fadd5db55459c4c401842b47f7fee51068f86dd2894dd0dcfc2d2a/Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", size = 873068 }, - { url = "https://files.pythonhosted.org/packages/95/4e/5afab7b2b4b61a84e9c75b17814198ce515343a44e2ed4488fac314cd0a9/Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", size = 446244 }, - { url = "https://files.pythonhosted.org/packages/9d/e6/f305eb61fb9a8580c525478a4a34c5ae1a9bcb12c3aee619114940bc513d/Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", size = 2906500 }, - { url = "https://files.pythonhosted.org/packages/3e/4f/af6846cfbc1550a3024e5d3775ede1e00474c40882c7bf5b37a43ca35e91/Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", size = 2943950 }, - { url = "https://files.pythonhosted.org/packages/b3/e7/ca2993c7682d8629b62630ebf0d1f3bb3d579e667ce8e7ca03a0a0576a2d/Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61", size = 2918527 }, - { url = "https://files.pythonhosted.org/packages/b3/96/da98e7bedc4c51104d29cc61e5f449a502dd3dbc211944546a4cc65500d3/Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", size = 2845489 }, - { url = "https://files.pythonhosted.org/packages/e8/ef/ccbc16947d6ce943a7f57e1a40596c75859eeb6d279c6994eddd69615265/Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", size = 2914080 }, - { url = "https://files.pythonhosted.org/packages/80/d6/0bd38d758d1afa62a5524172f0b18626bb2392d717ff94806f741fcd5ee9/Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", size = 2813051 }, - { url = "https://files.pythonhosted.org/packages/14/56/48859dd5d129d7519e001f06dcfbb6e2cf6db92b2702c0c2ce7d97e086c1/Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", size = 2938172 }, - { url = "https://files.pythonhosted.org/packages/3d/77/a236d5f8cd9e9f4348da5acc75ab032ab1ab2c03cc8f430d24eea2672888/Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8", size = 2933023 }, - { url = "https://files.pythonhosted.org/packages/f1/87/3b283efc0f5cb35f7f84c0c240b1e1a1003a5e47141a4881bf87c86d0ce2/Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f", size = 2935871 }, - { url = "https://files.pythonhosted.org/packages/f3/eb/2be4cc3e2141dc1a43ad4ca1875a72088229de38c68e842746b342667b2a/Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757", size = 2847784 }, - { url = "https://files.pythonhosted.org/packages/66/13/b58ddebfd35edde572ccefe6890cf7c493f0c319aad2a5badee134b4d8ec/Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0", size = 3034905 }, - { url = "https://files.pythonhosted.org/packages/84/9c/bc96b6c7db824998a49ed3b38e441a2cae9234da6fa11f6ed17e8cf4f147/Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b", size = 2929467 }, - { url = "https://files.pythonhosted.org/packages/e7/71/8f161dee223c7ff7fea9d44893fba953ce97cf2c3c33f78ba260a91bcff5/Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", size = 333169 }, - { url = "https://files.pythonhosted.org/packages/02/8a/fece0ee1057643cb2a5bbf59682de13f1725f8482b2c057d4e799d7ade75/Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", size = 357253 }, - { url = "https://files.pythonhosted.org/packages/5c/d0/5373ae13b93fe00095a58efcbce837fd470ca39f703a235d2a999baadfbc/Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28", size = 815693 }, - { url = "https://files.pythonhosted.org/packages/8e/48/f6e1cdf86751300c288c1459724bfa6917a80e30dbfc326f92cea5d3683a/Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f", size = 422489 }, - { url = "https://files.pythonhosted.org/packages/06/88/564958cedce636d0f1bed313381dfc4b4e3d3f6015a63dae6146e1b8c65c/Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", size = 873081 }, - { url = "https://files.pythonhosted.org/packages/58/79/b7026a8bb65da9a6bb7d14329fd2bd48d2b7f86d7329d5cc8ddc6a90526f/Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", size = 446244 }, - { url = "https://files.pythonhosted.org/packages/e5/18/c18c32ecea41b6c0004e15606e274006366fe19436b6adccc1ae7b2e50c2/Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", size = 2906505 }, - { url = "https://files.pythonhosted.org/packages/08/c8/69ec0496b1ada7569b62d85893d928e865df29b90736558d6c98c2031208/Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", size = 2944152 }, - { url = "https://files.pythonhosted.org/packages/ab/fb/0517cea182219d6768113a38167ef6d4eb157a033178cc938033a552ed6d/Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", size = 2919252 }, - { url = "https://files.pythonhosted.org/packages/c7/53/73a3431662e33ae61a5c80b1b9d2d18f58dfa910ae8dd696e57d39f1a2f5/Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", size = 2845955 }, - { url = "https://files.pythonhosted.org/packages/55/ac/bd280708d9c5ebdbf9de01459e625a3e3803cce0784f47d633562cf40e83/Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", size = 2914304 }, - { url = "https://files.pythonhosted.org/packages/76/58/5c391b41ecfc4527d2cc3350719b02e87cb424ef8ba2023fb662f9bf743c/Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", size = 2814452 }, - { url = "https://files.pythonhosted.org/packages/c7/4e/91b8256dfe99c407f174924b65a01f5305e303f486cc7a2e8a5d43c8bec3/Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", size = 2938751 }, - { url = "https://files.pythonhosted.org/packages/5a/a6/e2a39a5d3b412938362bbbeba5af904092bf3f95b867b4a3eb856104074e/Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", size = 2933757 }, - { url = "https://files.pythonhosted.org/packages/13/f0/358354786280a509482e0e77c1a5459e439766597d280f28cb097642fc26/Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9", size = 2936146 }, - { url = "https://files.pythonhosted.org/packages/80/f7/daf538c1060d3a88266b80ecc1d1c98b79553b3f117a485653f17070ea2a/Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb", size = 2848055 }, - { url = "https://files.pythonhosted.org/packages/ad/cf/0eaa0585c4077d3c2d1edf322d8e97aabf317941d3a72d7b3ad8bce004b0/Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111", size = 3035102 }, - { url = "https://files.pythonhosted.org/packages/d8/63/1c1585b2aa554fe6dbce30f0c18bdbc877fa9a1bf5ff17677d9cca0ac122/Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839", size = 2930029 }, - { url = "https://files.pythonhosted.org/packages/5f/3b/4e3fd1893eb3bbfef8e5a80d4508bec17a57bb92d586c85c12d28666bb13/Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", size = 333276 }, - { url = "https://files.pythonhosted.org/packages/3d/d5/942051b45a9e883b5b6e98c041698b1eb2012d25e5948c58d6bf85b1bb43/Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", size = 357255 }, - { url = "https://files.pythonhosted.org/packages/0a/9f/fb37bb8ffc52a8da37b1c03c459a8cd55df7a57bdccd8831d500e994a0ca/Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5", size = 815681 }, - { url = "https://files.pythonhosted.org/packages/06/b3/dbd332a988586fefb0aa49c779f59f47cae76855c2d00f450364bb574cac/Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8", size = 422475 }, - { url = "https://files.pythonhosted.org/packages/bb/80/6aaddc2f63dbcf2d93c2d204e49c11a9ec93a8c7c63261e2b4bd35198283/Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f", size = 2906173 }, - { url = "https://files.pythonhosted.org/packages/ea/1d/e6ca79c96ff5b641df6097d299347507d39a9604bde8915e76bf026d6c77/Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648", size = 2943803 }, - { url = "https://files.pythonhosted.org/packages/ac/a3/d98d2472e0130b7dd3acdbb7f390d478123dbf62b7d32bda5c830a96116d/Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0", size = 2918946 }, - { url = "https://files.pythonhosted.org/packages/c4/a5/c69e6d272aee3e1423ed005d8915a7eaa0384c7de503da987f2d224d0721/Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089", size = 2845707 }, - { url = "https://files.pythonhosted.org/packages/58/9f/4149d38b52725afa39067350696c09526de0125ebfbaab5acc5af28b42ea/Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368", size = 2936231 }, - { url = "https://files.pythonhosted.org/packages/5a/5a/145de884285611838a16bebfdb060c231c52b8f84dfbe52b852a15780386/Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c", size = 2848157 }, - { url = "https://files.pythonhosted.org/packages/50/ae/408b6bfb8525dadebd3b3dd5b19d631da4f7d46420321db44cd99dcf2f2c/Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284", size = 3035122 }, - { url = "https://files.pythonhosted.org/packages/af/85/a94e5cfaa0ca449d8f91c3d6f78313ebf919a0dbd55a100c711c6e9655bc/Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7", size = 2930206 }, - { url = "https://files.pythonhosted.org/packages/c2/f0/a61d9262cd01351df22e57ad7c34f66794709acab13f34be2675f45bf89d/Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0", size = 333804 }, - { url = "https://files.pythonhosted.org/packages/7e/c1/ec214e9c94000d1c1974ec67ced1c970c148aa6b8d8373066123fc3dbf06/Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b", size = 358517 }, + { url = "https://files.pythonhosted.org/packages/6d/3a/dbf4fb970c1019a57b5e492e1e0eae745d32e59ba4d6161ab5422b08eefe/Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", size = 873045, upload-time = "2023-09-07T14:03:16.894Z" }, + { url = "https://files.pythonhosted.org/packages/dd/11/afc14026ea7f44bd6eb9316d800d439d092c8d508752055ce8d03086079a/Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", size = 446218, upload-time = "2023-09-07T14:03:18.917Z" }, + { url = "https://files.pythonhosted.org/packages/36/83/7545a6e7729db43cb36c4287ae388d6885c85a86dd251768a47015dfde32/Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", size = 2903872, upload-time = "2023-09-07T14:03:20.398Z" }, + { url = "https://files.pythonhosted.org/packages/32/23/35331c4d9391fcc0f29fd9bec2c76e4b4eeab769afbc4b11dd2e1098fb13/Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", size = 2941254, upload-time = "2023-09-07T14:03:21.914Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/1671acb450c902edb64bd765d73603797c6c7280a9ada85a195f6b78c6e5/Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", size = 2857293, upload-time = "2023-09-07T14:03:24Z" }, + { url = "https://files.pythonhosted.org/packages/d5/00/40f760cc27007912b327fe15bf6bfd8eaecbe451687f72a8abc587d503b3/Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", size = 3002385, upload-time = "2023-09-07T14:03:26.248Z" }, + { url = "https://files.pythonhosted.org/packages/b8/cb/8aaa83f7a4caa131757668c0fb0c4b6384b09ffa77f2fba9570d87ab587d/Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", size = 2911104, upload-time = "2023-09-07T14:03:27.849Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c4/65456561d89d3c49f46b7fbeb8fe6e449f13bdc8ea7791832c5d476b2faf/Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", size = 2809981, upload-time = "2023-09-07T14:03:29.92Z" }, + { url = "https://files.pythonhosted.org/packages/05/1b/cf49528437bae28abce5f6e059f0d0be6fecdcc1d3e33e7c54b3ca498425/Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", size = 2935297, upload-time = "2023-09-07T14:03:32.035Z" }, + { url = "https://files.pythonhosted.org/packages/81/ff/190d4af610680bf0c5a09eb5d1eac6e99c7c8e216440f9c7cfd42b7adab5/Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", size = 2930735, upload-time = "2023-09-07T14:03:33.801Z" }, + { url = "https://files.pythonhosted.org/packages/80/7d/f1abbc0c98f6e09abd3cad63ec34af17abc4c44f308a7a539010f79aae7a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c", size = 2933107, upload-time = "2024-10-18T12:32:09.016Z" }, + { url = "https://files.pythonhosted.org/packages/34/ce/5a5020ba48f2b5a4ad1c0522d095ad5847a0be508e7d7569c8630ce25062/Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1", size = 2845400, upload-time = "2024-10-18T12:32:11.134Z" }, + { url = "https://files.pythonhosted.org/packages/44/89/fa2c4355ab1eecf3994e5a0a7f5492c6ff81dfcb5f9ba7859bd534bb5c1a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2", size = 3031985, upload-time = "2024-10-18T12:32:12.813Z" }, + { url = "https://files.pythonhosted.org/packages/af/a4/79196b4a1674143d19dca400866b1a4d1a089040df7b93b88ebae81f3447/Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec", size = 2927099, upload-time = "2024-10-18T12:32:14.733Z" }, + { url = "https://files.pythonhosted.org/packages/e9/54/1c0278556a097f9651e657b873ab08f01b9a9ae4cac128ceb66427d7cd20/Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", size = 333172, upload-time = "2023-09-07T14:03:35.212Z" }, + { url = "https://files.pythonhosted.org/packages/f7/65/b785722e941193fd8b571afd9edbec2a9b838ddec4375d8af33a50b8dab9/Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", size = 357255, upload-time = "2023-09-07T14:03:36.447Z" }, + { url = "https://files.pythonhosted.org/packages/96/12/ad41e7fadd5db55459c4c401842b47f7fee51068f86dd2894dd0dcfc2d2a/Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", size = 873068, upload-time = "2023-09-07T14:03:37.779Z" }, + { url = "https://files.pythonhosted.org/packages/95/4e/5afab7b2b4b61a84e9c75b17814198ce515343a44e2ed4488fac314cd0a9/Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", size = 446244, upload-time = "2023-09-07T14:03:39.223Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e6/f305eb61fb9a8580c525478a4a34c5ae1a9bcb12c3aee619114940bc513d/Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", size = 2906500, upload-time = "2023-09-07T14:03:40.858Z" }, + { url = "https://files.pythonhosted.org/packages/3e/4f/af6846cfbc1550a3024e5d3775ede1e00474c40882c7bf5b37a43ca35e91/Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", size = 2943950, upload-time = "2023-09-07T14:03:42.896Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e7/ca2993c7682d8629b62630ebf0d1f3bb3d579e667ce8e7ca03a0a0576a2d/Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61", size = 2918527, upload-time = "2023-09-07T14:03:44.552Z" }, + { url = "https://files.pythonhosted.org/packages/b3/96/da98e7bedc4c51104d29cc61e5f449a502dd3dbc211944546a4cc65500d3/Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", size = 2845489, upload-time = "2023-09-07T14:03:46.594Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ef/ccbc16947d6ce943a7f57e1a40596c75859eeb6d279c6994eddd69615265/Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", size = 2914080, upload-time = "2023-09-07T14:03:48.204Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/0bd38d758d1afa62a5524172f0b18626bb2392d717ff94806f741fcd5ee9/Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", size = 2813051, upload-time = "2023-09-07T14:03:50.348Z" }, + { url = "https://files.pythonhosted.org/packages/14/56/48859dd5d129d7519e001f06dcfbb6e2cf6db92b2702c0c2ce7d97e086c1/Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", size = 2938172, upload-time = "2023-09-07T14:03:52.395Z" }, + { url = "https://files.pythonhosted.org/packages/3d/77/a236d5f8cd9e9f4348da5acc75ab032ab1ab2c03cc8f430d24eea2672888/Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8", size = 2933023, upload-time = "2023-09-07T14:03:53.96Z" }, + { url = "https://files.pythonhosted.org/packages/f1/87/3b283efc0f5cb35f7f84c0c240b1e1a1003a5e47141a4881bf87c86d0ce2/Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f", size = 2935871, upload-time = "2024-10-18T12:32:16.688Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/2be4cc3e2141dc1a43ad4ca1875a72088229de38c68e842746b342667b2a/Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757", size = 2847784, upload-time = "2024-10-18T12:32:18.459Z" }, + { url = "https://files.pythonhosted.org/packages/66/13/b58ddebfd35edde572ccefe6890cf7c493f0c319aad2a5badee134b4d8ec/Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0", size = 3034905, upload-time = "2024-10-18T12:32:20.192Z" }, + { url = "https://files.pythonhosted.org/packages/84/9c/bc96b6c7db824998a49ed3b38e441a2cae9234da6fa11f6ed17e8cf4f147/Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b", size = 2929467, upload-time = "2024-10-18T12:32:21.774Z" }, + { url = "https://files.pythonhosted.org/packages/e7/71/8f161dee223c7ff7fea9d44893fba953ce97cf2c3c33f78ba260a91bcff5/Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", size = 333169, upload-time = "2023-09-07T14:03:55.404Z" }, + { url = "https://files.pythonhosted.org/packages/02/8a/fece0ee1057643cb2a5bbf59682de13f1725f8482b2c057d4e799d7ade75/Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", size = 357253, upload-time = "2023-09-07T14:03:56.643Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/5373ae13b93fe00095a58efcbce837fd470ca39f703a235d2a999baadfbc/Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28", size = 815693, upload-time = "2024-10-18T12:32:23.824Z" }, + { url = "https://files.pythonhosted.org/packages/8e/48/f6e1cdf86751300c288c1459724bfa6917a80e30dbfc326f92cea5d3683a/Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f", size = 422489, upload-time = "2024-10-18T12:32:25.641Z" }, + { url = "https://files.pythonhosted.org/packages/06/88/564958cedce636d0f1bed313381dfc4b4e3d3f6015a63dae6146e1b8c65c/Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", size = 873081, upload-time = "2023-09-07T14:03:57.967Z" }, + { url = "https://files.pythonhosted.org/packages/58/79/b7026a8bb65da9a6bb7d14329fd2bd48d2b7f86d7329d5cc8ddc6a90526f/Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", size = 446244, upload-time = "2023-09-07T14:03:59.319Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/c18c32ecea41b6c0004e15606e274006366fe19436b6adccc1ae7b2e50c2/Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", size = 2906505, upload-time = "2023-09-07T14:04:01.327Z" }, + { url = "https://files.pythonhosted.org/packages/08/c8/69ec0496b1ada7569b62d85893d928e865df29b90736558d6c98c2031208/Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", size = 2944152, upload-time = "2023-09-07T14:04:03.033Z" }, + { url = "https://files.pythonhosted.org/packages/ab/fb/0517cea182219d6768113a38167ef6d4eb157a033178cc938033a552ed6d/Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", size = 2919252, upload-time = "2023-09-07T14:04:04.675Z" }, + { url = "https://files.pythonhosted.org/packages/c7/53/73a3431662e33ae61a5c80b1b9d2d18f58dfa910ae8dd696e57d39f1a2f5/Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", size = 2845955, upload-time = "2023-09-07T14:04:06.585Z" }, + { url = "https://files.pythonhosted.org/packages/55/ac/bd280708d9c5ebdbf9de01459e625a3e3803cce0784f47d633562cf40e83/Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", size = 2914304, upload-time = "2023-09-07T14:04:08.668Z" }, + { url = "https://files.pythonhosted.org/packages/76/58/5c391b41ecfc4527d2cc3350719b02e87cb424ef8ba2023fb662f9bf743c/Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", size = 2814452, upload-time = "2023-09-07T14:04:10.736Z" }, + { url = "https://files.pythonhosted.org/packages/c7/4e/91b8256dfe99c407f174924b65a01f5305e303f486cc7a2e8a5d43c8bec3/Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", size = 2938751, upload-time = "2023-09-07T14:04:12.875Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a6/e2a39a5d3b412938362bbbeba5af904092bf3f95b867b4a3eb856104074e/Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", size = 2933757, upload-time = "2023-09-07T14:04:14.551Z" }, + { url = "https://files.pythonhosted.org/packages/13/f0/358354786280a509482e0e77c1a5459e439766597d280f28cb097642fc26/Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9", size = 2936146, upload-time = "2024-10-18T12:32:27.257Z" }, + { url = "https://files.pythonhosted.org/packages/80/f7/daf538c1060d3a88266b80ecc1d1c98b79553b3f117a485653f17070ea2a/Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb", size = 2848055, upload-time = "2024-10-18T12:32:29.376Z" }, + { url = "https://files.pythonhosted.org/packages/ad/cf/0eaa0585c4077d3c2d1edf322d8e97aabf317941d3a72d7b3ad8bce004b0/Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111", size = 3035102, upload-time = "2024-10-18T12:32:31.371Z" }, + { url = "https://files.pythonhosted.org/packages/d8/63/1c1585b2aa554fe6dbce30f0c18bdbc877fa9a1bf5ff17677d9cca0ac122/Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839", size = 2930029, upload-time = "2024-10-18T12:32:33.293Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3b/4e3fd1893eb3bbfef8e5a80d4508bec17a57bb92d586c85c12d28666bb13/Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", size = 333276, upload-time = "2023-09-07T14:04:16.49Z" }, + { url = "https://files.pythonhosted.org/packages/3d/d5/942051b45a9e883b5b6e98c041698b1eb2012d25e5948c58d6bf85b1bb43/Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", size = 357255, upload-time = "2023-09-07T14:04:17.83Z" }, + { url = "https://files.pythonhosted.org/packages/0a/9f/fb37bb8ffc52a8da37b1c03c459a8cd55df7a57bdccd8831d500e994a0ca/Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5", size = 815681, upload-time = "2024-10-18T12:32:34.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/b3/dbd332a988586fefb0aa49c779f59f47cae76855c2d00f450364bb574cac/Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8", size = 422475, upload-time = "2024-10-18T12:32:36.485Z" }, + { url = "https://files.pythonhosted.org/packages/bb/80/6aaddc2f63dbcf2d93c2d204e49c11a9ec93a8c7c63261e2b4bd35198283/Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f", size = 2906173, upload-time = "2024-10-18T12:32:37.978Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/e6ca79c96ff5b641df6097d299347507d39a9604bde8915e76bf026d6c77/Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648", size = 2943803, upload-time = "2024-10-18T12:32:39.606Z" }, + { url = "https://files.pythonhosted.org/packages/ac/a3/d98d2472e0130b7dd3acdbb7f390d478123dbf62b7d32bda5c830a96116d/Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0", size = 2918946, upload-time = "2024-10-18T12:32:41.679Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a5/c69e6d272aee3e1423ed005d8915a7eaa0384c7de503da987f2d224d0721/Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089", size = 2845707, upload-time = "2024-10-18T12:32:43.478Z" }, + { url = "https://files.pythonhosted.org/packages/58/9f/4149d38b52725afa39067350696c09526de0125ebfbaab5acc5af28b42ea/Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368", size = 2936231, upload-time = "2024-10-18T12:32:45.224Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5a/145de884285611838a16bebfdb060c231c52b8f84dfbe52b852a15780386/Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c", size = 2848157, upload-time = "2024-10-18T12:32:46.894Z" }, + { url = "https://files.pythonhosted.org/packages/50/ae/408b6bfb8525dadebd3b3dd5b19d631da4f7d46420321db44cd99dcf2f2c/Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284", size = 3035122, upload-time = "2024-10-18T12:32:48.844Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/a94e5cfaa0ca449d8f91c3d6f78313ebf919a0dbd55a100c711c6e9655bc/Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7", size = 2930206, upload-time = "2024-10-18T12:32:51.198Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f0/a61d9262cd01351df22e57ad7c34f66794709acab13f34be2675f45bf89d/Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0", size = 333804, upload-time = "2024-10-18T12:32:52.661Z" }, + { url = "https://files.pythonhosted.org/packages/7e/c1/ec214e9c94000d1c1974ec67ced1c970c148aa6b8d8373066123fc3dbf06/Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b", size = 358517, upload-time = "2024-10-18T12:32:54.066Z" }, ] [[package]] name = "certifi" version = "2023.11.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/91/c89518dd4fe1f3a4e3f6ab7ff23cb00ef2e8c9adf99dacc618ad5e068e28/certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", size = 163637 } +sdist = { url = "https://files.pythonhosted.org/packages/d4/91/c89518dd4fe1f3a4e3f6ab7ff23cb00ef2e8c9adf99dacc618ad5e068e28/certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", size = 163637, upload-time = "2023-11-18T02:54:02.397Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/62/428ef076be88fa93716b576e4a01f919d25968913e817077a386fcbe4f42/certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474", size = 162530 }, + { url = "https://files.pythonhosted.org/packages/64/62/428ef076be88fa93716b576e4a01f919d25968913e817077a386fcbe4f42/certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474", size = 162530, upload-time = "2023-11-18T02:54:00.083Z" }, ] [[package]] @@ -223,108 +237,108 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, - { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, - { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, - { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, - { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, - { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, - { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, - { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, - { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, - { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload-time = "2024-09-04T20:43:30.027Z" }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload-time = "2024-09-04T20:43:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, ] [[package]] name = "charset-normalizer" version = "3.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } +sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809, upload-time = "2023-11-01T04:04:59.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, - { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, - { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, - { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, - { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, - { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, - { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, - { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, - { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, - { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, - { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, - { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, - { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, - { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, - { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, - { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, - { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, - { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, - { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, - { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, - { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, - { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, - { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, - { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, - { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, - { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, - { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, - { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, - { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, - { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, + { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219, upload-time = "2023-11-01T04:02:29.048Z" }, + { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521, upload-time = "2023-11-01T04:02:32.452Z" }, + { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383, upload-time = "2023-11-01T04:02:34.11Z" }, + { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223, upload-time = "2023-11-01T04:02:36.213Z" }, + { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101, upload-time = "2023-11-01T04:02:38.067Z" }, + { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699, upload-time = "2023-11-01T04:02:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065, upload-time = "2023-11-01T04:02:41.357Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505, upload-time = "2023-11-01T04:02:43.108Z" }, + { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425, upload-time = "2023-11-01T04:02:45.427Z" }, + { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287, upload-time = "2023-11-01T04:02:46.705Z" }, + { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929, upload-time = "2023-11-01T04:02:48.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605, upload-time = "2023-11-01T04:02:49.605Z" }, + { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646, upload-time = "2023-11-01T04:02:51.35Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846, upload-time = "2023-11-01T04:02:52.679Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343, upload-time = "2023-11-01T04:02:53.915Z" }, + { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647, upload-time = "2023-11-01T04:02:55.329Z" }, + { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434, upload-time = "2023-11-01T04:02:57.173Z" }, + { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979, upload-time = "2023-11-01T04:02:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582, upload-time = "2023-11-01T04:02:59.776Z" }, + { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645, upload-time = "2023-11-01T04:03:02.186Z" }, + { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398, upload-time = "2023-11-01T04:03:04.255Z" }, + { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273, upload-time = "2023-11-01T04:03:05.983Z" }, + { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577, upload-time = "2023-11-01T04:03:07.567Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747, upload-time = "2023-11-01T04:03:08.886Z" }, + { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375, upload-time = "2023-11-01T04:03:10.613Z" }, + { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474, upload-time = "2023-11-01T04:03:11.973Z" }, + { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232, upload-time = "2023-11-01T04:03:13.505Z" }, + { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859, upload-time = "2023-11-01T04:03:17.362Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509, upload-time = "2023-11-01T04:03:21.453Z" }, + { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870, upload-time = "2023-11-01T04:03:22.723Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892, upload-time = "2023-11-01T04:03:24.135Z" }, + { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213, upload-time = "2023-11-01T04:03:25.66Z" }, + { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404, upload-time = "2023-11-01T04:03:27.04Z" }, + { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275, upload-time = "2023-11-01T04:03:28.466Z" }, + { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518, upload-time = "2023-11-01T04:03:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182, upload-time = "2023-11-01T04:03:31.511Z" }, + { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869, upload-time = "2023-11-01T04:03:32.887Z" }, + { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042, upload-time = "2023-11-01T04:03:34.412Z" }, + { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275, upload-time = "2023-11-01T04:03:35.759Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819, upload-time = "2023-11-01T04:03:37.216Z" }, + { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415, upload-time = "2023-11-01T04:03:38.694Z" }, + { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212, upload-time = "2023-11-01T04:03:40.07Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167, upload-time = "2023-11-01T04:03:41.491Z" }, + { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041, upload-time = "2023-11-01T04:03:42.836Z" }, + { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397, upload-time = "2023-11-01T04:03:44.467Z" }, + { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543, upload-time = "2023-11-01T04:04:58.622Z" }, ] [[package]] @@ -334,18 +348,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload-time = "2023-08-17T17:29:11.868Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload-time = "2023-08-17T17:29:10.08Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] @@ -355,9 +369,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "humanfriendly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018 }, + { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, ] [[package]] @@ -367,18 +381,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624, upload-time = "2024-10-29T18:34:51.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424 }, + { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424, upload-time = "2024-10-29T18:34:49.815Z" }, ] [[package]] name = "configargparse" version = "1.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/4d/6c9ef746dfcc2a32e26f3860bb4a011c008c392b83eabdfb598d1a8bbe5d/configargparse-1.7.1.tar.gz", hash = "sha256:79c2ddae836a1e5914b71d58e4b9adbd9f7779d4e6351a637b7d2d9b6c46d3d9", size = 43958 } +sdist = { url = "https://files.pythonhosted.org/packages/85/4d/6c9ef746dfcc2a32e26f3860bb4a011c008c392b83eabdfb598d1a8bbe5d/configargparse-1.7.1.tar.gz", hash = "sha256:79c2ddae836a1e5914b71d58e4b9adbd9f7779d4e6351a637b7d2d9b6c46d3d9", size = 43958, upload-time = "2025-05-23T14:26:17.369Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/28/d28211d29bcc3620b1fece85a65ce5bb22f18670a03cd28ea4b75ede270c/configargparse-1.7.1-py3-none-any.whl", hash = "sha256:8b586a31f9d873abd1ca527ffbe58863c99f36d896e2829779803125e83be4b6", size = 25607 }, + { url = "https://files.pythonhosted.org/packages/31/28/d28211d29bcc3620b1fece85a65ce5bb22f18670a03cd28ea4b75ede270c/configargparse-1.7.1-py3-none-any.whl", hash = "sha256:8b586a31f9d873abd1ca527ffbe58863c99f36d896e2829779803125e83be4b6", size = 25607, upload-time = "2025-05-23T14:26:15.923Z" }, ] [[package]] @@ -393,38 +407,38 @@ resolution-markers = [ dependencies = [ { name = "numpy", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/11/a3/48ddc7ae832b000952cf4be64452381d150a41a2299c2eb19237168528d1/contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a", size = 13455881 } +sdist = { url = "https://files.pythonhosted.org/packages/11/a3/48ddc7ae832b000952cf4be64452381d150a41a2299c2eb19237168528d1/contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a", size = 13455881, upload-time = "2023-11-03T17:01:03.144Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/ea/f6e90933d82cc5aacf52f886a1c01f47f96eba99108ca2929c7b3ef45f82/contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8", size = 256873 }, - { url = "https://files.pythonhosted.org/packages/fe/26/43821d61b7ee62c1809ec852bc572aaf4c27f101ebcebbbcce29a5ee0445/contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4", size = 242211 }, - { url = "https://files.pythonhosted.org/packages/9b/99/c8fb63072a7573fe7682e1786a021f29f9c5f660a3aafcdce80b9ee8348d/contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f", size = 293195 }, - { url = "https://files.pythonhosted.org/packages/c7/a7/ae0b4bb8e0c865270d02ee619981413996dc10ddf1fd2689c938173ff62f/contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e", size = 332279 }, - { url = "https://files.pythonhosted.org/packages/94/7c/682228b9085ff323fb7e946fe139072e5f21b71360cf91f36ea079d4ea95/contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9", size = 305326 }, - { url = "https://files.pythonhosted.org/packages/58/56/e2c43dcfa1f9c7db4d5e3d6f5134b24ed953f4e2133a4b12f0062148db58/contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa", size = 310732 }, - { url = "https://files.pythonhosted.org/packages/94/0b/8495c4582057abc8377f945f6e11a86f1c07ad7b32fd4fdc968478cd0324/contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9", size = 803420 }, - { url = "https://files.pythonhosted.org/packages/d5/1f/40399c7da649297147d404aedaa675cc60018f48ad284630c0d1406133e3/contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab", size = 829204 }, - { url = "https://files.pythonhosted.org/packages/8b/01/4be433b60dce7cbce8315cbcdfc016e7d25430a8b94e272355dff79cc3a8/contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488", size = 165434 }, - { url = "https://files.pythonhosted.org/packages/fd/7c/168f8343f33d861305e18c56901ef1bb675d3c7f977f435ec72751a71a54/contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41", size = 186652 }, - { url = "https://files.pythonhosted.org/packages/9b/54/1dafec3c84df1d29119037330f7289db84a679cb2d5283af4ef24d89f532/contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727", size = 258243 }, - { url = "https://files.pythonhosted.org/packages/5b/ac/26fa1057f62beaa2af4c55c6ac733b114a403b746cfe0ce3dc6e4aec921a/contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd", size = 243408 }, - { url = "https://files.pythonhosted.org/packages/b7/33/cd0ecc80123f499d76d2fe2807cb4d5638ef8730735c580c8a8a03e1928e/contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a", size = 294142 }, - { url = "https://files.pythonhosted.org/packages/6d/75/1b7bf20bf6394e01df2c4b4b3d44d3dc280c16ddaff72724639100bd4314/contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063", size = 333129 }, - { url = "https://files.pythonhosted.org/packages/22/5b/fedd961dff1877e5d3b83c5201295cfdcdc2438884c2851aa7ecf6cec045/contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e", size = 307461 }, - { url = "https://files.pythonhosted.org/packages/e2/83/29a63bbc72839cc6b24b5a0e3d004d4ed4e8439f26460ad9a34e39251904/contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686", size = 313352 }, - { url = "https://files.pythonhosted.org/packages/4b/c7/4bac0fc4f1e802ab47e75076d83d2e1448e0668ba6cc9000cf4e9d5bd94a/contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286", size = 804127 }, - { url = "https://files.pythonhosted.org/packages/e3/47/b3fd5bdc2f6ec13502d57a5bc390ffe62648605ed1689c93b0015150a784/contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95", size = 829561 }, - { url = "https://files.pythonhosted.org/packages/5c/04/be16038e754169caea4d02d82f8e5cd97dece593e5ac9e05735da0afd0c5/contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6", size = 166197 }, - { url = "https://files.pythonhosted.org/packages/ca/2a/d197a412ec474391ee878b1218cf2fe9c6e963903755887fc5654c06636a/contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de", size = 187556 }, - { url = "https://files.pythonhosted.org/packages/4f/03/839da46999173226bead08794cbd7b4d37c9e6b02686ca74c93556b43258/contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0", size = 259253 }, - { url = "https://files.pythonhosted.org/packages/f3/9e/8fb3f53144269d3fecdd8786d3a4686eeff55b9b35a3c0772a3f62f71e36/contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4", size = 242555 }, - { url = "https://files.pythonhosted.org/packages/a6/85/9815ccb5a18ee8c9a46bd5ef20d02b292cd4a99c62553f38c87015f16d59/contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779", size = 288108 }, - { url = "https://files.pythonhosted.org/packages/5a/d9/4df5c26bd0f496c8cd7940fd53db95d07deeb98518f02f805ce570590da8/contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316", size = 330810 }, - { url = "https://files.pythonhosted.org/packages/67/d4/8aae9793a0cfde72959312521ebd3aa635c260c3d580448e8db6bdcdd1aa/contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399", size = 305290 }, - { url = "https://files.pythonhosted.org/packages/20/84/ffddcdcc579cbf7213fd92a3578ca08a931a3bf879a22deb5a83ffc5002c/contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0", size = 303937 }, - { url = "https://files.pythonhosted.org/packages/d8/ad/6e570cf525f909da94559ed716189f92f529bc7b5f78645733c44619a0e2/contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0", size = 801977 }, - { url = "https://files.pythonhosted.org/packages/36/b4/55f23482c596eca36d16fc668b147865c56fcf90353f4c57f073d8d5e532/contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431", size = 827442 }, - { url = "https://files.pythonhosted.org/packages/e9/47/9c081b1f11d6053cb0aa4c46b7de2ea2849a4a8d40de81c7bc3f99773b02/contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f", size = 165363 }, - { url = "https://files.pythonhosted.org/packages/8e/ae/a6353db548bff1a592b85ae6bb80275f0a51dc25a0410d059e5b33183e36/contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9", size = 187731 }, + { url = "https://files.pythonhosted.org/packages/e8/ea/f6e90933d82cc5aacf52f886a1c01f47f96eba99108ca2929c7b3ef45f82/contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8", size = 256873, upload-time = "2023-11-03T16:56:34.548Z" }, + { url = "https://files.pythonhosted.org/packages/fe/26/43821d61b7ee62c1809ec852bc572aaf4c27f101ebcebbbcce29a5ee0445/contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4", size = 242211, upload-time = "2023-11-03T16:56:38.028Z" }, + { url = "https://files.pythonhosted.org/packages/9b/99/c8fb63072a7573fe7682e1786a021f29f9c5f660a3aafcdce80b9ee8348d/contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f", size = 293195, upload-time = "2023-11-03T16:56:41.598Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a7/ae0b4bb8e0c865270d02ee619981413996dc10ddf1fd2689c938173ff62f/contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e", size = 332279, upload-time = "2023-11-03T16:56:46.08Z" }, + { url = "https://files.pythonhosted.org/packages/94/7c/682228b9085ff323fb7e946fe139072e5f21b71360cf91f36ea079d4ea95/contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9", size = 305326, upload-time = "2023-11-03T16:56:49.647Z" }, + { url = "https://files.pythonhosted.org/packages/58/56/e2c43dcfa1f9c7db4d5e3d6f5134b24ed953f4e2133a4b12f0062148db58/contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa", size = 310732, upload-time = "2023-11-03T16:56:53.773Z" }, + { url = "https://files.pythonhosted.org/packages/94/0b/8495c4582057abc8377f945f6e11a86f1c07ad7b32fd4fdc968478cd0324/contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9", size = 803420, upload-time = "2023-11-03T16:57:00.669Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1f/40399c7da649297147d404aedaa675cc60018f48ad284630c0d1406133e3/contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab", size = 829204, upload-time = "2023-11-03T16:57:07.813Z" }, + { url = "https://files.pythonhosted.org/packages/8b/01/4be433b60dce7cbce8315cbcdfc016e7d25430a8b94e272355dff79cc3a8/contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488", size = 165434, upload-time = "2023-11-03T16:57:10.601Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7c/168f8343f33d861305e18c56901ef1bb675d3c7f977f435ec72751a71a54/contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41", size = 186652, upload-time = "2023-11-03T16:57:13.57Z" }, + { url = "https://files.pythonhosted.org/packages/9b/54/1dafec3c84df1d29119037330f7289db84a679cb2d5283af4ef24d89f532/contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727", size = 258243, upload-time = "2023-11-03T16:57:16.604Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ac/26fa1057f62beaa2af4c55c6ac733b114a403b746cfe0ce3dc6e4aec921a/contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd", size = 243408, upload-time = "2023-11-03T16:57:20.021Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/cd0ecc80123f499d76d2fe2807cb4d5638ef8730735c580c8a8a03e1928e/contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a", size = 294142, upload-time = "2023-11-03T16:57:23.48Z" }, + { url = "https://files.pythonhosted.org/packages/6d/75/1b7bf20bf6394e01df2c4b4b3d44d3dc280c16ddaff72724639100bd4314/contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063", size = 333129, upload-time = "2023-11-03T16:57:27.141Z" }, + { url = "https://files.pythonhosted.org/packages/22/5b/fedd961dff1877e5d3b83c5201295cfdcdc2438884c2851aa7ecf6cec045/contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e", size = 307461, upload-time = "2023-11-03T16:57:30.537Z" }, + { url = "https://files.pythonhosted.org/packages/e2/83/29a63bbc72839cc6b24b5a0e3d004d4ed4e8439f26460ad9a34e39251904/contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686", size = 313352, upload-time = "2023-11-03T16:57:34.937Z" }, + { url = "https://files.pythonhosted.org/packages/4b/c7/4bac0fc4f1e802ab47e75076d83d2e1448e0668ba6cc9000cf4e9d5bd94a/contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286", size = 804127, upload-time = "2023-11-03T16:57:42.201Z" }, + { url = "https://files.pythonhosted.org/packages/e3/47/b3fd5bdc2f6ec13502d57a5bc390ffe62648605ed1689c93b0015150a784/contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95", size = 829561, upload-time = "2023-11-03T16:57:49.667Z" }, + { url = "https://files.pythonhosted.org/packages/5c/04/be16038e754169caea4d02d82f8e5cd97dece593e5ac9e05735da0afd0c5/contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6", size = 166197, upload-time = "2023-11-03T16:57:52.682Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2a/d197a412ec474391ee878b1218cf2fe9c6e963903755887fc5654c06636a/contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de", size = 187556, upload-time = "2023-11-03T16:57:55.286Z" }, + { url = "https://files.pythonhosted.org/packages/4f/03/839da46999173226bead08794cbd7b4d37c9e6b02686ca74c93556b43258/contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0", size = 259253, upload-time = "2023-11-03T16:57:58.572Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9e/8fb3f53144269d3fecdd8786d3a4686eeff55b9b35a3c0772a3f62f71e36/contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4", size = 242555, upload-time = "2023-11-03T16:58:01.48Z" }, + { url = "https://files.pythonhosted.org/packages/a6/85/9815ccb5a18ee8c9a46bd5ef20d02b292cd4a99c62553f38c87015f16d59/contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779", size = 288108, upload-time = "2023-11-03T16:58:05.546Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d9/4df5c26bd0f496c8cd7940fd53db95d07deeb98518f02f805ce570590da8/contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316", size = 330810, upload-time = "2023-11-03T16:58:09.568Z" }, + { url = "https://files.pythonhosted.org/packages/67/d4/8aae9793a0cfde72959312521ebd3aa635c260c3d580448e8db6bdcdd1aa/contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399", size = 305290, upload-time = "2023-11-03T16:58:13.017Z" }, + { url = "https://files.pythonhosted.org/packages/20/84/ffddcdcc579cbf7213fd92a3578ca08a931a3bf879a22deb5a83ffc5002c/contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0", size = 303937, upload-time = "2023-11-03T16:58:16.426Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ad/6e570cf525f909da94559ed716189f92f529bc7b5f78645733c44619a0e2/contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0", size = 801977, upload-time = "2023-11-03T16:58:23.539Z" }, + { url = "https://files.pythonhosted.org/packages/36/b4/55f23482c596eca36d16fc668b147865c56fcf90353f4c57f073d8d5e532/contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431", size = 827442, upload-time = "2023-11-03T16:58:30.724Z" }, + { url = "https://files.pythonhosted.org/packages/e9/47/9c081b1f11d6053cb0aa4c46b7de2ea2849a4a8d40de81c7bc3f99773b02/contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f", size = 165363, upload-time = "2023-11-03T16:58:33.54Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ae/a6353db548bff1a592b85ae6bb80275f0a51dc25a0410d059e5b33183e36/contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9", size = 187731, upload-time = "2023-11-03T16:58:36.585Z" }, ] [[package]] @@ -448,138 +462,178 @@ resolution-markers = [ dependencies = [ { name = "numpy", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174 } +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773 }, - { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149 }, - { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222 }, - { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234 }, - { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555 }, - { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238 }, - { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218 }, - { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867 }, - { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677 }, - { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234 }, - { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123 }, - { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419 }, - { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979 }, - { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653 }, - { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536 }, - { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397 }, - { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601 }, - { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288 }, - { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386 }, - { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018 }, - { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567 }, - { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655 }, - { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257 }, - { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034 }, - { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672 }, - { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234 }, - { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169 }, - { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859 }, - { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062 }, - { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932 }, - { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024 }, - { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578 }, - { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524 }, - { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730 }, - { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897 }, - { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751 }, - { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486 }, - { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106 }, - { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548 }, - { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297 }, - { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023 }, - { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157 }, - { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570 }, - { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713 }, - { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189 }, - { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251 }, - { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810 }, - { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871 }, - { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264 }, - { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819 }, - { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650 }, - { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833 }, - { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692 }, - { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424 }, - { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300 }, - { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769 }, - { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892 }, - { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748 }, - { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554 }, - { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118 }, - { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555 }, - { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295 }, - { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027 }, - { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428 }, - { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331 }, - { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831 }, - { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809 }, - { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593 }, - { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202 }, - { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207 }, - { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315 }, + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, ] [[package]] name = "coverage" -version = "7.6.4" +version = "7.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } +sdist = { url = "https://files.pythonhosted.org/packages/89/26/4a96807b193b011588099c3b5c89fbb05294e5b90e71018e065465f34eb6/coverage-7.12.0.tar.gz", hash = "sha256:fc11e0a4e372cb5f282f16ef90d4a585034050ccda536451901abfb19a57f40c", size = 819341, upload-time = "2025-11-18T13:34:20.766Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, - { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, - { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, - { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, - { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, - { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, - { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, - { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, - { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, - { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, - { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, - { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, - { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, - { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, - { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, - { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, - { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, - { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, - { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, - { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, - { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, - { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, - { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, - { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, - { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, - { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, - { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, - { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, - { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, - { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, - { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, - { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, - { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, - { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, - { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, - { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, - { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, - { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, - { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, - { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, - { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, - { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, - { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, - { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, - { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, - { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, - { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, + { url = "https://files.pythonhosted.org/packages/26/4a/0dc3de1c172d35abe512332cfdcc43211b6ebce629e4cc42e6cd25ed8f4d/coverage-7.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:32b75c2ba3f324ee37af3ccee5b30458038c50b349ad9b88cee85096132a575b", size = 217409, upload-time = "2025-11-18T13:31:53.122Z" }, + { url = "https://files.pythonhosted.org/packages/01/c3/086198b98db0109ad4f84241e8e9ea7e5fb2db8c8ffb787162d40c26cc76/coverage-7.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb2a1b6ab9fe833714a483a915de350abc624a37149649297624c8d57add089c", size = 217927, upload-time = "2025-11-18T13:31:54.458Z" }, + { url = "https://files.pythonhosted.org/packages/5d/5f/34614dbf5ce0420828fc6c6f915126a0fcb01e25d16cf141bf5361e6aea6/coverage-7.12.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5734b5d913c3755e72f70bf6cc37a0518d4f4745cde760c5d8e12005e62f9832", size = 244678, upload-time = "2025-11-18T13:31:55.805Z" }, + { url = "https://files.pythonhosted.org/packages/55/7b/6b26fb32e8e4a6989ac1d40c4e132b14556131493b1d06bc0f2be169c357/coverage-7.12.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b527a08cdf15753279b7afb2339a12073620b761d79b81cbe2cdebdb43d90daa", size = 246507, upload-time = "2025-11-18T13:31:57.05Z" }, + { url = "https://files.pythonhosted.org/packages/06/42/7d70e6603d3260199b90fb48b537ca29ac183d524a65cc31366b2e905fad/coverage-7.12.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9bb44c889fb68004e94cab71f6a021ec83eac9aeabdbb5a5a88821ec46e1da73", size = 248366, upload-time = "2025-11-18T13:31:58.362Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4a/d86b837923878424c72458c5b25e899a3c5ca73e663082a915f5b3c4d749/coverage-7.12.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4b59b501455535e2e5dde5881739897967b272ba25988c89145c12d772810ccb", size = 245366, upload-time = "2025-11-18T13:31:59.572Z" }, + { url = "https://files.pythonhosted.org/packages/e6/c2/2adec557e0aa9721875f06ced19730fdb7fc58e31b02b5aa56f2ebe4944d/coverage-7.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d8842f17095b9868a05837b7b1b73495293091bed870e099521ada176aa3e00e", size = 246408, upload-time = "2025-11-18T13:32:00.784Z" }, + { url = "https://files.pythonhosted.org/packages/5a/4b/8bd1f1148260df11c618e535fdccd1e5aaf646e55b50759006a4f41d8a26/coverage-7.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c5a6f20bf48b8866095c6820641e7ffbe23f2ac84a2efc218d91235e404c7777", size = 244416, upload-time = "2025-11-18T13:32:01.963Z" }, + { url = "https://files.pythonhosted.org/packages/0e/13/3a248dd6a83df90414c54a4e121fd081fb20602ca43955fbe1d60e2312a9/coverage-7.12.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:5f3738279524e988d9da2893f307c2093815c623f8d05a8f79e3eff3a7a9e553", size = 244681, upload-time = "2025-11-18T13:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/76/30/aa833827465a5e8c938935f5d91ba055f70516941078a703740aaf1aa41f/coverage-7.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0d68c1f7eabbc8abe582d11fa393ea483caf4f44b0af86881174769f185c94d", size = 245300, upload-time = "2025-11-18T13:32:04.686Z" }, + { url = "https://files.pythonhosted.org/packages/38/24/f85b3843af1370fb3739fa7571819b71243daa311289b31214fe3e8c9d68/coverage-7.12.0-cp310-cp310-win32.whl", hash = "sha256:7670d860e18b1e3ee5930b17a7d55ae6287ec6e55d9799982aa103a2cc1fa2ef", size = 220008, upload-time = "2025-11-18T13:32:05.806Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a2/c7da5b9566f7164db9eefa133d17761ecb2c2fde9385d754e5b5c80f710d/coverage-7.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:f999813dddeb2a56aab5841e687b68169da0d3f6fc78ccf50952fa2463746022", size = 220943, upload-time = "2025-11-18T13:32:07.166Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0c/0dfe7f0487477d96432e4815537263363fb6dd7289743a796e8e51eabdf2/coverage-7.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa124a3683d2af98bd9d9c2bfa7a5076ca7e5ab09fdb96b81fa7d89376ae928f", size = 217535, upload-time = "2025-11-18T13:32:08.812Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f5/f9a4a053a5bbff023d3bec259faac8f11a1e5a6479c2ccf586f910d8dac7/coverage-7.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d93fbf446c31c0140208dcd07c5d882029832e8ed7891a39d6d44bd65f2316c3", size = 218044, upload-time = "2025-11-18T13:32:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/95/c5/84fc3697c1fa10cd8571919bf9693f693b7373278daaf3b73e328d502bc8/coverage-7.12.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:52ca620260bd8cd6027317bdd8b8ba929be1d741764ee765b42c4d79a408601e", size = 248440, upload-time = "2025-11-18T13:32:12.536Z" }, + { url = "https://files.pythonhosted.org/packages/f4/36/2d93fbf6a04670f3874aed397d5a5371948a076e3249244a9e84fb0e02d6/coverage-7.12.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f3433ffd541380f3a0e423cff0f4926d55b0cc8c1d160fdc3be24a4c03aa65f7", size = 250361, upload-time = "2025-11-18T13:32:13.852Z" }, + { url = "https://files.pythonhosted.org/packages/5d/49/66dc65cc456a6bfc41ea3d0758c4afeaa4068a2b2931bf83be6894cf1058/coverage-7.12.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7bbb321d4adc9f65e402c677cd1c8e4c2d0105d3ce285b51b4d87f1d5db5245", size = 252472, upload-time = "2025-11-18T13:32:15.068Z" }, + { url = "https://files.pythonhosted.org/packages/35/1f/ebb8a18dffd406db9fcd4b3ae42254aedcaf612470e8712f12041325930f/coverage-7.12.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:22a7aade354a72dff3b59c577bfd18d6945c61f97393bc5fb7bd293a4237024b", size = 248592, upload-time = "2025-11-18T13:32:16.328Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/67f213c06e5ea3b3d4980df7dc344d7fea88240b5fe878a5dcbdfe0e2315/coverage-7.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3ff651dcd36d2fea66877cd4a82de478004c59b849945446acb5baf9379a1b64", size = 250167, upload-time = "2025-11-18T13:32:17.687Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/e52aef68154164ea40cc8389c120c314c747fe63a04b013a5782e989b77f/coverage-7.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:31b8b2e38391a56e3cea39d22a23faaa7c3fc911751756ef6d2621d2a9daf742", size = 248238, upload-time = "2025-11-18T13:32:19.2Z" }, + { url = "https://files.pythonhosted.org/packages/1f/a4/4d88750bcf9d6d66f77865e5a05a20e14db44074c25fd22519777cb69025/coverage-7.12.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:297bc2da28440f5ae51c845a47c8175a4db0553a53827886e4fb25c66633000c", size = 247964, upload-time = "2025-11-18T13:32:21.027Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/b74693158899d5b47b0bf6238d2c6722e20ba749f86b74454fac0696bb00/coverage-7.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ff7651cc01a246908eac162a6a86fc0dbab6de1ad165dfb9a1e2ec660b44984", size = 248862, upload-time = "2025-11-18T13:32:22.304Z" }, + { url = "https://files.pythonhosted.org/packages/18/de/6af6730227ce0e8ade307b1cc4a08e7f51b419a78d02083a86c04ccceb29/coverage-7.12.0-cp311-cp311-win32.whl", hash = "sha256:313672140638b6ddb2c6455ddeda41c6a0b208298034544cfca138978c6baed6", size = 220033, upload-time = "2025-11-18T13:32:23.714Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/e7f63021a7c4fe20994359fcdeae43cbef4a4d0ca36a5a1639feeea5d9e1/coverage-7.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a1783ed5bd0d5938d4435014626568dc7f93e3cb99bc59188cc18857c47aa3c4", size = 220966, upload-time = "2025-11-18T13:32:25.599Z" }, + { url = "https://files.pythonhosted.org/packages/77/e8/deae26453f37c20c3aa0c4433a1e32cdc169bf415cce223a693117aa3ddd/coverage-7.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:4648158fd8dd9381b5847622df1c90ff314efbfc1df4550092ab6013c238a5fc", size = 219637, upload-time = "2025-11-18T13:32:27.265Z" }, + { url = "https://files.pythonhosted.org/packages/02/bf/638c0427c0f0d47638242e2438127f3c8ee3cfc06c7fdeb16778ed47f836/coverage-7.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:29644c928772c78512b48e14156b81255000dcfd4817574ff69def189bcb3647", size = 217704, upload-time = "2025-11-18T13:32:28.906Z" }, + { url = "https://files.pythonhosted.org/packages/08/e1/706fae6692a66c2d6b871a608bbde0da6281903fa0e9f53a39ed441da36a/coverage-7.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8638cbb002eaa5d7c8d04da667813ce1067080b9a91099801a0053086e52b736", size = 218064, upload-time = "2025-11-18T13:32:30.161Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8b/eb0231d0540f8af3ffda39720ff43cb91926489d01524e68f60e961366e4/coverage-7.12.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:083631eeff5eb9992c923e14b810a179798bb598e6a0dd60586819fc23be6e60", size = 249560, upload-time = "2025-11-18T13:32:31.835Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a1/67fb52af642e974d159b5b379e4d4c59d0ebe1288677fbd04bbffe665a82/coverage-7.12.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:99d5415c73ca12d558e07776bd957c4222c687b9f1d26fa0e1b57e3598bdcde8", size = 252318, upload-time = "2025-11-18T13:32:33.178Z" }, + { url = "https://files.pythonhosted.org/packages/41/e5/38228f31b2c7665ebf9bdfdddd7a184d56450755c7e43ac721c11a4b8dab/coverage-7.12.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e949ebf60c717c3df63adb4a1a366c096c8d7fd8472608cd09359e1bd48ef59f", size = 253403, upload-time = "2025-11-18T13:32:34.45Z" }, + { url = "https://files.pythonhosted.org/packages/ec/4b/df78e4c8188f9960684267c5a4897836f3f0f20a20c51606ee778a1d9749/coverage-7.12.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6d907ddccbca819afa2cd014bc69983b146cca2735a0b1e6259b2a6c10be1e70", size = 249984, upload-time = "2025-11-18T13:32:35.747Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/bb163933d195a345c6f63eab9e55743413d064c291b6220df754075c2769/coverage-7.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b1518ecbad4e6173f4c6e6c4a46e49555ea5679bf3feda5edb1b935c7c44e8a0", size = 251339, upload-time = "2025-11-18T13:32:37.352Z" }, + { url = "https://files.pythonhosted.org/packages/15/40/c9b29cdb8412c837cdcbc2cfa054547dd83affe6cbbd4ce4fdb92b6ba7d1/coverage-7.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:51777647a749abdf6f6fd8c7cffab12de68ab93aab15efc72fbbb83036c2a068", size = 249489, upload-time = "2025-11-18T13:32:39.212Z" }, + { url = "https://files.pythonhosted.org/packages/c8/da/b3131e20ba07a0de4437a50ef3b47840dfabf9293675b0cd5c2c7f66dd61/coverage-7.12.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:42435d46d6461a3b305cdfcad7cdd3248787771f53fe18305548cba474e6523b", size = 249070, upload-time = "2025-11-18T13:32:40.598Z" }, + { url = "https://files.pythonhosted.org/packages/70/81/b653329b5f6302c08d683ceff6785bc60a34be9ae92a5c7b63ee7ee7acec/coverage-7.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5bcead88c8423e1855e64b8057d0544e33e4080b95b240c2a355334bb7ced937", size = 250929, upload-time = "2025-11-18T13:32:42.915Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/250ac3bca9f252a5fb1338b5ad01331ebb7b40223f72bef5b1b2cb03aa64/coverage-7.12.0-cp312-cp312-win32.whl", hash = "sha256:dcbb630ab034e86d2a0f79aefd2be07e583202f41e037602d438c80044957baa", size = 220241, upload-time = "2025-11-18T13:32:44.665Z" }, + { url = "https://files.pythonhosted.org/packages/64/1c/77e79e76d37ce83302f6c21980b45e09f8aa4551965213a10e62d71ce0ab/coverage-7.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:2fd8354ed5d69775ac42986a691fbf68b4084278710cee9d7c3eaa0c28fa982a", size = 221051, upload-time = "2025-11-18T13:32:46.008Z" }, + { url = "https://files.pythonhosted.org/packages/31/f5/641b8a25baae564f9e52cac0e2667b123de961985709a004e287ee7663cc/coverage-7.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:737c3814903be30695b2de20d22bcc5428fdae305c61ba44cdc8b3252984c49c", size = 219692, upload-time = "2025-11-18T13:32:47.372Z" }, + { url = "https://files.pythonhosted.org/packages/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47324fffca8d8eae7e185b5bb20c14645f23350f870c1649003618ea91a78941", size = 217725, upload-time = "2025-11-18T13:32:49.22Z" }, + { url = "https://files.pythonhosted.org/packages/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ccf3b2ede91decd2fb53ec73c1f949c3e034129d1e0b07798ff1d02ea0c8fa4a", size = 218098, upload-time = "2025-11-18T13:32:50.78Z" }, + { url = "https://files.pythonhosted.org/packages/fc/9c/b846bbc774ff81091a12a10203e70562c91ae71badda00c5ae5b613527b1/coverage-7.12.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b365adc70a6936c6b0582dc38746b33b2454148c02349345412c6e743efb646d", size = 249093, upload-time = "2025-11-18T13:32:52.554Z" }, + { url = "https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211", size = 251686, upload-time = "2025-11-18T13:32:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/cc/75/b095bd4b39d49c3be4bffbb3135fea18a99a431c52dd7513637c0762fecb/coverage-7.12.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:099d11698385d572ceafb3288a5b80fe1fc58bf665b3f9d362389de488361d3d", size = 252930, upload-time = "2025-11-18T13:32:56.417Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f3/466f63015c7c80550bead3093aacabf5380c1220a2a93c35d374cae8f762/coverage-7.12.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:473dc45d69694069adb7680c405fb1e81f60b2aff42c81e2f2c3feaf544d878c", size = 249296, upload-time = "2025-11-18T13:32:58.074Z" }, + { url = "https://files.pythonhosted.org/packages/27/86/eba2209bf2b7e28c68698fc13437519a295b2d228ba9e0ec91673e09fa92/coverage-7.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:583f9adbefd278e9de33c33d6846aa8f5d164fa49b47144180a0e037f0688bb9", size = 251068, upload-time = "2025-11-18T13:32:59.646Z" }, + { url = "https://files.pythonhosted.org/packages/ec/55/ca8ae7dbba962a3351f18940b359b94c6bafdd7757945fdc79ec9e452dc7/coverage-7.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2089cc445f2dc0af6f801f0d1355c025b76c24481935303cf1af28f636688f0", size = 249034, upload-time = "2025-11-18T13:33:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d7/39136149325cad92d420b023b5fd900dabdd1c3a0d1d5f148ef4a8cedef5/coverage-7.12.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:950411f1eb5d579999c5f66c62a40961f126fc71e5e14419f004471957b51508", size = 248853, upload-time = "2025-11-18T13:33:02.935Z" }, + { url = "https://files.pythonhosted.org/packages/fe/b6/76e1add8b87ef60e00643b0b7f8f7bb73d4bf5249a3be19ebefc5793dd25/coverage-7.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b1aab7302a87bafebfe76b12af681b56ff446dc6f32ed178ff9c092ca776e6bc", size = 250619, upload-time = "2025-11-18T13:33:04.336Z" }, + { url = "https://files.pythonhosted.org/packages/95/87/924c6dc64f9203f7a3c1832a6a0eee5a8335dbe5f1bdadcc278d6f1b4d74/coverage-7.12.0-cp313-cp313-win32.whl", hash = "sha256:d7e0d0303c13b54db495eb636bc2465b2fb8475d4c8bcec8fe4b5ca454dfbae8", size = 220261, upload-time = "2025-11-18T13:33:06.493Z" }, + { url = "https://files.pythonhosted.org/packages/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:ce61969812d6a98a981d147d9ac583a36ac7db7766f2e64a9d4d059c2fe29d07", size = 221072, upload-time = "2025-11-18T13:33:07.926Z" }, + { url = "https://files.pythonhosted.org/packages/70/49/5c9dc46205fef31b1b226a6e16513193715290584317fd4df91cdaf28b22/coverage-7.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:bcec6f47e4cb8a4c2dc91ce507f6eefc6a1b10f58df32cdc61dff65455031dfc", size = 219702, upload-time = "2025-11-18T13:33:09.631Z" }, + { url = "https://files.pythonhosted.org/packages/9b/62/f87922641c7198667994dd472a91e1d9b829c95d6c29529ceb52132436ad/coverage-7.12.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:459443346509476170d553035e4a3eed7b860f4fe5242f02de1010501956ce87", size = 218420, upload-time = "2025-11-18T13:33:11.153Z" }, + { url = "https://files.pythonhosted.org/packages/85/dd/1cc13b2395ef15dbb27d7370a2509b4aee77890a464fb35d72d428f84871/coverage-7.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04a79245ab2b7a61688958f7a855275997134bc84f4a03bc240cf64ff132abf6", size = 218773, upload-time = "2025-11-18T13:33:12.569Z" }, + { url = "https://files.pythonhosted.org/packages/74/40/35773cc4bb1e9d4658d4fb669eb4195b3151bef3bbd6f866aba5cd5dac82/coverage-7.12.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:09a86acaaa8455f13d6a99221d9654df249b33937b4e212b4e5a822065f12aa7", size = 260078, upload-time = "2025-11-18T13:33:14.037Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ee/231bb1a6ffc2905e396557585ebc6bdc559e7c66708376d245a1f1d330fc/coverage-7.12.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:907e0df1b71ba77463687a74149c6122c3f6aac56c2510a5d906b2f368208560", size = 262144, upload-time = "2025-11-18T13:33:15.601Z" }, + { url = "https://files.pythonhosted.org/packages/28/be/32f4aa9f3bf0b56f3971001b56508352c7753915345d45fab4296a986f01/coverage-7.12.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b57e2d0ddd5f0582bae5437c04ee71c46cd908e7bc5d4d0391f9a41e812dd12", size = 264574, upload-time = "2025-11-18T13:33:17.354Z" }, + { url = "https://files.pythonhosted.org/packages/68/7c/00489fcbc2245d13ab12189b977e0cf06ff3351cb98bc6beba8bd68c5902/coverage-7.12.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:58c1c6aa677f3a1411fe6fb28ec3a942e4f665df036a3608816e0847fad23296", size = 259298, upload-time = "2025-11-18T13:33:18.958Z" }, + { url = "https://files.pythonhosted.org/packages/96/b4/f0760d65d56c3bea95b449e02570d4abd2549dc784bf39a2d4721a2d8ceb/coverage-7.12.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4c589361263ab2953e3c4cd2a94db94c4ad4a8e572776ecfbad2389c626e4507", size = 262150, upload-time = "2025-11-18T13:33:20.644Z" }, + { url = "https://files.pythonhosted.org/packages/c5/71/9a9314df00f9326d78c1e5a910f520d599205907432d90d1c1b7a97aa4b1/coverage-7.12.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:91b810a163ccad2e43b1faa11d70d3cf4b6f3d83f9fd5f2df82a32d47b648e0d", size = 259763, upload-time = "2025-11-18T13:33:22.189Z" }, + { url = "https://files.pythonhosted.org/packages/10/34/01a0aceed13fbdf925876b9a15d50862eb8845454301fe3cdd1df08b2182/coverage-7.12.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:40c867af715f22592e0d0fb533a33a71ec9e0f73a6945f722a0c85c8c1cbe3a2", size = 258653, upload-time = "2025-11-18T13:33:24.239Z" }, + { url = "https://files.pythonhosted.org/packages/8d/04/81d8fd64928acf1574bbb0181f66901c6c1c6279c8ccf5f84259d2c68ae9/coverage-7.12.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:68b0d0a2d84f333de875666259dadf28cc67858bc8fd8b3f1eae84d3c2bec455", size = 260856, upload-time = "2025-11-18T13:33:26.365Z" }, + { url = "https://files.pythonhosted.org/packages/f2/76/fa2a37bfaeaf1f766a2d2360a25a5297d4fb567098112f6517475eee120b/coverage-7.12.0-cp313-cp313t-win32.whl", hash = "sha256:73f9e7fbd51a221818fd11b7090eaa835a353ddd59c236c57b2199486b116c6d", size = 220936, upload-time = "2025-11-18T13:33:28.165Z" }, + { url = "https://files.pythonhosted.org/packages/f9/52/60f64d932d555102611c366afb0eb434b34266b1d9266fc2fe18ab641c47/coverage-7.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:24cff9d1f5743f67db7ba46ff284018a6e9aeb649b67aa1e70c396aa1b7cb23c", size = 222001, upload-time = "2025-11-18T13:33:29.656Z" }, + { url = "https://files.pythonhosted.org/packages/77/df/c303164154a5a3aea7472bf323b7c857fed93b26618ed9fc5c2955566bb0/coverage-7.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c87395744f5c77c866d0f5a43d97cc39e17c7f1cb0115e54a2fe67ca75c5d14d", size = 220273, upload-time = "2025-11-18T13:33:31.415Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/fc12db0883478d6e12bbd62d481210f0c8daf036102aa11434a0c5755825/coverage-7.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a1c59b7dc169809a88b21a936eccf71c3895a78f5592051b1af8f4d59c2b4f92", size = 217777, upload-time = "2025-11-18T13:33:32.86Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c1/ce3e525d223350c6ec16b9be8a057623f54226ef7f4c2fee361ebb6a02b8/coverage-7.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8787b0f982e020adb732b9f051f3e49dd5054cebbc3f3432061278512a2b1360", size = 218100, upload-time = "2025-11-18T13:33:34.532Z" }, + { url = "https://files.pythonhosted.org/packages/15/87/113757441504aee3808cb422990ed7c8bcc2d53a6779c66c5adef0942939/coverage-7.12.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5ea5a9f7dc8877455b13dd1effd3202e0bca72f6f3ab09f9036b1bcf728f69ac", size = 249151, upload-time = "2025-11-18T13:33:36.135Z" }, + { url = "https://files.pythonhosted.org/packages/d9/1d/9529d9bd44049b6b05bb319c03a3a7e4b0a8a802d28fa348ad407e10706d/coverage-7.12.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fdba9f15849534594f60b47c9a30bc70409b54947319a7c4fd0e8e3d8d2f355d", size = 251667, upload-time = "2025-11-18T13:33:37.996Z" }, + { url = "https://files.pythonhosted.org/packages/11/bb/567e751c41e9c03dc29d3ce74b8c89a1e3396313e34f255a2a2e8b9ebb56/coverage-7.12.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a00594770eb715854fb1c57e0dea08cce6720cfbc531accdb9850d7c7770396c", size = 253003, upload-time = "2025-11-18T13:33:39.553Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b3/c2cce2d8526a02fb9e9ca14a263ca6fc074449b33a6afa4892838c903528/coverage-7.12.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5560c7e0d82b42eb1951e4f68f071f8017c824ebfd5a6ebe42c60ac16c6c2434", size = 249185, upload-time = "2025-11-18T13:33:42.086Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a7/967f93bb66e82c9113c66a8d0b65ecf72fc865adfba5a145f50c7af7e58d/coverage-7.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2e26b481c9159c2773a37947a9718cfdc58893029cdfb177531793e375cfc", size = 251025, upload-time = "2025-11-18T13:33:43.634Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b2/f2f6f56337bc1af465d5b2dc1ee7ee2141b8b9272f3bf6213fcbc309a836/coverage-7.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6e1a8c066dabcde56d5d9fed6a66bc19a2883a3fe051f0c397a41fc42aedd4cc", size = 248979, upload-time = "2025-11-18T13:33:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7a/bf4209f45a4aec09d10a01a57313a46c0e0e8f4c55ff2965467d41a92036/coverage-7.12.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f7ba9da4726e446d8dd8aae5a6cd872511184a5d861de80a86ef970b5dacce3e", size = 248800, upload-time = "2025-11-18T13:33:47.546Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b7/1e01b8696fb0521810f60c5bbebf699100d6754183e6cc0679bf2ed76531/coverage-7.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e0f483ab4f749039894abaf80c2f9e7ed77bbf3c737517fb88c8e8e305896a17", size = 250460, upload-time = "2025-11-18T13:33:49.537Z" }, + { url = "https://files.pythonhosted.org/packages/71/ae/84324fb9cb46c024760e706353d9b771a81b398d117d8c1fe010391c186f/coverage-7.12.0-cp314-cp314-win32.whl", hash = "sha256:76336c19a9ef4a94b2f8dc79f8ac2da3f193f625bb5d6f51a328cd19bfc19933", size = 220533, upload-time = "2025-11-18T13:33:51.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/71/1033629deb8460a8f97f83e6ac4ca3b93952e2b6f826056684df8275e015/coverage-7.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c1059b600aec6ef090721f8f633f60ed70afaffe8ecab85b59df748f24b31fe", size = 221348, upload-time = "2025-11-18T13:33:52.776Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/ac8107a902f623b0c251abdb749be282dc2ab61854a8a4fcf49e276fce2f/coverage-7.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:172cf3a34bfef42611963e2b661302a8931f44df31629e5b1050567d6b90287d", size = 219922, upload-time = "2025-11-18T13:33:54.316Z" }, + { url = "https://files.pythonhosted.org/packages/79/6e/f27af2d4da367f16077d21ef6fe796c874408219fa6dd3f3efe7751bd910/coverage-7.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:aa7d48520a32cb21c7a9b31f81799e8eaec7239db36c3b670be0fa2403828d1d", size = 218511, upload-time = "2025-11-18T13:33:56.343Z" }, + { url = "https://files.pythonhosted.org/packages/67/dd/65fd874aa460c30da78f9d259400d8e6a4ef457d61ab052fd248f0050558/coverage-7.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:90d58ac63bc85e0fb919f14d09d6caa63f35a5512a2205284b7816cafd21bb03", size = 218771, upload-time = "2025-11-18T13:33:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/55/e0/7c6b71d327d8068cb79c05f8f45bf1b6145f7a0de23bbebe63578fe5240a/coverage-7.12.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ca8ecfa283764fdda3eae1bdb6afe58bf78c2c3ec2b2edcb05a671f0bba7b3f9", size = 260151, upload-time = "2025-11-18T13:33:59.597Z" }, + { url = "https://files.pythonhosted.org/packages/49/ce/4697457d58285b7200de6b46d606ea71066c6e674571a946a6ea908fb588/coverage-7.12.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:874fe69a0785d96bd066059cd4368022cebbec1a8958f224f0016979183916e6", size = 262257, upload-time = "2025-11-18T13:34:01.166Z" }, + { url = "https://files.pythonhosted.org/packages/2f/33/acbc6e447aee4ceba88c15528dbe04a35fb4d67b59d393d2e0d6f1e242c1/coverage-7.12.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5b3c889c0b8b283a24d721a9eabc8ccafcfc3aebf167e4cd0d0e23bf8ec4e339", size = 264671, upload-time = "2025-11-18T13:34:02.795Z" }, + { url = "https://files.pythonhosted.org/packages/87/ec/e2822a795c1ed44d569980097be839c5e734d4c0c1119ef8e0a073496a30/coverage-7.12.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8bb5b894b3ec09dcd6d3743229dc7f2c42ef7787dc40596ae04c0edda487371e", size = 259231, upload-time = "2025-11-18T13:34:04.397Z" }, + { url = "https://files.pythonhosted.org/packages/72/c5/a7ec5395bb4a49c9b7ad97e63f0c92f6bf4a9e006b1393555a02dae75f16/coverage-7.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:79a44421cd5fba96aa57b5e3b5a4d3274c449d4c622e8f76882d76635501fd13", size = 262137, upload-time = "2025-11-18T13:34:06.068Z" }, + { url = "https://files.pythonhosted.org/packages/67/0c/02c08858b764129f4ecb8e316684272972e60777ae986f3865b10940bdd6/coverage-7.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:33baadc0efd5c7294f436a632566ccc1f72c867f82833eb59820ee37dc811c6f", size = 259745, upload-time = "2025-11-18T13:34:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/5a/04/4fd32b7084505f3829a8fe45c1a74a7a728cb251aaadbe3bec04abcef06d/coverage-7.12.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c406a71f544800ef7e9e0000af706b88465f3573ae8b8de37e5f96c59f689ad1", size = 258570, upload-time = "2025-11-18T13:34:09.676Z" }, + { url = "https://files.pythonhosted.org/packages/48/35/2365e37c90df4f5342c4fa202223744119fe31264ee2924f09f074ea9b6d/coverage-7.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e71bba6a40883b00c6d571599b4627f50c360b3d0d02bfc658168936be74027b", size = 260899, upload-time = "2025-11-18T13:34:11.259Z" }, + { url = "https://files.pythonhosted.org/packages/05/56/26ab0464ca733fa325e8e71455c58c1c374ce30f7c04cebb88eabb037b18/coverage-7.12.0-cp314-cp314t-win32.whl", hash = "sha256:9157a5e233c40ce6613dead4c131a006adfda70e557b6856b97aceed01b0e27a", size = 221313, upload-time = "2025-11-18T13:34:12.863Z" }, + { url = "https://files.pythonhosted.org/packages/da/1c/017a3e1113ed34d998b27d2c6dba08a9e7cb97d362f0ec988fcd873dcf81/coverage-7.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e84da3a0fd233aeec797b981c51af1cabac74f9bd67be42458365b30d11b5291", size = 222423, upload-time = "2025-11-18T13:34:15.14Z" }, + { url = "https://files.pythonhosted.org/packages/4c/36/bcc504fdd5169301b52568802bb1b9cdde2e27a01d39fbb3b4b508ab7c2c/coverage-7.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:01d24af36fedda51c2b1aca56e4330a3710f83b02a5ff3743a6b015ffa7c9384", size = 220459, upload-time = "2025-11-18T13:34:17.222Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a3/43b749004e3c09452e39bb56347a008f0a0668aad37324a99b5c8ca91d9e/coverage-7.12.0-py3-none-any.whl", hash = "sha256:159d50c0b12e060b15ed3d39f87ed43d4f7f7ad40b8a534f4dd331adbb51104a", size = 209503, upload-time = "2025-11-18T13:34:18.892Z" }, ] [package.optional-dependencies] @@ -591,80 +645,81 @@ toml = [ name = "cycler" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, ] [[package]] name = "cython" version = "3.0.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/68/09/ffb61f29b8e3d207c444032b21328327d753e274ea081bc74e009827cc81/Cython-3.0.8.tar.gz", hash = "sha256:8333423d8fd5765e7cceea3a9985dd1e0a5dfeb2734629e1a2ed2d6233d39de6", size = 2744096 } +sdist = { url = "https://files.pythonhosted.org/packages/68/09/ffb61f29b8e3d207c444032b21328327d753e274ea081bc74e009827cc81/Cython-3.0.8.tar.gz", hash = "sha256:8333423d8fd5765e7cceea3a9985dd1e0a5dfeb2734629e1a2ed2d6233d39de6", size = 2744096, upload-time = "2024-01-10T11:01:02.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/f4/d2542e186fe33ec1cc542770fb17466421ed54f4ffe04d00fe9549d0a467/Cython-3.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a846e0a38e2b24e9a5c5dc74b0e54c6e29420d88d1dafabc99e0fc0f3e338636", size = 3100459 }, - { url = "https://files.pythonhosted.org/packages/fc/27/2652f395aa708fb3081148e0df3ab700bd7288636c65332ef7febad6a380/Cython-3.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45523fdc2b78d79b32834cc1cc12dc2ca8967af87e22a3ee1bff20e77c7f5520", size = 3456626 }, - { url = "https://files.pythonhosted.org/packages/f9/bd/e8a1d26d04c08a67bcc383f2ea5493a4e77f37a8770ead00a238b08ad729/Cython-3.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa0b7f3f841fe087410cab66778e2d3fb20ae2d2078a2be3dffe66c6574be39", size = 3621379 }, - { url = "https://files.pythonhosted.org/packages/03/ae/ead7ec03d0062d439879d41b7830e4f2480213f7beabf2f7052a191cc6f7/Cython-3.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e87294e33e40c289c77a135f491cd721bd089f193f956f7b8ed5aa2d0b8c558f", size = 3671873 }, - { url = "https://files.pythonhosted.org/packages/63/b0/81dad725604d7b529c492f873a7fa1b5800704a9f26e100ed25e9fd8d057/Cython-3.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a1df7a129344b1215c20096d33c00193437df1a8fcca25b71f17c23b1a44f782", size = 3463832 }, - { url = "https://files.pythonhosted.org/packages/13/cd/72b8e0af597ac1b376421847acf6d6fa252e60059a2a00dcf05ceb16d28f/Cython-3.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:13c2a5e57a0358da467d97667297bf820b62a1a87ae47c5f87938b9bb593acbd", size = 3618325 }, - { url = "https://files.pythonhosted.org/packages/ef/73/11a4355d8b8966504c751e5bcb25916c4140de27bb2ba1b54ff21994d7fe/Cython-3.0.8-cp310-cp310-win32.whl", hash = "sha256:96b028f044f5880e3cb18ecdcfc6c8d3ce9d0af28418d5ab464509f26d8adf12", size = 2571305 }, - { url = "https://files.pythonhosted.org/packages/18/15/fdc0c3552d20f9337b134a36d786da24e47998fc39f62cb61c1534f26123/Cython-3.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:8140597a8b5cc4f119a1190f5a2228a84f5ca6d8d9ec386cfce24663f48b2539", size = 2776113 }, - { url = "https://files.pythonhosted.org/packages/db/a7/f4a0bc9a80e23b380daa2ebb4879bf434aaa0b3b91f7ad8a7f9762b4bd1b/Cython-3.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aae26f9663e50caf9657148403d9874eea41770ecdd6caf381d177c2b1bb82ba", size = 3113615 }, - { url = "https://files.pythonhosted.org/packages/e9/e9/e9295df74246c165b91253a473bfa179debf739c9bee961cbb3ae56c2b79/Cython-3.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:547eb3cdb2f8c6f48e6865d5a741d9dd051c25b3ce076fbca571727977b28ac3", size = 3436320 }, - { url = "https://files.pythonhosted.org/packages/26/2c/6a887c957aa53e44f928119dea628a5dfacc8e875424034f5fecac9daba4/Cython-3.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a567d4b9ba70b26db89d75b243529de9e649a2f56384287533cf91512705bee", size = 3591755 }, - { url = "https://files.pythonhosted.org/packages/ba/b8/f9c97bae6281da50b3ecb1f7fef0f7f7851eae084609b364717a2b366bf1/Cython-3.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51d1426263b0e82fb22bda8ea60dc77a428581cc19e97741011b938445d383f1", size = 3636099 }, - { url = "https://files.pythonhosted.org/packages/17/ae/cd055c2c081c67a6fcad1d8d17d82bd6395b14c6741e3a938f40318c8bc5/Cython-3.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c26daaeccda072459b48d211415fd1e5507c06bcd976fa0d5b8b9f1063467d7b", size = 3458119 }, - { url = "https://files.pythonhosted.org/packages/72/ab/ac6f5548d6194f4bb2fc8c6c996aa7369f0fa1403e4d4de787d9e9309b27/Cython-3.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:289ce7838208211cd166e975865fd73b0649bf118170b6cebaedfbdaf4a37795", size = 3614418 }, - { url = "https://files.pythonhosted.org/packages/70/e2/3e3e448b7a94887bec3235bcb71957b6681dc42b4536459f8f54d46fa936/Cython-3.0.8-cp311-cp311-win32.whl", hash = "sha256:c8aa05f5e17f8042a3be052c24f2edc013fb8af874b0bf76907d16c51b4e7871", size = 2572819 }, - { url = "https://files.pythonhosted.org/packages/85/7d/58635941dfbb5b4e197adb88080b9cbfb230dc3b75683698a530a1989bdb/Cython-3.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:000dc9e135d0eec6ecb2b40a5b02d0868a2f8d2e027a41b0fe16a908a9e6de02", size = 2784167 }, - { url = "https://files.pythonhosted.org/packages/3d/8e/28f8c6109990eef7317ab7e43644092b49a88a39f9373dcd19318946df09/Cython-3.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:90d3fe31db55685d8cb97d43b0ec39ef614fcf660f83c77ed06aa670cb0e164f", size = 3135638 }, - { url = "https://files.pythonhosted.org/packages/83/1f/4720cb682b8ed1ab9749dea35351a66dd29b6a022628cce038415660c384/Cython-3.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e24791ddae2324e88e3c902a765595c738f19ae34ee66bfb1a6dac54b1833419", size = 3340052 }, - { url = "https://files.pythonhosted.org/packages/8a/47/ec3fceb9e8f7d6fa130216b8740038e1df7c8e5f215bba363fcf1272a6c1/Cython-3.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f020fa1c0552052e0660790b8153b79e3fc9a15dbd8f1d0b841fe5d204a6ae6", size = 3510079 }, - { url = "https://files.pythonhosted.org/packages/71/31/b458127851e248effb909e2791b55870914863cde7c60b94db5ee65d7867/Cython-3.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18bfa387d7a7f77d7b2526af69a65dbd0b731b8d941aaff5becff8e21f6d7717", size = 3573972 }, - { url = "https://files.pythonhosted.org/packages/6b/d5/ca6513844d0634abd05ba12304053a454bb70441a9520afa9897d4300156/Cython-3.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fe81b339cffd87c0069c6049b4d33e28bdd1874625ee515785bf42c9fdff3658", size = 3356158 }, - { url = "https://files.pythonhosted.org/packages/33/59/98a87b6264f4ad45c820db13c4ec657567476efde020c49443cc842a86af/Cython-3.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80fd94c076e1e1b1ee40a309be03080b75f413e8997cddcf401a118879863388", size = 3522312 }, - { url = "https://files.pythonhosted.org/packages/2b/cb/132115d07a0b9d4f075e0741db70a5416b424dcd875b2bb0dd805e818222/Cython-3.0.8-cp312-cp312-win32.whl", hash = "sha256:85077915a93e359a9b920280d214dc0cf8a62773e1f3d7d30fab8ea4daed670c", size = 2602579 }, - { url = "https://files.pythonhosted.org/packages/b4/69/cb4620287cd9ef461103e122c0a2ae7f7ecf183e02510676fb5a15c95b05/Cython-3.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:0cb2dcc565c7851f75d496f724a384a790fab12d1b82461b663e66605bec429a", size = 2791268 }, - { url = "https://files.pythonhosted.org/packages/e3/7f/f584f5d15323feb897d42ef0e9d910649e2150d7a30cf7e7a8cc1d236e6f/Cython-3.0.8-py2.py3-none-any.whl", hash = "sha256:171b27051253d3f9108e9759e504ba59ff06e7f7ba944457f94deaf9c21bf0b6", size = 1168213 }, + { url = "https://files.pythonhosted.org/packages/63/f4/d2542e186fe33ec1cc542770fb17466421ed54f4ffe04d00fe9549d0a467/Cython-3.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a846e0a38e2b24e9a5c5dc74b0e54c6e29420d88d1dafabc99e0fc0f3e338636", size = 3100459, upload-time = "2024-01-10T11:33:49.545Z" }, + { url = "https://files.pythonhosted.org/packages/fc/27/2652f395aa708fb3081148e0df3ab700bd7288636c65332ef7febad6a380/Cython-3.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45523fdc2b78d79b32834cc1cc12dc2ca8967af87e22a3ee1bff20e77c7f5520", size = 3456626, upload-time = "2024-01-10T11:01:44.897Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bd/e8a1d26d04c08a67bcc383f2ea5493a4e77f37a8770ead00a238b08ad729/Cython-3.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa0b7f3f841fe087410cab66778e2d3fb20ae2d2078a2be3dffe66c6574be39", size = 3621379, upload-time = "2024-01-10T11:01:48.777Z" }, + { url = "https://files.pythonhosted.org/packages/03/ae/ead7ec03d0062d439879d41b7830e4f2480213f7beabf2f7052a191cc6f7/Cython-3.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e87294e33e40c289c77a135f491cd721bd089f193f956f7b8ed5aa2d0b8c558f", size = 3671873, upload-time = "2024-01-10T11:01:51.858Z" }, + { url = "https://files.pythonhosted.org/packages/63/b0/81dad725604d7b529c492f873a7fa1b5800704a9f26e100ed25e9fd8d057/Cython-3.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a1df7a129344b1215c20096d33c00193437df1a8fcca25b71f17c23b1a44f782", size = 3463832, upload-time = "2024-01-10T11:01:55.364Z" }, + { url = "https://files.pythonhosted.org/packages/13/cd/72b8e0af597ac1b376421847acf6d6fa252e60059a2a00dcf05ceb16d28f/Cython-3.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:13c2a5e57a0358da467d97667297bf820b62a1a87ae47c5f87938b9bb593acbd", size = 3618325, upload-time = "2024-01-10T11:01:59.03Z" }, + { url = "https://files.pythonhosted.org/packages/ef/73/11a4355d8b8966504c751e5bcb25916c4140de27bb2ba1b54ff21994d7fe/Cython-3.0.8-cp310-cp310-win32.whl", hash = "sha256:96b028f044f5880e3cb18ecdcfc6c8d3ce9d0af28418d5ab464509f26d8adf12", size = 2571305, upload-time = "2024-01-10T11:02:02.589Z" }, + { url = "https://files.pythonhosted.org/packages/18/15/fdc0c3552d20f9337b134a36d786da24e47998fc39f62cb61c1534f26123/Cython-3.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:8140597a8b5cc4f119a1190f5a2228a84f5ca6d8d9ec386cfce24663f48b2539", size = 2776113, upload-time = "2024-01-10T11:02:05.581Z" }, + { url = "https://files.pythonhosted.org/packages/db/a7/f4a0bc9a80e23b380daa2ebb4879bf434aaa0b3b91f7ad8a7f9762b4bd1b/Cython-3.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aae26f9663e50caf9657148403d9874eea41770ecdd6caf381d177c2b1bb82ba", size = 3113615, upload-time = "2024-01-10T11:34:05.899Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e9/e9295df74246c165b91253a473bfa179debf739c9bee961cbb3ae56c2b79/Cython-3.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:547eb3cdb2f8c6f48e6865d5a741d9dd051c25b3ce076fbca571727977b28ac3", size = 3436320, upload-time = "2024-01-10T11:02:08.689Z" }, + { url = "https://files.pythonhosted.org/packages/26/2c/6a887c957aa53e44f928119dea628a5dfacc8e875424034f5fecac9daba4/Cython-3.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a567d4b9ba70b26db89d75b243529de9e649a2f56384287533cf91512705bee", size = 3591755, upload-time = "2024-01-10T11:02:11.773Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b8/f9c97bae6281da50b3ecb1f7fef0f7f7851eae084609b364717a2b366bf1/Cython-3.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51d1426263b0e82fb22bda8ea60dc77a428581cc19e97741011b938445d383f1", size = 3636099, upload-time = "2024-01-10T11:02:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/17/ae/cd055c2c081c67a6fcad1d8d17d82bd6395b14c6741e3a938f40318c8bc5/Cython-3.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c26daaeccda072459b48d211415fd1e5507c06bcd976fa0d5b8b9f1063467d7b", size = 3458119, upload-time = "2024-01-10T11:02:19.103Z" }, + { url = "https://files.pythonhosted.org/packages/72/ab/ac6f5548d6194f4bb2fc8c6c996aa7369f0fa1403e4d4de787d9e9309b27/Cython-3.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:289ce7838208211cd166e975865fd73b0649bf118170b6cebaedfbdaf4a37795", size = 3614418, upload-time = "2024-01-10T11:02:22.732Z" }, + { url = "https://files.pythonhosted.org/packages/70/e2/3e3e448b7a94887bec3235bcb71957b6681dc42b4536459f8f54d46fa936/Cython-3.0.8-cp311-cp311-win32.whl", hash = "sha256:c8aa05f5e17f8042a3be052c24f2edc013fb8af874b0bf76907d16c51b4e7871", size = 2572819, upload-time = "2024-01-10T11:02:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/58635941dfbb5b4e197adb88080b9cbfb230dc3b75683698a530a1989bdb/Cython-3.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:000dc9e135d0eec6ecb2b40a5b02d0868a2f8d2e027a41b0fe16a908a9e6de02", size = 2784167, upload-time = "2024-01-10T11:02:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8e/28f8c6109990eef7317ab7e43644092b49a88a39f9373dcd19318946df09/Cython-3.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:90d3fe31db55685d8cb97d43b0ec39ef614fcf660f83c77ed06aa670cb0e164f", size = 3135638, upload-time = "2024-01-10T11:34:22.889Z" }, + { url = "https://files.pythonhosted.org/packages/83/1f/4720cb682b8ed1ab9749dea35351a66dd29b6a022628cce038415660c384/Cython-3.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e24791ddae2324e88e3c902a765595c738f19ae34ee66bfb1a6dac54b1833419", size = 3340052, upload-time = "2024-01-10T11:02:32.471Z" }, + { url = "https://files.pythonhosted.org/packages/8a/47/ec3fceb9e8f7d6fa130216b8740038e1df7c8e5f215bba363fcf1272a6c1/Cython-3.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f020fa1c0552052e0660790b8153b79e3fc9a15dbd8f1d0b841fe5d204a6ae6", size = 3510079, upload-time = "2024-01-10T11:02:35.312Z" }, + { url = "https://files.pythonhosted.org/packages/71/31/b458127851e248effb909e2791b55870914863cde7c60b94db5ee65d7867/Cython-3.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18bfa387d7a7f77d7b2526af69a65dbd0b731b8d941aaff5becff8e21f6d7717", size = 3573972, upload-time = "2024-01-10T11:02:39.044Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d5/ca6513844d0634abd05ba12304053a454bb70441a9520afa9897d4300156/Cython-3.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fe81b339cffd87c0069c6049b4d33e28bdd1874625ee515785bf42c9fdff3658", size = 3356158, upload-time = "2024-01-10T11:02:42.125Z" }, + { url = "https://files.pythonhosted.org/packages/33/59/98a87b6264f4ad45c820db13c4ec657567476efde020c49443cc842a86af/Cython-3.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80fd94c076e1e1b1ee40a309be03080b75f413e8997cddcf401a118879863388", size = 3522312, upload-time = "2024-01-10T11:02:45.056Z" }, + { url = "https://files.pythonhosted.org/packages/2b/cb/132115d07a0b9d4f075e0741db70a5416b424dcd875b2bb0dd805e818222/Cython-3.0.8-cp312-cp312-win32.whl", hash = "sha256:85077915a93e359a9b920280d214dc0cf8a62773e1f3d7d30fab8ea4daed670c", size = 2602579, upload-time = "2024-01-10T11:02:48.368Z" }, + { url = "https://files.pythonhosted.org/packages/b4/69/cb4620287cd9ef461103e122c0a2ae7f7ecf183e02510676fb5a15c95b05/Cython-3.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:0cb2dcc565c7851f75d496f724a384a790fab12d1b82461b663e66605bec429a", size = 2791268, upload-time = "2024-01-10T11:02:51.483Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7f/f584f5d15323feb897d42ef0e9d910649e2150d7a30cf7e7a8cc1d236e6f/Cython-3.0.8-py2.py3-none-any.whl", hash = "sha256:171b27051253d3f9108e9759e504ba59ff06e7f7ba944457f94deaf9c21bf0b6", size = 1168213, upload-time = "2024-01-10T11:00:56.857Z" }, ] [[package]] name = "easydict" version = "1.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/d2/deb3296d08097fedd622d423c0ec8b68b78c1704b3f1545326f6ce05c75c/easydict-1.11.tar.gz", hash = "sha256:dcb1d2ed28eb300c8e46cd371340373abc62f7c14d6dea74fdfc6f1069061c78", size = 6644 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d2/deb3296d08097fedd622d423c0ec8b68b78c1704b3f1545326f6ce05c75c/easydict-1.11.tar.gz", hash = "sha256:dcb1d2ed28eb300c8e46cd371340373abc62f7c14d6dea74fdfc6f1069061c78", size = 6644, upload-time = "2023-10-23T23:01:37.686Z" } [[package]] name = "exceptiongroup" version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264, upload-time = "2023-11-21T08:42:17.407Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210 }, + { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210, upload-time = "2023-11-21T08:42:15.525Z" }, ] [[package]] name = "fastapi" -version = "0.116.1" +version = "0.122.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "annotated-doc" }, { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/d7/6c8b3bfe33eeffa208183ec037fee0cce9f7f024089ab1c5d12ef04bd27c/fastapi-0.116.1.tar.gz", hash = "sha256:ed52cbf946abfd70c5a0dccb24673f0670deeb517a88b3544d03c2a6bf283143", size = 296485 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/de/3ee97a4f6ffef1fb70bf20561e4f88531633bb5045dc6cebc0f8471f764d/fastapi-0.122.0.tar.gz", hash = "sha256:cd9b5352031f93773228af8b4c443eedc2ac2aa74b27780387b853c3726fb94b", size = 346436, upload-time = "2025-11-24T19:17:47.95Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565", size = 95631 }, + { url = "https://files.pythonhosted.org/packages/7a/93/aa8072af4ff37b795f6bbf43dcaf61115f40f49935c7dbb180c9afc3f421/fastapi-0.122.0-py3-none-any.whl", hash = "sha256:a456e8915dfc6c8914a50d9651133bd47ec96d331c5b44600baa635538a30d67", size = 110671, upload-time = "2025-11-24T19:17:45.96Z" }, ] [[package]] name = "filelock" version = "3.13.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/70/41905c80dcfe71b22fb06827b8eae65781783d4a14194bce79d16a013263/filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", size = 14553 } +sdist = { url = "https://files.pythonhosted.org/packages/70/70/41905c80dcfe71b22fb06827b8eae65781783d4a14194bce79d16a013263/filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", size = 14553, upload-time = "2023-10-30T18:29:39.035Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/54/84d42a0bee35edba99dee7b59a8d4970eccdd44b99fe728ed912106fc781/filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c", size = 11740 }, + { url = "https://files.pythonhosted.org/packages/81/54/84d42a0bee35edba99dee7b59a8d4970eccdd44b99fe728ed912106fc781/filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c", size = 11740, upload-time = "2023-10-30T18:29:37.267Z" }, ] [[package]] @@ -678,9 +733,9 @@ dependencies = [ { name = "jinja2" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58", size = 674171 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58", size = 674171, upload-time = "2023-09-30T14:36:12.918Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638", size = 99724 }, + { url = "https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638", size = 99724, upload-time = "2023-09-30T14:36:10.961Z" }, ] [[package]] @@ -690,9 +745,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "flask" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/40/6a/a8d56d60bcfa1ec3e4fdad81b45aafd508c3bd5c244a16526fa29139d7d4/flask_cors-4.0.1.tar.gz", hash = "sha256:eeb69b342142fdbf4766ad99357a7f3876a2ceb77689dc10ff912aac06c389e4", size = 30306 } +sdist = { url = "https://files.pythonhosted.org/packages/40/6a/a8d56d60bcfa1ec3e4fdad81b45aafd508c3bd5c244a16526fa29139d7d4/flask_cors-4.0.1.tar.gz", hash = "sha256:eeb69b342142fdbf4766ad99357a7f3876a2ceb77689dc10ff912aac06c389e4", size = 30306, upload-time = "2024-05-04T19:49:43.538Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/52/2aa6285f104616f73ee1ad7905a16b2b35af0143034ad0cf7b64bcba715c/Flask_Cors-4.0.1-py2.py3-none-any.whl", hash = "sha256:f2a704e4458665580c074b714c4627dd5a306b333deb9074d0b1794dfa2fb677", size = 14290 }, + { url = "https://files.pythonhosted.org/packages/8b/52/2aa6285f104616f73ee1ad7905a16b2b35af0143034ad0cf7b64bcba715c/Flask_Cors-4.0.1-py2.py3-none-any.whl", hash = "sha256:f2a704e4458665580c074b714c4627dd5a306b333deb9074d0b1794dfa2fb677", size = 14290, upload-time = "2024-05-04T19:49:41.721Z" }, ] [[package]] @@ -703,60 +758,60 @@ dependencies = [ { name = "flask" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/6e/2f4e13e373bb49e68c02c51ceadd22d172715a06716f9299d9df01b6ddb2/Flask-Login-0.6.3.tar.gz", hash = "sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333", size = 48834 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/6e/2f4e13e373bb49e68c02c51ceadd22d172715a06716f9299d9df01b6ddb2/Flask-Login-0.6.3.tar.gz", hash = "sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333", size = 48834, upload-time = "2023-10-30T14:53:21.151Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/f5/67e9cc5c2036f58115f9fe0f00d203cf6780c3ff8ae0e705e7a9d9e8ff9e/Flask_Login-0.6.3-py3-none-any.whl", hash = "sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d", size = 17303 }, + { url = "https://files.pythonhosted.org/packages/59/f5/67e9cc5c2036f58115f9fe0f00d203cf6780c3ff8ae0e705e7a9d9e8ff9e/Flask_Login-0.6.3-py3-none-any.whl", hash = "sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d", size = 17303, upload-time = "2023-10-30T14:53:19.636Z" }, ] [[package]] name = "flatbuffers" version = "23.5.26" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0c/6e/3e52cd294d8e7a61e010973cce076a0cb2c6c0dfd4d0b7a13648c1b98329/flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89", size = 22114 } +sdist = { url = "https://files.pythonhosted.org/packages/0c/6e/3e52cd294d8e7a61e010973cce076a0cb2c6c0dfd4d0b7a13648c1b98329/flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89", size = 22114, upload-time = "2023-05-26T17:35:16.034Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/12/d5c79ee252793ffe845d58a913197bfa02ae9a0b5c9bc3dc4b58d477b9e7/flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1", size = 26744 }, + { url = "https://files.pythonhosted.org/packages/6f/12/d5c79ee252793ffe845d58a913197bfa02ae9a0b5c9bc3dc4b58d477b9e7/flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1", size = 26744, upload-time = "2023-05-26T17:35:14.269Z" }, ] [[package]] name = "fonttools" version = "4.47.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/cd/75d24afa673edf92fd04657fad7d3b5e20c4abc3cad5bc14e5e30051c1f0/fonttools-4.47.2.tar.gz", hash = "sha256:7df26dd3650e98ca45f1e29883c96a0b9f5bb6af8d632a6a108bc744fa0bd9b3", size = 3410067 } +sdist = { url = "https://files.pythonhosted.org/packages/e5/cd/75d24afa673edf92fd04657fad7d3b5e20c4abc3cad5bc14e5e30051c1f0/fonttools-4.47.2.tar.gz", hash = "sha256:7df26dd3650e98ca45f1e29883c96a0b9f5bb6af8d632a6a108bc744fa0bd9b3", size = 3410067, upload-time = "2024-01-11T11:22:45.293Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/19/30/02de0b7f3d72f2c4fce3e512b166c1bdbe5a687408474b61eb0114be921c/fonttools-4.47.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b629108351d25512d4ea1a8393a2dba325b7b7d7308116b605ea3f8e1be88df", size = 2779949 }, - { url = "https://files.pythonhosted.org/packages/9a/52/1a5e1373afb78a040ea0c371ab8a79da121060a8e518968bb8f41457ca90/fonttools-4.47.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c19044256c44fe299d9a73456aabee4b4d06c6b930287be93b533b4737d70aa1", size = 2281336 }, - { url = "https://files.pythonhosted.org/packages/c5/ce/9d3b5bf51aafee024566ebb374f5b040381d92660cb04647af3c5860c611/fonttools-4.47.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8be28c036b9f186e8c7eaf8a11b42373e7e4949f9e9f370202b9da4c4c3f56c", size = 4541692 }, - { url = "https://files.pythonhosted.org/packages/e8/68/af41b7cfd35c7418e17b6a43bb106be4b0f0e5feb405a88dee29b186f2a7/fonttools-4.47.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f83a4daef6d2a202acb9bf572958f91cfde5b10c8ee7fb1d09a4c81e5d851fd8", size = 4600529 }, - { url = "https://files.pythonhosted.org/packages/ab/7e/428dbb4cfc342b7a05cbc9d349e134e7fad6588f4ce2a7128e8e3e58ad3b/fonttools-4.47.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5a5318ba5365d992666ac4fe35365f93004109d18858a3e18ae46f67907670", size = 4524215 }, - { url = "https://files.pythonhosted.org/packages/a6/61/762fad1cc1debc4626f2eb373fa999591c63c231fce53d5073574a639531/fonttools-4.47.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8f57ecd742545362a0f7186774b2d1c53423ed9ece67689c93a1055b236f638c", size = 4584778 }, - { url = "https://files.pythonhosted.org/packages/04/30/170ca22284c1d825470e8b5871d6b25d3a70e2f5b185ffb1647d5e11ee4d/fonttools-4.47.2-cp310-cp310-win32.whl", hash = "sha256:a1c154bb85dc9a4cf145250c88d112d88eb414bad81d4cb524d06258dea1bdc0", size = 2131876 }, - { url = "https://files.pythonhosted.org/packages/df/07/4a30437bed355b838b8ce31d14c5983334c31adc97e70c6ecff90c60d6d2/fonttools-4.47.2-cp310-cp310-win_amd64.whl", hash = "sha256:3e2b95dce2ead58fb12524d0ca7d63a63459dd489e7e5838c3cd53557f8933e1", size = 2177937 }, - { url = "https://files.pythonhosted.org/packages/dd/1d/670372323642eada0f7743cfcdd156de6a28d37769c916421fec2f32c814/fonttools-4.47.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:29495d6d109cdbabe73cfb6f419ce67080c3ef9ea1e08d5750240fd4b0c4763b", size = 2782908 }, - { url = "https://files.pythonhosted.org/packages/c1/36/5f0bb863a6575db4c4b67fa9be7f98e4c551dd87638ef327bc180b988998/fonttools-4.47.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0a1d313a415eaaba2b35d6cd33536560deeebd2ed758b9bfb89ab5d97dc5deac", size = 2283501 }, - { url = "https://files.pythonhosted.org/packages/bd/1e/95de682a86567426bcc40a56c9b118ffa97de6cbfcc293addf20994e329d/fonttools-4.47.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90f898cdd67f52f18049250a6474185ef6544c91f27a7bee70d87d77a8daf89c", size = 4848039 }, - { url = "https://files.pythonhosted.org/packages/ef/95/92a0b5fc844c1db734752f8a51431de519cd6b02e7e561efa9e9fd415544/fonttools-4.47.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3480eeb52770ff75140fe7d9a2ec33fb67b07efea0ab5129c7e0c6a639c40c70", size = 4893166 }, - { url = "https://files.pythonhosted.org/packages/ff/e6/ed9dd7ee1afd6cd70eb7237688118fe489dbde962e3765c91c86c095f84b/fonttools-4.47.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0255dbc128fee75fb9be364806b940ed450dd6838672a150d501ee86523ac61e", size = 4815529 }, - { url = "https://files.pythonhosted.org/packages/6b/67/cdffa0b3cd8f863b45125c335bbd3d9dc16ec42f5a8d5b64dd1244c5ce6b/fonttools-4.47.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f791446ff297fd5f1e2247c188de53c1bfb9dd7f0549eba55b73a3c2087a2703", size = 4875414 }, - { url = "https://files.pythonhosted.org/packages/b8/fb/41638e748c8f20f5483987afcf9be746d3ccb9e9600ca62128a27c791a82/fonttools-4.47.2-cp311-cp311-win32.whl", hash = "sha256:740947906590a878a4bde7dd748e85fefa4d470a268b964748403b3ab2aeed6c", size = 2130073 }, - { url = "https://files.pythonhosted.org/packages/a0/ef/93321cf55180a778b4d97919b28739874c0afab90e7b9f5b232db70f47c2/fonttools-4.47.2-cp311-cp311-win_amd64.whl", hash = "sha256:63fbed184979f09a65aa9c88b395ca539c94287ba3a364517698462e13e457c9", size = 2178744 }, - { url = "https://files.pythonhosted.org/packages/c0/bd/4dd1e8a9e632f325d9203ce543402f912f26efd213c8d9efec0180fbac64/fonttools-4.47.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4ec558c543609e71b2275c4894e93493f65d2f41c15fe1d089080c1d0bb4d635", size = 2754076 }, - { url = "https://files.pythonhosted.org/packages/e6/4d/c2ebaac81dadbc3fc3c3c2fa5fe7b16429dc713b1b8ace49e11e92904d78/fonttools-4.47.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e040f905d542362e07e72e03612a6270c33d38281fd573160e1003e43718d68d", size = 2263784 }, - { url = "https://files.pythonhosted.org/packages/d3/f6/9d484cd275845c7e503a8669a5952a7fa089c7a881babb4dce5ebe6fc5d1/fonttools-4.47.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dd58cc03016b281bd2c74c84cdaa6bd3ce54c5a7f47478b7657b930ac3ed8eb", size = 4769142 }, - { url = "https://files.pythonhosted.org/packages/7a/bf/c6ae0768a531b38245aac0bb8d30bc05d53d499e09fccdc5d72e7c8d28b6/fonttools-4.47.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32ab2e9702dff0dd4510c7bb958f265a8d3dd5c0e2547e7b5f7a3df4979abb07", size = 4853241 }, - { url = "https://files.pythonhosted.org/packages/2b/f0/c06709666cb7722447efb70ea456c302bd6eb3b997d30076401fb32bca4b/fonttools-4.47.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a808f3c1d1df1f5bf39be869b6e0c263570cdafb5bdb2df66087733f566ea71", size = 4730447 }, - { url = "https://files.pythonhosted.org/packages/3e/71/4c758ae5f4f8047904fc1c6bbbb828248c94cc7aa6406af3a62ede766f25/fonttools-4.47.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac71e2e201df041a2891067dc36256755b1229ae167edbdc419b16da78732c2f", size = 4809265 }, - { url = "https://files.pythonhosted.org/packages/81/f6/a6912c11280607d48947341e2167502605a3917925c835afcd7dfcabc289/fonttools-4.47.2-cp312-cp312-win32.whl", hash = "sha256:69731e8bea0578b3c28fdb43dbf95b9386e2d49a399e9a4ad736b8e479b08085", size = 2118363 }, - { url = "https://files.pythonhosted.org/packages/81/4b/42d0488765ea5aa308b4e8197cb75366b2124240a73e86f98b6107ccf282/fonttools-4.47.2-cp312-cp312-win_amd64.whl", hash = "sha256:b3e1304e5f19ca861d86a72218ecce68f391646d85c851742d265787f55457a4", size = 2165866 }, - { url = "https://files.pythonhosted.org/packages/af/2f/c34b0f99d46766cf49566d1ee2ee3606e4c9880b5a7d734257dc61c804e9/fonttools-4.47.2-py3-none-any.whl", hash = "sha256:7eb7ad665258fba68fd22228a09f347469d95a97fb88198e133595947a20a184", size = 1063011 }, + { url = "https://files.pythonhosted.org/packages/19/30/02de0b7f3d72f2c4fce3e512b166c1bdbe5a687408474b61eb0114be921c/fonttools-4.47.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b629108351d25512d4ea1a8393a2dba325b7b7d7308116b605ea3f8e1be88df", size = 2779949, upload-time = "2024-01-11T11:19:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/9a/52/1a5e1373afb78a040ea0c371ab8a79da121060a8e518968bb8f41457ca90/fonttools-4.47.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c19044256c44fe299d9a73456aabee4b4d06c6b930287be93b533b4737d70aa1", size = 2281336, upload-time = "2024-01-11T11:20:08.835Z" }, + { url = "https://files.pythonhosted.org/packages/c5/ce/9d3b5bf51aafee024566ebb374f5b040381d92660cb04647af3c5860c611/fonttools-4.47.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8be28c036b9f186e8c7eaf8a11b42373e7e4949f9e9f370202b9da4c4c3f56c", size = 4541692, upload-time = "2024-01-11T11:20:13.378Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/af41b7cfd35c7418e17b6a43bb106be4b0f0e5feb405a88dee29b186f2a7/fonttools-4.47.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f83a4daef6d2a202acb9bf572958f91cfde5b10c8ee7fb1d09a4c81e5d851fd8", size = 4600529, upload-time = "2024-01-11T11:20:17.27Z" }, + { url = "https://files.pythonhosted.org/packages/ab/7e/428dbb4cfc342b7a05cbc9d349e134e7fad6588f4ce2a7128e8e3e58ad3b/fonttools-4.47.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5a5318ba5365d992666ac4fe35365f93004109d18858a3e18ae46f67907670", size = 4524215, upload-time = "2024-01-11T11:20:21.061Z" }, + { url = "https://files.pythonhosted.org/packages/a6/61/762fad1cc1debc4626f2eb373fa999591c63c231fce53d5073574a639531/fonttools-4.47.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8f57ecd742545362a0f7186774b2d1c53423ed9ece67689c93a1055b236f638c", size = 4584778, upload-time = "2024-01-11T11:20:25.815Z" }, + { url = "https://files.pythonhosted.org/packages/04/30/170ca22284c1d825470e8b5871d6b25d3a70e2f5b185ffb1647d5e11ee4d/fonttools-4.47.2-cp310-cp310-win32.whl", hash = "sha256:a1c154bb85dc9a4cf145250c88d112d88eb414bad81d4cb524d06258dea1bdc0", size = 2131876, upload-time = "2024-01-11T11:20:30.261Z" }, + { url = "https://files.pythonhosted.org/packages/df/07/4a30437bed355b838b8ce31d14c5983334c31adc97e70c6ecff90c60d6d2/fonttools-4.47.2-cp310-cp310-win_amd64.whl", hash = "sha256:3e2b95dce2ead58fb12524d0ca7d63a63459dd489e7e5838c3cd53557f8933e1", size = 2177937, upload-time = "2024-01-11T11:20:33.814Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1d/670372323642eada0f7743cfcdd156de6a28d37769c916421fec2f32c814/fonttools-4.47.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:29495d6d109cdbabe73cfb6f419ce67080c3ef9ea1e08d5750240fd4b0c4763b", size = 2782908, upload-time = "2024-01-11T11:20:37.495Z" }, + { url = "https://files.pythonhosted.org/packages/c1/36/5f0bb863a6575db4c4b67fa9be7f98e4c551dd87638ef327bc180b988998/fonttools-4.47.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0a1d313a415eaaba2b35d6cd33536560deeebd2ed758b9bfb89ab5d97dc5deac", size = 2283501, upload-time = "2024-01-11T11:20:42.027Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1e/95de682a86567426bcc40a56c9b118ffa97de6cbfcc293addf20994e329d/fonttools-4.47.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90f898cdd67f52f18049250a6474185ef6544c91f27a7bee70d87d77a8daf89c", size = 4848039, upload-time = "2024-01-11T11:20:47.038Z" }, + { url = "https://files.pythonhosted.org/packages/ef/95/92a0b5fc844c1db734752f8a51431de519cd6b02e7e561efa9e9fd415544/fonttools-4.47.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3480eeb52770ff75140fe7d9a2ec33fb67b07efea0ab5129c7e0c6a639c40c70", size = 4893166, upload-time = "2024-01-11T11:20:50.855Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/ed9dd7ee1afd6cd70eb7237688118fe489dbde962e3765c91c86c095f84b/fonttools-4.47.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0255dbc128fee75fb9be364806b940ed450dd6838672a150d501ee86523ac61e", size = 4815529, upload-time = "2024-01-11T11:20:54.696Z" }, + { url = "https://files.pythonhosted.org/packages/6b/67/cdffa0b3cd8f863b45125c335bbd3d9dc16ec42f5a8d5b64dd1244c5ce6b/fonttools-4.47.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f791446ff297fd5f1e2247c188de53c1bfb9dd7f0549eba55b73a3c2087a2703", size = 4875414, upload-time = "2024-01-11T11:20:58.435Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fb/41638e748c8f20f5483987afcf9be746d3ccb9e9600ca62128a27c791a82/fonttools-4.47.2-cp311-cp311-win32.whl", hash = "sha256:740947906590a878a4bde7dd748e85fefa4d470a268b964748403b3ab2aeed6c", size = 2130073, upload-time = "2024-01-11T11:21:02.056Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ef/93321cf55180a778b4d97919b28739874c0afab90e7b9f5b232db70f47c2/fonttools-4.47.2-cp311-cp311-win_amd64.whl", hash = "sha256:63fbed184979f09a65aa9c88b395ca539c94287ba3a364517698462e13e457c9", size = 2178744, upload-time = "2024-01-11T11:21:05.88Z" }, + { url = "https://files.pythonhosted.org/packages/c0/bd/4dd1e8a9e632f325d9203ce543402f912f26efd213c8d9efec0180fbac64/fonttools-4.47.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4ec558c543609e71b2275c4894e93493f65d2f41c15fe1d089080c1d0bb4d635", size = 2754076, upload-time = "2024-01-11T11:21:09.745Z" }, + { url = "https://files.pythonhosted.org/packages/e6/4d/c2ebaac81dadbc3fc3c3c2fa5fe7b16429dc713b1b8ace49e11e92904d78/fonttools-4.47.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e040f905d542362e07e72e03612a6270c33d38281fd573160e1003e43718d68d", size = 2263784, upload-time = "2024-01-11T11:21:13.367Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f6/9d484cd275845c7e503a8669a5952a7fa089c7a881babb4dce5ebe6fc5d1/fonttools-4.47.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dd58cc03016b281bd2c74c84cdaa6bd3ce54c5a7f47478b7657b930ac3ed8eb", size = 4769142, upload-time = "2024-01-11T11:21:17.615Z" }, + { url = "https://files.pythonhosted.org/packages/7a/bf/c6ae0768a531b38245aac0bb8d30bc05d53d499e09fccdc5d72e7c8d28b6/fonttools-4.47.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32ab2e9702dff0dd4510c7bb958f265a8d3dd5c0e2547e7b5f7a3df4979abb07", size = 4853241, upload-time = "2024-01-11T11:21:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f0/c06709666cb7722447efb70ea456c302bd6eb3b997d30076401fb32bca4b/fonttools-4.47.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a808f3c1d1df1f5bf39be869b6e0c263570cdafb5bdb2df66087733f566ea71", size = 4730447, upload-time = "2024-01-11T11:21:24.755Z" }, + { url = "https://files.pythonhosted.org/packages/3e/71/4c758ae5f4f8047904fc1c6bbbb828248c94cc7aa6406af3a62ede766f25/fonttools-4.47.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac71e2e201df041a2891067dc36256755b1229ae167edbdc419b16da78732c2f", size = 4809265, upload-time = "2024-01-11T11:21:28.586Z" }, + { url = "https://files.pythonhosted.org/packages/81/f6/a6912c11280607d48947341e2167502605a3917925c835afcd7dfcabc289/fonttools-4.47.2-cp312-cp312-win32.whl", hash = "sha256:69731e8bea0578b3c28fdb43dbf95b9386e2d49a399e9a4ad736b8e479b08085", size = 2118363, upload-time = "2024-01-11T11:21:33.245Z" }, + { url = "https://files.pythonhosted.org/packages/81/4b/42d0488765ea5aa308b4e8197cb75366b2124240a73e86f98b6107ccf282/fonttools-4.47.2-cp312-cp312-win_amd64.whl", hash = "sha256:b3e1304e5f19ca861d86a72218ecce68f391646d85c851742d265787f55457a4", size = 2165866, upload-time = "2024-01-11T11:21:37.23Z" }, + { url = "https://files.pythonhosted.org/packages/af/2f/c34b0f99d46766cf49566d1ee2ee3606e4c9880b5a7d734257dc61c804e9/fonttools-4.47.2-py3-none-any.whl", hash = "sha256:7eb7ad665258fba68fd22228a09f347469d95a97fb88198e133595947a20a184", size = 1063011, upload-time = "2024-01-11T11:22:41.676Z" }, ] [[package]] name = "fsspec" version = "2023.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/08/cac914ff6ff46c4500fc4323a939dbe7a0f528cca04e7fd3e859611dea41/fsspec-2023.12.2.tar.gz", hash = "sha256:8548d39e8810b59c38014934f6b31e57f40c1b20f911f4cc2b85389c7e9bf0cb", size = 167507 } +sdist = { url = "https://files.pythonhosted.org/packages/fa/08/cac914ff6ff46c4500fc4323a939dbe7a0f528cca04e7fd3e859611dea41/fsspec-2023.12.2.tar.gz", hash = "sha256:8548d39e8810b59c38014934f6b31e57f40c1b20f911f4cc2b85389c7e9bf0cb", size = 167507, upload-time = "2023-12-11T21:19:54.832Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/25/fab23259a52ece5670dcb8452e1af34b89e6135ecc17cd4b54b4b479eac6/fsspec-2023.12.2-py3-none-any.whl", hash = "sha256:d800d87f72189a745fa3d6b033b9dc4a34ad069f60ca60b943a63599f5501960", size = 168979 }, + { url = "https://files.pythonhosted.org/packages/70/25/fab23259a52ece5670dcb8452e1af34b89e6135ecc17cd4b54b4b479eac6/fsspec-2023.12.2-py3-none-any.whl", hash = "sha256:d800d87f72189a745fa3d6b033b9dc4a34ad069f60ca60b943a63599f5501960", size = 168979, upload-time = "2023-12-11T21:19:52.446Z" }, ] [[package]] @@ -766,9 +821,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a5/d3/8650919bc3c7c6e90ee3fa7fd618bf373cbbe55dff043bd67353dbb20cd8/ftfy-6.3.1.tar.gz", hash = "sha256:9b3c3d90f84fb267fe64d375a07b7f8912d817cf86009ae134aa03e1819506ec", size = 308927 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/d3/8650919bc3c7c6e90ee3fa7fd618bf373cbbe55dff043bd67353dbb20cd8/ftfy-6.3.1.tar.gz", hash = "sha256:9b3c3d90f84fb267fe64d375a07b7f8912d817cf86009ae134aa03e1819506ec", size = 308927, upload-time = "2024-10-26T00:50:35.149Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/6e/81d47999aebc1b155f81eca4477a616a70f238a2549848c38983f3c22a82/ftfy-6.3.1-py3-none-any.whl", hash = "sha256:7c70eb532015cd2f9adb53f101fb6c7945988d023a085d127d1573dc49dd0083", size = 44821 }, + { url = "https://files.pythonhosted.org/packages/ab/6e/81d47999aebc1b155f81eca4477a616a70f238a2549848c38983f3c22a82/ftfy-6.3.1-py3-none-any.whl", hash = "sha256:7c70eb532015cd2f9adb53f101fb6c7945988d023a085d127d1573dc49dd0083", size = 44821, upload-time = "2024-10-26T00:50:33.425Z" }, ] [[package]] @@ -781,41 +836,41 @@ dependencies = [ { name = "zope-event" }, { name = "zope-interface" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/f0/be10ed5d7721ed2317d7feb59e167603217156c2a6d57f128523e24e673d/gevent-24.10.3.tar.gz", hash = "sha256:aa7ee1bd5cabb2b7ef35105f863b386c8d5e332f754b60cfc354148bd70d35d1", size = 6108837 } +sdist = { url = "https://files.pythonhosted.org/packages/70/f0/be10ed5d7721ed2317d7feb59e167603217156c2a6d57f128523e24e673d/gevent-24.10.3.tar.gz", hash = "sha256:aa7ee1bd5cabb2b7ef35105f863b386c8d5e332f754b60cfc354148bd70d35d1", size = 6108837, upload-time = "2024-10-18T16:06:25.867Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/6f/a2100e7883c7bdfc2b45cb60b310ca748762a21596258b9dd01c5c093dbc/gevent-24.10.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:d7a1ad0f2da582f5bd238bca067e1c6c482c30c15a6e4d14aaa3215cbb2232f3", size = 3014382 }, - { url = "https://files.pythonhosted.org/packages/7a/b1/460e4884ed6185d9eb9c4c2e9639d2b254197e46513301c0f63dec22dc90/gevent-24.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4e526fdc279c655c1e809b0c34b45844182c2a6b219802da5e411bd2cf5a8ad", size = 4853460 }, - { url = "https://files.pythonhosted.org/packages/ca/f6/7ded98760d381229183ecce8db2edcce96f13e23807d31a90c66dae85304/gevent-24.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57a5c4e0bdac482c5f02f240d0354e61362df73501ef6ebafce8ef635cad7527", size = 4977636 }, - { url = "https://files.pythonhosted.org/packages/7d/21/7b928e6029eedb93ef94fc0aee701f497af2e601f0ec00aac0e72e3f450e/gevent-24.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d67daed8383326dc8b5e58d88e148d29b6b52274a489e383530b0969ae7b9cb9", size = 5058031 }, - { url = "https://files.pythonhosted.org/packages/00/98/12c03fd004fbeeca01276ffc589f5a368fd741d02582ab7006d1bdef57e7/gevent-24.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e24ffea72e27987979c009536fd0868e52239b44afe6cf7135ce8aafd0f108e", size = 6683694 }, - { url = "https://files.pythonhosted.org/packages/64/4c/ea14d971452d3da09e49267e052d8312f112c7835120aed78d22ef14efee/gevent-24.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c1d80090485da1ea3d99205fe97908b31188c1f4857f08b333ffaf2de2e89d18", size = 5286063 }, - { url = "https://files.pythonhosted.org/packages/39/3f/397efff27e637d7306caa00d1560512c44028c25c70be1e72c46b79b1b66/gevent-24.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0c129f81d60cda614acb4b0c5731997ca05b031fb406fcb58ad53a7ade53b13", size = 6817462 }, - { url = "https://files.pythonhosted.org/packages/aa/5d/19939eaa7c5b7c0f37e0a0665a911ddfe1e35c25c512446fc356a065c16e/gevent-24.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:26ca7a6b42d35129617025ac801135118333cad75856ffc3217b38e707383eba", size = 1566631 }, - { url = "https://files.pythonhosted.org/packages/6e/01/1be5cf013826d8baae235976d6a94f3628014fd2db7c071aeec13f82b4d1/gevent-24.10.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:68c3a0d8402755eba7f69022e42e8021192a721ca8341908acc222ea597029b6", size = 2966909 }, - { url = "https://files.pythonhosted.org/packages/fe/3e/7fa9ab023f24d8689e2c77951981f8ea1f25089e0349a0bf8b35ee9b9277/gevent-24.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d850a453d66336272be4f1d3a8126777f3efdaea62d053b4829857f91e09755", size = 4913247 }, - { url = "https://files.pythonhosted.org/packages/db/63/6e40eaaa3c2abd1561faff11dc3e6781f8c25e975354b8835762834415af/gevent-24.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e58ee3723f1fbe07d66892f1caa7481c306f653a6829b6fd16cb23d618a5915", size = 5049036 }, - { url = "https://files.pythonhosted.org/packages/94/89/158bc32cdc898dda0481040ac18650022e73133d93460c5af56ca622fe9a/gevent-24.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b52382124eca13135a3abe4f65c6bd428656975980a48e51b17aeab68bdb14db", size = 5107299 }, - { url = "https://files.pythonhosted.org/packages/64/91/1abe62ee350fdfac186d33f615d0d3a0b3b140e7ccf23c73547aa0deec44/gevent-24.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ca2266e08f43c0e22c028801dff7d92a0b102ef20e4caeb6a46abfb95f6a328", size = 6819625 }, - { url = "https://files.pythonhosted.org/packages/92/8b/0b2fe0d36b7c4d463e46cc68eaf6c14488bd7d86cc37e995c64a0ff7d02f/gevent-24.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d758f0d4dbf32502ec87bb9b536ca8055090a16f8305f0ada3ce6f34e70f2fd7", size = 5474079 }, - { url = "https://files.pythonhosted.org/packages/12/7b/9f5abbf0021a50321314f850697e0f46d2e5081168223af2d8544af9d19f/gevent-24.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0de6eb3d55c03138fda567d9bfed28487ce5d0928c5107549767a93efdf2be26", size = 6901323 }, - { url = "https://files.pythonhosted.org/packages/8a/63/607715c621ae78ed581b7ba36d076df63feeb352993d521327f865056771/gevent-24.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:385710355eadecdb70428a5ae3e7e5a45dcf888baa1426884588be9d25ac4290", size = 1549468 }, - { url = "https://files.pythonhosted.org/packages/d9/e4/4edbe17001bb3e6fade4ad2d85ca8f9e4eabcbde4aa29aa6889281616e3e/gevent-24.10.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ad8fb70aa0ebc935729c9699ac31b210a49b689a7b27b7ac9f91676475f3f53", size = 2970952 }, - { url = "https://files.pythonhosted.org/packages/3c/a6/ce0824fe9398ba6b00028a74840f12be1165d5feaacdc028ea953db3d6c3/gevent-24.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f18689f7a70d2ed0e75bad5036ec3c89690a493d4cfac8d7cdb258ac04b132bd", size = 5172230 }, - { url = "https://files.pythonhosted.org/packages/25/d4/9002cfb585bfa52c860ed4b1349d1a6400bdf2df9f1bd21df5ff33eea33c/gevent-24.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f4f171d4d2018170454d84c934842e1b5f6ce7468ba298f6e7f7cff15000a3", size = 5338394 }, - { url = "https://files.pythonhosted.org/packages/0c/98/222f1a14f22ad2d1cbcc37edb74095264c1f9c7ab49e6423693383462b8a/gevent-24.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7021e26d70189b33c27173d4173f27bf4685d6b6f1c0ea50e5335f8491cb110c", size = 5437989 }, - { url = "https://files.pythonhosted.org/packages/bf/e8/cbb46afea3c7ecdc7289e15cb4a6f89903f4f9754a27ca320d3e465abc78/gevent-24.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34aea15f9c79f27a8faeaa361bc1e72c773a9b54a1996a2ec4eefc8bcd59a824", size = 6838539 }, - { url = "https://files.pythonhosted.org/packages/69/c3/e43e348f23da404a6d4368a14453ed097cdfca97d5212eaceb987d04a0e1/gevent-24.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8af65a4d4feaec6042c666d22c322a310fba3b47e841ad52f724b9c3ce5da48e", size = 5513842 }, - { url = "https://files.pythonhosted.org/packages/c2/76/84b7c19c072a80900118717a85236859127d630cdf8b079fe42f19649f12/gevent-24.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:89c4115e3f5ada55f92b61701a46043fe42f702b5af863b029e4c1a76f6cc2d4", size = 6927374 }, - { url = "https://files.pythonhosted.org/packages/5e/69/0ab1b04c363547058fb5035275c144957b80b36cb6aee715fe6181b0cee9/gevent-24.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:1ce6dab94c0b0d24425ba55712de2f8c9cb21267150ca63f5bb3a0e1f165da99", size = 1546701 }, - { url = "https://files.pythonhosted.org/packages/f7/2d/c783583d7999cd2f2e7aa2d6a1c333d663003ca61255a89ff6a891be95f4/gevent-24.10.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:f147e38423fbe96e8731f60a63475b3d2cab2f3d10578d8ee9d10c507c58a2ff", size = 2962857 }, - { url = "https://files.pythonhosted.org/packages/f3/77/d3ce96fd49406f61976e9a3b6c742b97bb274d3b30c68ff190c5b5f81afd/gevent-24.10.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e6984ec96fc95fd67488555c38ece3015be1f38b1bcceb27b7d6c36b343008", size = 5141676 }, - { url = "https://files.pythonhosted.org/packages/49/f4/f99f893770c316b9d2f03bd684947126cbed0321b89fe5423838974c2025/gevent-24.10.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:051b22e2758accfddb0457728bfc9abf8c3f2ce6bca43f1ff6e07b5ed9e49bf4", size = 5310248 }, - { url = "https://files.pythonhosted.org/packages/e3/0c/67257ba906f76ed82e8f0bd8c00c2a0687b360a1050b70db7e58dff749ab/gevent-24.10.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb5edb6433764119a664bbb148d2aea9990950aa89cc3498f475c2408d523ea3", size = 5407304 }, - { url = "https://files.pythonhosted.org/packages/35/6c/3a72da7c224b0111728130c0f1abc3ee07feff91b37e0ea83db98f4a3eaf/gevent-24.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce417bcaaab496bc9c77f75566531e9d93816262037b8b2dbb88b0fdcd66587c", size = 6818624 }, - { url = "https://files.pythonhosted.org/packages/a3/96/cc5f6ecba032a45fc312fe0db2908a893057fd81361eea93845d6c325556/gevent-24.10.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:1c3a828b033fb02b7c31da4d75014a1f82e6c072fc0523456569a57f8b025861", size = 5484356 }, - { url = "https://files.pythonhosted.org/packages/7c/97/e680b2b2f0c291ae4db9813ffbf02c22c2a0f14c8f1a613971385e29ef67/gevent-24.10.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f2ae3efbbd120cdf4a68b7abc27a37e61e6f443c5a06ec2c6ad94c37cd8471ec", size = 6903191 }, - { url = "https://files.pythonhosted.org/packages/1b/1c/b4181957da062d1c060974ec6cb798cc24aeeb28e8cd2ece84eb4b4991f7/gevent-24.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:9e1210334a9bc9f76c3d008e0785ca62214f8a54e1325f6c2ecab3b6a572a015", size = 1545117 }, - { url = "https://files.pythonhosted.org/packages/89/2b/bf4af9950b8f9abd5b4025858f6311930de550e3498bbfeb47c914701a1d/gevent-24.10.3-pp310-pypy310_pp73-macosx_11_0_universal2.whl", hash = "sha256:e534e6a968d74463b11de6c9c67f4b4bf61775fb00f2e6e0f7fcdd412ceade18", size = 1271541 }, + { url = "https://files.pythonhosted.org/packages/6b/6f/a2100e7883c7bdfc2b45cb60b310ca748762a21596258b9dd01c5c093dbc/gevent-24.10.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:d7a1ad0f2da582f5bd238bca067e1c6c482c30c15a6e4d14aaa3215cbb2232f3", size = 3014382, upload-time = "2024-10-18T15:37:34.041Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b1/460e4884ed6185d9eb9c4c2e9639d2b254197e46513301c0f63dec22dc90/gevent-24.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4e526fdc279c655c1e809b0c34b45844182c2a6b219802da5e411bd2cf5a8ad", size = 4853460, upload-time = "2024-10-18T16:19:39.515Z" }, + { url = "https://files.pythonhosted.org/packages/ca/f6/7ded98760d381229183ecce8db2edcce96f13e23807d31a90c66dae85304/gevent-24.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57a5c4e0bdac482c5f02f240d0354e61362df73501ef6ebafce8ef635cad7527", size = 4977636, upload-time = "2024-10-18T16:18:45.464Z" }, + { url = "https://files.pythonhosted.org/packages/7d/21/7b928e6029eedb93ef94fc0aee701f497af2e601f0ec00aac0e72e3f450e/gevent-24.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d67daed8383326dc8b5e58d88e148d29b6b52274a489e383530b0969ae7b9cb9", size = 5058031, upload-time = "2024-10-18T16:23:10.719Z" }, + { url = "https://files.pythonhosted.org/packages/00/98/12c03fd004fbeeca01276ffc589f5a368fd741d02582ab7006d1bdef57e7/gevent-24.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e24ffea72e27987979c009536fd0868e52239b44afe6cf7135ce8aafd0f108e", size = 6683694, upload-time = "2024-10-18T15:59:35.475Z" }, + { url = "https://files.pythonhosted.org/packages/64/4c/ea14d971452d3da09e49267e052d8312f112c7835120aed78d22ef14efee/gevent-24.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c1d80090485da1ea3d99205fe97908b31188c1f4857f08b333ffaf2de2e89d18", size = 5286063, upload-time = "2024-10-18T16:38:24.113Z" }, + { url = "https://files.pythonhosted.org/packages/39/3f/397efff27e637d7306caa00d1560512c44028c25c70be1e72c46b79b1b66/gevent-24.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0c129f81d60cda614acb4b0c5731997ca05b031fb406fcb58ad53a7ade53b13", size = 6817462, upload-time = "2024-10-18T16:02:48.427Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5d/19939eaa7c5b7c0f37e0a0665a911ddfe1e35c25c512446fc356a065c16e/gevent-24.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:26ca7a6b42d35129617025ac801135118333cad75856ffc3217b38e707383eba", size = 1566631, upload-time = "2024-10-18T16:08:38.489Z" }, + { url = "https://files.pythonhosted.org/packages/6e/01/1be5cf013826d8baae235976d6a94f3628014fd2db7c071aeec13f82b4d1/gevent-24.10.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:68c3a0d8402755eba7f69022e42e8021192a721ca8341908acc222ea597029b6", size = 2966909, upload-time = "2024-10-18T15:37:31.43Z" }, + { url = "https://files.pythonhosted.org/packages/fe/3e/7fa9ab023f24d8689e2c77951981f8ea1f25089e0349a0bf8b35ee9b9277/gevent-24.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d850a453d66336272be4f1d3a8126777f3efdaea62d053b4829857f91e09755", size = 4913247, upload-time = "2024-10-18T16:19:41.792Z" }, + { url = "https://files.pythonhosted.org/packages/db/63/6e40eaaa3c2abd1561faff11dc3e6781f8c25e975354b8835762834415af/gevent-24.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e58ee3723f1fbe07d66892f1caa7481c306f653a6829b6fd16cb23d618a5915", size = 5049036, upload-time = "2024-10-18T16:18:47.419Z" }, + { url = "https://files.pythonhosted.org/packages/94/89/158bc32cdc898dda0481040ac18650022e73133d93460c5af56ca622fe9a/gevent-24.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b52382124eca13135a3abe4f65c6bd428656975980a48e51b17aeab68bdb14db", size = 5107299, upload-time = "2024-10-18T16:23:12.296Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/1abe62ee350fdfac186d33f615d0d3a0b3b140e7ccf23c73547aa0deec44/gevent-24.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ca2266e08f43c0e22c028801dff7d92a0b102ef20e4caeb6a46abfb95f6a328", size = 6819625, upload-time = "2024-10-18T15:59:38.226Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/0b2fe0d36b7c4d463e46cc68eaf6c14488bd7d86cc37e995c64a0ff7d02f/gevent-24.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d758f0d4dbf32502ec87bb9b536ca8055090a16f8305f0ada3ce6f34e70f2fd7", size = 5474079, upload-time = "2024-10-18T16:38:26.866Z" }, + { url = "https://files.pythonhosted.org/packages/12/7b/9f5abbf0021a50321314f850697e0f46d2e5081168223af2d8544af9d19f/gevent-24.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0de6eb3d55c03138fda567d9bfed28487ce5d0928c5107549767a93efdf2be26", size = 6901323, upload-time = "2024-10-18T16:02:50.066Z" }, + { url = "https://files.pythonhosted.org/packages/8a/63/607715c621ae78ed581b7ba36d076df63feeb352993d521327f865056771/gevent-24.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:385710355eadecdb70428a5ae3e7e5a45dcf888baa1426884588be9d25ac4290", size = 1549468, upload-time = "2024-10-18T16:01:30.331Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e4/4edbe17001bb3e6fade4ad2d85ca8f9e4eabcbde4aa29aa6889281616e3e/gevent-24.10.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ad8fb70aa0ebc935729c9699ac31b210a49b689a7b27b7ac9f91676475f3f53", size = 2970952, upload-time = "2024-10-18T15:37:31.389Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a6/ce0824fe9398ba6b00028a74840f12be1165d5feaacdc028ea953db3d6c3/gevent-24.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f18689f7a70d2ed0e75bad5036ec3c89690a493d4cfac8d7cdb258ac04b132bd", size = 5172230, upload-time = "2024-10-18T16:19:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/25/d4/9002cfb585bfa52c860ed4b1349d1a6400bdf2df9f1bd21df5ff33eea33c/gevent-24.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f4f171d4d2018170454d84c934842e1b5f6ce7468ba298f6e7f7cff15000a3", size = 5338394, upload-time = "2024-10-18T16:18:49.371Z" }, + { url = "https://files.pythonhosted.org/packages/0c/98/222f1a14f22ad2d1cbcc37edb74095264c1f9c7ab49e6423693383462b8a/gevent-24.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7021e26d70189b33c27173d4173f27bf4685d6b6f1c0ea50e5335f8491cb110c", size = 5437989, upload-time = "2024-10-18T16:23:13.851Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e8/cbb46afea3c7ecdc7289e15cb4a6f89903f4f9754a27ca320d3e465abc78/gevent-24.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34aea15f9c79f27a8faeaa361bc1e72c773a9b54a1996a2ec4eefc8bcd59a824", size = 6838539, upload-time = "2024-10-18T15:59:40.489Z" }, + { url = "https://files.pythonhosted.org/packages/69/c3/e43e348f23da404a6d4368a14453ed097cdfca97d5212eaceb987d04a0e1/gevent-24.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8af65a4d4feaec6042c666d22c322a310fba3b47e841ad52f724b9c3ce5da48e", size = 5513842, upload-time = "2024-10-18T16:38:29.538Z" }, + { url = "https://files.pythonhosted.org/packages/c2/76/84b7c19c072a80900118717a85236859127d630cdf8b079fe42f19649f12/gevent-24.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:89c4115e3f5ada55f92b61701a46043fe42f702b5af863b029e4c1a76f6cc2d4", size = 6927374, upload-time = "2024-10-18T16:02:51.669Z" }, + { url = "https://files.pythonhosted.org/packages/5e/69/0ab1b04c363547058fb5035275c144957b80b36cb6aee715fe6181b0cee9/gevent-24.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:1ce6dab94c0b0d24425ba55712de2f8c9cb21267150ca63f5bb3a0e1f165da99", size = 1546701, upload-time = "2024-10-18T15:54:53.562Z" }, + { url = "https://files.pythonhosted.org/packages/f7/2d/c783583d7999cd2f2e7aa2d6a1c333d663003ca61255a89ff6a891be95f4/gevent-24.10.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:f147e38423fbe96e8731f60a63475b3d2cab2f3d10578d8ee9d10c507c58a2ff", size = 2962857, upload-time = "2024-10-18T15:37:33.098Z" }, + { url = "https://files.pythonhosted.org/packages/f3/77/d3ce96fd49406f61976e9a3b6c742b97bb274d3b30c68ff190c5b5f81afd/gevent-24.10.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e6984ec96fc95fd67488555c38ece3015be1f38b1bcceb27b7d6c36b343008", size = 5141676, upload-time = "2024-10-18T16:19:45.484Z" }, + { url = "https://files.pythonhosted.org/packages/49/f4/f99f893770c316b9d2f03bd684947126cbed0321b89fe5423838974c2025/gevent-24.10.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:051b22e2758accfddb0457728bfc9abf8c3f2ce6bca43f1ff6e07b5ed9e49bf4", size = 5310248, upload-time = "2024-10-18T16:18:51.175Z" }, + { url = "https://files.pythonhosted.org/packages/e3/0c/67257ba906f76ed82e8f0bd8c00c2a0687b360a1050b70db7e58dff749ab/gevent-24.10.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb5edb6433764119a664bbb148d2aea9990950aa89cc3498f475c2408d523ea3", size = 5407304, upload-time = "2024-10-18T16:23:15.348Z" }, + { url = "https://files.pythonhosted.org/packages/35/6c/3a72da7c224b0111728130c0f1abc3ee07feff91b37e0ea83db98f4a3eaf/gevent-24.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce417bcaaab496bc9c77f75566531e9d93816262037b8b2dbb88b0fdcd66587c", size = 6818624, upload-time = "2024-10-18T15:59:42.068Z" }, + { url = "https://files.pythonhosted.org/packages/a3/96/cc5f6ecba032a45fc312fe0db2908a893057fd81361eea93845d6c325556/gevent-24.10.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:1c3a828b033fb02b7c31da4d75014a1f82e6c072fc0523456569a57f8b025861", size = 5484356, upload-time = "2024-10-18T16:38:31.709Z" }, + { url = "https://files.pythonhosted.org/packages/7c/97/e680b2b2f0c291ae4db9813ffbf02c22c2a0f14c8f1a613971385e29ef67/gevent-24.10.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f2ae3efbbd120cdf4a68b7abc27a37e61e6f443c5a06ec2c6ad94c37cd8471ec", size = 6903191, upload-time = "2024-10-18T16:02:53.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/1c/b4181957da062d1c060974ec6cb798cc24aeeb28e8cd2ece84eb4b4991f7/gevent-24.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:9e1210334a9bc9f76c3d008e0785ca62214f8a54e1325f6c2ecab3b6a572a015", size = 1545117, upload-time = "2024-10-18T15:45:47.375Z" }, + { url = "https://files.pythonhosted.org/packages/89/2b/bf4af9950b8f9abd5b4025858f6311930de550e3498bbfeb47c914701a1d/gevent-24.10.3-pp310-pypy310_pp73-macosx_11_0_universal2.whl", hash = "sha256:e534e6a968d74463b11de6c9c67f4b4bf61775fb00f2e6e0f7fcdd412ceade18", size = 1271541, upload-time = "2024-10-18T15:37:53.146Z" }, ] [[package]] @@ -828,103 +883,103 @@ dependencies = [ { name = "gevent" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/14/d4eddae757de44985718a9e38d9e6f2a923d764ed97d0f1cbc1a8aa2b0ef/geventhttpclient-2.3.1.tar.gz", hash = "sha256:b40ddac8517c456818942c7812f555f84702105c82783238c9fcb8dc12675185", size = 69345 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/14/d4eddae757de44985718a9e38d9e6f2a923d764ed97d0f1cbc1a8aa2b0ef/geventhttpclient-2.3.1.tar.gz", hash = "sha256:b40ddac8517c456818942c7812f555f84702105c82783238c9fcb8dc12675185", size = 69345, upload-time = "2024-04-18T21:39:50.83Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/a5/5e49d6a581b3f1399425e22961c6e341e90c12fa2193ed0adee9afbd864c/geventhttpclient-2.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da22ab7bf5af4ba3d07cffee6de448b42696e53e7ac1fe97ed289037733bf1c2", size = 71729 }, - { url = "https://files.pythonhosted.org/packages/eb/23/4ff584e5f344dae64b5bc588b65c4ea81083f9d662b9f64cf5f28e5ae9cc/geventhttpclient-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2399e3d4e2fae8bbd91756189da6e9d84adf8f3eaace5eef0667874a705a29f8", size = 52062 }, - { url = "https://files.pythonhosted.org/packages/bb/60/6bd8badb97b31a49f4c2b79466abce208a97dad95d447893c7546063fc8a/geventhttpclient-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3e33e87d0d5b9f5782c4e6d3cb7e3592fea41af52713137d04776df7646d71b", size = 51645 }, - { url = "https://files.pythonhosted.org/packages/e1/62/47d431bf05f74aa683d63163a11432bda8f576c86dec8c3bc9d6a156ee03/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c071db313866c3d0510feb6c0f40ec086ccf7e4a845701b6316c82c06e8b9b29", size = 117838 }, - { url = "https://files.pythonhosted.org/packages/6c/8b/e7c9ae813bb41883a96ad9afcf86465219c3bb682daa8b09448481edef8a/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f36f0c6ef88a27e60af8369d9c2189fe372c6f2943182a7568e0f2ad33bb69f1", size = 123272 }, - { url = "https://files.pythonhosted.org/packages/4d/26/71e9b2526009faadda9f588dac04f8bf837a5b97628ab44145efc3fa796e/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4624843c03a5337282a42247d987c2531193e57255ee307b36eeb4f243a0c21", size = 114319 }, - { url = "https://files.pythonhosted.org/packages/34/8c/1da2960293c42b7a6b01dbe3204b569e4cdb55b8289cb1c7154826500f19/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d614573621ba827c417786057e1e20e9f96c4f6b3878c55b1b7b54e1026693bc", size = 112705 }, - { url = "https://files.pythonhosted.org/packages/a7/a1/4d08ecf0f213fdc63f78a217f87c07c1cb9891e68cdf74c8cbca76298bdb/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5d51330a40ac9762879d0e296c279c1beae8cfa6484bb196ac829242c416b709", size = 121236 }, - { url = "https://files.pythonhosted.org/packages/4f/f7/42ece3e1f54602c518d74364a214da3b35b6be267b335564b7e9f0d37705/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc9f2162d4e8cb86bb5322d99bfd552088a3eacd540a841298f06bb8bc1f1f03", size = 117859 }, - { url = "https://files.pythonhosted.org/packages/1f/8e/de026b3697bffe5fa1a4938a3882107e378eea826905acf8e46c69b71ffd/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:06e59d3397e63c65ecc7a7561a5289f0cf2e2c2252e29632741e792f57f5d124", size = 127268 }, - { url = "https://files.pythonhosted.org/packages/54/bf/1ee99a322467e6825a24612d306a46ca94b51088170d1b5de0df1c82ab2a/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4436eef515b3e0c1d4a453ae32e047290e780a623c1eddb11026ae9d5fb03d42", size = 116426 }, - { url = "https://files.pythonhosted.org/packages/72/54/10c8ec745b3dcbfd52af62977fec85829749c0325e1a5429d050a4b45e75/geventhttpclient-2.3.1-cp310-cp310-win32.whl", hash = "sha256:5d1cf7d8a4f8e15cc8fd7d88ac4cdb058d6274203a42587e594cc9f0850ac862", size = 47599 }, - { url = "https://files.pythonhosted.org/packages/da/0d/36a47cdeaa83c3b4efdbd18d77720fa27dc40600998f4dedd7c4a1259862/geventhttpclient-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:4deaebc121036f7ea95430c2d0f80ab085b15280e6ab677a6360b70e57020e7f", size = 48302 }, - { url = "https://files.pythonhosted.org/packages/56/ad/1fcbbea0465f04d4425960e3737d4d8ae6407043cfc88688fb17b9064160/geventhttpclient-2.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0ae055b9ce1704f2ce72c0847df28f4e14dbb3eea79256cda6c909d82688ea3", size = 71733 }, - { url = "https://files.pythonhosted.org/packages/06/1a/10e547adb675beea407ff7117ecb4e5063534569ac14bb4360279d2888dd/geventhttpclient-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f087af2ac439495b5388841d6f3c4de8d2573ca9870593d78f7b554aa5cfa7f5", size = 52060 }, - { url = "https://files.pythonhosted.org/packages/e0/c0/9960ac6e8818a00702743cd2a9637d6f26909ac7ac59ca231f446e367b20/geventhttpclient-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76c367d175810facfe56281e516c9a5a4a191eff76641faaa30aa33882ed4b2f", size = 51649 }, - { url = "https://files.pythonhosted.org/packages/58/3a/b032cd8f885dafdfa002a8a0e4e21b633713798ec08e19010b815fbfead6/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a58376d0d461fe0322ff2ad362553b437daee1eeb92b4c0e3b1ffef9e77defbe", size = 117987 }, - { url = "https://files.pythonhosted.org/packages/94/36/6493a5cbc20c269a51186946947f3ca2eae687e05831289891027bd038c3/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f440cc704f8a9869848a109b2c401805c17c070539b2014e7b884ecfc8591e33", size = 123356 }, - { url = "https://files.pythonhosted.org/packages/2f/07/b66d9a13b97a7e59d84b4faf704113aa963aaf3a0f71c9138c8740d57d5c/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f10c62994f9052f23948c19de930b2d1f063240462c8bd7077c2b3290e61f4fa", size = 114460 }, - { url = "https://files.pythonhosted.org/packages/4e/72/1467b9e1ef63aecfe3b42333fb7607f66129dffaeca231f97e4be6f71803/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c45d9f3dd9627844c12e9ca347258c7be585bed54046336220e25ea6eac155", size = 112808 }, - { url = "https://files.pythonhosted.org/packages/ce/ef/64894efd67cb3459074c734736ecacff398cd841a5538dc70e3e77d35500/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:77c1a2c6e3854bf87cd5588b95174640c8a881716bd07fa0d131d082270a6795", size = 122049 }, - { url = "https://files.pythonhosted.org/packages/c5/c8/1b13b4ea4bb88d7c2db56d070a52daf4757b3139afd83885e81455cb422f/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ce649d4e25c2d56023471df0bf1e8e2ab67dfe4ff12ce3e8fe7e6fae30cd672a", size = 118755 }, - { url = "https://files.pythonhosted.org/packages/d1/06/95ac63fa1ee118a4d5824aa0a6b0dc3a2934a2f4ce695bf6747e1744d813/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:265d9f31b4ac8f688eebef0bd4c814ffb37a16f769ad0c8c8b8c24a84db8eab5", size = 128053 }, - { url = "https://files.pythonhosted.org/packages/8a/27/3d6dbbd128e1b965bae198bffa4b5552cd635397e3d2bbcc7d9592890ca9/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2de436a9d61dae877e4e811fb3e2594e2a1df1b18f4280878f318aef48a562b9", size = 117316 }, - { url = "https://files.pythonhosted.org/packages/ed/9a/8b65daf417ff982fa1928ebc6ebdfb081750d426f877f0056288aaa689e8/geventhttpclient-2.3.1-cp311-cp311-win32.whl", hash = "sha256:83e22178b9480b0a95edf0053d4f30b717d0b696b3c262beabe6964d9c5224b1", size = 47598 }, - { url = "https://files.pythonhosted.org/packages/ab/83/ed0d14787861cf30beddd3aadc29ad07d75555de43c629ba514ddd2978d0/geventhttpclient-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:97b072a282233384c1302a7dee88ad8bfedc916f06b1bc1da54f84980f1406a9", size = 48301 }, - { url = "https://files.pythonhosted.org/packages/82/ee/bf3d26170a518d2b1254f44202f2fa4490496b476ee24046ff6c34e79c08/geventhttpclient-2.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e1c90abcc2735cd8dd2d2572a13da32f6625392dc04862decb5c6476a3ddee22", size = 71742 }, - { url = "https://files.pythonhosted.org/packages/77/72/bd64b2a491094a3fbf7f3c314bb3c3918afb652783a8a9db07b86072da35/geventhttpclient-2.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5deb41c2f51247b4e568c14964f59d7b8e537eff51900564c88af3200004e678", size = 52070 }, - { url = "https://files.pythonhosted.org/packages/85/96/e25becfde16c5551ba04ed2beac1f018e2efc70275ec19ae3765ff634ff2/geventhttpclient-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c6f1a56a66a90c4beae2f009b5e9d42db9a58ced165aa35441ace04d69cb7b37", size = 51650 }, - { url = "https://files.pythonhosted.org/packages/5d/b8/fe6e938a369b3742103d04e5771e1ec7b18c047ac30b06a8e9704e2d34fc/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ee6e741849c29e3129b1ec3828ac3a5e5dcb043402f852ea92c52334fb8cabf", size = 118507 }, - { url = "https://files.pythonhosted.org/packages/68/0b/381d01de049b02dc70addbcc1c8e24d15500bff6a9e89103c4aa8eb352c3/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d0972096a63b1ddaa73fa3dab2c7a136e3ab8bf7999a2f85a5dee851fa77cdd", size = 124061 }, - { url = "https://files.pythonhosted.org/packages/c6/e6/7c97b5bf41cc403b2936a0887a85550b3153aa4b60c0c5062c49cd6286f2/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00675ba682fb7d19d659c14686fa8a52a65e3f301b56c2a4ee6333b380dd9467", size = 115060 }, - { url = "https://files.pythonhosted.org/packages/45/1f/3e02464449c74a8146f27218471578c1dfabf18731cf047520b76e1b6331/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea77b67c186df90473416f4403839728f70ef6cf1689cec97b4f6bbde392a8a8", size = 113762 }, - { url = "https://files.pythonhosted.org/packages/4f/a4/08551776f7d6b219d6f73ca25be88806007b16af51a1dbfed7192528e1c3/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ddcc3f0fdffd9a3801e1005b73026202cffed8199863fdef9315bea9a860a032", size = 122018 }, - { url = "https://files.pythonhosted.org/packages/70/14/ba91417ac7cbce8d553f72c885a19c6b9d7f9dc7de81b7814551cf020a57/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c9f1ef4ec048563cc621a47ff01a4f10048ff8b676d7a4d75e5433ed8e703e56", size = 118884 }, - { url = "https://files.pythonhosted.org/packages/7c/78/e1f2c30e11bda8347a74b3a7254f727ff53ea260244da77d76b96779a006/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:a364b30bec7a0a00dbe256e2b6807e4dc866bead7ac84aaa51ca5e2c3d15c258", size = 128224 }, - { url = "https://files.pythonhosted.org/packages/ac/2f/b7fd96e9cfa9d9719b0c9feb50b4cbb341d1940e34fd3305006efa8c3e33/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:25d255383d3d6a6fbd643bb51ae1a7e4f6f7b0dbd5f3225b537d0bd0432eaf39", size = 117758 }, - { url = "https://files.pythonhosted.org/packages/fb/e0/1384c9a76379ab257b75df92283797861dcae592dd98e471df254f87c635/geventhttpclient-2.3.1-cp312-cp312-win32.whl", hash = "sha256:ad0b507e354d2f398186dcb12fe526d0594e7c9387b514fb843f7a14fdf1729a", size = 47595 }, - { url = "https://files.pythonhosted.org/packages/54/e3/6b8dbb24e3941e20abbe7736e59290c5d4182057ea1d984d46c853208bcd/geventhttpclient-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:7924e0883bc2b177cfe27aa65af6bb9dd57f3e26905c7675a2d1f3ef69df7cca", size = 48271 }, - { url = "https://files.pythonhosted.org/packages/ee/9f/251b1b7e665523137a8711f0f0029196cf18b57741135f01aea80a56f16c/geventhttpclient-2.3.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c31431e38df45b3c79bf3c9427c796adb8263d622bc6fa25e2f6ba916c2aad93", size = 49827 }, - { url = "https://files.pythonhosted.org/packages/74/c7/ad4c23de669191e1c83cfa28c51d3b50fc246d72e1ee40d4d5b330532492/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:855ab1e145575769b180b57accb0573a77cd6a7392f40a6ef7bc9a4926ebd77b", size = 54017 }, - { url = "https://files.pythonhosted.org/packages/04/7b/59fc8c8fbd10596abfc46dc103654e3d9676de64229d8eee4b0a4ac2e890/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a374aad77c01539e786d0c7829bec2eba034ccd45733c1bf9811ad18d2a8ecd", size = 58359 }, - { url = "https://files.pythonhosted.org/packages/94/b7/743552b0ecda75458c83d55d62937e29c9ee9a42598f57d4025d5de70004/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c1e97460608304f400485ac099736fff3566d3d8db2038533d466f8cf5de5a", size = 54262 }, - { url = "https://files.pythonhosted.org/packages/18/60/10f6215b6cc76b5845a7f4b9c3d1f47d7ecd84ce8769b1e27e0482d605d7/geventhttpclient-2.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4f843f81ee44ba4c553a1b3f73115e0ad8f00044023c24db29f5b1df3da08465", size = 48343 }, + { url = "https://files.pythonhosted.org/packages/a2/a5/5e49d6a581b3f1399425e22961c6e341e90c12fa2193ed0adee9afbd864c/geventhttpclient-2.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da22ab7bf5af4ba3d07cffee6de448b42696e53e7ac1fe97ed289037733bf1c2", size = 71729, upload-time = "2024-04-18T21:38:06.866Z" }, + { url = "https://files.pythonhosted.org/packages/eb/23/4ff584e5f344dae64b5bc588b65c4ea81083f9d662b9f64cf5f28e5ae9cc/geventhttpclient-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2399e3d4e2fae8bbd91756189da6e9d84adf8f3eaace5eef0667874a705a29f8", size = 52062, upload-time = "2024-04-18T21:38:08.433Z" }, + { url = "https://files.pythonhosted.org/packages/bb/60/6bd8badb97b31a49f4c2b79466abce208a97dad95d447893c7546063fc8a/geventhttpclient-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3e33e87d0d5b9f5782c4e6d3cb7e3592fea41af52713137d04776df7646d71b", size = 51645, upload-time = "2024-04-18T21:38:10.139Z" }, + { url = "https://files.pythonhosted.org/packages/e1/62/47d431bf05f74aa683d63163a11432bda8f576c86dec8c3bc9d6a156ee03/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c071db313866c3d0510feb6c0f40ec086ccf7e4a845701b6316c82c06e8b9b29", size = 117838, upload-time = "2024-04-18T21:38:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/6c/8b/e7c9ae813bb41883a96ad9afcf86465219c3bb682daa8b09448481edef8a/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f36f0c6ef88a27e60af8369d9c2189fe372c6f2943182a7568e0f2ad33bb69f1", size = 123272, upload-time = "2024-04-18T21:38:13.704Z" }, + { url = "https://files.pythonhosted.org/packages/4d/26/71e9b2526009faadda9f588dac04f8bf837a5b97628ab44145efc3fa796e/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4624843c03a5337282a42247d987c2531193e57255ee307b36eeb4f243a0c21", size = 114319, upload-time = "2024-04-18T21:38:15.097Z" }, + { url = "https://files.pythonhosted.org/packages/34/8c/1da2960293c42b7a6b01dbe3204b569e4cdb55b8289cb1c7154826500f19/geventhttpclient-2.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d614573621ba827c417786057e1e20e9f96c4f6b3878c55b1b7b54e1026693bc", size = 112705, upload-time = "2024-04-18T21:38:17.005Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a1/4d08ecf0f213fdc63f78a217f87c07c1cb9891e68cdf74c8cbca76298bdb/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5d51330a40ac9762879d0e296c279c1beae8cfa6484bb196ac829242c416b709", size = 121236, upload-time = "2024-04-18T21:38:18.831Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f7/42ece3e1f54602c518d74364a214da3b35b6be267b335564b7e9f0d37705/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc9f2162d4e8cb86bb5322d99bfd552088a3eacd540a841298f06bb8bc1f1f03", size = 117859, upload-time = "2024-04-18T21:38:20.917Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8e/de026b3697bffe5fa1a4938a3882107e378eea826905acf8e46c69b71ffd/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:06e59d3397e63c65ecc7a7561a5289f0cf2e2c2252e29632741e792f57f5d124", size = 127268, upload-time = "2024-04-18T21:38:22.676Z" }, + { url = "https://files.pythonhosted.org/packages/54/bf/1ee99a322467e6825a24612d306a46ca94b51088170d1b5de0df1c82ab2a/geventhttpclient-2.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4436eef515b3e0c1d4a453ae32e047290e780a623c1eddb11026ae9d5fb03d42", size = 116426, upload-time = "2024-04-18T21:38:24.228Z" }, + { url = "https://files.pythonhosted.org/packages/72/54/10c8ec745b3dcbfd52af62977fec85829749c0325e1a5429d050a4b45e75/geventhttpclient-2.3.1-cp310-cp310-win32.whl", hash = "sha256:5d1cf7d8a4f8e15cc8fd7d88ac4cdb058d6274203a42587e594cc9f0850ac862", size = 47599, upload-time = "2024-04-18T21:38:26.385Z" }, + { url = "https://files.pythonhosted.org/packages/da/0d/36a47cdeaa83c3b4efdbd18d77720fa27dc40600998f4dedd7c4a1259862/geventhttpclient-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:4deaebc121036f7ea95430c2d0f80ab085b15280e6ab677a6360b70e57020e7f", size = 48302, upload-time = "2024-04-18T21:38:28.297Z" }, + { url = "https://files.pythonhosted.org/packages/56/ad/1fcbbea0465f04d4425960e3737d4d8ae6407043cfc88688fb17b9064160/geventhttpclient-2.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0ae055b9ce1704f2ce72c0847df28f4e14dbb3eea79256cda6c909d82688ea3", size = 71733, upload-time = "2024-04-18T21:38:30.357Z" }, + { url = "https://files.pythonhosted.org/packages/06/1a/10e547adb675beea407ff7117ecb4e5063534569ac14bb4360279d2888dd/geventhttpclient-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f087af2ac439495b5388841d6f3c4de8d2573ca9870593d78f7b554aa5cfa7f5", size = 52060, upload-time = "2024-04-18T21:38:32.561Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c0/9960ac6e8818a00702743cd2a9637d6f26909ac7ac59ca231f446e367b20/geventhttpclient-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76c367d175810facfe56281e516c9a5a4a191eff76641faaa30aa33882ed4b2f", size = 51649, upload-time = "2024-04-18T21:38:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/58/3a/b032cd8f885dafdfa002a8a0e4e21b633713798ec08e19010b815fbfead6/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a58376d0d461fe0322ff2ad362553b437daee1eeb92b4c0e3b1ffef9e77defbe", size = 117987, upload-time = "2024-04-18T21:38:37.661Z" }, + { url = "https://files.pythonhosted.org/packages/94/36/6493a5cbc20c269a51186946947f3ca2eae687e05831289891027bd038c3/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f440cc704f8a9869848a109b2c401805c17c070539b2014e7b884ecfc8591e33", size = 123356, upload-time = "2024-04-18T21:38:39.705Z" }, + { url = "https://files.pythonhosted.org/packages/2f/07/b66d9a13b97a7e59d84b4faf704113aa963aaf3a0f71c9138c8740d57d5c/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f10c62994f9052f23948c19de930b2d1f063240462c8bd7077c2b3290e61f4fa", size = 114460, upload-time = "2024-04-18T21:38:40.947Z" }, + { url = "https://files.pythonhosted.org/packages/4e/72/1467b9e1ef63aecfe3b42333fb7607f66129dffaeca231f97e4be6f71803/geventhttpclient-2.3.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c45d9f3dd9627844c12e9ca347258c7be585bed54046336220e25ea6eac155", size = 112808, upload-time = "2024-04-18T21:38:42.684Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/64894efd67cb3459074c734736ecacff398cd841a5538dc70e3e77d35500/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:77c1a2c6e3854bf87cd5588b95174640c8a881716bd07fa0d131d082270a6795", size = 122049, upload-time = "2024-04-18T21:38:44.184Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c8/1b13b4ea4bb88d7c2db56d070a52daf4757b3139afd83885e81455cb422f/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ce649d4e25c2d56023471df0bf1e8e2ab67dfe4ff12ce3e8fe7e6fae30cd672a", size = 118755, upload-time = "2024-04-18T21:38:45.654Z" }, + { url = "https://files.pythonhosted.org/packages/d1/06/95ac63fa1ee118a4d5824aa0a6b0dc3a2934a2f4ce695bf6747e1744d813/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:265d9f31b4ac8f688eebef0bd4c814ffb37a16f769ad0c8c8b8c24a84db8eab5", size = 128053, upload-time = "2024-04-18T21:38:47.247Z" }, + { url = "https://files.pythonhosted.org/packages/8a/27/3d6dbbd128e1b965bae198bffa4b5552cd635397e3d2bbcc7d9592890ca9/geventhttpclient-2.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2de436a9d61dae877e4e811fb3e2594e2a1df1b18f4280878f318aef48a562b9", size = 117316, upload-time = "2024-04-18T21:38:49.086Z" }, + { url = "https://files.pythonhosted.org/packages/ed/9a/8b65daf417ff982fa1928ebc6ebdfb081750d426f877f0056288aaa689e8/geventhttpclient-2.3.1-cp311-cp311-win32.whl", hash = "sha256:83e22178b9480b0a95edf0053d4f30b717d0b696b3c262beabe6964d9c5224b1", size = 47598, upload-time = "2024-04-18T21:38:50.919Z" }, + { url = "https://files.pythonhosted.org/packages/ab/83/ed0d14787861cf30beddd3aadc29ad07d75555de43c629ba514ddd2978d0/geventhttpclient-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:97b072a282233384c1302a7dee88ad8bfedc916f06b1bc1da54f84980f1406a9", size = 48301, upload-time = "2024-04-18T21:38:52.14Z" }, + { url = "https://files.pythonhosted.org/packages/82/ee/bf3d26170a518d2b1254f44202f2fa4490496b476ee24046ff6c34e79c08/geventhttpclient-2.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e1c90abcc2735cd8dd2d2572a13da32f6625392dc04862decb5c6476a3ddee22", size = 71742, upload-time = "2024-04-18T21:38:54.167Z" }, + { url = "https://files.pythonhosted.org/packages/77/72/bd64b2a491094a3fbf7f3c314bb3c3918afb652783a8a9db07b86072da35/geventhttpclient-2.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5deb41c2f51247b4e568c14964f59d7b8e537eff51900564c88af3200004e678", size = 52070, upload-time = "2024-04-18T21:38:55.484Z" }, + { url = "https://files.pythonhosted.org/packages/85/96/e25becfde16c5551ba04ed2beac1f018e2efc70275ec19ae3765ff634ff2/geventhttpclient-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c6f1a56a66a90c4beae2f009b5e9d42db9a58ced165aa35441ace04d69cb7b37", size = 51650, upload-time = "2024-04-18T21:38:57.022Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b8/fe6e938a369b3742103d04e5771e1ec7b18c047ac30b06a8e9704e2d34fc/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ee6e741849c29e3129b1ec3828ac3a5e5dcb043402f852ea92c52334fb8cabf", size = 118507, upload-time = "2024-04-18T21:38:58.936Z" }, + { url = "https://files.pythonhosted.org/packages/68/0b/381d01de049b02dc70addbcc1c8e24d15500bff6a9e89103c4aa8eb352c3/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d0972096a63b1ddaa73fa3dab2c7a136e3ab8bf7999a2f85a5dee851fa77cdd", size = 124061, upload-time = "2024-04-18T21:39:00.473Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e6/7c97b5bf41cc403b2936a0887a85550b3153aa4b60c0c5062c49cd6286f2/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00675ba682fb7d19d659c14686fa8a52a65e3f301b56c2a4ee6333b380dd9467", size = 115060, upload-time = "2024-04-18T21:39:02.323Z" }, + { url = "https://files.pythonhosted.org/packages/45/1f/3e02464449c74a8146f27218471578c1dfabf18731cf047520b76e1b6331/geventhttpclient-2.3.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea77b67c186df90473416f4403839728f70ef6cf1689cec97b4f6bbde392a8a8", size = 113762, upload-time = "2024-04-18T21:39:03.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a4/08551776f7d6b219d6f73ca25be88806007b16af51a1dbfed7192528e1c3/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ddcc3f0fdffd9a3801e1005b73026202cffed8199863fdef9315bea9a860a032", size = 122018, upload-time = "2024-04-18T21:39:05.781Z" }, + { url = "https://files.pythonhosted.org/packages/70/14/ba91417ac7cbce8d553f72c885a19c6b9d7f9dc7de81b7814551cf020a57/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c9f1ef4ec048563cc621a47ff01a4f10048ff8b676d7a4d75e5433ed8e703e56", size = 118884, upload-time = "2024-04-18T21:39:08.001Z" }, + { url = "https://files.pythonhosted.org/packages/7c/78/e1f2c30e11bda8347a74b3a7254f727ff53ea260244da77d76b96779a006/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:a364b30bec7a0a00dbe256e2b6807e4dc866bead7ac84aaa51ca5e2c3d15c258", size = 128224, upload-time = "2024-04-18T21:39:09.31Z" }, + { url = "https://files.pythonhosted.org/packages/ac/2f/b7fd96e9cfa9d9719b0c9feb50b4cbb341d1940e34fd3305006efa8c3e33/geventhttpclient-2.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:25d255383d3d6a6fbd643bb51ae1a7e4f6f7b0dbd5f3225b537d0bd0432eaf39", size = 117758, upload-time = "2024-04-18T21:39:11.287Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e0/1384c9a76379ab257b75df92283797861dcae592dd98e471df254f87c635/geventhttpclient-2.3.1-cp312-cp312-win32.whl", hash = "sha256:ad0b507e354d2f398186dcb12fe526d0594e7c9387b514fb843f7a14fdf1729a", size = 47595, upload-time = "2024-04-18T21:39:12.535Z" }, + { url = "https://files.pythonhosted.org/packages/54/e3/6b8dbb24e3941e20abbe7736e59290c5d4182057ea1d984d46c853208bcd/geventhttpclient-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:7924e0883bc2b177cfe27aa65af6bb9dd57f3e26905c7675a2d1f3ef69df7cca", size = 48271, upload-time = "2024-04-18T21:39:14.479Z" }, + { url = "https://files.pythonhosted.org/packages/ee/9f/251b1b7e665523137a8711f0f0029196cf18b57741135f01aea80a56f16c/geventhttpclient-2.3.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c31431e38df45b3c79bf3c9427c796adb8263d622bc6fa25e2f6ba916c2aad93", size = 49827, upload-time = "2024-04-18T21:39:36.14Z" }, + { url = "https://files.pythonhosted.org/packages/74/c7/ad4c23de669191e1c83cfa28c51d3b50fc246d72e1ee40d4d5b330532492/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:855ab1e145575769b180b57accb0573a77cd6a7392f40a6ef7bc9a4926ebd77b", size = 54017, upload-time = "2024-04-18T21:39:37.577Z" }, + { url = "https://files.pythonhosted.org/packages/04/7b/59fc8c8fbd10596abfc46dc103654e3d9676de64229d8eee4b0a4ac2e890/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a374aad77c01539e786d0c7829bec2eba034ccd45733c1bf9811ad18d2a8ecd", size = 58359, upload-time = "2024-04-18T21:39:39.437Z" }, + { url = "https://files.pythonhosted.org/packages/94/b7/743552b0ecda75458c83d55d62937e29c9ee9a42598f57d4025d5de70004/geventhttpclient-2.3.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c1e97460608304f400485ac099736fff3566d3d8db2038533d466f8cf5de5a", size = 54262, upload-time = "2024-04-18T21:39:40.866Z" }, + { url = "https://files.pythonhosted.org/packages/18/60/10f6215b6cc76b5845a7f4b9c3d1f47d7ecd84ce8769b1e27e0482d605d7/geventhttpclient-2.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4f843f81ee44ba4c553a1b3f73115e0ad8f00044023c24db29f5b1df3da08465", size = 48343, upload-time = "2024-04-18T21:39:42.173Z" }, ] [[package]] name = "greenlet" version = "3.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022, upload-time = "2024-09-20T18:21:04.506Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235 }, - { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168 }, - { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826 }, - { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443 }, - { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295 }, - { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544 }, - { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456 }, - { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111 }, - { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392 }, - { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479 }, - { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404 }, - { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813 }, - { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517 }, - { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831 }, - { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413 }, - { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619 }, - { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198 }, - { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930 }, - { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, - { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, - { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, - { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, - { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, - { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, - { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, - { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, - { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, - { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, - { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, - { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, - { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, - { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, - { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, - { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, - { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, - { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, - { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, - { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, - { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, - { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, - { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, - { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, - { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, + { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235, upload-time = "2024-09-20T17:07:18.761Z" }, + { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168, upload-time = "2024-09-20T17:36:43.774Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826, upload-time = "2024-09-20T17:39:16.921Z" }, + { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443, upload-time = "2024-09-20T17:44:21.896Z" }, + { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295, upload-time = "2024-09-20T17:08:37.951Z" }, + { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544, upload-time = "2024-09-20T17:08:27.894Z" }, + { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456, upload-time = "2024-09-20T17:44:11.755Z" }, + { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111, upload-time = "2024-09-20T17:09:22.104Z" }, + { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392, upload-time = "2024-09-20T17:28:51.988Z" }, + { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479, upload-time = "2024-09-20T17:07:22.332Z" }, + { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404, upload-time = "2024-09-20T17:36:45.588Z" }, + { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813, upload-time = "2024-09-20T17:39:19.052Z" }, + { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517, upload-time = "2024-09-20T17:44:24.101Z" }, + { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831, upload-time = "2024-09-20T17:08:40.577Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413, upload-time = "2024-09-20T17:08:31.728Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619, upload-time = "2024-09-20T17:44:14.222Z" }, + { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198, upload-time = "2024-09-20T17:09:23.903Z" }, + { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930, upload-time = "2024-09-20T17:25:18.656Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260, upload-time = "2024-09-20T17:08:07.301Z" }, + { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064, upload-time = "2024-09-20T17:36:47.628Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420, upload-time = "2024-09-20T17:39:21.258Z" }, + { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035, upload-time = "2024-09-20T17:44:26.501Z" }, + { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105, upload-time = "2024-09-20T17:08:42.048Z" }, + { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077, upload-time = "2024-09-20T17:08:33.707Z" }, + { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975, upload-time = "2024-09-20T17:44:15.989Z" }, + { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955, upload-time = "2024-09-20T17:09:25.539Z" }, + { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655, upload-time = "2024-09-20T17:21:22.427Z" }, + { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990, upload-time = "2024-09-20T17:08:26.312Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175, upload-time = "2024-09-20T17:36:48.983Z" }, + { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425, upload-time = "2024-09-20T17:39:22.705Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736, upload-time = "2024-09-20T17:44:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347, upload-time = "2024-09-20T17:08:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583, upload-time = "2024-09-20T17:08:36.85Z" }, + { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039, upload-time = "2024-09-20T17:44:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716, upload-time = "2024-09-20T17:09:27.112Z" }, + { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490, upload-time = "2024-09-20T17:17:09.501Z" }, + { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731, upload-time = "2024-09-20T17:36:50.376Z" }, + { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304, upload-time = "2024-09-20T17:39:24.55Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537, upload-time = "2024-09-20T17:44:31.102Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506, upload-time = "2024-09-20T17:08:47.852Z" }, + { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753, upload-time = "2024-09-20T17:08:38.079Z" }, + { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731, upload-time = "2024-09-20T17:44:20.556Z" }, + { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112, upload-time = "2024-09-20T17:09:28.753Z" }, ] [[package]] @@ -934,33 +989,33 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/34/72/9614c465dc206155d93eff0ca20d42e1e35afc533971379482de953521a4/gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec", size = 375031 } +sdist = { url = "https://files.pythonhosted.org/packages/34/72/9614c465dc206155d93eff0ca20d42e1e35afc533971379482de953521a4/gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec", size = 375031, upload-time = "2024-08-10T20:25:27.378Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029 }, + { url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029, upload-time = "2024-08-10T20:25:24.996Z" }, ] [[package]] name = "h11" version = "0.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, ] [[package]] name = "hf-xet" version = "1.1.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/0a/a0f56735940fde6dd627602fec9ab3bad23f66a272397560abd65aba416e/hf_xet-1.1.7.tar.gz", hash = "sha256:20cec8db4561338824a3b5f8c19774055b04a8df7fff0cb1ff2cb1a0c1607b80", size = 477719 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/0a/a0f56735940fde6dd627602fec9ab3bad23f66a272397560abd65aba416e/hf_xet-1.1.7.tar.gz", hash = "sha256:20cec8db4561338824a3b5f8c19774055b04a8df7fff0cb1ff2cb1a0c1607b80", size = 477719, upload-time = "2025-08-06T00:30:55.741Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/7c/8d7803995caf14e7d19a392a486a040f923e2cfeff824e9b800b92072f76/hf_xet-1.1.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:60dae4b44d520819e54e216a2505685248ec0adbdb2dd4848b17aa85a0375cde", size = 2761743 }, - { url = "https://files.pythonhosted.org/packages/51/a3/fa5897099454aa287022a34a30e68dbff0e617760f774f8bd1db17f06bd4/hf_xet-1.1.7-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b109f4c11e01c057fc82004c9e51e6cdfe2cb230637644ade40c599739067b2e", size = 2624331 }, - { url = "https://files.pythonhosted.org/packages/86/50/2446a132267e60b8a48b2e5835d6e24fd988000d0f5b9b15ebd6d64ef769/hf_xet-1.1.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6efaaf1a5a9fc3a501d3e71e88a6bfebc69ee3a716d0e713a931c8b8d920038f", size = 3183844 }, - { url = "https://files.pythonhosted.org/packages/20/8f/ccc670616bb9beee867c6bb7139f7eab2b1370fe426503c25f5cbb27b148/hf_xet-1.1.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:751571540f9c1fbad9afcf222a5fb96daf2384bf821317b8bfb0c59d86078513", size = 3074209 }, - { url = "https://files.pythonhosted.org/packages/21/0a/4c30e1eb77205565b854f5e4a82cf1f056214e4dc87f2918ebf83d47ae14/hf_xet-1.1.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:18b61bbae92d56ae731b92087c44efcac216071182c603fc535f8e29ec4b09b8", size = 3239602 }, - { url = "https://files.pythonhosted.org/packages/f5/1e/fc7e9baf14152662ef0b35fa52a6e889f770a7ed14ac239de3c829ecb47e/hf_xet-1.1.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:713f2bff61b252f8523739969f247aa354ad8e6d869b8281e174e2ea1bb8d604", size = 3348184 }, - { url = "https://files.pythonhosted.org/packages/a3/73/e354eae84ceff117ec3560141224724794828927fcc013c5b449bf0b8745/hf_xet-1.1.7-cp37-abi3-win_amd64.whl", hash = "sha256:2e356da7d284479ae0f1dea3cf5a2f74fdf925d6dca84ac4341930d892c7cb34", size = 2820008 }, + { url = "https://files.pythonhosted.org/packages/b1/7c/8d7803995caf14e7d19a392a486a040f923e2cfeff824e9b800b92072f76/hf_xet-1.1.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:60dae4b44d520819e54e216a2505685248ec0adbdb2dd4848b17aa85a0375cde", size = 2761743, upload-time = "2025-08-06T00:30:50.634Z" }, + { url = "https://files.pythonhosted.org/packages/51/a3/fa5897099454aa287022a34a30e68dbff0e617760f774f8bd1db17f06bd4/hf_xet-1.1.7-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b109f4c11e01c057fc82004c9e51e6cdfe2cb230637644ade40c599739067b2e", size = 2624331, upload-time = "2025-08-06T00:30:49.212Z" }, + { url = "https://files.pythonhosted.org/packages/86/50/2446a132267e60b8a48b2e5835d6e24fd988000d0f5b9b15ebd6d64ef769/hf_xet-1.1.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6efaaf1a5a9fc3a501d3e71e88a6bfebc69ee3a716d0e713a931c8b8d920038f", size = 3183844, upload-time = "2025-08-06T00:30:47.582Z" }, + { url = "https://files.pythonhosted.org/packages/20/8f/ccc670616bb9beee867c6bb7139f7eab2b1370fe426503c25f5cbb27b148/hf_xet-1.1.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:751571540f9c1fbad9afcf222a5fb96daf2384bf821317b8bfb0c59d86078513", size = 3074209, upload-time = "2025-08-06T00:30:45.509Z" }, + { url = "https://files.pythonhosted.org/packages/21/0a/4c30e1eb77205565b854f5e4a82cf1f056214e4dc87f2918ebf83d47ae14/hf_xet-1.1.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:18b61bbae92d56ae731b92087c44efcac216071182c603fc535f8e29ec4b09b8", size = 3239602, upload-time = "2025-08-06T00:30:52.41Z" }, + { url = "https://files.pythonhosted.org/packages/f5/1e/fc7e9baf14152662ef0b35fa52a6e889f770a7ed14ac239de3c829ecb47e/hf_xet-1.1.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:713f2bff61b252f8523739969f247aa354ad8e6d869b8281e174e2ea1bb8d604", size = 3348184, upload-time = "2025-08-06T00:30:54.105Z" }, + { url = "https://files.pythonhosted.org/packages/a3/73/e354eae84ceff117ec3560141224724794828927fcc013c5b449bf0b8745/hf_xet-1.1.7-cp37-abi3-win_amd64.whl", hash = "sha256:2e356da7d284479ae0f1dea3cf5a2f74fdf925d6dca84ac4341930d892c7cb34", size = 2820008, upload-time = "2025-08-06T00:30:57.056Z" }, ] [[package]] @@ -971,45 +1026,45 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/56/78a38490b834fa0942cbe6d39bd8a7fd76316e8940319305a98d2b320366/httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535", size = 81036 } +sdist = { url = "https://files.pythonhosted.org/packages/18/56/78a38490b834fa0942cbe6d39bd8a7fd76316e8940319305a98d2b320366/httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535", size = 81036, upload-time = "2023-11-10T13:37:42.496Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/ba/78b0a99c4da0ff8b0f59defa2f13ca4668189b134bd9840b6202a93d9a0f/httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7", size = 76943 }, + { url = "https://files.pythonhosted.org/packages/56/ba/78b0a99c4da0ff8b0f59defa2f13ca4668189b134bd9840b6202a93d9a0f/httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7", size = 76943, upload-time = "2023-11-10T13:37:40.937Z" }, ] [[package]] name = "httptools" version = "0.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639 } +sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload-time = "2024-10-16T19:45:08.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780 }, - { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297 }, - { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130 }, - { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148 }, - { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949 }, - { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591 }, - { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344 }, - { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029 }, - { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492 }, - { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891 }, - { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788 }, - { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214 }, - { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120 }, - { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565 }, - { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683 }, - { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337 }, - { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796 }, - { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837 }, - { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289 }, - { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779 }, - { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634 }, - { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214 }, - { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431 }, - { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121 }, - { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805 }, - { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858 }, - { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042 }, - { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682 }, + { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780, upload-time = "2024-10-16T19:44:06.882Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297, upload-time = "2024-10-16T19:44:08.129Z" }, + { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130, upload-time = "2024-10-16T19:44:09.45Z" }, + { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148, upload-time = "2024-10-16T19:44:11.539Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949, upload-time = "2024-10-16T19:44:13.388Z" }, + { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591, upload-time = "2024-10-16T19:44:15.258Z" }, + { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344, upload-time = "2024-10-16T19:44:16.54Z" }, + { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029, upload-time = "2024-10-16T19:44:18.427Z" }, + { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492, upload-time = "2024-10-16T19:44:19.515Z" }, + { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891, upload-time = "2024-10-16T19:44:21.067Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788, upload-time = "2024-10-16T19:44:22.958Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214, upload-time = "2024-10-16T19:44:24.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120, upload-time = "2024-10-16T19:44:26.295Z" }, + { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565, upload-time = "2024-10-16T19:44:29.188Z" }, + { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683, upload-time = "2024-10-16T19:44:30.175Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337, upload-time = "2024-10-16T19:44:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796, upload-time = "2024-10-16T19:44:32.825Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837, upload-time = "2024-10-16T19:44:33.974Z" }, + { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289, upload-time = "2024-10-16T19:44:35.111Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779, upload-time = "2024-10-16T19:44:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634, upload-time = "2024-10-16T19:44:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload-time = "2024-10-16T19:44:38.738Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload-time = "2024-10-16T19:44:39.818Z" }, + { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload-time = "2024-10-16T19:44:41.189Z" }, + { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805, upload-time = "2024-10-16T19:44:42.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858, upload-time = "2024-10-16T19:44:43.959Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042, upload-time = "2024-10-16T19:44:45.071Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682, upload-time = "2024-10-16T19:44:46.46Z" }, ] [[package]] @@ -1022,14 +1077,14 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "huggingface-hub" -version = "0.34.4" +version = "0.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -1041,9 +1096,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/45/c9/bdbe19339f76d12985bc03572f330a01a93c04dffecaaea3061bdd7fb892/huggingface_hub-0.34.4.tar.gz", hash = "sha256:a4228daa6fb001be3f4f4bdaf9a0db00e1739235702848df00885c9b5742c85c", size = 459768 } +sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/7b/bb06b061991107cd8783f300adff3e7b7f284e330fd82f507f2a1417b11d/huggingface_hub-0.34.4-py3-none-any.whl", hash = "sha256:9b365d781739c93ff90c359844221beef048403f1bc1f1c123c191257c3c890a", size = 561452 }, + { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, ] [[package]] @@ -1053,18 +1108,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyreadline3", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794 }, + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, ] [[package]] name = "idna" version = "3.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } +sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426, upload-time = "2023-11-25T15:40:54.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567, upload-time = "2023-11-25T15:40:52.604Z" }, ] [[package]] @@ -1075,14 +1130,14 @@ dependencies = [ { name = "numpy" }, { name = "pillow" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/38/f4c568318c656352d211eec6954460dc3af0b7583a6682308f8a66e4c19b/imageio-2.33.1.tar.gz", hash = "sha256:78722d40b137bd98f5ec7312119f8aea9ad2049f76f434748eb306b6937cc1ce", size = 387374 } +sdist = { url = "https://files.pythonhosted.org/packages/25/38/f4c568318c656352d211eec6954460dc3af0b7583a6682308f8a66e4c19b/imageio-2.33.1.tar.gz", hash = "sha256:78722d40b137bd98f5ec7312119f8aea9ad2049f76f434748eb306b6937cc1ce", size = 387374, upload-time = "2023-12-11T02:26:44.715Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/69/3aaa69cb0748e33e644fda114c9abd3186ce369edd4fca11107e9f39c6a7/imageio-2.33.1-py3-none-any.whl", hash = "sha256:c5094c48ccf6b2e6da8b4061cd95e1209380afafcbeae4a4e280938cce227e1d", size = 313345 }, + { url = "https://files.pythonhosted.org/packages/c0/69/3aaa69cb0748e33e644fda114c9abd3186ce369edd4fca11107e9f39c6a7/imageio-2.33.1-py3-none-any.whl", hash = "sha256:c5094c48ccf6b2e6da8b4061cd95e1209380afafcbeae4a4e280938cce227e1d", size = 313345, upload-time = "2023-12-11T02:26:42.724Z" }, ] [[package]] name = "immich-ml" -version = "2.0.1" +version = "2.3.1" source = { editable = "." } dependencies = [ { name = "aiocache" }, @@ -1238,9 +1293,9 @@ types = [ name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, ] [[package]] @@ -1265,15 +1320,15 @@ dependencies = [ { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0b/8d/0f4af90999ca96cf8cb846eb5ae27c5ef5b390f9c090dd19e4fa76364c13/insightface-0.7.3.tar.gz", hash = "sha256:f191f719612ebb37018f41936814500544cd0f86e6fcd676c023f354c668ddf7", size = 439490 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/8d/0f4af90999ca96cf8cb846eb5ae27c5ef5b390f9c090dd19e4fa76364c13/insightface-0.7.3.tar.gz", hash = "sha256:f191f719612ebb37018f41936814500544cd0f86e6fcd676c023f354c668ddf7", size = 439490, upload-time = "2023-04-02T08:01:54.541Z" } [[package]] name = "itsdangerous" version = "2.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143, upload-time = "2022-03-24T15:12:15.102Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749 }, + { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749, upload-time = "2022-03-24T15:12:13.2Z" }, ] [[package]] @@ -1283,85 +1338,85 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245, upload-time = "2024-05-05T23:42:02.455Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, + { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271, upload-time = "2024-05-05T23:41:59.928Z" }, ] [[package]] name = "joblib" version = "1.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/0f/d3b33b9f106dddef461f6df1872b7881321b247f3d255b87f61a7636f7fe/joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1", size = 1987720 } +sdist = { url = "https://files.pythonhosted.org/packages/15/0f/d3b33b9f106dddef461f6df1872b7881321b247f3d255b87f61a7636f7fe/joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1", size = 1987720, upload-time = "2023-08-09T09:23:40.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/40/d551139c85db202f1f384ba8bcf96aca2f329440a844f924c8a0040b6d02/joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9", size = 302207 }, + { url = "https://files.pythonhosted.org/packages/10/40/d551139c85db202f1f384ba8bcf96aca2f329440a844f924c8a0040b6d02/joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9", size = 302207, upload-time = "2023-08-09T09:23:34.583Z" }, ] [[package]] name = "kiwisolver" version = "1.4.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/2d/226779e405724344fc678fcc025b812587617ea1a48b9442628b688e85ea/kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec", size = 97552 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2d/226779e405724344fc678fcc025b812587617ea1a48b9442628b688e85ea/kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec", size = 97552, upload-time = "2023-08-24T09:30:39.861Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/56/cb02dcefdaab40df636b91e703b172966b444605a0ea313549f3ffc05bd3/kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af", size = 127397 }, - { url = "https://files.pythonhosted.org/packages/0e/c1/d084f8edb26533a191415d5173157080837341f9a06af9dd1a75f727abb4/kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3", size = 68125 }, - { url = "https://files.pythonhosted.org/packages/23/11/6fb190bae4b279d712a834e7b1da89f6dcff6791132f7399aa28a57c3565/kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4", size = 66211 }, - { url = "https://files.pythonhosted.org/packages/b3/13/5e9e52feb33e9e063f76b2c5eb09cb977f5bba622df3210081bfb26ec9a3/kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1", size = 1637145 }, - { url = "https://files.pythonhosted.org/packages/6f/40/4ab1fdb57fced80ce5903f04ae1aed7c1d5939dda4fd0c0aa526c12fe28a/kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff", size = 1617849 }, - { url = "https://files.pythonhosted.org/packages/49/ca/61ef43bd0832c7253b370735b0c38972c140c8774889b884372a629a8189/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a", size = 1400921 }, - { url = "https://files.pythonhosted.org/packages/68/6f/854f6a845c00b4257482468e08d8bc386f4929ee499206142378ba234419/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa", size = 1513009 }, - { url = "https://files.pythonhosted.org/packages/50/65/76f303377167d12eb7a9b423d6771b39fe5c4373e4a42f075805b1f581ae/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c", size = 1444819 }, - { url = "https://files.pythonhosted.org/packages/7e/ee/98cdf9dde129551467138b6e18cc1cc901e75ecc7ffb898c6f49609f33b1/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b", size = 1817054 }, - { url = "https://files.pythonhosted.org/packages/e6/5b/ab569016ec4abc7b496f6cb8a3ab511372c99feb6a23d948cda97e0db6da/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770", size = 1918613 }, - { url = "https://files.pythonhosted.org/packages/93/ac/39b9f99d2474b1ac7af1ddfe5756ddf9b6a8f24c5f3a32cd4c010317fc6b/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0", size = 1872650 }, - { url = "https://files.pythonhosted.org/packages/40/5b/be568548266516b114d1776120281ea9236c732fb6032a1f8f3b1e5e921c/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525", size = 1827415 }, - { url = "https://files.pythonhosted.org/packages/d4/80/c0c13d2a17a12937a19ef378bf35e94399fd171ed6ec05bcee0f038e1eaf/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b", size = 1838094 }, - { url = "https://files.pythonhosted.org/packages/70/d1/5ab93ee00ca5af708929cc12fbe665b6f1ed4ad58088e70dc00e87e0d107/kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238", size = 46585 }, - { url = "https://files.pythonhosted.org/packages/4a/a1/8a9c9be45c642fa12954855d8b3a02d9fd8551165a558835a19508fec2e6/kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276", size = 56095 }, - { url = "https://files.pythonhosted.org/packages/2a/eb/9e099ad7c47c279995d2d20474e1821100a5f10f847739bd65b1c1f02442/kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5", size = 127403 }, - { url = "https://files.pythonhosted.org/packages/a6/94/695922e71288855fc7cace3bdb52edda9d7e50edba77abb0c9d7abb51e96/kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90", size = 68156 }, - { url = "https://files.pythonhosted.org/packages/4a/fe/23d7fa78f7c66086d196406beb1fb2eaf629dd7adc01c3453033303d17fa/kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797", size = 66166 }, - { url = "https://files.pythonhosted.org/packages/f1/68/f472bf16c9141bb1bea5c0b8c66c68fc1ccb048efdbd8f0872b92125724e/kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9", size = 1334300 }, - { url = "https://files.pythonhosted.org/packages/8d/26/b4569d1f29751fca22ee915b4ebfef5974f4ef239b3335fc072882bd62d9/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437", size = 1426579 }, - { url = "https://files.pythonhosted.org/packages/f3/a3/804fc7c8bf233806ec0321c9da35971578620f2ab4fafe67d76100b3ce52/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9", size = 1541360 }, - { url = "https://files.pythonhosted.org/packages/07/ef/286e1d26524854f6fbd6540e8364d67a8857d61038ac743e11edc42fe217/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da", size = 1470091 }, - { url = "https://files.pythonhosted.org/packages/17/ba/17a706b232308e65f57deeccae503c268292e6a091313f6ce833a23093ea/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e", size = 1426259 }, - { url = "https://files.pythonhosted.org/packages/d0/f3/a0925611c9d6c2f37c5935a39203cadec6883aa914e013b46c84c4c2e641/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8", size = 1847516 }, - { url = "https://files.pythonhosted.org/packages/da/85/82d59bb8f7c4c9bb2785138b72462cb1b161668f8230c58bbb28c0403cd5/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d", size = 1946228 }, - { url = "https://files.pythonhosted.org/packages/34/3c/6a37f444c0233993881e5db3a6a1775925d4d9d2f2609bb325bb1348ed94/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0", size = 1901716 }, - { url = "https://files.pythonhosted.org/packages/cd/7e/180425790efc00adfd47db14e1e341cb4826516982334129012b971121a6/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f", size = 1852871 }, - { url = "https://files.pythonhosted.org/packages/1b/9a/13c68b2edb1fa74321e60893a9a5829788e135138e68060cf44e2d92d2c3/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f", size = 1870265 }, - { url = "https://files.pythonhosted.org/packages/9f/0a/fa56a0fdee5da2b4c79899c0f6bd1aefb29d9438c2d66430e78793571c6b/kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac", size = 46649 }, - { url = "https://files.pythonhosted.org/packages/1e/37/d3c2d4ba2719059a0f12730947bbe1ad5ee8bff89e8c35319dcb2c9ddb4c/kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355", size = 56116 }, - { url = "https://files.pythonhosted.org/packages/f3/7a/debbce859be1a2711eb8437818107137192007b88d17b5cfdb556f457b42/kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a", size = 125484 }, - { url = "https://files.pythonhosted.org/packages/2d/e0/bf8df75ba93b9e035cc6757dd5dcaf63084fdc1c846ae134e818bd7e0f03/kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192", size = 67332 }, - { url = "https://files.pythonhosted.org/packages/26/61/58bb691f6880588be3a4801d199bd776032ece07203faf3e4a8b377f7d9b/kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45", size = 64987 }, - { url = "https://files.pythonhosted.org/packages/8e/a3/96ac5413068b237c006f54dd8d70114e8756d70e3da7613c5aef20627e22/kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7", size = 1370613 }, - { url = "https://files.pythonhosted.org/packages/4d/12/f48539e6e17068b59c7f12f4d6214b973431b8e3ac83af525cafd27cebec/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db", size = 1463183 }, - { url = "https://files.pythonhosted.org/packages/f3/70/26c99be8eb034cc8e3f62e0760af1fbdc97a842a7cbc252f7978507d41c2/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff", size = 1581248 }, - { url = "https://files.pythonhosted.org/packages/17/f6/f75f20e543639b09b2de7fc864274a5a9b96cda167a6210a1d9d19306b9d/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228", size = 1508815 }, - { url = "https://files.pythonhosted.org/packages/e3/d5/bc0f22ac108743062ab703f8d6d71c9c7b077b8839fa358700bfb81770b8/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16", size = 1466042 }, - { url = "https://files.pythonhosted.org/packages/75/18/98142500f21d6838bcab49ec919414a1f0c6d049d21ddadf139124db6a70/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9", size = 1885159 }, - { url = "https://files.pythonhosted.org/packages/21/49/a241eff9e0ee013368c1d17957f9d345b0957493c3a43d82ebb558c90b0a/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162", size = 1981694 }, - { url = "https://files.pythonhosted.org/packages/90/90/9490c3de4788123041b1d600d64434f1eed809a2ce9f688075a22166b289/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4", size = 1941579 }, - { url = "https://files.pythonhosted.org/packages/b7/bb/a0cc488ef2aa92d7d304318c8549d3ec8dfe6dd3c2c67a44e3922b77bc4f/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3", size = 1888168 }, - { url = "https://files.pythonhosted.org/packages/4f/e9/9c0de8e45fef3d63f85eed3b1757f9aa511065942866331ef8b99421f433/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a", size = 1908464 }, - { url = "https://files.pythonhosted.org/packages/a3/60/4f0fd50b08f5be536ea0cef518ac7255d9dab43ca40f3b93b60e3ddf80dd/kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20", size = 46473 }, - { url = "https://files.pythonhosted.org/packages/63/50/2746566bdf4a6a842d117367d05c90cfb87ac04e9e2845aa1fa21f071362/kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9", size = 56004 }, + { url = "https://files.pythonhosted.org/packages/f1/56/cb02dcefdaab40df636b91e703b172966b444605a0ea313549f3ffc05bd3/kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af", size = 127397, upload-time = "2023-08-24T09:28:18.105Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c1/d084f8edb26533a191415d5173157080837341f9a06af9dd1a75f727abb4/kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3", size = 68125, upload-time = "2023-08-24T09:28:19.218Z" }, + { url = "https://files.pythonhosted.org/packages/23/11/6fb190bae4b279d712a834e7b1da89f6dcff6791132f7399aa28a57c3565/kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4", size = 66211, upload-time = "2023-08-24T09:28:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/b3/13/5e9e52feb33e9e063f76b2c5eb09cb977f5bba622df3210081bfb26ec9a3/kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1", size = 1637145, upload-time = "2023-08-24T09:28:21.439Z" }, + { url = "https://files.pythonhosted.org/packages/6f/40/4ab1fdb57fced80ce5903f04ae1aed7c1d5939dda4fd0c0aa526c12fe28a/kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff", size = 1617849, upload-time = "2023-08-24T09:28:23.004Z" }, + { url = "https://files.pythonhosted.org/packages/49/ca/61ef43bd0832c7253b370735b0c38972c140c8774889b884372a629a8189/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a", size = 1400921, upload-time = "2023-08-24T09:28:24.331Z" }, + { url = "https://files.pythonhosted.org/packages/68/6f/854f6a845c00b4257482468e08d8bc386f4929ee499206142378ba234419/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa", size = 1513009, upload-time = "2023-08-24T09:28:25.636Z" }, + { url = "https://files.pythonhosted.org/packages/50/65/76f303377167d12eb7a9b423d6771b39fe5c4373e4a42f075805b1f581ae/kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c", size = 1444819, upload-time = "2023-08-24T09:28:27.547Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ee/98cdf9dde129551467138b6e18cc1cc901e75ecc7ffb898c6f49609f33b1/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b", size = 1817054, upload-time = "2023-08-24T09:28:28.839Z" }, + { url = "https://files.pythonhosted.org/packages/e6/5b/ab569016ec4abc7b496f6cb8a3ab511372c99feb6a23d948cda97e0db6da/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770", size = 1918613, upload-time = "2023-08-24T09:28:30.351Z" }, + { url = "https://files.pythonhosted.org/packages/93/ac/39b9f99d2474b1ac7af1ddfe5756ddf9b6a8f24c5f3a32cd4c010317fc6b/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0", size = 1872650, upload-time = "2023-08-24T09:28:32.303Z" }, + { url = "https://files.pythonhosted.org/packages/40/5b/be568548266516b114d1776120281ea9236c732fb6032a1f8f3b1e5e921c/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525", size = 1827415, upload-time = "2023-08-24T09:28:34.141Z" }, + { url = "https://files.pythonhosted.org/packages/d4/80/c0c13d2a17a12937a19ef378bf35e94399fd171ed6ec05bcee0f038e1eaf/kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b", size = 1838094, upload-time = "2023-08-24T09:28:35.97Z" }, + { url = "https://files.pythonhosted.org/packages/70/d1/5ab93ee00ca5af708929cc12fbe665b6f1ed4ad58088e70dc00e87e0d107/kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238", size = 46585, upload-time = "2023-08-24T09:28:37.326Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a1/8a9c9be45c642fa12954855d8b3a02d9fd8551165a558835a19508fec2e6/kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276", size = 56095, upload-time = "2023-08-24T09:28:38.325Z" }, + { url = "https://files.pythonhosted.org/packages/2a/eb/9e099ad7c47c279995d2d20474e1821100a5f10f847739bd65b1c1f02442/kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5", size = 127403, upload-time = "2023-08-24T09:28:39.3Z" }, + { url = "https://files.pythonhosted.org/packages/a6/94/695922e71288855fc7cace3bdb52edda9d7e50edba77abb0c9d7abb51e96/kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90", size = 68156, upload-time = "2023-08-24T09:28:40.301Z" }, + { url = "https://files.pythonhosted.org/packages/4a/fe/23d7fa78f7c66086d196406beb1fb2eaf629dd7adc01c3453033303d17fa/kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797", size = 66166, upload-time = "2023-08-24T09:28:41.235Z" }, + { url = "https://files.pythonhosted.org/packages/f1/68/f472bf16c9141bb1bea5c0b8c66c68fc1ccb048efdbd8f0872b92125724e/kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9", size = 1334300, upload-time = "2023-08-24T09:28:42.409Z" }, + { url = "https://files.pythonhosted.org/packages/8d/26/b4569d1f29751fca22ee915b4ebfef5974f4ef239b3335fc072882bd62d9/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437", size = 1426579, upload-time = "2023-08-24T09:28:43.677Z" }, + { url = "https://files.pythonhosted.org/packages/f3/a3/804fc7c8bf233806ec0321c9da35971578620f2ab4fafe67d76100b3ce52/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9", size = 1541360, upload-time = "2023-08-24T09:28:45.939Z" }, + { url = "https://files.pythonhosted.org/packages/07/ef/286e1d26524854f6fbd6540e8364d67a8857d61038ac743e11edc42fe217/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da", size = 1470091, upload-time = "2023-08-24T09:28:47.959Z" }, + { url = "https://files.pythonhosted.org/packages/17/ba/17a706b232308e65f57deeccae503c268292e6a091313f6ce833a23093ea/kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e", size = 1426259, upload-time = "2023-08-24T09:28:49.224Z" }, + { url = "https://files.pythonhosted.org/packages/d0/f3/a0925611c9d6c2f37c5935a39203cadec6883aa914e013b46c84c4c2e641/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8", size = 1847516, upload-time = "2023-08-24T09:28:50.979Z" }, + { url = "https://files.pythonhosted.org/packages/da/85/82d59bb8f7c4c9bb2785138b72462cb1b161668f8230c58bbb28c0403cd5/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d", size = 1946228, upload-time = "2023-08-24T09:28:52.812Z" }, + { url = "https://files.pythonhosted.org/packages/34/3c/6a37f444c0233993881e5db3a6a1775925d4d9d2f2609bb325bb1348ed94/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0", size = 1901716, upload-time = "2023-08-24T09:28:54.115Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7e/180425790efc00adfd47db14e1e341cb4826516982334129012b971121a6/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f", size = 1852871, upload-time = "2023-08-24T09:28:55.433Z" }, + { url = "https://files.pythonhosted.org/packages/1b/9a/13c68b2edb1fa74321e60893a9a5829788e135138e68060cf44e2d92d2c3/kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f", size = 1870265, upload-time = "2023-08-24T09:28:56.855Z" }, + { url = "https://files.pythonhosted.org/packages/9f/0a/fa56a0fdee5da2b4c79899c0f6bd1aefb29d9438c2d66430e78793571c6b/kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac", size = 46649, upload-time = "2023-08-24T09:28:58.021Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/d3c2d4ba2719059a0f12730947bbe1ad5ee8bff89e8c35319dcb2c9ddb4c/kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355", size = 56116, upload-time = "2023-08-24T09:28:58.994Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7a/debbce859be1a2711eb8437818107137192007b88d17b5cfdb556f457b42/kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a", size = 125484, upload-time = "2023-08-24T09:28:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e0/bf8df75ba93b9e035cc6757dd5dcaf63084fdc1c846ae134e818bd7e0f03/kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192", size = 67332, upload-time = "2023-08-24T09:29:01.733Z" }, + { url = "https://files.pythonhosted.org/packages/26/61/58bb691f6880588be3a4801d199bd776032ece07203faf3e4a8b377f7d9b/kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45", size = 64987, upload-time = "2023-08-24T09:29:02.789Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a3/96ac5413068b237c006f54dd8d70114e8756d70e3da7613c5aef20627e22/kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7", size = 1370613, upload-time = "2023-08-24T09:29:03.912Z" }, + { url = "https://files.pythonhosted.org/packages/4d/12/f48539e6e17068b59c7f12f4d6214b973431b8e3ac83af525cafd27cebec/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db", size = 1463183, upload-time = "2023-08-24T09:29:05.244Z" }, + { url = "https://files.pythonhosted.org/packages/f3/70/26c99be8eb034cc8e3f62e0760af1fbdc97a842a7cbc252f7978507d41c2/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff", size = 1581248, upload-time = "2023-08-24T09:29:06.531Z" }, + { url = "https://files.pythonhosted.org/packages/17/f6/f75f20e543639b09b2de7fc864274a5a9b96cda167a6210a1d9d19306b9d/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228", size = 1508815, upload-time = "2023-08-24T09:29:07.867Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d5/bc0f22ac108743062ab703f8d6d71c9c7b077b8839fa358700bfb81770b8/kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16", size = 1466042, upload-time = "2023-08-24T09:29:09.403Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/98142500f21d6838bcab49ec919414a1f0c6d049d21ddadf139124db6a70/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9", size = 1885159, upload-time = "2023-08-24T09:29:10.66Z" }, + { url = "https://files.pythonhosted.org/packages/21/49/a241eff9e0ee013368c1d17957f9d345b0957493c3a43d82ebb558c90b0a/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162", size = 1981694, upload-time = "2023-08-24T09:29:12.469Z" }, + { url = "https://files.pythonhosted.org/packages/90/90/9490c3de4788123041b1d600d64434f1eed809a2ce9f688075a22166b289/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4", size = 1941579, upload-time = "2023-08-24T09:29:13.743Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bb/a0cc488ef2aa92d7d304318c8549d3ec8dfe6dd3c2c67a44e3922b77bc4f/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3", size = 1888168, upload-time = "2023-08-24T09:29:15.097Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e9/9c0de8e45fef3d63f85eed3b1757f9aa511065942866331ef8b99421f433/kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a", size = 1908464, upload-time = "2023-08-24T09:29:16.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/60/4f0fd50b08f5be536ea0cef518ac7255d9dab43ca40f3b93b60e3ddf80dd/kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20", size = 46473, upload-time = "2023-08-24T09:29:17.956Z" }, + { url = "https://files.pythonhosted.org/packages/63/50/2746566bdf4a6a842d117367d05c90cfb87ac04e9e2845aa1fa21f071362/kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9", size = 56004, upload-time = "2023-08-24T09:29:19.329Z" }, ] [[package]] name = "lazy-loader" version = "0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0e/3a/1630a735bfdf9eb857a3b9a53317a1e1658ea97a1b4b39dcb0f71dae81f8/lazy_loader-0.3.tar.gz", hash = "sha256:3b68898e34f5b2a29daaaac172c6555512d0f32074f147e2254e4a6d9d838f37", size = 12268 } +sdist = { url = "https://files.pythonhosted.org/packages/0e/3a/1630a735bfdf9eb857a3b9a53317a1e1658ea97a1b4b39dcb0f71dae81f8/lazy_loader-0.3.tar.gz", hash = "sha256:3b68898e34f5b2a29daaaac172c6555512d0f32074f147e2254e4a6d9d838f37", size = 12268, upload-time = "2023-06-30T21:12:55.362Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/c3/65b3814e155836acacf720e5be3b5757130346670ac454fee29d3eda1381/lazy_loader-0.3-py3-none-any.whl", hash = "sha256:1e9e76ee8631e264c62ce10006718e80b2cfc74340d17d1031e0f84af7478554", size = 9087 }, + { url = "https://files.pythonhosted.org/packages/a1/c3/65b3814e155836acacf720e5be3b5757130346670ac454fee29d3eda1381/lazy_loader-0.3-py3-none-any.whl", hash = "sha256:1e9e76ee8631e264c62ce10006718e80b2cfc74340d17d1031e0f84af7478554", size = 9087, upload-time = "2023-06-30T21:12:51.09Z" }, ] [[package]] name = "locust" -version = "2.39.1" +version = "2.42.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "configargparse" }, @@ -1373,24 +1428,24 @@ dependencies = [ { name = "locust-cloud" }, { name = "msgpack" }, { name = "psutil" }, + { name = "pytest" }, { name = "python-engineio" }, { name = "python-socketio", extra = ["client"] }, { name = "pywin32", marker = "sys_platform == 'win32'" }, { name = "pyzmq" }, { name = "requests" }, - { name = "setuptools" }, { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/c8/10aa5445c404eed389b56877e6714c1787190cc09dd70059ce3765979ec5/locust-2.39.1.tar.gz", hash = "sha256:6bdd19e27edf9a1c84391d6cf6e9a737dfb832be7dfbf39053191ae31b9cc498", size = 1409902 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/69/076f6a1eb4e5813eea864f5a9a5311385c5cc71c46377ed7cec824eca0a1/locust-2.42.5.tar.gz", hash = "sha256:83b8cfc38bd88b3d9daf9790be24239356ccd1160d9b357fa9c7af32907a8860", size = 1418586, upload-time = "2025-11-20T16:45:44.806Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/b3/b2f4b2ca88b1e72eba7be2b2982533b887f8b709d222db78eb9602aa5121/locust-2.39.1-py3-none-any.whl", hash = "sha256:fd5148f2f1a4ed34aee968abc4393674e69d1b5e1b54db50a397f6eb09ce0b04", size = 1428155 }, + { url = "https://files.pythonhosted.org/packages/2d/a9/ce92490466f719e658b5815a4778669c12a4b907ff7ca51e0a94baedf5b2/locust-2.42.5-py3-none-any.whl", hash = "sha256:fa654eb501bf4bad665310ead59c9d7b209d057717795fbbcc977f61af1fdf64", size = 1437168, upload-time = "2025-11-20T16:45:42.855Z" }, ] [[package]] name = "locust-cloud" -version = "1.26.3" +version = "1.29.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "configargparse" }, @@ -1400,9 +1455,9 @@ dependencies = [ { name = "python-socketio", extra = ["client"] }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/84/ad/10b299b134068a4250a9156e6832a717406abe1dfea2482a07ae7bdca8f3/locust_cloud-1.26.3.tar.gz", hash = "sha256:587acfd4d2dee715fb5f0c3c2d922770babf0b7cff7b2927afbb693a9cd193cc", size = 456042 } +sdist = { url = "https://files.pythonhosted.org/packages/35/51/7367b8f13df5fdda001b717574091ea223820be0e2d22caa0e9cfefba556/locust_cloud-1.29.3.tar.gz", hash = "sha256:1b88c1fa8eeb73557f3ab25e16b037283df9a48282be8e91fb4fae84ef7bb367", size = 457304, upload-time = "2025-11-26T13:37:19.318Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/6a/276fc50a9d170e7cbb6715735480cb037abb526639bca85491576e6eee4a/locust_cloud-1.26.3-py3-none-any.whl", hash = "sha256:8cb4b8bb9adcd5b99327bc8ed1d98cf67a29d9d29512651e6e94869de6f1faa8", size = 410023 }, + { url = "https://files.pythonhosted.org/packages/6d/31/4850f0ac5e109007278dbf7d1368565ce43b589aa74e6c6c481c597968db/locust_cloud-1.29.3-py3-none-any.whl", hash = "sha256:1898f09287865b1590d44d5eb71586a40a3895c52bf9bfc826fd6a384fb389d5", size = 413421, upload-time = "2025-11-26T13:37:16.613Z" }, ] [[package]] @@ -1412,47 +1467,47 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] name = "markupsafe" version = "2.1.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/7c/59a3248f411813f8ccba92a55feaac4bf360d29e2ff05ee7d8e1ef2d7dbf/MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", size = 19132 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/7c/59a3248f411813f8ccba92a55feaac4bf360d29e2ff05ee7d8e1ef2d7dbf/MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", size = 19132, upload-time = "2023-06-02T21:43:45.578Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/1d/713d443799d935f4d26a4f1510c9e61b1d288592fb869845e5cc92a1e055/MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", size = 17846 }, - { url = "https://files.pythonhosted.org/packages/f7/9c/86cbd8e0e1d81f0ba420f20539dd459c50537c7751e28102dbfee2b6f28c/MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", size = 13720 }, - { url = "https://files.pythonhosted.org/packages/a6/56/f1d4ee39e898a9e63470cbb7fae1c58cce6874f25f54220b89213a47f273/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", size = 26498 }, - { url = "https://files.pythonhosted.org/packages/12/b3/d9ed2c0971e1435b8a62354b18d3060b66c8cb1d368399ec0b9baa7c0ee5/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", size = 25691 }, - { url = "https://files.pythonhosted.org/packages/bf/b7/c5ba9b7ad9ad21fc4a60df226615cf43ead185d328b77b0327d603d00cc5/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", size = 25366 }, - { url = "https://files.pythonhosted.org/packages/71/61/f5673d7aac2cf7f203859008bb3fc2b25187aa330067c5e9955e5c5ebbab/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", size = 30505 }, - { url = "https://files.pythonhosted.org/packages/47/26/932140621773bfd4df3223fbdd9e78de3477f424f0d2987c313b1cb655ff/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", size = 29616 }, - { url = "https://files.pythonhosted.org/packages/3c/c8/74d13c999cbb49e3460bf769025659a37ef4a8e884de629720ab4e42dcdb/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", size = 29891 }, - { url = "https://files.pythonhosted.org/packages/96/e4/4db3b1abc5a1fe7295aa0683eafd13832084509c3b8236f3faf8dd4eff75/MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", size = 16525 }, - { url = "https://files.pythonhosted.org/packages/84/a8/c4aebb8a14a1d39d5135eb8233a0b95831cdc42c4088358449c3ed657044/MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", size = 17083 }, - { url = "https://files.pythonhosted.org/packages/fe/09/c31503cb8150cf688c1534a7135cc39bb9092f8e0e6369ec73494d16ee0e/MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", size = 17862 }, - { url = "https://files.pythonhosted.org/packages/c0/c7/171f5ac6b065e1425e8fabf4a4dfbeca76fd8070072c6a41bd5c07d90d8b/MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", size = 13738 }, - { url = "https://files.pythonhosted.org/packages/a2/f7/9175ad1b8152092f7c3b78c513c1bdfe9287e0564447d1c2d3d1a2471540/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", size = 28891 }, - { url = "https://files.pythonhosted.org/packages/fe/21/2eff1de472ca6c99ec3993eab11308787b9879af9ca8bbceb4868cf4f2ca/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", size = 28096 }, - { url = "https://files.pythonhosted.org/packages/f4/a0/103f94793c3bf829a18d2415117334ece115aeca56f2df1c47fa02c6dbd6/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", size = 27631 }, - { url = "https://files.pythonhosted.org/packages/43/70/f24470f33b2035b035ef0c0ffebf57006beb2272cf3df068fc5154e04ead/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", size = 33863 }, - { url = "https://files.pythonhosted.org/packages/32/d4/ce98c4ca713d91c4a17c1a184785cc00b9e9c25699d618956c2b9999500a/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", size = 32591 }, - { url = "https://files.pythonhosted.org/packages/bb/82/f88ccb3ca6204a4536cf7af5abdad7c3657adac06ab33699aa67279e0744/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", size = 33186 }, - { url = "https://files.pythonhosted.org/packages/44/53/93405d37bb04a10c43b1bdd6f548097478d494d7eadb4b364e3e1337f0cc/MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", size = 16537 }, - { url = "https://files.pythonhosted.org/packages/be/bb/08b85bc194034efbf572e70c3951549c8eca0ada25363afc154386b5390a/MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", size = 17089 }, - { url = "https://files.pythonhosted.org/packages/89/5a/ee546f2aa73a1d6fcfa24272f356fe06d29acca81e76b8d32ca53e429a2e/MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", size = 17849 }, - { url = "https://files.pythonhosted.org/packages/3a/72/9f683a059bde096776e8acf9aa34cbbba21ddc399861fe3953790d4f2cde/MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", size = 13700 }, - { url = "https://files.pythonhosted.org/packages/9d/78/92f15eb9b1e8f1668a9787ba103cf6f8d19a9efed8150245404836145c24/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11", size = 29319 }, - { url = "https://files.pythonhosted.org/packages/51/94/9a04085114ff2c24f7424dbc890a281d73c5a74ea935dc2e69c66a3bd558/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", size = 28314 }, - { url = "https://files.pythonhosted.org/packages/ec/53/fcb3214bd370185e223b209ce6bb010fb887ea57173ca4f75bd211b24e10/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", size = 27696 }, - { url = "https://files.pythonhosted.org/packages/e7/33/54d29854716725d7826079b8984dd235fac76dab1c32321e555d493e61f5/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", size = 33746 }, - { url = "https://files.pythonhosted.org/packages/11/40/ea7f85e2681d29bc9301c757257de561923924f24de1802d9c3baa396bb4/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", size = 32131 }, - { url = "https://files.pythonhosted.org/packages/41/f1/bc770c37ecd58638c18f8ec85df205dacb818ccf933692082fd93010a4bc/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", size = 32878 }, - { url = "https://files.pythonhosted.org/packages/49/74/bf95630aab0a9ed6a67556cd4e54f6aeb0e74f4cb0fd2f229154873a4be4/MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", size = 16426 }, - { url = "https://files.pythonhosted.org/packages/44/44/dbaf65876e258facd65f586dde158387ab89963e7f2235551afc9c2e24c2/MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", size = 16979 }, + { url = "https://files.pythonhosted.org/packages/20/1d/713d443799d935f4d26a4f1510c9e61b1d288592fb869845e5cc92a1e055/MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", size = 17846, upload-time = "2023-06-02T21:42:33.954Z" }, + { url = "https://files.pythonhosted.org/packages/f7/9c/86cbd8e0e1d81f0ba420f20539dd459c50537c7751e28102dbfee2b6f28c/MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", size = 13720, upload-time = "2023-06-02T21:42:35.102Z" }, + { url = "https://files.pythonhosted.org/packages/a6/56/f1d4ee39e898a9e63470cbb7fae1c58cce6874f25f54220b89213a47f273/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", size = 26498, upload-time = "2023-06-02T21:42:36.608Z" }, + { url = "https://files.pythonhosted.org/packages/12/b3/d9ed2c0971e1435b8a62354b18d3060b66c8cb1d368399ec0b9baa7c0ee5/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", size = 25691, upload-time = "2023-06-02T21:42:37.778Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b7/c5ba9b7ad9ad21fc4a60df226615cf43ead185d328b77b0327d603d00cc5/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", size = 25366, upload-time = "2023-06-02T21:42:39.441Z" }, + { url = "https://files.pythonhosted.org/packages/71/61/f5673d7aac2cf7f203859008bb3fc2b25187aa330067c5e9955e5c5ebbab/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", size = 30505, upload-time = "2023-06-02T21:42:41.088Z" }, + { url = "https://files.pythonhosted.org/packages/47/26/932140621773bfd4df3223fbdd9e78de3477f424f0d2987c313b1cb655ff/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", size = 29616, upload-time = "2023-06-02T21:42:42.273Z" }, + { url = "https://files.pythonhosted.org/packages/3c/c8/74d13c999cbb49e3460bf769025659a37ef4a8e884de629720ab4e42dcdb/MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", size = 29891, upload-time = "2023-06-02T21:42:43.635Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/4db3b1abc5a1fe7295aa0683eafd13832084509c3b8236f3faf8dd4eff75/MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", size = 16525, upload-time = "2023-06-02T21:42:45.271Z" }, + { url = "https://files.pythonhosted.org/packages/84/a8/c4aebb8a14a1d39d5135eb8233a0b95831cdc42c4088358449c3ed657044/MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", size = 17083, upload-time = "2023-06-02T21:42:46.948Z" }, + { url = "https://files.pythonhosted.org/packages/fe/09/c31503cb8150cf688c1534a7135cc39bb9092f8e0e6369ec73494d16ee0e/MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", size = 17862, upload-time = "2023-06-02T21:42:48.569Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/171f5ac6b065e1425e8fabf4a4dfbeca76fd8070072c6a41bd5c07d90d8b/MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", size = 13738, upload-time = "2023-06-02T21:42:49.727Z" }, + { url = "https://files.pythonhosted.org/packages/a2/f7/9175ad1b8152092f7c3b78c513c1bdfe9287e0564447d1c2d3d1a2471540/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", size = 28891, upload-time = "2023-06-02T21:42:51.33Z" }, + { url = "https://files.pythonhosted.org/packages/fe/21/2eff1de472ca6c99ec3993eab11308787b9879af9ca8bbceb4868cf4f2ca/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", size = 28096, upload-time = "2023-06-02T21:42:52.966Z" }, + { url = "https://files.pythonhosted.org/packages/f4/a0/103f94793c3bf829a18d2415117334ece115aeca56f2df1c47fa02c6dbd6/MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", size = 27631, upload-time = "2023-06-02T21:42:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/43/70/f24470f33b2035b035ef0c0ffebf57006beb2272cf3df068fc5154e04ead/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", size = 33863, upload-time = "2023-06-02T21:42:55.777Z" }, + { url = "https://files.pythonhosted.org/packages/32/d4/ce98c4ca713d91c4a17c1a184785cc00b9e9c25699d618956c2b9999500a/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", size = 32591, upload-time = "2023-06-02T21:42:57.415Z" }, + { url = "https://files.pythonhosted.org/packages/bb/82/f88ccb3ca6204a4536cf7af5abdad7c3657adac06ab33699aa67279e0744/MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", size = 33186, upload-time = "2023-06-02T21:42:59.107Z" }, + { url = "https://files.pythonhosted.org/packages/44/53/93405d37bb04a10c43b1bdd6f548097478d494d7eadb4b364e3e1337f0cc/MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", size = 16537, upload-time = "2023-06-02T21:43:00.927Z" }, + { url = "https://files.pythonhosted.org/packages/be/bb/08b85bc194034efbf572e70c3951549c8eca0ada25363afc154386b5390a/MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", size = 17089, upload-time = "2023-06-02T21:43:02.355Z" }, + { url = "https://files.pythonhosted.org/packages/89/5a/ee546f2aa73a1d6fcfa24272f356fe06d29acca81e76b8d32ca53e429a2e/MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", size = 17849, upload-time = "2023-09-07T16:00:43.795Z" }, + { url = "https://files.pythonhosted.org/packages/3a/72/9f683a059bde096776e8acf9aa34cbbba21ddc399861fe3953790d4f2cde/MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", size = 13700, upload-time = "2023-09-07T16:00:45.384Z" }, + { url = "https://files.pythonhosted.org/packages/9d/78/92f15eb9b1e8f1668a9787ba103cf6f8d19a9efed8150245404836145c24/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11", size = 29319, upload-time = "2023-09-07T16:00:46.48Z" }, + { url = "https://files.pythonhosted.org/packages/51/94/9a04085114ff2c24f7424dbc890a281d73c5a74ea935dc2e69c66a3bd558/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", size = 28314, upload-time = "2023-09-07T16:00:47.64Z" }, + { url = "https://files.pythonhosted.org/packages/ec/53/fcb3214bd370185e223b209ce6bb010fb887ea57173ca4f75bd211b24e10/MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", size = 27696, upload-time = "2023-09-07T16:00:48.92Z" }, + { url = "https://files.pythonhosted.org/packages/e7/33/54d29854716725d7826079b8984dd235fac76dab1c32321e555d493e61f5/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", size = 33746, upload-time = "2023-09-07T16:00:50.081Z" }, + { url = "https://files.pythonhosted.org/packages/11/40/ea7f85e2681d29bc9301c757257de561923924f24de1802d9c3baa396bb4/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", size = 32131, upload-time = "2023-09-07T16:00:51.822Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/bc770c37ecd58638c18f8ec85df205dacb818ccf933692082fd93010a4bc/MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", size = 32878, upload-time = "2023-09-07T16:00:53.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/74/bf95630aab0a9ed6a67556cd4e54f6aeb0e74f4cb0fd2f229154873a4be4/MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", size = 16426, upload-time = "2023-09-07T16:00:55.987Z" }, + { url = "https://files.pythonhosted.org/packages/44/44/dbaf65876e258facd65f586dde158387ab89963e7f2235551afc9c2e24c2/MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", size = 16979, upload-time = "2023-09-07T16:00:57.77Z" }, ] [[package]] @@ -1475,26 +1530,26 @@ dependencies = [ { name = "pyparsing", marker = "python_full_version < '3.11'" }, { name = "python-dateutil", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/ab/38a0e94cb01dacb50f06957c2bed1c83b8f9dac6618988a37b2487862944/matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1", size = 35866957 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/ab/38a0e94cb01dacb50f06957c2bed1c83b8f9dac6618988a37b2487862944/matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1", size = 35866957, upload-time = "2023-11-17T21:16:40.15Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/d0/fc5f6796a1956f5b9a33555611d01a3cec038f000c3d70ecb051b1631ac4/matplotlib-3.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7", size = 7590640 }, - { url = "https://files.pythonhosted.org/packages/57/44/007b592809f50883c910db9ec4b81b16dfa0136407250fb581824daabf03/matplotlib-3.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367", size = 7484350 }, - { url = "https://files.pythonhosted.org/packages/01/87/c7b24f3048234fe10184560263be2173311376dc3d1fa329de7f012d6ce5/matplotlib-3.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18", size = 11382388 }, - { url = "https://files.pythonhosted.org/packages/19/e5/a4ea514515f270224435c69359abb7a3d152ed31b9ee3ba5e63017461945/matplotlib-3.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31", size = 11611959 }, - { url = "https://files.pythonhosted.org/packages/09/23/ab5a562c9acb81e351b084bea39f65b153918417fb434619cf5a19f44a55/matplotlib-3.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a", size = 9536938 }, - { url = "https://files.pythonhosted.org/packages/46/37/b5e27ab30ecc0a3694c8a78287b5ef35dad0c3095c144fcc43081170bfd6/matplotlib-3.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a", size = 7643836 }, - { url = "https://files.pythonhosted.org/packages/a9/0d/53afb186adafc7326d093b8333e8a79974c495095771659f4304626c4bc7/matplotlib-3.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63", size = 7593458 }, - { url = "https://files.pythonhosted.org/packages/ce/25/a557ee10ac9dce1300850024707ce1850a6958f1673a9194be878b99d631/matplotlib-3.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8", size = 7486840 }, - { url = "https://files.pythonhosted.org/packages/e7/3d/72712b3895ee180f6e342638a8591c31912fbcc09ce9084cc256da16d0a0/matplotlib-3.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6", size = 11387332 }, - { url = "https://files.pythonhosted.org/packages/92/1a/cd3e0c90d1a763ad90073e13b189b4702f11becf4e71dbbad70a7a149811/matplotlib-3.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788", size = 11616911 }, - { url = "https://files.pythonhosted.org/packages/78/4a/bad239071477305a3758eb4810615e310a113399cddd7682998be9f01e97/matplotlib-3.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0", size = 9549260 }, - { url = "https://files.pythonhosted.org/packages/26/5a/27fd341e4510257789f19a4b4be8bb90d1113b8f176c3dab562b4f21466e/matplotlib-3.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717", size = 7645742 }, - { url = "https://files.pythonhosted.org/packages/e4/1b/864d28d5a72d586ac137f4ca54d5afc8b869720e30d508dbd9adcce4d231/matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627", size = 7590988 }, - { url = "https://files.pythonhosted.org/packages/9a/b0/dd2b60f2dd90fbc21d1d3129c36a453c322d7995d5e3589f5b3c59ee528d/matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4", size = 7483594 }, - { url = "https://files.pythonhosted.org/packages/33/da/9942533ad9f96753bde0e5a5d48eacd6c21de8ea1ad16570e31bda8a017f/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d", size = 11380843 }, - { url = "https://files.pythonhosted.org/packages/fc/52/bfd36eb4745a3b21b3946c2c3a15679b620e14574fe2b98e9451b65ef578/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331", size = 11604608 }, - { url = "https://files.pythonhosted.org/packages/6d/8c/0cdfbf604d4ea3dfa77435176c51e233cc408ad8f3efbf8d2c9f57cbdafb/matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213", size = 9545252 }, - { url = "https://files.pythonhosted.org/packages/2e/51/c77a14869b7eb9d6fb440e811b754fc3950d6868c38ace57d0632b674415/matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630", size = 7645067 }, + { url = "https://files.pythonhosted.org/packages/92/d0/fc5f6796a1956f5b9a33555611d01a3cec038f000c3d70ecb051b1631ac4/matplotlib-3.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7", size = 7590640, upload-time = "2023-11-17T21:17:02.834Z" }, + { url = "https://files.pythonhosted.org/packages/57/44/007b592809f50883c910db9ec4b81b16dfa0136407250fb581824daabf03/matplotlib-3.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367", size = 7484350, upload-time = "2023-11-17T21:17:12.281Z" }, + { url = "https://files.pythonhosted.org/packages/01/87/c7b24f3048234fe10184560263be2173311376dc3d1fa329de7f012d6ce5/matplotlib-3.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18", size = 11382388, upload-time = "2023-11-17T21:17:26.461Z" }, + { url = "https://files.pythonhosted.org/packages/19/e5/a4ea514515f270224435c69359abb7a3d152ed31b9ee3ba5e63017461945/matplotlib-3.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31", size = 11611959, upload-time = "2023-11-17T21:17:40.541Z" }, + { url = "https://files.pythonhosted.org/packages/09/23/ab5a562c9acb81e351b084bea39f65b153918417fb434619cf5a19f44a55/matplotlib-3.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a", size = 9536938, upload-time = "2023-11-17T21:17:49.925Z" }, + { url = "https://files.pythonhosted.org/packages/46/37/b5e27ab30ecc0a3694c8a78287b5ef35dad0c3095c144fcc43081170bfd6/matplotlib-3.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a", size = 7643836, upload-time = "2023-11-17T21:17:58.379Z" }, + { url = "https://files.pythonhosted.org/packages/a9/0d/53afb186adafc7326d093b8333e8a79974c495095771659f4304626c4bc7/matplotlib-3.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63", size = 7593458, upload-time = "2023-11-17T21:18:06.141Z" }, + { url = "https://files.pythonhosted.org/packages/ce/25/a557ee10ac9dce1300850024707ce1850a6958f1673a9194be878b99d631/matplotlib-3.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8", size = 7486840, upload-time = "2023-11-17T21:18:13.706Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/72712b3895ee180f6e342638a8591c31912fbcc09ce9084cc256da16d0a0/matplotlib-3.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6", size = 11387332, upload-time = "2023-11-17T21:18:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/92/1a/cd3e0c90d1a763ad90073e13b189b4702f11becf4e71dbbad70a7a149811/matplotlib-3.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788", size = 11616911, upload-time = "2023-11-17T21:18:35.27Z" }, + { url = "https://files.pythonhosted.org/packages/78/4a/bad239071477305a3758eb4810615e310a113399cddd7682998be9f01e97/matplotlib-3.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0", size = 9549260, upload-time = "2023-11-17T21:18:44.836Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/27fd341e4510257789f19a4b4be8bb90d1113b8f176c3dab562b4f21466e/matplotlib-3.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717", size = 7645742, upload-time = "2023-11-17T21:18:53.448Z" }, + { url = "https://files.pythonhosted.org/packages/e4/1b/864d28d5a72d586ac137f4ca54d5afc8b869720e30d508dbd9adcce4d231/matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627", size = 7590988, upload-time = "2023-11-17T21:19:01.119Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b0/dd2b60f2dd90fbc21d1d3129c36a453c322d7995d5e3589f5b3c59ee528d/matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4", size = 7483594, upload-time = "2023-11-17T21:19:09.865Z" }, + { url = "https://files.pythonhosted.org/packages/33/da/9942533ad9f96753bde0e5a5d48eacd6c21de8ea1ad16570e31bda8a017f/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d", size = 11380843, upload-time = "2023-11-17T21:19:20.46Z" }, + { url = "https://files.pythonhosted.org/packages/fc/52/bfd36eb4745a3b21b3946c2c3a15679b620e14574fe2b98e9451b65ef578/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331", size = 11604608, upload-time = "2023-11-17T21:19:31.363Z" }, + { url = "https://files.pythonhosted.org/packages/6d/8c/0cdfbf604d4ea3dfa77435176c51e233cc408ad8f3efbf8d2c9f57cbdafb/matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213", size = 9545252, upload-time = "2023-11-17T21:19:42.271Z" }, + { url = "https://files.pythonhosted.org/packages/2e/51/c77a14869b7eb9d6fb440e811b754fc3950d6868c38ace57d0632b674415/matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630", size = 7645067, upload-time = "2023-11-17T21:19:50.091Z" }, ] [[package]] @@ -1526,126 +1581,126 @@ dependencies = [ { name = "pyparsing", marker = "python_full_version >= '3.11'" }, { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/91/f2939bb60b7ebf12478b030e0d7f340247390f402b3b189616aad790c366/matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076", size = 34804044 } +sdist = { url = "https://files.pythonhosted.org/packages/43/91/f2939bb60b7ebf12478b030e0d7f340247390f402b3b189616aad790c366/matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076", size = 34804044, upload-time = "2025-07-31T18:09:33.805Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/89/5355cdfe43242cb4d1a64a67cb6831398b665ad90e9702c16247cbd8d5ab/matplotlib-3.10.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5d4773a6d1c106ca05cb5a5515d277a6bb96ed09e5c8fab6b7741b8fcaa62c8f", size = 8229094 }, - { url = "https://files.pythonhosted.org/packages/34/bc/ba802650e1c69650faed261a9df004af4c6f21759d7a1ec67fe972f093b3/matplotlib-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc88af74e7ba27de6cbe6faee916024ea35d895ed3d61ef6f58c4ce97da7185a", size = 8091464 }, - { url = "https://files.pythonhosted.org/packages/ac/64/8d0c8937dee86c286625bddb1902efacc3e22f2b619f5b5a8df29fe5217b/matplotlib-3.10.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:64c4535419d5617f7363dad171a5a59963308e0f3f813c4bed6c9e6e2c131512", size = 8653163 }, - { url = "https://files.pythonhosted.org/packages/11/dc/8dfc0acfbdc2fc2336c72561b7935cfa73db9ca70b875d8d3e1b3a6f371a/matplotlib-3.10.5-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a277033048ab22d34f88a3c5243938cef776493f6201a8742ed5f8b553201343", size = 9490635 }, - { url = "https://files.pythonhosted.org/packages/54/02/e3fdfe0f2e9fb05f3a691d63876639dbf684170fdcf93231e973104153b4/matplotlib-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4a6470a118a2e93022ecc7d3bd16b3114b2004ea2bf014fff875b3bc99b70c6", size = 9539036 }, - { url = "https://files.pythonhosted.org/packages/c1/29/82bf486ff7f4dbedfb11ccc207d0575cbe3be6ea26f75be514252bde3d70/matplotlib-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:7e44cada61bec8833c106547786814dd4a266c1b2964fd25daa3804f1b8d4467", size = 8093529 }, - { url = "https://files.pythonhosted.org/packages/aa/c7/1f2db90a1d43710478bb1e9b57b162852f79234d28e4f48a28cc415aa583/matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf", size = 8239216 }, - { url = "https://files.pythonhosted.org/packages/82/6d/ca6844c77a4f89b1c9e4d481c412e1d1dbabf2aae2cbc5aa2da4a1d6683e/matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf", size = 8102130 }, - { url = "https://files.pythonhosted.org/packages/1d/1e/5e187a30cc673a3e384f3723e5f3c416033c1d8d5da414f82e4e731128ea/matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a", size = 8666471 }, - { url = "https://files.pythonhosted.org/packages/03/c0/95540d584d7d645324db99a845ac194e915ef75011a0d5e19e1b5cee7e69/matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc", size = 9500518 }, - { url = "https://files.pythonhosted.org/packages/ba/2e/e019352099ea58b4169adb9c6e1a2ad0c568c6377c2b677ee1f06de2adc7/matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89", size = 9552372 }, - { url = "https://files.pythonhosted.org/packages/b7/81/3200b792a5e8b354f31f4101ad7834743ad07b6d620259f2059317b25e4d/matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903", size = 8100634 }, - { url = "https://files.pythonhosted.org/packages/52/46/a944f6f0c1f5476a0adfa501969d229ce5ae60cf9a663be0e70361381f89/matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420", size = 7978880 }, - { url = "https://files.pythonhosted.org/packages/66/1e/c6f6bcd882d589410b475ca1fc22e34e34c82adff519caf18f3e6dd9d682/matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2", size = 8253056 }, - { url = "https://files.pythonhosted.org/packages/53/e6/d6f7d1b59413f233793dda14419776f5f443bcccb2dfc84b09f09fe05dbe/matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389", size = 8110131 }, - { url = "https://files.pythonhosted.org/packages/66/2b/bed8a45e74957549197a2ac2e1259671cd80b55ed9e1fe2b5c94d88a9202/matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea", size = 8669603 }, - { url = "https://files.pythonhosted.org/packages/7e/a7/315e9435b10d057f5e52dfc603cd353167ae28bb1a4e033d41540c0067a4/matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468", size = 9508127 }, - { url = "https://files.pythonhosted.org/packages/7f/d9/edcbb1f02ca99165365d2768d517898c22c6040187e2ae2ce7294437c413/matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369", size = 9566926 }, - { url = "https://files.pythonhosted.org/packages/3b/d9/6dd924ad5616c97b7308e6320cf392c466237a82a2040381163b7500510a/matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b", size = 8107599 }, - { url = "https://files.pythonhosted.org/packages/0e/f3/522dc319a50f7b0279fbe74f86f7a3506ce414bc23172098e8d2bdf21894/matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2", size = 7978173 }, - { url = "https://files.pythonhosted.org/packages/8d/05/4f3c1f396075f108515e45cb8d334aff011a922350e502a7472e24c52d77/matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed", size = 8253586 }, - { url = "https://files.pythonhosted.org/packages/2f/2c/e084415775aac7016c3719fe7006cdb462582c6c99ac142f27303c56e243/matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1", size = 8110715 }, - { url = "https://files.pythonhosted.org/packages/52/1b/233e3094b749df16e3e6cd5a44849fd33852e692ad009cf7de00cf58ddf6/matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7", size = 8669397 }, - { url = "https://files.pythonhosted.org/packages/e8/ec/03f9e003a798f907d9f772eed9b7c6a9775d5bd00648b643ebfb88e25414/matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f", size = 9508646 }, - { url = "https://files.pythonhosted.org/packages/91/e7/c051a7a386680c28487bca27d23b02d84f63e3d2a9b4d2fc478e6a42e37e/matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4", size = 9567424 }, - { url = "https://files.pythonhosted.org/packages/36/c2/24302e93ff431b8f4173ee1dd88976c8d80483cadbc5d3d777cef47b3a1c/matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe", size = 8107809 }, - { url = "https://files.pythonhosted.org/packages/0b/33/423ec6a668d375dad825197557ed8fbdb74d62b432c1ed8235465945475f/matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674", size = 7978078 }, - { url = "https://files.pythonhosted.org/packages/51/17/521fc16ec766455c7bb52cc046550cf7652f6765ca8650ff120aa2d197b6/matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c", size = 8295590 }, - { url = "https://files.pythonhosted.org/packages/f8/12/23c28b2c21114c63999bae129fce7fd34515641c517ae48ce7b7dcd33458/matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e", size = 8158518 }, - { url = "https://files.pythonhosted.org/packages/81/f8/aae4eb25e8e7190759f3cb91cbeaa344128159ac92bb6b409e24f8711f78/matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b", size = 8691815 }, - { url = "https://files.pythonhosted.org/packages/d0/ba/450c39ebdd486bd33a359fc17365ade46c6a96bf637bbb0df7824de2886c/matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea", size = 9522814 }, - { url = "https://files.pythonhosted.org/packages/89/11/9c66f6a990e27bb9aa023f7988d2d5809cb98aa39c09cbf20fba75a542ef/matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124", size = 9573917 }, - { url = "https://files.pythonhosted.org/packages/b3/69/8b49394de92569419e5e05e82e83df9b749a0ff550d07631ea96ed2eb35a/matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce", size = 8181034 }, - { url = "https://files.pythonhosted.org/packages/47/23/82dc435bb98a2fc5c20dffcac8f0b083935ac28286413ed8835df40d0baa/matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154", size = 8023337 }, - { url = "https://files.pythonhosted.org/packages/ac/e0/26b6cfde31f5383503ee45dcb7e691d45dadf0b3f54639332b59316a97f8/matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715", size = 8253591 }, - { url = "https://files.pythonhosted.org/packages/c1/89/98488c7ef7ea20ea659af7499628c240a608b337af4be2066d644cfd0a0f/matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837", size = 8112566 }, - { url = "https://files.pythonhosted.org/packages/52/67/42294dfedc82aea55e1a767daf3263aacfb5a125f44ba189e685bab41b6f/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202", size = 9513281 }, - { url = "https://files.pythonhosted.org/packages/e7/68/f258239e0cf34c2cbc816781c7ab6fca768452e6bf1119aedd2bd4a882a3/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb", size = 9780873 }, - { url = "https://files.pythonhosted.org/packages/89/64/f4881554006bd12e4558bd66778bdd15d47b00a1f6c6e8b50f6208eda4b3/matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975", size = 9568954 }, - { url = "https://files.pythonhosted.org/packages/06/f8/42779d39c3f757e1f012f2dda3319a89fb602bd2ef98ce8faf0281f4febd/matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667", size = 8237465 }, - { url = "https://files.pythonhosted.org/packages/cf/f8/153fd06b5160f0cd27c8b9dd797fcc9fb56ac6a0ebf3c1f765b6b68d3c8a/matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516", size = 8108898 }, - { url = "https://files.pythonhosted.org/packages/9a/ee/c4b082a382a225fe0d2a73f1f57cf6f6f132308805b493a54c8641006238/matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e", size = 8295636 }, - { url = "https://files.pythonhosted.org/packages/30/73/2195fa2099718b21a20da82dfc753bf2af58d596b51aefe93e359dd5915a/matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a", size = 8158575 }, - { url = "https://files.pythonhosted.org/packages/f6/e9/a08cdb34618a91fa08f75e6738541da5cacde7c307cea18ff10f0d03fcff/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569", size = 9522815 }, - { url = "https://files.pythonhosted.org/packages/4e/bb/34d8b7e0d1bb6d06ef45db01dfa560d5a67b1c40c0b998ce9ccde934bb09/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012", size = 9783514 }, - { url = "https://files.pythonhosted.org/packages/12/09/d330d1e55dcca2e11b4d304cc5227f52e2512e46828d6249b88e0694176e/matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592", size = 9573932 }, - { url = "https://files.pythonhosted.org/packages/eb/3b/f70258ac729aa004aca673800a53a2b0a26d49ca1df2eaa03289a1c40f81/matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959", size = 8322003 }, - { url = "https://files.pythonhosted.org/packages/5b/60/3601f8ce6d76a7c81c7f25a0e15fde0d6b66226dd187aa6d2838e6374161/matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b", size = 8153849 }, - { url = "https://files.pythonhosted.org/packages/e4/eb/7d4c5de49eb78294e1a8e2be8a6ecff8b433e921b731412a56cd1abd3567/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b5fa2e941f77eb579005fb804026f9d0a1082276118d01cc6051d0d9626eaa7f", size = 8222360 }, - { url = "https://files.pythonhosted.org/packages/16/8a/e435db90927b66b16d69f8f009498775f4469f8de4d14b87856965e58eba/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1fc0d2a3241cdcb9daaca279204a3351ce9df3c0e7e621c7e04ec28aaacaca30", size = 8087462 }, - { url = "https://files.pythonhosted.org/packages/0b/dd/06c0e00064362f5647f318e00b435be2ff76a1bdced97c5eaf8347311fbe/matplotlib-3.10.5-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8dee65cb1424b7dc982fe87895b5613d4e691cc57117e8af840da0148ca6c1d7", size = 8659802 }, - { url = "https://files.pythonhosted.org/packages/dc/d6/e921be4e1a5f7aca5194e1f016cb67ec294548e530013251f630713e456d/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f", size = 8233224 }, - { url = "https://files.pythonhosted.org/packages/ec/74/a2b9b04824b9c349c8f1b2d21d5af43fa7010039427f2b133a034cb09e59/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b", size = 8098539 }, - { url = "https://files.pythonhosted.org/packages/fc/66/cd29ebc7f6c0d2a15d216fb572573e8fc38bd5d6dec3bd9d7d904c0949f7/matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61", size = 8672192 }, + { url = "https://files.pythonhosted.org/packages/d1/89/5355cdfe43242cb4d1a64a67cb6831398b665ad90e9702c16247cbd8d5ab/matplotlib-3.10.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5d4773a6d1c106ca05cb5a5515d277a6bb96ed09e5c8fab6b7741b8fcaa62c8f", size = 8229094, upload-time = "2025-07-31T18:07:36.507Z" }, + { url = "https://files.pythonhosted.org/packages/34/bc/ba802650e1c69650faed261a9df004af4c6f21759d7a1ec67fe972f093b3/matplotlib-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc88af74e7ba27de6cbe6faee916024ea35d895ed3d61ef6f58c4ce97da7185a", size = 8091464, upload-time = "2025-07-31T18:07:38.864Z" }, + { url = "https://files.pythonhosted.org/packages/ac/64/8d0c8937dee86c286625bddb1902efacc3e22f2b619f5b5a8df29fe5217b/matplotlib-3.10.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:64c4535419d5617f7363dad171a5a59963308e0f3f813c4bed6c9e6e2c131512", size = 8653163, upload-time = "2025-07-31T18:07:41.141Z" }, + { url = "https://files.pythonhosted.org/packages/11/dc/8dfc0acfbdc2fc2336c72561b7935cfa73db9ca70b875d8d3e1b3a6f371a/matplotlib-3.10.5-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a277033048ab22d34f88a3c5243938cef776493f6201a8742ed5f8b553201343", size = 9490635, upload-time = "2025-07-31T18:07:42.936Z" }, + { url = "https://files.pythonhosted.org/packages/54/02/e3fdfe0f2e9fb05f3a691d63876639dbf684170fdcf93231e973104153b4/matplotlib-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4a6470a118a2e93022ecc7d3bd16b3114b2004ea2bf014fff875b3bc99b70c6", size = 9539036, upload-time = "2025-07-31T18:07:45.18Z" }, + { url = "https://files.pythonhosted.org/packages/c1/29/82bf486ff7f4dbedfb11ccc207d0575cbe3be6ea26f75be514252bde3d70/matplotlib-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:7e44cada61bec8833c106547786814dd4a266c1b2964fd25daa3804f1b8d4467", size = 8093529, upload-time = "2025-07-31T18:07:49.553Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c7/1f2db90a1d43710478bb1e9b57b162852f79234d28e4f48a28cc415aa583/matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf", size = 8239216, upload-time = "2025-07-31T18:07:51.947Z" }, + { url = "https://files.pythonhosted.org/packages/82/6d/ca6844c77a4f89b1c9e4d481c412e1d1dbabf2aae2cbc5aa2da4a1d6683e/matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf", size = 8102130, upload-time = "2025-07-31T18:07:53.65Z" }, + { url = "https://files.pythonhosted.org/packages/1d/1e/5e187a30cc673a3e384f3723e5f3c416033c1d8d5da414f82e4e731128ea/matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a", size = 8666471, upload-time = "2025-07-31T18:07:55.304Z" }, + { url = "https://files.pythonhosted.org/packages/03/c0/95540d584d7d645324db99a845ac194e915ef75011a0d5e19e1b5cee7e69/matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc", size = 9500518, upload-time = "2025-07-31T18:07:57.199Z" }, + { url = "https://files.pythonhosted.org/packages/ba/2e/e019352099ea58b4169adb9c6e1a2ad0c568c6377c2b677ee1f06de2adc7/matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89", size = 9552372, upload-time = "2025-07-31T18:07:59.41Z" }, + { url = "https://files.pythonhosted.org/packages/b7/81/3200b792a5e8b354f31f4101ad7834743ad07b6d620259f2059317b25e4d/matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903", size = 8100634, upload-time = "2025-07-31T18:08:01.801Z" }, + { url = "https://files.pythonhosted.org/packages/52/46/a944f6f0c1f5476a0adfa501969d229ce5ae60cf9a663be0e70361381f89/matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420", size = 7978880, upload-time = "2025-07-31T18:08:03.407Z" }, + { url = "https://files.pythonhosted.org/packages/66/1e/c6f6bcd882d589410b475ca1fc22e34e34c82adff519caf18f3e6dd9d682/matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2", size = 8253056, upload-time = "2025-07-31T18:08:05.385Z" }, + { url = "https://files.pythonhosted.org/packages/53/e6/d6f7d1b59413f233793dda14419776f5f443bcccb2dfc84b09f09fe05dbe/matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389", size = 8110131, upload-time = "2025-07-31T18:08:07.293Z" }, + { url = "https://files.pythonhosted.org/packages/66/2b/bed8a45e74957549197a2ac2e1259671cd80b55ed9e1fe2b5c94d88a9202/matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea", size = 8669603, upload-time = "2025-07-31T18:08:09.064Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a7/315e9435b10d057f5e52dfc603cd353167ae28bb1a4e033d41540c0067a4/matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468", size = 9508127, upload-time = "2025-07-31T18:08:10.845Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d9/edcbb1f02ca99165365d2768d517898c22c6040187e2ae2ce7294437c413/matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369", size = 9566926, upload-time = "2025-07-31T18:08:13.186Z" }, + { url = "https://files.pythonhosted.org/packages/3b/d9/6dd924ad5616c97b7308e6320cf392c466237a82a2040381163b7500510a/matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b", size = 8107599, upload-time = "2025-07-31T18:08:15.116Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f3/522dc319a50f7b0279fbe74f86f7a3506ce414bc23172098e8d2bdf21894/matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2", size = 7978173, upload-time = "2025-07-31T18:08:21.518Z" }, + { url = "https://files.pythonhosted.org/packages/8d/05/4f3c1f396075f108515e45cb8d334aff011a922350e502a7472e24c52d77/matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed", size = 8253586, upload-time = "2025-07-31T18:08:23.107Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2c/e084415775aac7016c3719fe7006cdb462582c6c99ac142f27303c56e243/matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1", size = 8110715, upload-time = "2025-07-31T18:08:24.675Z" }, + { url = "https://files.pythonhosted.org/packages/52/1b/233e3094b749df16e3e6cd5a44849fd33852e692ad009cf7de00cf58ddf6/matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7", size = 8669397, upload-time = "2025-07-31T18:08:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ec/03f9e003a798f907d9f772eed9b7c6a9775d5bd00648b643ebfb88e25414/matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f", size = 9508646, upload-time = "2025-07-31T18:08:28.848Z" }, + { url = "https://files.pythonhosted.org/packages/91/e7/c051a7a386680c28487bca27d23b02d84f63e3d2a9b4d2fc478e6a42e37e/matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4", size = 9567424, upload-time = "2025-07-31T18:08:30.726Z" }, + { url = "https://files.pythonhosted.org/packages/36/c2/24302e93ff431b8f4173ee1dd88976c8d80483cadbc5d3d777cef47b3a1c/matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe", size = 8107809, upload-time = "2025-07-31T18:08:33.928Z" }, + { url = "https://files.pythonhosted.org/packages/0b/33/423ec6a668d375dad825197557ed8fbdb74d62b432c1ed8235465945475f/matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674", size = 7978078, upload-time = "2025-07-31T18:08:36.764Z" }, + { url = "https://files.pythonhosted.org/packages/51/17/521fc16ec766455c7bb52cc046550cf7652f6765ca8650ff120aa2d197b6/matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c", size = 8295590, upload-time = "2025-07-31T18:08:38.521Z" }, + { url = "https://files.pythonhosted.org/packages/f8/12/23c28b2c21114c63999bae129fce7fd34515641c517ae48ce7b7dcd33458/matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e", size = 8158518, upload-time = "2025-07-31T18:08:40.195Z" }, + { url = "https://files.pythonhosted.org/packages/81/f8/aae4eb25e8e7190759f3cb91cbeaa344128159ac92bb6b409e24f8711f78/matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b", size = 8691815, upload-time = "2025-07-31T18:08:42.238Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ba/450c39ebdd486bd33a359fc17365ade46c6a96bf637bbb0df7824de2886c/matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea", size = 9522814, upload-time = "2025-07-31T18:08:44.914Z" }, + { url = "https://files.pythonhosted.org/packages/89/11/9c66f6a990e27bb9aa023f7988d2d5809cb98aa39c09cbf20fba75a542ef/matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124", size = 9573917, upload-time = "2025-07-31T18:08:47.038Z" }, + { url = "https://files.pythonhosted.org/packages/b3/69/8b49394de92569419e5e05e82e83df9b749a0ff550d07631ea96ed2eb35a/matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce", size = 8181034, upload-time = "2025-07-31T18:08:48.943Z" }, + { url = "https://files.pythonhosted.org/packages/47/23/82dc435bb98a2fc5c20dffcac8f0b083935ac28286413ed8835df40d0baa/matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154", size = 8023337, upload-time = "2025-07-31T18:08:50.791Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e0/26b6cfde31f5383503ee45dcb7e691d45dadf0b3f54639332b59316a97f8/matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715", size = 8253591, upload-time = "2025-07-31T18:08:53.254Z" }, + { url = "https://files.pythonhosted.org/packages/c1/89/98488c7ef7ea20ea659af7499628c240a608b337af4be2066d644cfd0a0f/matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837", size = 8112566, upload-time = "2025-07-31T18:08:55.116Z" }, + { url = "https://files.pythonhosted.org/packages/52/67/42294dfedc82aea55e1a767daf3263aacfb5a125f44ba189e685bab41b6f/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202", size = 9513281, upload-time = "2025-07-31T18:08:56.885Z" }, + { url = "https://files.pythonhosted.org/packages/e7/68/f258239e0cf34c2cbc816781c7ab6fca768452e6bf1119aedd2bd4a882a3/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb", size = 9780873, upload-time = "2025-07-31T18:08:59.241Z" }, + { url = "https://files.pythonhosted.org/packages/89/64/f4881554006bd12e4558bd66778bdd15d47b00a1f6c6e8b50f6208eda4b3/matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975", size = 9568954, upload-time = "2025-07-31T18:09:01.244Z" }, + { url = "https://files.pythonhosted.org/packages/06/f8/42779d39c3f757e1f012f2dda3319a89fb602bd2ef98ce8faf0281f4febd/matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667", size = 8237465, upload-time = "2025-07-31T18:09:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f8/153fd06b5160f0cd27c8b9dd797fcc9fb56ac6a0ebf3c1f765b6b68d3c8a/matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516", size = 8108898, upload-time = "2025-07-31T18:09:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/c4b082a382a225fe0d2a73f1f57cf6f6f132308805b493a54c8641006238/matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e", size = 8295636, upload-time = "2025-07-31T18:09:07.306Z" }, + { url = "https://files.pythonhosted.org/packages/30/73/2195fa2099718b21a20da82dfc753bf2af58d596b51aefe93e359dd5915a/matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a", size = 8158575, upload-time = "2025-07-31T18:09:09.083Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e9/a08cdb34618a91fa08f75e6738541da5cacde7c307cea18ff10f0d03fcff/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569", size = 9522815, upload-time = "2025-07-31T18:09:11.191Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/34d8b7e0d1bb6d06ef45db01dfa560d5a67b1c40c0b998ce9ccde934bb09/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012", size = 9783514, upload-time = "2025-07-31T18:09:13.307Z" }, + { url = "https://files.pythonhosted.org/packages/12/09/d330d1e55dcca2e11b4d304cc5227f52e2512e46828d6249b88e0694176e/matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592", size = 9573932, upload-time = "2025-07-31T18:09:15.335Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3b/f70258ac729aa004aca673800a53a2b0a26d49ca1df2eaa03289a1c40f81/matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959", size = 8322003, upload-time = "2025-07-31T18:09:17.416Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/3601f8ce6d76a7c81c7f25a0e15fde0d6b66226dd187aa6d2838e6374161/matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b", size = 8153849, upload-time = "2025-07-31T18:09:19.673Z" }, + { url = "https://files.pythonhosted.org/packages/e4/eb/7d4c5de49eb78294e1a8e2be8a6ecff8b433e921b731412a56cd1abd3567/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b5fa2e941f77eb579005fb804026f9d0a1082276118d01cc6051d0d9626eaa7f", size = 8222360, upload-time = "2025-07-31T18:09:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/16/8a/e435db90927b66b16d69f8f009498775f4469f8de4d14b87856965e58eba/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1fc0d2a3241cdcb9daaca279204a3351ce9df3c0e7e621c7e04ec28aaacaca30", size = 8087462, upload-time = "2025-07-31T18:09:23.504Z" }, + { url = "https://files.pythonhosted.org/packages/0b/dd/06c0e00064362f5647f318e00b435be2ff76a1bdced97c5eaf8347311fbe/matplotlib-3.10.5-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8dee65cb1424b7dc982fe87895b5613d4e691cc57117e8af840da0148ca6c1d7", size = 8659802, upload-time = "2025-07-31T18:09:25.256Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d6/e921be4e1a5f7aca5194e1f016cb67ec294548e530013251f630713e456d/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f", size = 8233224, upload-time = "2025-07-31T18:09:27.512Z" }, + { url = "https://files.pythonhosted.org/packages/ec/74/a2b9b04824b9c349c8f1b2d21d5af43fa7010039427f2b133a034cb09e59/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b", size = 8098539, upload-time = "2025-07-31T18:09:29.629Z" }, + { url = "https://files.pythonhosted.org/packages/fc/66/cd29ebc7f6c0d2a15d216fb572573e8fc38bd5d6dec3bd9d7d904c0949f7/matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61", size = 8672192, upload-time = "2025-07-31T18:09:31.407Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "mpmath" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] [[package]] name = "msgpack" version = "1.0.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c2/d5/5662032db1571110b5b51647aed4b56dfbd01bfae789fa566a2be1f385d1/msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87", size = 166311 } +sdist = { url = "https://files.pythonhosted.org/packages/c2/d5/5662032db1571110b5b51647aed4b56dfbd01bfae789fa566a2be1f385d1/msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87", size = 166311, upload-time = "2023-09-28T13:20:36.726Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/3a/2e2e902afcd751738e38d88af976fc4010b16e8e821945f4cbf32f75f9c3/msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862", size = 304827 }, - { url = "https://files.pythonhosted.org/packages/86/a6/490792a524a82e855bdf3885ecb73d7b3a0b17744b3cf4a40aea13ceca38/msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329", size = 234959 }, - { url = "https://files.pythonhosted.org/packages/ad/72/d39ed43bfb2ec6968d768318477adb90c474bdc59b2437170c6697ee4115/msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b", size = 231970 }, - { url = "https://files.pythonhosted.org/packages/a2/90/2d769e693654f036acfb462b54dacb3ae345699999897ca34f6bd9534fe9/msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6", size = 522440 }, - { url = "https://files.pythonhosted.org/packages/46/95/d0440400485eab1bf50f1efe5118967b539f3191d994c3dfc220657594cd/msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee", size = 530797 }, - { url = "https://files.pythonhosted.org/packages/76/33/35df717bc095c6e938b3c65ed117b95048abc24d1614427685123fb2f0af/msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d", size = 520372 }, - { url = "https://files.pythonhosted.org/packages/af/d1/abbdd58a43827fbec5d98427a7a535c620890289b9d927154465313d6967/msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d", size = 527287 }, - { url = "https://files.pythonhosted.org/packages/0c/ac/66625b05091b97ca2c7418eb2d2af152f033d969519f9315556a4ed800fe/msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1", size = 560715 }, - { url = "https://files.pythonhosted.org/packages/de/4e/a0e8611f94bac32d2c1c4ad05bb1c0ae61132e3398e0b44a93e6d7830968/msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681", size = 532614 }, - { url = "https://files.pythonhosted.org/packages/9b/07/0b3f089684ca330602b2994248eda2898a7232e4b63882b9271164ef672e/msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9", size = 216340 }, - { url = "https://files.pythonhosted.org/packages/4b/14/c62fbc8dff118f1558e43b9469d56a1f37bbb35febadc3163efaedd01500/msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415", size = 222828 }, - { url = "https://files.pythonhosted.org/packages/f9/b3/309de40dc7406b7f3492332c5ee2b492a593c2a9bb97ea48ebf2f5279999/msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84", size = 305096 }, - { url = "https://files.pythonhosted.org/packages/15/56/a677cd761a2cefb2e3ffe7e684633294dccb161d78e8ea6da9277e45b4a2/msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93", size = 235210 }, - { url = "https://files.pythonhosted.org/packages/f5/4e/1ab4a982cbd90f988e49f849fc1212f2c04a59870c59daabf8950617e2aa/msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8", size = 231952 }, - { url = "https://files.pythonhosted.org/packages/6d/74/bd02044eb628c7361ad2bd8c1a6147af5c6c2bbceb77b3b1da20f4a8a9c5/msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46", size = 549511 }, - { url = "https://files.pythonhosted.org/packages/df/09/dee50913ba5cc047f7fd7162f09453a676e7935c84b3bf3a398e12108677/msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b", size = 557980 }, - { url = "https://files.pythonhosted.org/packages/26/a5/78a7d87f5f8ffe4c32167afa15d4957db649bab4822f909d8d765339bbab/msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e", size = 545547 }, - { url = "https://files.pythonhosted.org/packages/d4/53/698c10913947f97f6fe7faad86a34e6aa1b66cea2df6f99105856bd346d9/msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002", size = 554669 }, - { url = "https://files.pythonhosted.org/packages/f5/3f/9730c6cb574b15d349b80cd8523a7df4b82058528339f952ea1c32ac8a10/msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c", size = 583353 }, - { url = "https://files.pythonhosted.org/packages/4c/bc/dc184d943692671149848438fb3bed3a3de288ce7998cb91bc98f40f201b/msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e", size = 557455 }, - { url = "https://files.pythonhosted.org/packages/cf/7b/1bc69d4a56c8d2f4f2dfbe4722d40344af9a85b6fb3b09cfb350ba6a42f6/msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1", size = 216367 }, - { url = "https://files.pythonhosted.org/packages/b4/3d/c8dd23050eefa3d9b9c5b8329ed3308c2f2f80f65825e9ea4b7fa621cdab/msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82", size = 222860 }, - { url = "https://files.pythonhosted.org/packages/d7/47/20dff6b4512cf3575550c8801bc53fe7d540f4efef9c5c37af51760fcdcf/msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b", size = 305759 }, - { url = "https://files.pythonhosted.org/packages/6f/8a/34f1726d2c9feccec3d946776e9bce8f20ae09d8b91899fc20b296c942af/msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4", size = 235330 }, - { url = "https://files.pythonhosted.org/packages/9c/f6/e64c72577d6953789c3cb051b059a4b56317056b3c65013952338ed8a34e/msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee", size = 232537 }, - { url = "https://files.pythonhosted.org/packages/89/75/1ed3a96e12941873fd957e016cc40c0c178861a872bd45e75b9a188eb422/msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5", size = 546561 }, - { url = "https://files.pythonhosted.org/packages/e5/0a/c6a1390f9c6a31da0fecbbfdb86b1cb39ad302d9e24f9cca3d9e14c364f0/msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672", size = 559009 }, - { url = "https://files.pythonhosted.org/packages/a5/74/99f6077754665613ea1f37b3d91c10129f6976b7721ab4d0973023808e5a/msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075", size = 543882 }, - { url = "https://files.pythonhosted.org/packages/9c/7e/dc0dc8de2bf27743b31691149258f9b1bd4bf3c44c105df3df9b97081cd1/msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba", size = 546949 }, - { url = "https://files.pythonhosted.org/packages/78/61/91bae9474def032f6c333d62889bbeda9e1554c6b123375ceeb1767efd78/msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c", size = 579836 }, - { url = "https://files.pythonhosted.org/packages/5d/4d/d98592099d4f18945f89cf3e634dc0cb128bb33b1b93f85a84173d35e181/msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5", size = 556587 }, - { url = "https://files.pythonhosted.org/packages/5e/44/6556ffe169bf2c0e974e2ea25fb82a7e55ebcf52a81b03a5e01820de5f84/msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9", size = 216509 }, - { url = "https://files.pythonhosted.org/packages/dc/c1/63903f30d51d165e132e5221a2a4a1bbfab7508b68131c871d70bffac78a/msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf", size = 223287 }, + { url = "https://files.pythonhosted.org/packages/41/3a/2e2e902afcd751738e38d88af976fc4010b16e8e821945f4cbf32f75f9c3/msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862", size = 304827, upload-time = "2023-09-28T13:18:30.258Z" }, + { url = "https://files.pythonhosted.org/packages/86/a6/490792a524a82e855bdf3885ecb73d7b3a0b17744b3cf4a40aea13ceca38/msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329", size = 234959, upload-time = "2023-09-28T13:18:32.146Z" }, + { url = "https://files.pythonhosted.org/packages/ad/72/d39ed43bfb2ec6968d768318477adb90c474bdc59b2437170c6697ee4115/msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b", size = 231970, upload-time = "2023-09-28T13:18:34.134Z" }, + { url = "https://files.pythonhosted.org/packages/a2/90/2d769e693654f036acfb462b54dacb3ae345699999897ca34f6bd9534fe9/msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6", size = 522440, upload-time = "2023-09-28T13:18:35.866Z" }, + { url = "https://files.pythonhosted.org/packages/46/95/d0440400485eab1bf50f1efe5118967b539f3191d994c3dfc220657594cd/msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee", size = 530797, upload-time = "2023-09-28T13:18:37.653Z" }, + { url = "https://files.pythonhosted.org/packages/76/33/35df717bc095c6e938b3c65ed117b95048abc24d1614427685123fb2f0af/msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d", size = 520372, upload-time = "2023-09-28T13:18:39.685Z" }, + { url = "https://files.pythonhosted.org/packages/af/d1/abbdd58a43827fbec5d98427a7a535c620890289b9d927154465313d6967/msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d", size = 527287, upload-time = "2023-09-28T13:18:41.051Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ac/66625b05091b97ca2c7418eb2d2af152f033d969519f9315556a4ed800fe/msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1", size = 560715, upload-time = "2023-09-28T13:18:42.883Z" }, + { url = "https://files.pythonhosted.org/packages/de/4e/a0e8611f94bac32d2c1c4ad05bb1c0ae61132e3398e0b44a93e6d7830968/msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681", size = 532614, upload-time = "2023-09-28T13:18:44.679Z" }, + { url = "https://files.pythonhosted.org/packages/9b/07/0b3f089684ca330602b2994248eda2898a7232e4b63882b9271164ef672e/msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9", size = 216340, upload-time = "2023-09-28T13:18:46.588Z" }, + { url = "https://files.pythonhosted.org/packages/4b/14/c62fbc8dff118f1558e43b9469d56a1f37bbb35febadc3163efaedd01500/msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415", size = 222828, upload-time = "2023-09-28T13:18:47.875Z" }, + { url = "https://files.pythonhosted.org/packages/f9/b3/309de40dc7406b7f3492332c5ee2b492a593c2a9bb97ea48ebf2f5279999/msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84", size = 305096, upload-time = "2023-09-28T13:18:49.678Z" }, + { url = "https://files.pythonhosted.org/packages/15/56/a677cd761a2cefb2e3ffe7e684633294dccb161d78e8ea6da9277e45b4a2/msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93", size = 235210, upload-time = "2023-09-28T13:18:51.039Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4e/1ab4a982cbd90f988e49f849fc1212f2c04a59870c59daabf8950617e2aa/msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8", size = 231952, upload-time = "2023-09-28T13:18:52.871Z" }, + { url = "https://files.pythonhosted.org/packages/6d/74/bd02044eb628c7361ad2bd8c1a6147af5c6c2bbceb77b3b1da20f4a8a9c5/msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46", size = 549511, upload-time = "2023-09-28T13:18:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/df/09/dee50913ba5cc047f7fd7162f09453a676e7935c84b3bf3a398e12108677/msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b", size = 557980, upload-time = "2023-09-28T13:18:56.058Z" }, + { url = "https://files.pythonhosted.org/packages/26/a5/78a7d87f5f8ffe4c32167afa15d4957db649bab4822f909d8d765339bbab/msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e", size = 545547, upload-time = "2023-09-28T13:18:57.396Z" }, + { url = "https://files.pythonhosted.org/packages/d4/53/698c10913947f97f6fe7faad86a34e6aa1b66cea2df6f99105856bd346d9/msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002", size = 554669, upload-time = "2023-09-28T13:18:58.957Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3f/9730c6cb574b15d349b80cd8523a7df4b82058528339f952ea1c32ac8a10/msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c", size = 583353, upload-time = "2023-09-28T13:19:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/4c/bc/dc184d943692671149848438fb3bed3a3de288ce7998cb91bc98f40f201b/msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e", size = 557455, upload-time = "2023-09-28T13:19:03.201Z" }, + { url = "https://files.pythonhosted.org/packages/cf/7b/1bc69d4a56c8d2f4f2dfbe4722d40344af9a85b6fb3b09cfb350ba6a42f6/msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1", size = 216367, upload-time = "2023-09-28T13:19:04.554Z" }, + { url = "https://files.pythonhosted.org/packages/b4/3d/c8dd23050eefa3d9b9c5b8329ed3308c2f2f80f65825e9ea4b7fa621cdab/msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82", size = 222860, upload-time = "2023-09-28T13:19:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d7/47/20dff6b4512cf3575550c8801bc53fe7d540f4efef9c5c37af51760fcdcf/msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b", size = 305759, upload-time = "2023-09-28T13:19:08.148Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8a/34f1726d2c9feccec3d946776e9bce8f20ae09d8b91899fc20b296c942af/msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4", size = 235330, upload-time = "2023-09-28T13:19:09.417Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f6/e64c72577d6953789c3cb051b059a4b56317056b3c65013952338ed8a34e/msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee", size = 232537, upload-time = "2023-09-28T13:19:10.898Z" }, + { url = "https://files.pythonhosted.org/packages/89/75/1ed3a96e12941873fd957e016cc40c0c178861a872bd45e75b9a188eb422/msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5", size = 546561, upload-time = "2023-09-28T13:19:12.779Z" }, + { url = "https://files.pythonhosted.org/packages/e5/0a/c6a1390f9c6a31da0fecbbfdb86b1cb39ad302d9e24f9cca3d9e14c364f0/msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672", size = 559009, upload-time = "2023-09-28T13:19:14.373Z" }, + { url = "https://files.pythonhosted.org/packages/a5/74/99f6077754665613ea1f37b3d91c10129f6976b7721ab4d0973023808e5a/msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075", size = 543882, upload-time = "2023-09-28T13:19:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/9c/7e/dc0dc8de2bf27743b31691149258f9b1bd4bf3c44c105df3df9b97081cd1/msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba", size = 546949, upload-time = "2023-09-28T13:19:18.114Z" }, + { url = "https://files.pythonhosted.org/packages/78/61/91bae9474def032f6c333d62889bbeda9e1554c6b123375ceeb1767efd78/msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c", size = 579836, upload-time = "2023-09-28T13:19:19.729Z" }, + { url = "https://files.pythonhosted.org/packages/5d/4d/d98592099d4f18945f89cf3e634dc0cb128bb33b1b93f85a84173d35e181/msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5", size = 556587, upload-time = "2023-09-28T13:19:21.666Z" }, + { url = "https://files.pythonhosted.org/packages/5e/44/6556ffe169bf2c0e974e2ea25fb82a7e55ebcf52a81b03a5e01820de5f84/msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9", size = 216509, upload-time = "2023-09-28T13:19:23.161Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c1/63903f30d51d165e132e5221a2a4a1bbfab7508b68131c871d70bffac78a/msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf", size = 223287, upload-time = "2023-09-28T13:19:25.097Z" }, ] [[package]] name = "mypy" -version = "1.17.1" +version = "1.18.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, @@ -1653,89 +1708,89 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/22/ea637422dedf0bf36f3ef238eab4e455e2a0dcc3082b5cc067615347ab8e/mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01", size = 3352570 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b", size = 3448846, upload-time = "2025-09-19T00:11:10.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/a9/3d7aa83955617cdf02f94e50aab5c830d205cfa4320cf124ff64acce3a8e/mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972", size = 11003299 }, - { url = "https://files.pythonhosted.org/packages/83/e8/72e62ff837dd5caaac2b4a5c07ce769c8e808a00a65e5d8f94ea9c6f20ab/mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7", size = 10125451 }, - { url = "https://files.pythonhosted.org/packages/7d/10/f3f3543f6448db11881776f26a0ed079865926b0c841818ee22de2c6bbab/mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df", size = 11916211 }, - { url = "https://files.pythonhosted.org/packages/06/bf/63e83ed551282d67bb3f7fea2cd5561b08d2bb6eb287c096539feb5ddbc5/mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390", size = 12652687 }, - { url = "https://files.pythonhosted.org/packages/69/66/68f2eeef11facf597143e85b694a161868b3b006a5fbad50e09ea117ef24/mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94", size = 12896322 }, - { url = "https://files.pythonhosted.org/packages/a3/87/8e3e9c2c8bd0d7e071a89c71be28ad088aaecbadf0454f46a540bda7bca6/mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b", size = 9507962 }, - { url = "https://files.pythonhosted.org/packages/46/cf/eadc80c4e0a70db1c08921dcc220357ba8ab2faecb4392e3cebeb10edbfa/mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58", size = 10921009 }, - { url = "https://files.pythonhosted.org/packages/5d/c1/c869d8c067829ad30d9bdae051046561552516cfb3a14f7f0347b7d973ee/mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5", size = 10047482 }, - { url = "https://files.pythonhosted.org/packages/98/b9/803672bab3fe03cee2e14786ca056efda4bb511ea02dadcedde6176d06d0/mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd", size = 11832883 }, - { url = "https://files.pythonhosted.org/packages/88/fb/fcdac695beca66800918c18697b48833a9a6701de288452b6715a98cfee1/mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b", size = 12566215 }, - { url = "https://files.pythonhosted.org/packages/7f/37/a932da3d3dace99ee8eb2043b6ab03b6768c36eb29a02f98f46c18c0da0e/mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5", size = 12751956 }, - { url = "https://files.pythonhosted.org/packages/8c/cf/6438a429e0f2f5cab8bc83e53dbebfa666476f40ee322e13cac5e64b79e7/mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b", size = 9507307 }, - { url = "https://files.pythonhosted.org/packages/17/a2/7034d0d61af8098ec47902108553122baa0f438df8a713be860f7407c9e6/mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb", size = 11086295 }, - { url = "https://files.pythonhosted.org/packages/14/1f/19e7e44b594d4b12f6ba8064dbe136505cec813549ca3e5191e40b1d3cc2/mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403", size = 10112355 }, - { url = "https://files.pythonhosted.org/packages/5b/69/baa33927e29e6b4c55d798a9d44db5d394072eef2bdc18c3e2048c9ed1e9/mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056", size = 11875285 }, - { url = "https://files.pythonhosted.org/packages/90/13/f3a89c76b0a41e19490b01e7069713a30949d9a6c147289ee1521bcea245/mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341", size = 12737895 }, - { url = "https://files.pythonhosted.org/packages/23/a1/c4ee79ac484241301564072e6476c5a5be2590bc2e7bfd28220033d2ef8f/mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb", size = 12931025 }, - { url = "https://files.pythonhosted.org/packages/89/b8/7409477be7919a0608900e6320b155c72caab4fef46427c5cc75f85edadd/mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19", size = 9584664 }, - { url = "https://files.pythonhosted.org/packages/5b/82/aec2fc9b9b149f372850291827537a508d6c4d3664b1750a324b91f71355/mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7", size = 11075338 }, - { url = "https://files.pythonhosted.org/packages/07/ac/ee93fbde9d2242657128af8c86f5d917cd2887584cf948a8e3663d0cd737/mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81", size = 10113066 }, - { url = "https://files.pythonhosted.org/packages/5a/68/946a1e0be93f17f7caa56c45844ec691ca153ee8b62f21eddda336a2d203/mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6", size = 11875473 }, - { url = "https://files.pythonhosted.org/packages/9f/0f/478b4dce1cb4f43cf0f0d00fba3030b21ca04a01b74d1cd272a528cf446f/mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849", size = 12744296 }, - { url = "https://files.pythonhosted.org/packages/ca/70/afa5850176379d1b303f992a828de95fc14487429a7139a4e0bdd17a8279/mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14", size = 12914657 }, - { url = "https://files.pythonhosted.org/packages/53/f9/4a83e1c856a3d9c8f6edaa4749a4864ee98486e9b9dbfbc93842891029c2/mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a", size = 9593320 }, - { url = "https://files.pythonhosted.org/packages/38/56/79c2fac86da57c7d8c48622a05873eaab40b905096c33597462713f5af90/mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733", size = 11040037 }, - { url = "https://files.pythonhosted.org/packages/4d/c3/adabe6ff53638e3cad19e3547268482408323b1e68bf082c9119000cd049/mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd", size = 10131550 }, - { url = "https://files.pythonhosted.org/packages/b8/c5/2e234c22c3bdeb23a7817af57a58865a39753bde52c74e2c661ee0cfc640/mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0", size = 11872963 }, - { url = "https://files.pythonhosted.org/packages/ab/26/c13c130f35ca8caa5f2ceab68a247775648fdcd6c9a18f158825f2bc2410/mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a", size = 12710189 }, - { url = "https://files.pythonhosted.org/packages/82/df/c7d79d09f6de8383fe800521d066d877e54d30b4fb94281c262be2df84ef/mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91", size = 12900322 }, - { url = "https://files.pythonhosted.org/packages/b8/98/3d5a48978b4f708c55ae832619addc66d677f6dc59f3ebad71bae8285ca6/mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed", size = 9751879 }, - { url = "https://files.pythonhosted.org/packages/1d/f3/8fcd2af0f5b806f6cf463efaffd3c9548a28f84220493ecd38d127b6b66d/mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9", size = 2283411 }, + { url = "https://files.pythonhosted.org/packages/03/6f/657961a0743cff32e6c0611b63ff1c1970a0b482ace35b069203bf705187/mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c", size = 12807973, upload-time = "2025-09-19T00:10:35.282Z" }, + { url = "https://files.pythonhosted.org/packages/10/e9/420822d4f661f13ca8900f5fa239b40ee3be8b62b32f3357df9a3045a08b/mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e", size = 11896527, upload-time = "2025-09-19T00:10:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/aa/73/a05b2bbaa7005f4642fcfe40fb73f2b4fb6bb44229bd585b5878e9a87ef8/mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b", size = 12507004, upload-time = "2025-09-19T00:11:05.411Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/f6e4b9f0d031c11ccbd6f17da26564f3a0f3c4155af344006434b0a05a9d/mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66", size = 13245947, upload-time = "2025-09-19T00:10:46.923Z" }, + { url = "https://files.pythonhosted.org/packages/d7/97/19727e7499bfa1ae0773d06afd30ac66a58ed7437d940c70548634b24185/mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428", size = 13499217, upload-time = "2025-09-19T00:09:39.472Z" }, + { url = "https://files.pythonhosted.org/packages/9f/4f/90dc8c15c1441bf31cf0f9918bb077e452618708199e530f4cbd5cede6ff/mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed", size = 9766753, upload-time = "2025-09-19T00:10:49.161Z" }, + { url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f", size = 12731198, upload-time = "2025-09-19T00:09:44.857Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341", size = 11817879, upload-time = "2025-09-19T00:09:47.131Z" }, + { url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d", size = 12427292, upload-time = "2025-09-19T00:10:22.472Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86", size = 13163750, upload-time = "2025-09-19T00:09:51.472Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37", size = 13351827, upload-time = "2025-09-19T00:09:58.311Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8", size = 9757983, upload-time = "2025-09-19T00:10:09.071Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34", size = 12908273, upload-time = "2025-09-19T00:10:58.321Z" }, + { url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764", size = 11920910, upload-time = "2025-09-19T00:10:20.043Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893", size = 12465585, upload-time = "2025-09-19T00:10:33.005Z" }, + { url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914", size = 13348562, upload-time = "2025-09-19T00:10:11.51Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8", size = 13533296, upload-time = "2025-09-19T00:10:06.568Z" }, + { url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074", size = 9828828, upload-time = "2025-09-19T00:10:28.203Z" }, + { url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc", size = 12898728, upload-time = "2025-09-19T00:10:01.33Z" }, + { url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e", size = 11910758, upload-time = "2025-09-19T00:10:42.607Z" }, + { url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986", size = 12475342, upload-time = "2025-09-19T00:11:00.371Z" }, + { url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d", size = 13338709, upload-time = "2025-09-19T00:11:03.358Z" }, + { url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba", size = 13529806, upload-time = "2025-09-19T00:10:26.073Z" }, + { url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544", size = 9833262, upload-time = "2025-09-19T00:10:40.035Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce", size = 12893775, upload-time = "2025-09-19T00:10:03.814Z" }, + { url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d", size = 11936852, upload-time = "2025-09-19T00:10:51.631Z" }, + { url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c", size = 12480242, upload-time = "2025-09-19T00:11:07.955Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" }, + { url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" }, + { url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" }, ] [[package]] name = "mypy-extensions" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, ] [[package]] name = "networkx" version = "3.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/80/a84676339aaae2f1cfdf9f418701dd634aef9cc76f708ef55c36ff39c3ca/networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", size = 2073928 } +sdist = { url = "https://files.pythonhosted.org/packages/c4/80/a84676339aaae2f1cfdf9f418701dd634aef9cc76f708ef55c36ff39c3ca/networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", size = 2073928, upload-time = "2023-10-28T08:41:39.364Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772 }, + { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772, upload-time = "2023-10-28T08:41:36.945Z" }, ] [[package]] name = "numpy" version = "1.26.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } +sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468 }, - { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411 }, - { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016 }, - { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889 }, - { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746 }, - { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620 }, - { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659 }, - { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905 }, - { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554 }, - { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127 }, - { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994 }, - { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005 }, - { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297 }, - { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567 }, - { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812 }, - { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913 }, - { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 }, - { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 }, - { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 }, - { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 }, - { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 }, - { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 }, - { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 }, - { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, + { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468, upload-time = "2024-02-05T23:48:01.194Z" }, + { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411, upload-time = "2024-02-05T23:48:29.038Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016, upload-time = "2024-02-05T23:48:54.098Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889, upload-time = "2024-02-05T23:49:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746, upload-time = "2024-02-05T23:49:51.983Z" }, + { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620, upload-time = "2024-02-05T23:50:22.515Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659, upload-time = "2024-02-05T23:50:35.834Z" }, + { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905, upload-time = "2024-02-05T23:51:03.701Z" }, + { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554, upload-time = "2024-02-05T23:51:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127, upload-time = "2024-02-05T23:52:15.314Z" }, + { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994, upload-time = "2024-02-05T23:52:47.569Z" }, + { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005, upload-time = "2024-02-05T23:53:15.637Z" }, + { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297, upload-time = "2024-02-05T23:53:42.16Z" }, + { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, + { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, ] [[package]] @@ -1746,9 +1801,9 @@ dependencies = [ { name = "antlr4-python3-runtime" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/48/6388f1bb9da707110532cb70ec4d2822858ddfb44f1cdf1233c20a80ea4b/omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7", size = 3298120 } +sdist = { url = "https://files.pythonhosted.org/packages/09/48/6388f1bb9da707110532cb70ec4d2822858ddfb44f1cdf1233c20a80ea4b/omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7", size = 3298120, upload-time = "2022-12-08T20:59:22.753Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500 }, + { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, ] [[package]] @@ -1759,31 +1814,31 @@ dependencies = [ { name = "numpy" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/fe/0978403c8d710ece2f34006367e78de80410743fe0e7680c8f33f2dab20d/onnx-1.16.0.tar.gz", hash = "sha256:237c6987c6c59d9f44b6136f5819af79574f8d96a760a1fa843bede11f3822f7", size = 12303017 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/fe/0978403c8d710ece2f34006367e78de80410743fe0e7680c8f33f2dab20d/onnx-1.16.0.tar.gz", hash = "sha256:237c6987c6c59d9f44b6136f5819af79574f8d96a760a1fa843bede11f3822f7", size = 12303017, upload-time = "2024-03-25T15:33:46.091Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/0b/f4705e4a3fa6fd0de971302fdae17ad176b024eca8c24360f0e37c00f9df/onnx-1.16.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:9eadbdce25b19d6216f426d6d99b8bc877a65ed92cbef9707751c6669190ba4f", size = 16514483 }, - { url = "https://files.pythonhosted.org/packages/b8/1c/50310a559857951fc6e069cf5d89deebe34287997d1c5928bca435456f62/onnx-1.16.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:034ae21a2aaa2e9c14119a840d2926d213c27aad29e5e3edaa30145a745048e1", size = 15012939 }, - { url = "https://files.pythonhosted.org/packages/ef/6e/96be6692ebcd8da568084d753f386ce08efa1f99b216f346ee281edd6cc3/onnx-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec22a43d74eb1f2303373e2fbe7fbcaa45fb225f4eb146edfed1356ada7a9aea", size = 15791856 }, - { url = "https://files.pythonhosted.org/packages/49/5f/d8e1a24247f506a77cbe22341c72ca91bea3b468c5d6bca2047d885ea3c6/onnx-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298f28a2b5ac09145fa958513d3d1e6b349ccf86a877dbdcccad57713fe360b3", size = 15922279 }, - { url = "https://files.pythonhosted.org/packages/cb/14/562e4ac22cdf41f4465e3b114ef1a9467d513eeff0b9c2285c2da5db6ed1/onnx-1.16.0-cp310-cp310-win32.whl", hash = "sha256:66300197b52beca08bc6262d43c103289c5d45fde43fb51922ed1eb83658cf0c", size = 14335703 }, - { url = "https://files.pythonhosted.org/packages/3b/e2/471ff83b3862967791d67f630000afce038756afbdf0665a3d767677c851/onnx-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:ae0029f5e47bf70a1a62e7f88c80bca4ef39b844a89910039184221775df5e43", size = 14435099 }, - { url = "https://files.pythonhosted.org/packages/a4/b8/7accf3f93eee498711f0b7f07f6e93906e031622473e85ce9cd3578f6a92/onnx-1.16.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:f51179d4af3372b4f3800c558d204b592c61e4b4a18b8f61e0eea7f46211221a", size = 16514376 }, - { url = "https://files.pythonhosted.org/packages/cc/24/a328236b594d5fea23f70a3a8139e730cb43334f0b24693831c47c9064f0/onnx-1.16.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5202559070afec5144332db216c20f2fff8323cf7f6512b0ca11b215eacc5bf3", size = 15012839 }, - { url = "https://files.pythonhosted.org/packages/80/12/57187bab3f830a47fa65eafe4fbaef01dfdf5042cf82a41fa440fab68766/onnx-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77579e7c15b4df39d29465b216639a5f9b74026bdd9e4b6306cd19a32dcfe67c", size = 15791944 }, - { url = "https://files.pythonhosted.org/packages/df/48/63f68b65d041aedffab41eea930563ca52aab70dbaa7d4820501618c1a70/onnx-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e60ca76ac24b65c25860d0f2d2cdd96d6320d062a01dd8ce87c5743603789b8", size = 15922450 }, - { url = "https://files.pythonhosted.org/packages/08/1b/4bdf4534f5ff08973725ba5409f95bbf64e2789cd20be615880dae689973/onnx-1.16.0-cp311-cp311-win32.whl", hash = "sha256:81b4ee01bc554e8a2b11ac6439882508a5377a1c6b452acd69a1eebb83571117", size = 14335808 }, - { url = "https://files.pythonhosted.org/packages/aa/d0/0514d02d2e84e7bb48a105877eae4065e54d7dabb60d0b60214fe2677346/onnx-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:7449241e70b847b9c3eb8dae622df8c1b456d11032a9d7e26e0ee8a698d5bf86", size = 14434905 }, - { url = "https://files.pythonhosted.org/packages/42/87/577adadda30ee08041e81ef02a331ca9d1a8df93a2e4c4c53ec56fbbc2ac/onnx-1.16.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:03a627488b1a9975d95d6a55582af3e14c7f3bb87444725b999935ddd271d352", size = 16516304 }, - { url = "https://files.pythonhosted.org/packages/e3/1b/6e1ea37e081cc49a28f0e4d3830b4c8525081354cf9f5529c6c92268fc77/onnx-1.16.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c392faeabd9283ee344ccb4b067d1fea9dfc614fa1f0de7c47589efd79e15e78", size = 15016538 }, - { url = "https://files.pythonhosted.org/packages/6d/07/f8fefd5eb0984be42ef677f0b7db7527edc4529224a34a3c31f7b12ec80d/onnx-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0efeb46985de08f0efe758cb54ad3457e821a05c2eaf5ba2ccb8cd1602c08084", size = 15790415 }, - { url = "https://files.pythonhosted.org/packages/11/71/c219ce6d4b5205c77405af7f2de2511ad4eeffbfeb77a422151e893de0ea/onnx-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf14a3d32234f23e44abb73a755cb96a423fac7f004e8f046f36b10214151ee", size = 15922224 }, - { url = "https://files.pythonhosted.org/packages/8e/a4/554a6e5741b42406c5b1970d04685d7f2012019d4178408ed4b3ec953033/onnx-1.16.0-cp312-cp312-win32.whl", hash = "sha256:62a2e27ae8ba5fc9b4a2620301446a517b5ffaaf8566611de7a7c2160f5bcf4c", size = 14336234 }, - { url = "https://files.pythonhosted.org/packages/e9/a1/8aecec497010ad34e7656408df1868d94483c5c56bc991f4088c06150896/onnx-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:3e0860fea94efde777e81a6f68f65761ed5e5f3adea2e050d7fbe373a9ae05b3", size = 14436591 }, + { url = "https://files.pythonhosted.org/packages/c8/0b/f4705e4a3fa6fd0de971302fdae17ad176b024eca8c24360f0e37c00f9df/onnx-1.16.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:9eadbdce25b19d6216f426d6d99b8bc877a65ed92cbef9707751c6669190ba4f", size = 16514483, upload-time = "2024-03-25T15:25:07.947Z" }, + { url = "https://files.pythonhosted.org/packages/b8/1c/50310a559857951fc6e069cf5d89deebe34287997d1c5928bca435456f62/onnx-1.16.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:034ae21a2aaa2e9c14119a840d2926d213c27aad29e5e3edaa30145a745048e1", size = 15012939, upload-time = "2024-03-25T15:25:11.632Z" }, + { url = "https://files.pythonhosted.org/packages/ef/6e/96be6692ebcd8da568084d753f386ce08efa1f99b216f346ee281edd6cc3/onnx-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec22a43d74eb1f2303373e2fbe7fbcaa45fb225f4eb146edfed1356ada7a9aea", size = 15791856, upload-time = "2024-03-25T15:25:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/49/5f/d8e1a24247f506a77cbe22341c72ca91bea3b468c5d6bca2047d885ea3c6/onnx-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298f28a2b5ac09145fa958513d3d1e6b349ccf86a877dbdcccad57713fe360b3", size = 15922279, upload-time = "2024-03-25T15:25:18.939Z" }, + { url = "https://files.pythonhosted.org/packages/cb/14/562e4ac22cdf41f4465e3b114ef1a9467d513eeff0b9c2285c2da5db6ed1/onnx-1.16.0-cp310-cp310-win32.whl", hash = "sha256:66300197b52beca08bc6262d43c103289c5d45fde43fb51922ed1eb83658cf0c", size = 14335703, upload-time = "2024-03-25T15:25:22.611Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e2/471ff83b3862967791d67f630000afce038756afbdf0665a3d767677c851/onnx-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:ae0029f5e47bf70a1a62e7f88c80bca4ef39b844a89910039184221775df5e43", size = 14435099, upload-time = "2024-03-25T15:25:25.05Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b8/7accf3f93eee498711f0b7f07f6e93906e031622473e85ce9cd3578f6a92/onnx-1.16.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:f51179d4af3372b4f3800c558d204b592c61e4b4a18b8f61e0eea7f46211221a", size = 16514376, upload-time = "2024-03-25T15:25:27.899Z" }, + { url = "https://files.pythonhosted.org/packages/cc/24/a328236b594d5fea23f70a3a8139e730cb43334f0b24693831c47c9064f0/onnx-1.16.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5202559070afec5144332db216c20f2fff8323cf7f6512b0ca11b215eacc5bf3", size = 15012839, upload-time = "2024-03-25T15:25:31.16Z" }, + { url = "https://files.pythonhosted.org/packages/80/12/57187bab3f830a47fa65eafe4fbaef01dfdf5042cf82a41fa440fab68766/onnx-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77579e7c15b4df39d29465b216639a5f9b74026bdd9e4b6306cd19a32dcfe67c", size = 15791944, upload-time = "2024-03-25T15:25:34.778Z" }, + { url = "https://files.pythonhosted.org/packages/df/48/63f68b65d041aedffab41eea930563ca52aab70dbaa7d4820501618c1a70/onnx-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e60ca76ac24b65c25860d0f2d2cdd96d6320d062a01dd8ce87c5743603789b8", size = 15922450, upload-time = "2024-03-25T15:25:37.983Z" }, + { url = "https://files.pythonhosted.org/packages/08/1b/4bdf4534f5ff08973725ba5409f95bbf64e2789cd20be615880dae689973/onnx-1.16.0-cp311-cp311-win32.whl", hash = "sha256:81b4ee01bc554e8a2b11ac6439882508a5377a1c6b452acd69a1eebb83571117", size = 14335808, upload-time = "2024-03-25T15:25:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d0/0514d02d2e84e7bb48a105877eae4065e54d7dabb60d0b60214fe2677346/onnx-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:7449241e70b847b9c3eb8dae622df8c1b456d11032a9d7e26e0ee8a698d5bf86", size = 14434905, upload-time = "2024-03-25T15:25:42.905Z" }, + { url = "https://files.pythonhosted.org/packages/42/87/577adadda30ee08041e81ef02a331ca9d1a8df93a2e4c4c53ec56fbbc2ac/onnx-1.16.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:03a627488b1a9975d95d6a55582af3e14c7f3bb87444725b999935ddd271d352", size = 16516304, upload-time = "2024-03-25T15:25:45.875Z" }, + { url = "https://files.pythonhosted.org/packages/e3/1b/6e1ea37e081cc49a28f0e4d3830b4c8525081354cf9f5529c6c92268fc77/onnx-1.16.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c392faeabd9283ee344ccb4b067d1fea9dfc614fa1f0de7c47589efd79e15e78", size = 15016538, upload-time = "2024-03-25T15:25:49.396Z" }, + { url = "https://files.pythonhosted.org/packages/6d/07/f8fefd5eb0984be42ef677f0b7db7527edc4529224a34a3c31f7b12ec80d/onnx-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0efeb46985de08f0efe758cb54ad3457e821a05c2eaf5ba2ccb8cd1602c08084", size = 15790415, upload-time = "2024-03-25T15:25:51.929Z" }, + { url = "https://files.pythonhosted.org/packages/11/71/c219ce6d4b5205c77405af7f2de2511ad4eeffbfeb77a422151e893de0ea/onnx-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf14a3d32234f23e44abb73a755cb96a423fac7f004e8f046f36b10214151ee", size = 15922224, upload-time = "2024-03-25T15:25:55.049Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a4/554a6e5741b42406c5b1970d04685d7f2012019d4178408ed4b3ec953033/onnx-1.16.0-cp312-cp312-win32.whl", hash = "sha256:62a2e27ae8ba5fc9b4a2620301446a517b5ffaaf8566611de7a7c2160f5bcf4c", size = 14336234, upload-time = "2024-03-25T15:25:57.998Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a1/8aecec497010ad34e7656408df1868d94483c5c56bc991f4088c06150896/onnx-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:3e0860fea94efde777e81a6f68f65761ed5e5f3adea2e050d7fbe373a9ae05b3", size = 14436591, upload-time = "2024-03-25T15:26:01.252Z" }, ] [[package]] name = "onnxruntime" -version = "1.22.1" +version = "1.23.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coloredlogs" }, @@ -1794,24 +1849,28 @@ dependencies = [ { name = "sympy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/76/b9/664a1ffee62fa51529fac27b37409d5d28cadee8d97db806fcba68339b7e/onnxruntime-1.22.1-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:80e7f51da1f5201c1379b8d6ef6170505cd800e40da216290f5e06be01aadf95", size = 34319864 }, - { url = "https://files.pythonhosted.org/packages/b9/64/bc7221e92c994931024e22b22401b962c299e991558c3d57f7e34538b4b9/onnxruntime-1.22.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89ddfdbbdaf7e3a59515dee657f6515601d55cb21a0f0f48c81aefc54ff1b73", size = 14472246 }, - { url = "https://files.pythonhosted.org/packages/84/57/901eddbfb59ac4d008822b236450d5765cafcd450c787019416f8d3baf11/onnxruntime-1.22.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bddc75868bcf6f9ed76858a632f65f7b1846bdcefc6d637b1e359c2c68609964", size = 16459905 }, - { url = "https://files.pythonhosted.org/packages/de/90/d6a1eb9b47e66a18afe7d1cf7cf0b2ef966ffa6f44d9f32d94c2be2860fb/onnxruntime-1.22.1-cp310-cp310-win_amd64.whl", hash = "sha256:01e2f21b2793eb0c8642d2be3cee34cc7d96b85f45f6615e4e220424158877ce", size = 12689001 }, - { url = "https://files.pythonhosted.org/packages/82/ff/4a1a6747e039ef29a8d4ee4510060e9a805982b6da906a3da2306b7a3be6/onnxruntime-1.22.1-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:f4581bccb786da68725d8eac7c63a8f31a89116b8761ff8b4989dc58b61d49a0", size = 34324148 }, - { url = "https://files.pythonhosted.org/packages/0b/05/9f1929723f1cca8c9fb1b2b97ac54ce61362c7201434d38053ea36ee4225/onnxruntime-1.22.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ae7526cf10f93454beb0f751e78e5cb7619e3b92f9fc3bd51aa6f3b7a8977e5", size = 14473779 }, - { url = "https://files.pythonhosted.org/packages/59/f3/c93eb4167d4f36ea947930f82850231f7ce0900cb00e1a53dc4995b60479/onnxruntime-1.22.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6effa1299ac549a05c784d50292e3378dbbf010346ded67400193b09ddc2f04", size = 16460799 }, - { url = "https://files.pythonhosted.org/packages/a8/01/e536397b03e4462d3260aee5387e6f606c8fa9d2b20b1728f988c3c72891/onnxruntime-1.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:f28a42bb322b4ca6d255531bb334a2b3e21f172e37c1741bd5e66bc4b7b61f03", size = 12689881 }, - { url = "https://files.pythonhosted.org/packages/48/70/ca2a4d38a5deccd98caa145581becb20c53684f451e89eb3a39915620066/onnxruntime-1.22.1-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:a938d11c0dc811badf78e435daa3899d9af38abee950d87f3ab7430eb5b3cf5a", size = 34342883 }, - { url = "https://files.pythonhosted.org/packages/29/e5/00b099b4d4f6223b610421080d0eed9327ef9986785c9141819bbba0d396/onnxruntime-1.22.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:984cea2a02fcc5dfea44ade9aca9fe0f7a8a2cd6f77c258fc4388238618f3928", size = 14473861 }, - { url = "https://files.pythonhosted.org/packages/0a/50/519828a5292a6ccd8d5cd6d2f72c6b36ea528a2ef68eca69647732539ffa/onnxruntime-1.22.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2d39a530aff1ec8d02e365f35e503193991417788641b184f5b1e8c9a6d5ce8d", size = 16475713 }, - { url = "https://files.pythonhosted.org/packages/5d/54/7139d463bb0a312890c9a5db87d7815d4a8cce9e6f5f28d04f0b55fcb160/onnxruntime-1.22.1-cp312-cp312-win_amd64.whl", hash = "sha256:6a64291d57ea966a245f749eb970f4fa05a64d26672e05a83fdb5db6b7d62f87", size = 12690910 }, - { url = "https://files.pythonhosted.org/packages/e0/39/77cefa829740bd830915095d8408dce6d731b244e24b1f64fe3df9f18e86/onnxruntime-1.22.1-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:d29c7d87b6cbed8fecfd09dca471832384d12a69e1ab873e5effbb94adc3e966", size = 34342026 }, - { url = "https://files.pythonhosted.org/packages/d2/a6/444291524cb52875b5de980a6e918072514df63a57a7120bf9dfae3aeed1/onnxruntime-1.22.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:460487d83b7056ba98f1f7bac80287224c31d8149b15712b0d6f5078fcc33d0f", size = 14474014 }, - { url = "https://files.pythonhosted.org/packages/87/9d/45a995437879c18beff26eacc2322f4227224d04c6ac3254dce2e8950190/onnxruntime-1.22.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0c37070268ba4e02a1a9d28560cd00cd1e94f0d4f275cbef283854f861a65fa", size = 16475427 }, - { url = "https://files.pythonhosted.org/packages/4c/06/9c765e66ad32a7e709ce4cb6b95d7eaa9cb4d92a6e11ea97c20ffecaf765/onnxruntime-1.22.1-cp313-cp313-win_amd64.whl", hash = "sha256:70980d729145a36a05f74b573435531f55ef9503bcda81fc6c3d6b9306199982", size = 12690841 }, - { url = "https://files.pythonhosted.org/packages/52/8c/02af24ee1c8dce4e6c14a1642a7a56cebe323d2fa01d9a360a638f7e4b75/onnxruntime-1.22.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33a7980bbc4b7f446bac26c3785652fe8730ed02617d765399e89ac7d44e0f7d", size = 14479333 }, - { url = "https://files.pythonhosted.org/packages/5d/15/d75fd66aba116ce3732bb1050401394c5ec52074c4f7ee18db8838dd4667/onnxruntime-1.22.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7e823624b015ea879d976cbef8bfaed2f7e2cc233d7506860a76dd37f8f381", size = 16477261 }, + { url = "https://files.pythonhosted.org/packages/35/d6/311b1afea060015b56c742f3531168c1644650767f27ef40062569960587/onnxruntime-1.23.2-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:a7730122afe186a784660f6ec5807138bf9d792fa1df76556b27307ea9ebcbe3", size = 17195934, upload-time = "2025-10-27T23:06:14.143Z" }, + { url = "https://files.pythonhosted.org/packages/db/db/81bf3d7cecfbfed9092b6b4052e857a769d62ed90561b410014e0aae18db/onnxruntime-1.23.2-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:b28740f4ecef1738ea8f807461dd541b8287d5650b5be33bca7b474e3cbd1f36", size = 19153079, upload-time = "2025-10-27T23:05:57.686Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4d/a382452b17cf70a2313153c520ea4c96ab670c996cb3a95cc5d5ac7bfdac/onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f7d1fe034090a1e371b7f3ca9d3ccae2fabae8c1d8844fb7371d1ea38e8e8d2", size = 15219883, upload-time = "2025-10-22T03:46:21.66Z" }, + { url = "https://files.pythonhosted.org/packages/fb/56/179bf90679984c85b417664c26aae4f427cba7514bd2d65c43b181b7b08b/onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4ca88747e708e5c67337b0f65eed4b7d0dd70d22ac332038c9fc4635760018f7", size = 17370357, upload-time = "2025-10-22T03:46:57.968Z" }, + { url = "https://files.pythonhosted.org/packages/cd/6d/738e50c47c2fd285b1e6c8083f15dac1a5f6199213378a5f14092497296d/onnxruntime-1.23.2-cp310-cp310-win_amd64.whl", hash = "sha256:0be6a37a45e6719db5120e9986fcd30ea205ac8103fd1fb74b6c33348327a0cc", size = 13467651, upload-time = "2025-10-27T23:06:11.904Z" }, + { url = "https://files.pythonhosted.org/packages/44/be/467b00f09061572f022ffd17e49e49e5a7a789056bad95b54dfd3bee73ff/onnxruntime-1.23.2-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:6f91d2c9b0965e86827a5ba01531d5b669770b01775b23199565d6c1f136616c", size = 17196113, upload-time = "2025-10-22T03:47:33.526Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a8/3c23a8f75f93122d2b3410bfb74d06d0f8da4ac663185f91866b03f7da1b/onnxruntime-1.23.2-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:87d8b6eaf0fbeb6835a60a4265fde7a3b60157cf1b2764773ac47237b4d48612", size = 19153857, upload-time = "2025-10-22T03:46:37.578Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d8/506eed9af03d86f8db4880a4c47cd0dffee973ef7e4f4cff9f1d4bcf7d22/onnxruntime-1.23.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbfd2fca76c855317568c1b36a885ddea2272c13cb0e395002c402f2360429a6", size = 15220095, upload-time = "2025-10-22T03:46:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/e9/80/113381ba832d5e777accedc6cb41d10f9eca82321ae31ebb6bcede530cea/onnxruntime-1.23.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da44b99206e77734c5819aa2142c69e64f3b46edc3bd314f6a45a932defc0b3e", size = 17372080, upload-time = "2025-10-22T03:47:00.265Z" }, + { url = "https://files.pythonhosted.org/packages/3a/db/1b4a62e23183a0c3fe441782462c0ede9a2a65c6bbffb9582fab7c7a0d38/onnxruntime-1.23.2-cp311-cp311-win_amd64.whl", hash = "sha256:902c756d8b633ce0dedd889b7c08459433fbcf35e9c38d1c03ddc020f0648c6e", size = 13468349, upload-time = "2025-10-22T03:47:25.783Z" }, + { url = "https://files.pythonhosted.org/packages/1b/9e/f748cd64161213adeef83d0cb16cb8ace1e62fa501033acdd9f9341fff57/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:b8f029a6b98d3cf5be564d52802bb50a8489ab73409fa9db0bf583eabb7c2321", size = 17195929, upload-time = "2025-10-22T03:47:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/91/9d/a81aafd899b900101988ead7fb14974c8a58695338ab6a0f3d6b0100f30b/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:218295a8acae83905f6f1aed8cacb8e3eb3bd7513a13fe4ba3b2664a19fc4a6b", size = 19157705, upload-time = "2025-10-22T03:46:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/4e40f2fba272a6698d62be2cd21ddc3675edfc1a4b9ddefcc4648f115315/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76ff670550dc23e58ea9bc53b5149b99a44e63b34b524f7b8547469aaa0dcb8c", size = 15226915, upload-time = "2025-10-22T03:46:27.773Z" }, + { url = "https://files.pythonhosted.org/packages/ef/88/9cc25d2bafe6bc0d4d3c1db3ade98196d5b355c0b273e6a5dc09c5d5d0d5/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f9b4ae77f8e3c9bee50c27bc1beede83f786fe1d52e99ac85aa8d65a01e9b77", size = 17382649, upload-time = "2025-10-22T03:47:02.782Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b4/569d298f9fc4d286c11c45e85d9ffa9e877af12ace98af8cab52396e8f46/onnxruntime-1.23.2-cp312-cp312-win_amd64.whl", hash = "sha256:25de5214923ce941a3523739d34a520aac30f21e631de53bba9174dc9c004435", size = 13470528, upload-time = "2025-10-22T03:47:28.106Z" }, + { url = "https://files.pythonhosted.org/packages/3d/41/fba0cabccecefe4a1b5fc8020c44febb334637f133acefc7ec492029dd2c/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:2ff531ad8496281b4297f32b83b01cdd719617e2351ffe0dba5684fb283afa1f", size = 17196337, upload-time = "2025-10-22T03:46:35.168Z" }, + { url = "https://files.pythonhosted.org/packages/fe/f9/2d49ca491c6a986acce9f1d1d5fc2099108958cc1710c28e89a032c9cfe9/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:162f4ca894ec3de1a6fd53589e511e06ecdc3ff646849b62a9da7489dee9ce95", size = 19157691, upload-time = "2025-10-22T03:46:43.518Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a1/428ee29c6eaf09a6f6be56f836213f104618fb35ac6cc586ff0f477263eb/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45d127d6e1e9b99d1ebeae9bcd8f98617a812f53f46699eafeb976275744826b", size = 15226898, upload-time = "2025-10-22T03:46:30.039Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2b/b57c8a2466a3126dbe0a792f56ad7290949b02f47b86216cd47d857e4b77/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8bace4e0d46480fbeeb7bbe1ffe1f080e6663a42d1086ff95c1551f2d39e7872", size = 17382518, upload-time = "2025-10-22T03:47:05.407Z" }, + { url = "https://files.pythonhosted.org/packages/4a/93/aba75358133b3a941d736816dd392f687e7eab77215a6e429879080b76b6/onnxruntime-1.23.2-cp313-cp313-win_amd64.whl", hash = "sha256:1f9cc0a55349c584f083c1c076e611a7c35d5b867d5d6e6d6c823bf821978088", size = 13470276, upload-time = "2025-10-22T03:47:31.193Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3d/6830fa61c69ca8e905f237001dbfc01689a4e4ab06147020a4518318881f/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d2385e774f46ac38f02b3a91a91e30263d41b2f1f4f26ae34805b2a9ddef466", size = 15229610, upload-time = "2025-10-22T03:46:32.239Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ca/862b1e7a639460f0ca25fd5b6135fb42cf9deea86d398a92e44dfda2279d/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2b9233c4947907fd1818d0e581c049c41ccc39b2856cc942ff6d26317cee145", size = 17394184, upload-time = "2025-10-22T03:47:08.127Z" }, ] [[package]] @@ -1848,10 +1907,10 @@ dependencies = [ { name = "sympy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/57/e9a080f2477b2a4c16925f766e4615fc545098b0f4e20cf8ad803e7a9672/onnxruntime_openvino-1.18.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:565b874d21bcd48126da7d62f57db019f5ec0e1f82ae9b0740afa2ad91f8d331", size = 41971800 }, - { url = "https://files.pythonhosted.org/packages/34/7d/b75913bce58f4ee9bf6a02d1b513b9fc82303a496ec698e6fb1f9d597cb4/onnxruntime_openvino-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:7f1931060f710a6c8e32121bb73044c4772ef5925802fc8776d3fe1e87ab3f75", size = 5963263 }, - { url = "https://files.pythonhosted.org/packages/7e/d3/8299b7285dc8fa7bd986b6f0d7c50b7f0fd13db50dd3b88b93ec269b1e08/onnxruntime_openvino-1.18.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb1723d386f70a8e26398d983ebe35d2c25ba56e9cdb382670ebbf1f5139f8ba", size = 41971927 }, - { url = "https://files.pythonhosted.org/packages/88/d9/ca0bfd7ed37153d9664ccdcfb4d0e5b1963563553b05cb4338b46968feb2/onnxruntime_openvino-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:874a1e263dd86674593e5a879257650b06a8609c4d5768c3d8ed8dc4ae874b9c", size = 5963464 }, + { url = "https://files.pythonhosted.org/packages/b3/57/e9a080f2477b2a4c16925f766e4615fc545098b0f4e20cf8ad803e7a9672/onnxruntime_openvino-1.18.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:565b874d21bcd48126da7d62f57db019f5ec0e1f82ae9b0740afa2ad91f8d331", size = 41971800, upload-time = "2024-06-25T06:30:37.042Z" }, + { url = "https://files.pythonhosted.org/packages/34/7d/b75913bce58f4ee9bf6a02d1b513b9fc82303a496ec698e6fb1f9d597cb4/onnxruntime_openvino-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:7f1931060f710a6c8e32121bb73044c4772ef5925802fc8776d3fe1e87ab3f75", size = 5963263, upload-time = "2024-06-24T13:38:15.906Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d3/8299b7285dc8fa7bd986b6f0d7c50b7f0fd13db50dd3b88b93ec269b1e08/onnxruntime_openvino-1.18.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb1723d386f70a8e26398d983ebe35d2c25ba56e9cdb382670ebbf1f5139f8ba", size = 41971927, upload-time = "2024-06-25T06:30:43.765Z" }, + { url = "https://files.pythonhosted.org/packages/88/d9/ca0bfd7ed37153d9664ccdcfb4d0e5b1963563553b05cb4338b46968feb2/onnxruntime_openvino-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:874a1e263dd86674593e5a879257650b06a8609c4d5768c3d8ed8dc4ae874b9c", size = 5963464, upload-time = "2024-06-24T13:38:18.437Z" }, ] [[package]] @@ -1861,14 +1920,14 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/06/68c27a523103dad5837dc5b87e71285280c4f098c60e4fe8a8db6486ab09/opencv-python-4.11.0.86.tar.gz", hash = "sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4", size = 95171956 } +sdist = { url = "https://files.pythonhosted.org/packages/17/06/68c27a523103dad5837dc5b87e71285280c4f098c60e4fe8a8db6486ab09/opencv-python-4.11.0.86.tar.gz", hash = "sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4", size = 95171956, upload-time = "2025-01-16T13:52:24.737Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/4d/53b30a2a3ac1f75f65a59eb29cf2ee7207ce64867db47036ad61743d5a23/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a", size = 37326322 }, - { url = "https://files.pythonhosted.org/packages/3b/84/0a67490741867eacdfa37bc18df96e08a9d579583b419010d7f3da8ff503/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66", size = 56723197 }, - { url = "https://files.pythonhosted.org/packages/f3/bd/29c126788da65c1fb2b5fb621b7fed0ed5f9122aa22a0868c5e2c15c6d23/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202", size = 42230439 }, - { url = "https://files.pythonhosted.org/packages/2c/8b/90eb44a40476fa0e71e05a0283947cfd74a5d36121a11d926ad6f3193cc4/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d", size = 62986597 }, - { url = "https://files.pythonhosted.org/packages/fb/d7/1d5941a9dde095468b288d989ff6539dd69cd429dbf1b9e839013d21b6f0/opencv_python-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b", size = 29384337 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/f1c30a92854540bf789e9cd5dde7ef49bbe63f855b85a2e6b3db8135c591/opencv_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec", size = 39488044 }, + { url = "https://files.pythonhosted.org/packages/05/4d/53b30a2a3ac1f75f65a59eb29cf2ee7207ce64867db47036ad61743d5a23/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a", size = 37326322, upload-time = "2025-01-16T13:52:25.887Z" }, + { url = "https://files.pythonhosted.org/packages/3b/84/0a67490741867eacdfa37bc18df96e08a9d579583b419010d7f3da8ff503/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66", size = 56723197, upload-time = "2025-01-16T13:55:21.222Z" }, + { url = "https://files.pythonhosted.org/packages/f3/bd/29c126788da65c1fb2b5fb621b7fed0ed5f9122aa22a0868c5e2c15c6d23/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202", size = 42230439, upload-time = "2025-01-16T13:51:35.822Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8b/90eb44a40476fa0e71e05a0283947cfd74a5d36121a11d926ad6f3193cc4/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d", size = 62986597, upload-time = "2025-01-16T13:52:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/1d5941a9dde095468b288d989ff6539dd69cd429dbf1b9e839013d21b6f0/opencv_python-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b", size = 29384337, upload-time = "2025-01-16T13:52:13.549Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/f1c30a92854540bf789e9cd5dde7ef49bbe63f855b85a2e6b3db8135c591/opencv_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec", size = 39488044, upload-time = "2025-01-16T13:52:21.928Z" }, ] [[package]] @@ -1878,186 +1937,190 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/36/2f/5b2b3ba52c864848885ba988f24b7f105052f68da9ab0e693cc7c25b0b30/opencv-python-headless-4.11.0.86.tar.gz", hash = "sha256:996eb282ca4b43ec6a3972414de0e2331f5d9cda2b41091a49739c19fb843798", size = 95177929 } +sdist = { url = "https://files.pythonhosted.org/packages/36/2f/5b2b3ba52c864848885ba988f24b7f105052f68da9ab0e693cc7c25b0b30/opencv-python-headless-4.11.0.86.tar.gz", hash = "sha256:996eb282ca4b43ec6a3972414de0e2331f5d9cda2b41091a49739c19fb843798", size = 95177929, upload-time = "2025-01-16T13:53:40.22Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/53/2c50afa0b1e05ecdb4603818e85f7d174e683d874ef63a6abe3ac92220c8/opencv_python_headless-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:48128188ade4a7e517237c8e1e11a9cdf5c282761473383e77beb875bb1e61ca", size = 37326460 }, - { url = "https://files.pythonhosted.org/packages/3b/43/68555327df94bb9b59a1fd645f63fafb0762515344d2046698762fc19d58/opencv_python_headless-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:a66c1b286a9de872c343ee7c3553b084244299714ebb50fbdcd76f07ebbe6c81", size = 56723330 }, - { url = "https://files.pythonhosted.org/packages/45/be/1438ce43ebe65317344a87e4b150865c5585f4c0db880a34cdae5ac46881/opencv_python_headless-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6efabcaa9df731f29e5ea9051776715b1bdd1845d7c9530065c7951d2a2899eb", size = 29487060 }, - { url = "https://files.pythonhosted.org/packages/dd/5c/c139a7876099916879609372bfa513b7f1257f7f1a908b0bdc1c2328241b/opencv_python_headless-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e0a27c19dd1f40ddff94976cfe43066fbbe9dfbb2ec1907d66c19caef42a57b", size = 49969856 }, - { url = "https://files.pythonhosted.org/packages/95/dd/ed1191c9dc91abcc9f752b499b7928aacabf10567bb2c2535944d848af18/opencv_python_headless-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:f447d8acbb0b6f2808da71fddd29c1cdd448d2bc98f72d9bb78a7a898fc9621b", size = 29324425 }, - { url = "https://files.pythonhosted.org/packages/86/8a/69176a64335aed183529207ba8bc3d329c2999d852b4f3818027203f50e6/opencv_python_headless-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:6c304df9caa7a6a5710b91709dd4786bf20a74d57672b3c31f7033cc638174ca", size = 39402386 }, + { url = "https://files.pythonhosted.org/packages/dc/53/2c50afa0b1e05ecdb4603818e85f7d174e683d874ef63a6abe3ac92220c8/opencv_python_headless-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:48128188ade4a7e517237c8e1e11a9cdf5c282761473383e77beb875bb1e61ca", size = 37326460, upload-time = "2025-01-16T13:52:57.015Z" }, + { url = "https://files.pythonhosted.org/packages/3b/43/68555327df94bb9b59a1fd645f63fafb0762515344d2046698762fc19d58/opencv_python_headless-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:a66c1b286a9de872c343ee7c3553b084244299714ebb50fbdcd76f07ebbe6c81", size = 56723330, upload-time = "2025-01-16T13:55:45.731Z" }, + { url = "https://files.pythonhosted.org/packages/45/be/1438ce43ebe65317344a87e4b150865c5585f4c0db880a34cdae5ac46881/opencv_python_headless-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6efabcaa9df731f29e5ea9051776715b1bdd1845d7c9530065c7951d2a2899eb", size = 29487060, upload-time = "2025-01-16T13:51:59.625Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5c/c139a7876099916879609372bfa513b7f1257f7f1a908b0bdc1c2328241b/opencv_python_headless-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e0a27c19dd1f40ddff94976cfe43066fbbe9dfbb2ec1907d66c19caef42a57b", size = 49969856, upload-time = "2025-01-16T13:53:29.654Z" }, + { url = "https://files.pythonhosted.org/packages/95/dd/ed1191c9dc91abcc9f752b499b7928aacabf10567bb2c2535944d848af18/opencv_python_headless-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:f447d8acbb0b6f2808da71fddd29c1cdd448d2bc98f72d9bb78a7a898fc9621b", size = 29324425, upload-time = "2025-01-16T13:52:49.048Z" }, + { url = "https://files.pythonhosted.org/packages/86/8a/69176a64335aed183529207ba8bc3d329c2999d852b4f3818027203f50e6/opencv_python_headless-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:6c304df9caa7a6a5710b91709dd4786bf20a74d57672b3c31f7033cc638174ca", size = 39402386, upload-time = "2025-01-16T13:52:56.418Z" }, ] [[package]] name = "orjson" -version = "3.11.3" +version = "3.11.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/4d/8df5f83256a809c22c4d6792ce8d43bb503be0fb7a8e4da9025754b09658/orjson-3.11.3.tar.gz", hash = "sha256:1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a", size = 5482394 } +sdist = { url = "https://files.pythonhosted.org/packages/c6/fe/ed708782d6709cc60eb4c2d8a361a440661f74134675c72990f2c48c785f/orjson-3.11.4.tar.gz", hash = "sha256:39485f4ab4c9b30a3943cfe99e1a213c4776fb69e8abd68f66b83d5a0b0fdc6d", size = 5945188, upload-time = "2025-10-24T15:50:38.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/64/4a3cef001c6cd9c64256348d4c13a7b09b857e3e1cbb5185917df67d8ced/orjson-3.11.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:29cb1f1b008d936803e2da3d7cba726fc47232c45df531b29edf0b232dd737e7", size = 238600 }, - { url = "https://files.pythonhosted.org/packages/10/ce/0c8c87f54f79d051485903dc46226c4d3220b691a151769156054df4562b/orjson-3.11.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97dceed87ed9139884a55db8722428e27bd8452817fbf1869c58b49fecab1120", size = 123526 }, - { url = "https://files.pythonhosted.org/packages/ef/d0/249497e861f2d438f45b3ab7b7b361484237414945169aa285608f9f7019/orjson-3.11.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:58533f9e8266cb0ac298e259ed7b4d42ed3fa0b78ce76860626164de49e0d467", size = 128075 }, - { url = "https://files.pythonhosted.org/packages/e5/64/00485702f640a0fd56144042a1ea196469f4a3ae93681871564bf74fa996/orjson-3.11.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c212cfdd90512fe722fa9bd620de4d46cda691415be86b2e02243242ae81873", size = 130483 }, - { url = "https://files.pythonhosted.org/packages/64/81/110d68dba3909171bf3f05619ad0cf187b430e64045ae4e0aa7ccfe25b15/orjson-3.11.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff835b5d3e67d9207343effb03760c00335f8b5285bfceefd4dc967b0e48f6a", size = 132539 }, - { url = "https://files.pythonhosted.org/packages/79/92/dba25c22b0ddfafa1e6516a780a00abac28d49f49e7202eb433a53c3e94e/orjson-3.11.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5aa4682912a450c2db89cbd92d356fef47e115dffba07992555542f344d301b", size = 135390 }, - { url = "https://files.pythonhosted.org/packages/44/1d/ca2230fd55edbd87b58a43a19032d63a4b180389a97520cc62c535b726f9/orjson-3.11.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7d18dd34ea2e860553a579df02041845dee0af8985dff7f8661306f95504ddf", size = 132966 }, - { url = "https://files.pythonhosted.org/packages/6e/b9/96bbc8ed3e47e52b487d504bd6861798977445fbc410da6e87e302dc632d/orjson-3.11.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d8b11701bc43be92ea42bd454910437b355dfb63696c06fe953ffb40b5f763b4", size = 131349 }, - { url = "https://files.pythonhosted.org/packages/c4/3c/418fbd93d94b0df71cddf96b7fe5894d64a5d890b453ac365120daec30f7/orjson-3.11.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:90368277087d4af32d38bd55f9da2ff466d25325bf6167c8f382d8ee40cb2bbc", size = 404087 }, - { url = "https://files.pythonhosted.org/packages/5b/a9/2bfd58817d736c2f63608dec0c34857339d423eeed30099b126562822191/orjson-3.11.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd7ff459fb393358d3a155d25b275c60b07a2c83dcd7ea962b1923f5a1134569", size = 146067 }, - { url = "https://files.pythonhosted.org/packages/33/ba/29023771f334096f564e48d82ed855a0ed3320389d6748a9c949e25be734/orjson-3.11.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f8d902867b699bcd09c176a280b1acdab57f924489033e53d0afe79817da37e6", size = 135506 }, - { url = "https://files.pythonhosted.org/packages/39/62/b5a1eca83f54cb3aa11a9645b8a22f08d97dbd13f27f83aae7c6666a0a05/orjson-3.11.3-cp310-cp310-win32.whl", hash = "sha256:bb93562146120bb51e6b154962d3dadc678ed0fce96513fa6bc06599bb6f6edc", size = 136352 }, - { url = "https://files.pythonhosted.org/packages/e3/c0/7ebfaa327d9a9ed982adc0d9420dbce9a3fec45b60ab32c6308f731333fa/orjson-3.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:976c6f1975032cc327161c65d4194c549f2589d88b105a5e3499429a54479770", size = 131539 }, - { url = "https://files.pythonhosted.org/packages/cd/8b/360674cd817faef32e49276187922a946468579fcaf37afdfb6c07046e92/orjson-3.11.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d2ae0cc6aeb669633e0124531f342a17d8e97ea999e42f12a5ad4adaa304c5f", size = 238238 }, - { url = "https://files.pythonhosted.org/packages/05/3d/5fa9ea4b34c1a13be7d9046ba98d06e6feb1d8853718992954ab59d16625/orjson-3.11.3-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:ba21dbb2493e9c653eaffdc38819b004b7b1b246fb77bfc93dc016fe664eac91", size = 127713 }, - { url = "https://files.pythonhosted.org/packages/e5/5f/e18367823925e00b1feec867ff5f040055892fc474bf5f7875649ecfa586/orjson-3.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00f1a271e56d511d1569937c0447d7dce5a99a33ea0dec76673706360a051904", size = 123241 }, - { url = "https://files.pythonhosted.org/packages/0f/bd/3c66b91c4564759cf9f473251ac1650e446c7ba92a7c0f9f56ed54f9f0e6/orjson-3.11.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b67e71e47caa6680d1b6f075a396d04fa6ca8ca09aafb428731da9b3ea32a5a6", size = 127895 }, - { url = "https://files.pythonhosted.org/packages/82/b5/dc8dcd609db4766e2967a85f63296c59d4722b39503e5b0bf7fd340d387f/orjson-3.11.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7d012ebddffcce8c85734a6d9e5f08180cd3857c5f5a3ac70185b43775d043d", size = 130303 }, - { url = "https://files.pythonhosted.org/packages/48/c2/d58ec5fd1270b2aa44c862171891adc2e1241bd7dab26c8f46eb97c6c6f1/orjson-3.11.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd759f75d6b8d1b62012b7f5ef9461d03c804f94d539a5515b454ba3a6588038", size = 132366 }, - { url = "https://files.pythonhosted.org/packages/73/87/0ef7e22eb8dd1ef940bfe3b9e441db519e692d62ed1aae365406a16d23d0/orjson-3.11.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6890ace0809627b0dff19cfad92d69d0fa3f089d3e359a2a532507bb6ba34efb", size = 135180 }, - { url = "https://files.pythonhosted.org/packages/bb/6a/e5bf7b70883f374710ad74faf99bacfc4b5b5a7797c1d5e130350e0e28a3/orjson-3.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d4a5e041ae435b815e568537755773d05dac031fee6a57b4ba70897a44d9d2", size = 132741 }, - { url = "https://files.pythonhosted.org/packages/bd/0c/4577fd860b6386ffaa56440e792af01c7882b56d2766f55384b5b0e9d39b/orjson-3.11.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d68bf97a771836687107abfca089743885fb664b90138d8761cce61d5625d55", size = 131104 }, - { url = "https://files.pythonhosted.org/packages/66/4b/83e92b2d67e86d1c33f2ea9411742a714a26de63641b082bdbf3d8e481af/orjson-3.11.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bfc27516ec46f4520b18ef645864cee168d2a027dbf32c5537cb1f3e3c22dac1", size = 403887 }, - { url = "https://files.pythonhosted.org/packages/6d/e5/9eea6a14e9b5ceb4a271a1fd2e1dec5f2f686755c0fab6673dc6ff3433f4/orjson-3.11.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f66b001332a017d7945e177e282a40b6997056394e3ed7ddb41fb1813b83e824", size = 145855 }, - { url = "https://files.pythonhosted.org/packages/45/78/8d4f5ad0c80ba9bf8ac4d0fc71f93a7d0dc0844989e645e2074af376c307/orjson-3.11.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:212e67806525d2561efbfe9e799633b17eb668b8964abed6b5319b2f1cfbae1f", size = 135361 }, - { url = "https://files.pythonhosted.org/packages/0b/5f/16386970370178d7a9b438517ea3d704efcf163d286422bae3b37b88dbb5/orjson-3.11.3-cp311-cp311-win32.whl", hash = "sha256:6e8e0c3b85575a32f2ffa59de455f85ce002b8bdc0662d6b9c2ed6d80ab5d204", size = 136190 }, - { url = "https://files.pythonhosted.org/packages/09/60/db16c6f7a41dd8ac9fb651f66701ff2aeb499ad9ebc15853a26c7c152448/orjson-3.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:6be2f1b5d3dc99a5ce5ce162fc741c22ba9f3443d3dd586e6a1211b7bc87bc7b", size = 131389 }, - { url = "https://files.pythonhosted.org/packages/3e/2a/bb811ad336667041dea9b8565c7c9faf2f59b47eb5ab680315eea612ef2e/orjson-3.11.3-cp311-cp311-win_arm64.whl", hash = "sha256:fafb1a99d740523d964b15c8db4eabbfc86ff29f84898262bf6e3e4c9e97e43e", size = 126120 }, - { url = "https://files.pythonhosted.org/packages/3d/b0/a7edab2a00cdcb2688e1c943401cb3236323e7bfd2839815c6131a3742f4/orjson-3.11.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8c752089db84333e36d754c4baf19c0e1437012242048439c7e80eb0e6426e3b", size = 238259 }, - { url = "https://files.pythonhosted.org/packages/e1/c6/ff4865a9cc398a07a83342713b5932e4dc3cb4bf4bc04e8f83dedfc0d736/orjson-3.11.3-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:9b8761b6cf04a856eb544acdd82fc594b978f12ac3602d6374a7edb9d86fd2c2", size = 127633 }, - { url = "https://files.pythonhosted.org/packages/6e/e6/e00bea2d9472f44fe8794f523e548ce0ad51eb9693cf538a753a27b8bda4/orjson-3.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b13974dc8ac6ba22feaa867fc19135a3e01a134b4f7c9c28162fed4d615008a", size = 123061 }, - { url = "https://files.pythonhosted.org/packages/54/31/9fbb78b8e1eb3ac605467cb846e1c08d0588506028b37f4ee21f978a51d4/orjson-3.11.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f83abab5bacb76d9c821fd5c07728ff224ed0e52d7a71b7b3de822f3df04e15c", size = 127956 }, - { url = "https://files.pythonhosted.org/packages/36/88/b0604c22af1eed9f98d709a96302006915cfd724a7ebd27d6dd11c22d80b/orjson-3.11.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6fbaf48a744b94091a56c62897b27c31ee2da93d826aa5b207131a1e13d4064", size = 130790 }, - { url = "https://files.pythonhosted.org/packages/0e/9d/1c1238ae9fffbfed51ba1e507731b3faaf6b846126a47e9649222b0fd06f/orjson-3.11.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc779b4f4bba2847d0d2940081a7b6f7b5877e05408ffbb74fa1faf4a136c424", size = 132385 }, - { url = "https://files.pythonhosted.org/packages/a3/b5/c06f1b090a1c875f337e21dd71943bc9d84087f7cdf8c6e9086902c34e42/orjson-3.11.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd4b909ce4c50faa2192da6bb684d9848d4510b736b0611b6ab4020ea6fd2d23", size = 135305 }, - { url = "https://files.pythonhosted.org/packages/a0/26/5f028c7d81ad2ebbf84414ba6d6c9cac03f22f5cd0d01eb40fb2d6a06b07/orjson-3.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:524b765ad888dc5518bbce12c77c2e83dee1ed6b0992c1790cc5fb49bb4b6667", size = 132875 }, - { url = "https://files.pythonhosted.org/packages/fe/d4/b8df70d9cfb56e385bf39b4e915298f9ae6c61454c8154a0f5fd7efcd42e/orjson-3.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:84fd82870b97ae3cdcea9d8746e592b6d40e1e4d4527835fc520c588d2ded04f", size = 130940 }, - { url = "https://files.pythonhosted.org/packages/da/5e/afe6a052ebc1a4741c792dd96e9f65bf3939d2094e8b356503b68d48f9f5/orjson-3.11.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fbecb9709111be913ae6879b07bafd4b0785b44c1eb5cac8ac76da048b3885a1", size = 403852 }, - { url = "https://files.pythonhosted.org/packages/f8/90/7bbabafeb2ce65915e9247f14a56b29c9334003536009ef5b122783fe67e/orjson-3.11.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9dba358d55aee552bd868de348f4736ca5a4086d9a62e2bfbbeeb5629fe8b0cc", size = 146293 }, - { url = "https://files.pythonhosted.org/packages/27/b3/2d703946447da8b093350570644a663df69448c9d9330e5f1d9cce997f20/orjson-3.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eabcf2e84f1d7105f84580e03012270c7e97ecb1fb1618bda395061b2a84a049", size = 135470 }, - { url = "https://files.pythonhosted.org/packages/38/70/b14dcfae7aff0e379b0119c8a812f8396678919c431efccc8e8a0263e4d9/orjson-3.11.3-cp312-cp312-win32.whl", hash = "sha256:3782d2c60b8116772aea8d9b7905221437fdf53e7277282e8d8b07c220f96cca", size = 136248 }, - { url = "https://files.pythonhosted.org/packages/35/b8/9e3127d65de7fff243f7f3e53f59a531bf6bb295ebe5db024c2503cc0726/orjson-3.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:79b44319268af2eaa3e315b92298de9a0067ade6e6003ddaef72f8e0bedb94f1", size = 131437 }, - { url = "https://files.pythonhosted.org/packages/51/92/a946e737d4d8a7fd84a606aba96220043dcc7d6988b9e7551f7f6d5ba5ad/orjson-3.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:0e92a4e83341ef79d835ca21b8bd13e27c859e4e9e4d7b63defc6e58462a3710", size = 125978 }, - { url = "https://files.pythonhosted.org/packages/fc/79/8932b27293ad35919571f77cb3693b5906cf14f206ef17546052a241fdf6/orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810", size = 238127 }, - { url = "https://files.pythonhosted.org/packages/1c/82/cb93cd8cf132cd7643b30b6c5a56a26c4e780c7a145db6f83de977b540ce/orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43", size = 127494 }, - { url = "https://files.pythonhosted.org/packages/a4/b8/2d9eb181a9b6bb71463a78882bcac1027fd29cf62c38a40cc02fc11d3495/orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27", size = 123017 }, - { url = "https://files.pythonhosted.org/packages/b4/14/a0e971e72d03b509190232356d54c0f34507a05050bd026b8db2bf2c192c/orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f", size = 127898 }, - { url = "https://files.pythonhosted.org/packages/8e/af/dc74536722b03d65e17042cc30ae586161093e5b1f29bccda24765a6ae47/orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c", size = 130742 }, - { url = "https://files.pythonhosted.org/packages/62/e6/7a3b63b6677bce089fe939353cda24a7679825c43a24e49f757805fc0d8a/orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be", size = 132377 }, - { url = "https://files.pythonhosted.org/packages/fc/cd/ce2ab93e2e7eaf518f0fd15e3068b8c43216c8a44ed82ac2b79ce5cef72d/orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d", size = 135313 }, - { url = "https://files.pythonhosted.org/packages/d0/b4/f98355eff0bd1a38454209bbc73372ce351ba29933cb3e2eba16c04b9448/orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2", size = 132908 }, - { url = "https://files.pythonhosted.org/packages/eb/92/8f5182d7bc2a1bed46ed960b61a39af8389f0ad476120cd99e67182bfb6d/orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f", size = 130905 }, - { url = "https://files.pythonhosted.org/packages/1a/60/c41ca753ce9ffe3d0f67b9b4c093bdd6e5fdb1bc53064f992f66bb99954d/orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee", size = 403812 }, - { url = "https://files.pythonhosted.org/packages/dd/13/e4a4f16d71ce1868860db59092e78782c67082a8f1dc06a3788aef2b41bc/orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e", size = 146277 }, - { url = "https://files.pythonhosted.org/packages/8d/8b/bafb7f0afef9344754a3a0597a12442f1b85a048b82108ef2c956f53babd/orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633", size = 135418 }, - { url = "https://files.pythonhosted.org/packages/60/d4/bae8e4f26afb2c23bea69d2f6d566132584d1c3a5fe89ee8c17b718cab67/orjson-3.11.3-cp313-cp313-win32.whl", hash = "sha256:2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b", size = 136216 }, - { url = "https://files.pythonhosted.org/packages/88/76/224985d9f127e121c8cad882cea55f0ebe39f97925de040b75ccd4b33999/orjson-3.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae", size = 131362 }, - { url = "https://files.pythonhosted.org/packages/e2/cf/0dce7a0be94bd36d1346be5067ed65ded6adb795fdbe3abd234c8d576d01/orjson-3.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce", size = 125989 }, - { url = "https://files.pythonhosted.org/packages/ef/77/d3b1fef1fc6aaeed4cbf3be2b480114035f4df8fa1a99d2dac1d40d6e924/orjson-3.11.3-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:cf4b81227ec86935568c7edd78352a92e97af8da7bd70bdfdaa0d2e0011a1ab4", size = 238115 }, - { url = "https://files.pythonhosted.org/packages/e4/6d/468d21d49bb12f900052edcfbf52c292022d0a323d7828dc6376e6319703/orjson-3.11.3-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:bc8bc85b81b6ac9fc4dae393a8c159b817f4c2c9dee5d12b773bddb3b95fc07e", size = 127493 }, - { url = "https://files.pythonhosted.org/packages/67/46/1e2588700d354aacdf9e12cc2d98131fb8ac6f31ca65997bef3863edb8ff/orjson-3.11.3-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:88dcfc514cfd1b0de038443c7b3e6a9797ffb1b3674ef1fd14f701a13397f82d", size = 122998 }, - { url = "https://files.pythonhosted.org/packages/3b/94/11137c9b6adb3779f1b34fd98be51608a14b430dbc02c6d41134fbba484c/orjson-3.11.3-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d61cd543d69715d5fc0a690c7c6f8dcc307bc23abef9738957981885f5f38229", size = 132915 }, - { url = "https://files.pythonhosted.org/packages/10/61/dccedcf9e9bcaac09fdabe9eaee0311ca92115699500efbd31950d878833/orjson-3.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2b7b153ed90ababadbef5c3eb39549f9476890d339cf47af563aea7e07db2451", size = 130907 }, - { url = "https://files.pythonhosted.org/packages/0e/fd/0e935539aa7b08b3ca0f817d73034f7eb506792aae5ecc3b7c6e679cdf5f/orjson-3.11.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:7909ae2460f5f494fecbcd10613beafe40381fd0316e35d6acb5f3a05bfda167", size = 403852 }, - { url = "https://files.pythonhosted.org/packages/4a/2b/50ae1a5505cd1043379132fdb2adb8a05f37b3e1ebffe94a5073321966fd/orjson-3.11.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2030c01cbf77bc67bee7eef1e7e31ecf28649353987775e3583062c752da0077", size = 146309 }, - { url = "https://files.pythonhosted.org/packages/cd/1d/a473c158e380ef6f32753b5f39a69028b25ec5be331c2049a2201bde2e19/orjson-3.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a0169ebd1cbd94b26c7a7ad282cf5c2744fce054133f959e02eb5265deae1872", size = 135424 }, - { url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl", hash = "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", size = 136266 }, - { url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", size = 131351 }, - { url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", size = 125985 }, + { url = "https://files.pythonhosted.org/packages/e0/30/5aed63d5af1c8b02fbd2a8d83e2a6c8455e30504c50dbf08c8b51403d873/orjson-3.11.4-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e3aa2118a3ece0d25489cbe48498de8a5d580e42e8d9979f65bf47900a15aba1", size = 243870, upload-time = "2025-10-24T15:48:28.908Z" }, + { url = "https://files.pythonhosted.org/packages/44/1f/da46563c08bef33c41fd63c660abcd2184b4d2b950c8686317d03b9f5f0c/orjson-3.11.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a69ab657a4e6733133a3dca82768f2f8b884043714e8d2b9ba9f52b6efef5c44", size = 130622, upload-time = "2025-10-24T15:48:31.361Z" }, + { url = "https://files.pythonhosted.org/packages/02/bd/b551a05d0090eab0bf8008a13a14edc0f3c3e0236aa6f5b697760dd2817b/orjson-3.11.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3740bffd9816fc0326ddc406098a3a8f387e42223f5f455f2a02a9f834ead80c", size = 129344, upload-time = "2025-10-24T15:48:32.71Z" }, + { url = "https://files.pythonhosted.org/packages/87/6c/9ddd5e609f443b2548c5e7df3c44d0e86df2c68587a0e20c50018cdec535/orjson-3.11.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65fd2f5730b1bf7f350c6dc896173d3460d235c4be007af73986d7cd9a2acd23", size = 136633, upload-time = "2025-10-24T15:48:34.128Z" }, + { url = "https://files.pythonhosted.org/packages/95/f2/9f04f2874c625a9fb60f6918c33542320661255323c272e66f7dcce14df2/orjson-3.11.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fdc3ae730541086158d549c97852e2eea6820665d4faf0f41bf99df41bc11ea", size = 137695, upload-time = "2025-10-24T15:48:35.654Z" }, + { url = "https://files.pythonhosted.org/packages/d2/c2/c7302afcbdfe8a891baae0e2cee091583a30e6fa613e8bdf33b0e9c8a8c7/orjson-3.11.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e10b4d65901da88845516ce9f7f9736f9638d19a1d483b3883dc0182e6e5edba", size = 136879, upload-time = "2025-10-24T15:48:37.483Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3a/b31c8f0182a3e27f48e703f46e61bb769666cd0dac4700a73912d07a1417/orjson-3.11.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6a03a678085f64b97f9d4a9ae69376ce91a3a9e9b56a82b1580d8e1d501aff", size = 136374, upload-time = "2025-10-24T15:48:38.624Z" }, + { url = "https://files.pythonhosted.org/packages/29/d0/fd9ab96841b090d281c46df566b7f97bc6c8cd9aff3f3ebe99755895c406/orjson-3.11.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c82e4f0b1c712477317434761fbc28b044c838b6b1240d895607441412371ac", size = 140519, upload-time = "2025-10-24T15:48:39.756Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ce/36eb0f15978bb88e33a3480e1a3fb891caa0f189ba61ce7713e0ccdadabf/orjson-3.11.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d58c166a18f44cc9e2bad03a327dc2d1a3d2e85b847133cfbafd6bfc6719bd79", size = 406522, upload-time = "2025-10-24T15:48:41.198Z" }, + { url = "https://files.pythonhosted.org/packages/85/11/e8af3161a288f5c6a00c188fc729c7ba193b0cbc07309a1a29c004347c30/orjson-3.11.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94f206766bf1ea30e1382e4890f763bd1eefddc580e08fec1ccdc20ddd95c827", size = 149790, upload-time = "2025-10-24T15:48:42.664Z" }, + { url = "https://files.pythonhosted.org/packages/ea/96/209d52db0cf1e10ed48d8c194841e383e23c2ced5a2ee766649fe0e32d02/orjson-3.11.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:41bf25fb39a34cf8edb4398818523277ee7096689db352036a9e8437f2f3ee6b", size = 140040, upload-time = "2025-10-24T15:48:44.042Z" }, + { url = "https://files.pythonhosted.org/packages/ef/0e/526db1395ccb74c3d59ac1660b9a325017096dc5643086b38f27662b4add/orjson-3.11.4-cp310-cp310-win32.whl", hash = "sha256:fa9627eba4e82f99ca6d29bc967f09aba446ee2b5a1ea728949ede73d313f5d3", size = 135955, upload-time = "2025-10-24T15:48:45.495Z" }, + { url = "https://files.pythonhosted.org/packages/e6/69/18a778c9de3702b19880e73c9866b91cc85f904b885d816ba1ab318b223c/orjson-3.11.4-cp310-cp310-win_amd64.whl", hash = "sha256:23ef7abc7fca96632d8174ac115e668c1e931b8fe4dde586e92a500bf1914dcc", size = 131577, upload-time = "2025-10-24T15:48:46.609Z" }, + { url = "https://files.pythonhosted.org/packages/63/1d/1ea6005fffb56715fd48f632611e163d1604e8316a5bad2288bee9a1c9eb/orjson-3.11.4-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5e59d23cd93ada23ec59a96f215139753fbfe3a4d989549bcb390f8c00370b39", size = 243498, upload-time = "2025-10-24T15:48:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/37/d7/ffed10c7da677f2a9da307d491b9eb1d0125b0307019c4ad3d665fd31f4f/orjson-3.11.4-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5c3aedecfc1beb988c27c79d52ebefab93b6c3921dbec361167e6559aba2d36d", size = 128961, upload-time = "2025-10-24T15:48:49.571Z" }, + { url = "https://files.pythonhosted.org/packages/a2/96/3e4d10a18866d1368f73c8c44b7fe37cc8a15c32f2a7620be3877d4c55a3/orjson-3.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da9e5301f1c2caa2a9a4a303480d79c9ad73560b2e7761de742ab39fe59d9175", size = 130321, upload-time = "2025-10-24T15:48:50.713Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1f/465f66e93f434f968dd74d5b623eb62c657bdba2332f5a8be9f118bb74c7/orjson-3.11.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8873812c164a90a79f65368f8f96817e59e35d0cc02786a5356f0e2abed78040", size = 129207, upload-time = "2025-10-24T15:48:52.193Z" }, + { url = "https://files.pythonhosted.org/packages/28/43/d1e94837543321c119dff277ae8e348562fe8c0fafbb648ef7cb0c67e521/orjson-3.11.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d7feb0741ebb15204e748f26c9638e6665a5fa93c37a2c73d64f1669b0ddc63", size = 136323, upload-time = "2025-10-24T15:48:54.806Z" }, + { url = "https://files.pythonhosted.org/packages/bf/04/93303776c8890e422a5847dd012b4853cdd88206b8bbd3edc292c90102d1/orjson-3.11.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ee5487fefee21e6910da4c2ee9eef005bee568a0879834df86f888d2ffbdd9", size = 137440, upload-time = "2025-10-24T15:48:56.326Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ef/75519d039e5ae6b0f34d0336854d55544ba903e21bf56c83adc51cd8bf82/orjson-3.11.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d40d46f348c0321df01507f92b95a377240c4ec31985225a6668f10e2676f9a", size = 136680, upload-time = "2025-10-24T15:48:57.476Z" }, + { url = "https://files.pythonhosted.org/packages/b5/18/bf8581eaae0b941b44efe14fee7b7862c3382fbc9a0842132cfc7cf5ecf4/orjson-3.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95713e5fc8af84d8edc75b785d2386f653b63d62b16d681687746734b4dfc0be", size = 136160, upload-time = "2025-10-24T15:48:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/c4/35/a6d582766d351f87fc0a22ad740a641b0a8e6fc47515e8614d2e4790ae10/orjson-3.11.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad73ede24f9083614d6c4ca9a85fe70e33be7bf047ec586ee2363bc7418fe4d7", size = 140318, upload-time = "2025-10-24T15:49:00.834Z" }, + { url = "https://files.pythonhosted.org/packages/76/b3/5a4801803ab2e2e2d703bce1a56540d9f99a9143fbec7bf63d225044fef8/orjson-3.11.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:842289889de515421f3f224ef9c1f1efb199a32d76d8d2ca2706fa8afe749549", size = 406330, upload-time = "2025-10-24T15:49:02.327Z" }, + { url = "https://files.pythonhosted.org/packages/80/55/a8f682f64833e3a649f620eafefee175cbfeb9854fc5b710b90c3bca45df/orjson-3.11.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3b2427ed5791619851c52a1261b45c233930977e7de8cf36de05636c708fa905", size = 149580, upload-time = "2025-10-24T15:49:03.517Z" }, + { url = "https://files.pythonhosted.org/packages/ad/e4/c132fa0c67afbb3eb88274fa98df9ac1f631a675e7877037c611805a4413/orjson-3.11.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c36e524af1d29982e9b190573677ea02781456b2e537d5840e4538a5ec41907", size = 139846, upload-time = "2025-10-24T15:49:04.761Z" }, + { url = "https://files.pythonhosted.org/packages/54/06/dc3491489efd651fef99c5908e13951abd1aead1257c67f16135f95ce209/orjson-3.11.4-cp311-cp311-win32.whl", hash = "sha256:87255b88756eab4a68ec61837ca754e5d10fa8bc47dc57f75cedfeaec358d54c", size = 135781, upload-time = "2025-10-24T15:49:05.969Z" }, + { url = "https://files.pythonhosted.org/packages/79/b7/5e5e8d77bd4ea02a6ac54c42c818afb01dd31961be8a574eb79f1d2cfb1e/orjson-3.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:e2d5d5d798aba9a0e1fede8d853fa899ce2cb930ec0857365f700dffc2c7af6a", size = 131391, upload-time = "2025-10-24T15:49:07.355Z" }, + { url = "https://files.pythonhosted.org/packages/0f/dc/9484127cc1aa213be398ed735f5f270eedcb0c0977303a6f6ddc46b60204/orjson-3.11.4-cp311-cp311-win_arm64.whl", hash = "sha256:6bb6bb41b14c95d4f2702bce9975fda4516f1db48e500102fc4d8119032ff045", size = 126252, upload-time = "2025-10-24T15:49:08.869Z" }, + { url = "https://files.pythonhosted.org/packages/63/51/6b556192a04595b93e277a9ff71cd0cc06c21a7df98bcce5963fa0f5e36f/orjson-3.11.4-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d4371de39319d05d3f482f372720b841c841b52f5385bd99c61ed69d55d9ab50", size = 243571, upload-time = "2025-10-24T15:49:10.008Z" }, + { url = "https://files.pythonhosted.org/packages/1c/2c/2602392ddf2601d538ff11848b98621cd465d1a1ceb9db9e8043181f2f7b/orjson-3.11.4-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:e41fd3b3cac850eaae78232f37325ed7d7436e11c471246b87b2cd294ec94853", size = 128891, upload-time = "2025-10-24T15:49:11.297Z" }, + { url = "https://files.pythonhosted.org/packages/4e/47/bf85dcf95f7a3a12bf223394a4f849430acd82633848d52def09fa3f46ad/orjson-3.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600e0e9ca042878c7fdf189cf1b028fe2c1418cc9195f6cb9824eb6ed99cb938", size = 130137, upload-time = "2025-10-24T15:49:12.544Z" }, + { url = "https://files.pythonhosted.org/packages/b4/4d/a0cb31007f3ab6f1fd2a1b17057c7c349bc2baf8921a85c0180cc7be8011/orjson-3.11.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7bbf9b333f1568ef5da42bc96e18bf30fd7f8d54e9ae066d711056add508e415", size = 129152, upload-time = "2025-10-24T15:49:13.754Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ef/2811def7ce3d8576b19e3929fff8f8f0d44bc5eb2e0fdecb2e6e6cc6c720/orjson-3.11.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4806363144bb6e7297b8e95870e78d30a649fdc4e23fc84daa80c8ebd366ce44", size = 136834, upload-time = "2025-10-24T15:49:15.307Z" }, + { url = "https://files.pythonhosted.org/packages/00/d4/9aee9e54f1809cec8ed5abd9bc31e8a9631d19460e3b8470145d25140106/orjson-3.11.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad355e8308493f527d41154e9053b86a5be892b3b359a5c6d5d95cda23601cb2", size = 137519, upload-time = "2025-10-24T15:49:16.557Z" }, + { url = "https://files.pythonhosted.org/packages/db/ea/67bfdb5465d5679e8ae8d68c11753aaf4f47e3e7264bad66dc2f2249e643/orjson-3.11.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a7517482667fb9f0ff1b2f16fe5829296ed7a655d04d68cd9711a4d8a4e708", size = 136749, upload-time = "2025-10-24T15:49:17.796Z" }, + { url = "https://files.pythonhosted.org/packages/01/7e/62517dddcfce6d53a39543cd74d0dccfcbdf53967017c58af68822100272/orjson-3.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97eb5942c7395a171cbfecc4ef6701fc3c403e762194683772df4c54cfbb2210", size = 136325, upload-time = "2025-10-24T15:49:19.347Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/40516739f99ab4c7ec3aaa5cc242d341fcb03a45d89edeeaabc5f69cb2cf/orjson-3.11.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:149d95d5e018bdd822e3f38c103b1a7c91f88d38a88aada5c4e9b3a73a244241", size = 140204, upload-time = "2025-10-24T15:49:20.545Z" }, + { url = "https://files.pythonhosted.org/packages/82/18/ff5734365623a8916e3a4037fcef1cd1782bfc14cf0992afe7940c5320bf/orjson-3.11.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:624f3951181eb46fc47dea3d221554e98784c823e7069edb5dbd0dc826ac909b", size = 406242, upload-time = "2025-10-24T15:49:21.884Z" }, + { url = "https://files.pythonhosted.org/packages/e1/43/96436041f0a0c8c8deca6a05ebeaf529bf1de04839f93ac5e7c479807aec/orjson-3.11.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:03bfa548cf35e3f8b3a96c4e8e41f753c686ff3d8e182ce275b1751deddab58c", size = 150013, upload-time = "2025-10-24T15:49:23.185Z" }, + { url = "https://files.pythonhosted.org/packages/1b/48/78302d98423ed8780479a1e682b9aecb869e8404545d999d34fa486e573e/orjson-3.11.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:525021896afef44a68148f6ed8a8bf8375553d6066c7f48537657f64823565b9", size = 139951, upload-time = "2025-10-24T15:49:24.428Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7b/ad613fdcdaa812f075ec0875143c3d37f8654457d2af17703905425981bf/orjson-3.11.4-cp312-cp312-win32.whl", hash = "sha256:b58430396687ce0f7d9eeb3dd47761ca7d8fda8e9eb92b3077a7a353a75efefa", size = 136049, upload-time = "2025-10-24T15:49:25.973Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3c/9cf47c3ff5f39b8350fb21ba65d789b6a1129d4cbb3033ba36c8a9023520/orjson-3.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:c6dbf422894e1e3c80a177133c0dda260f81428f9de16d61041949f6a2e5c140", size = 131461, upload-time = "2025-10-24T15:49:27.259Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3b/e2425f61e5825dc5b08c2a5a2b3af387eaaca22a12b9c8c01504f8614c36/orjson-3.11.4-cp312-cp312-win_arm64.whl", hash = "sha256:d38d2bc06d6415852224fcc9c0bfa834c25431e466dc319f0edd56cca81aa96e", size = 126167, upload-time = "2025-10-24T15:49:28.511Z" }, + { url = "https://files.pythonhosted.org/packages/23/15/c52aa7112006b0f3d6180386c3a46ae057f932ab3425bc6f6ac50431cca1/orjson-3.11.4-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2d6737d0e616a6e053c8b4acc9eccea6b6cce078533666f32d140e4f85002534", size = 243525, upload-time = "2025-10-24T15:49:29.737Z" }, + { url = "https://files.pythonhosted.org/packages/ec/38/05340734c33b933fd114f161f25a04e651b0c7c33ab95e9416ade5cb44b8/orjson-3.11.4-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:afb14052690aa328cc118a8e09f07c651d301a72e44920b887c519b313d892ff", size = 128871, upload-time = "2025-10-24T15:49:31.109Z" }, + { url = "https://files.pythonhosted.org/packages/55/b9/ae8d34899ff0c012039b5a7cb96a389b2476e917733294e498586b45472d/orjson-3.11.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38aa9e65c591febb1b0aed8da4d469eba239d434c218562df179885c94e1a3ad", size = 130055, upload-time = "2025-10-24T15:49:33.382Z" }, + { url = "https://files.pythonhosted.org/packages/33/aa/6346dd5073730451bee3681d901e3c337e7ec17342fb79659ec9794fc023/orjson-3.11.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f2cf4dfaf9163b0728d061bebc1e08631875c51cd30bf47cb9e3293bfbd7dcd5", size = 129061, upload-time = "2025-10-24T15:49:34.935Z" }, + { url = "https://files.pythonhosted.org/packages/39/e4/8eea51598f66a6c853c380979912d17ec510e8e66b280d968602e680b942/orjson-3.11.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89216ff3dfdde0e4070932e126320a1752c9d9a758d6a32ec54b3b9334991a6a", size = 136541, upload-time = "2025-10-24T15:49:36.923Z" }, + { url = "https://files.pythonhosted.org/packages/9a/47/cb8c654fa9adcc60e99580e17c32b9e633290e6239a99efa6b885aba9dbc/orjson-3.11.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9daa26ca8e97fae0ce8aa5d80606ef8f7914e9b129b6b5df9104266f764ce436", size = 137535, upload-time = "2025-10-24T15:49:38.307Z" }, + { url = "https://files.pythonhosted.org/packages/43/92/04b8cc5c2b729f3437ee013ce14a60ab3d3001465d95c184758f19362f23/orjson-3.11.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c8b2769dc31883c44a9cd126560327767f848eb95f99c36c9932f51090bfce9", size = 136703, upload-time = "2025-10-24T15:49:40.795Z" }, + { url = "https://files.pythonhosted.org/packages/aa/fd/d0733fcb9086b8be4ebcfcda2d0312865d17d0d9884378b7cffb29d0763f/orjson-3.11.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1469d254b9884f984026bd9b0fa5bbab477a4bfe558bba6848086f6d43eb5e73", size = 136293, upload-time = "2025-10-24T15:49:42.347Z" }, + { url = "https://files.pythonhosted.org/packages/c2/d7/3c5514e806837c210492d72ae30ccf050ce3f940f45bf085bab272699ef4/orjson-3.11.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:68e44722541983614e37117209a194e8c3ad07838ccb3127d96863c95ec7f1e0", size = 140131, upload-time = "2025-10-24T15:49:43.638Z" }, + { url = "https://files.pythonhosted.org/packages/9c/dd/ba9d32a53207babf65bd510ac4d0faaa818bd0df9a9c6f472fe7c254f2e3/orjson-3.11.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8e7805fda9672c12be2f22ae124dcd7b03928d6c197544fe12174b86553f3196", size = 406164, upload-time = "2025-10-24T15:49:45.498Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f9/f68ad68f4af7c7bde57cd514eaa2c785e500477a8bc8f834838eb696a685/orjson-3.11.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:04b69c14615fb4434ab867bf6f38b2d649f6f300af30a6705397e895f7aec67a", size = 149859, upload-time = "2025-10-24T15:49:46.981Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d2/7f847761d0c26818395b3d6b21fb6bc2305d94612a35b0a30eae65a22728/orjson-3.11.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:639c3735b8ae7f970066930e58cf0ed39a852d417c24acd4a25fc0b3da3c39a6", size = 139926, upload-time = "2025-10-24T15:49:48.321Z" }, + { url = "https://files.pythonhosted.org/packages/9f/37/acd14b12dc62db9a0e1d12386271b8661faae270b22492580d5258808975/orjson-3.11.4-cp313-cp313-win32.whl", hash = "sha256:6c13879c0d2964335491463302a6ca5ad98105fc5db3565499dcb80b1b4bd839", size = 136007, upload-time = "2025-10-24T15:49:49.938Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a9/967be009ddf0a1fffd7a67de9c36656b28c763659ef91352acc02cbe364c/orjson-3.11.4-cp313-cp313-win_amd64.whl", hash = "sha256:09bf242a4af98732db9f9a1ec57ca2604848e16f132e3f72edfd3c5c96de009a", size = 131314, upload-time = "2025-10-24T15:49:51.248Z" }, + { url = "https://files.pythonhosted.org/packages/cb/db/399abd6950fbd94ce125cb8cd1a968def95174792e127b0642781e040ed4/orjson-3.11.4-cp313-cp313-win_arm64.whl", hash = "sha256:a85f0adf63319d6c1ba06fb0dbf997fced64a01179cf17939a6caca662bf92de", size = 126152, upload-time = "2025-10-24T15:49:52.922Z" }, + { url = "https://files.pythonhosted.org/packages/25/e3/54ff63c093cc1697e758e4fceb53164dd2661a7d1bcd522260ba09f54533/orjson-3.11.4-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:42d43a1f552be1a112af0b21c10a5f553983c2a0938d2bbb8ecd8bc9fb572803", size = 243501, upload-time = "2025-10-24T15:49:54.288Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7d/e2d1076ed2e8e0ae9badca65bf7ef22710f93887b29eaa37f09850604e09/orjson-3.11.4-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:26a20f3fbc6c7ff2cb8e89c4c5897762c9d88cf37330c6a117312365d6781d54", size = 128862, upload-time = "2025-10-24T15:49:55.961Z" }, + { url = "https://files.pythonhosted.org/packages/9f/37/ca2eb40b90621faddfa9517dfe96e25f5ae4d8057a7c0cdd613c17e07b2c/orjson-3.11.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3f20be9048941c7ffa8fc523ccbd17f82e24df1549d1d1fe9317712d19938e", size = 130047, upload-time = "2025-10-24T15:49:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/c7/62/1021ed35a1f2bad9040f05fa4cc4f9893410df0ba3eaa323ccf899b1c90a/orjson-3.11.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aac364c758dc87a52e68e349924d7e4ded348dedff553889e4d9f22f74785316", size = 129073, upload-time = "2025-10-24T15:49:58.782Z" }, + { url = "https://files.pythonhosted.org/packages/e8/3f/f84d966ec2a6fd5f73b1a707e7cd876813422ae4bf9f0145c55c9c6a0f57/orjson-3.11.4-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5c54a6d76e3d741dcc3f2707f8eeb9ba2a791d3adbf18f900219b62942803b1", size = 136597, upload-time = "2025-10-24T15:50:00.12Z" }, + { url = "https://files.pythonhosted.org/packages/32/78/4fa0aeca65ee82bbabb49e055bd03fa4edea33f7c080c5c7b9601661ef72/orjson-3.11.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f28485bdca8617b79d44627f5fb04336897041dfd9fa66d383a49d09d86798bc", size = 137515, upload-time = "2025-10-24T15:50:01.57Z" }, + { url = "https://files.pythonhosted.org/packages/c1/9d/0c102e26e7fde40c4c98470796d050a2ec1953897e2c8ab0cb95b0759fa2/orjson-3.11.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bfc2a484cad3585e4ba61985a6062a4c2ed5c7925db6d39f1fa267c9d166487f", size = 136703, upload-time = "2025-10-24T15:50:02.944Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/2de7188705b4cdfaf0b6c97d2f7849c17d2003232f6e70df98602173f788/orjson-3.11.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e34dbd508cb91c54f9c9788923daca129fe5b55c5b4eebe713bf5ed3791280cf", size = 136311, upload-time = "2025-10-24T15:50:04.441Z" }, + { url = "https://files.pythonhosted.org/packages/e0/52/847fcd1a98407154e944feeb12e3b4d487a0e264c40191fb44d1269cbaa1/orjson-3.11.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b13c478fa413d4b4ee606ec8e11c3b2e52683a640b006bb586b3041c2ca5f606", size = 140127, upload-time = "2025-10-24T15:50:07.398Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ae/21d208f58bdb847dd4d0d9407e2929862561841baa22bdab7aea10ca088e/orjson-3.11.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:724ca721ecc8a831b319dcd72cfa370cc380db0bf94537f08f7edd0a7d4e1780", size = 406201, upload-time = "2025-10-24T15:50:08.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/55/0789d6de386c8366059db098a628e2ad8798069e94409b0d8935934cbcb9/orjson-3.11.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:977c393f2e44845ce1b540e19a786e9643221b3323dae190668a98672d43fb23", size = 149872, upload-time = "2025-10-24T15:50:10.234Z" }, + { url = "https://files.pythonhosted.org/packages/cc/1d/7ff81ea23310e086c17b41d78a72270d9de04481e6113dbe2ac19118f7fb/orjson-3.11.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1e539e382cf46edec157ad66b0b0872a90d829a6b71f17cb633d6c160a223155", size = 139931, upload-time = "2025-10-24T15:50:11.623Z" }, + { url = "https://files.pythonhosted.org/packages/77/92/25b886252c50ed64be68c937b562b2f2333b45afe72d53d719e46a565a50/orjson-3.11.4-cp314-cp314-win32.whl", hash = "sha256:d63076d625babab9db5e7836118bdfa086e60f37d8a174194ae720161eb12394", size = 136065, upload-time = "2025-10-24T15:50:13.025Z" }, + { url = "https://files.pythonhosted.org/packages/63/b8/718eecf0bb7e9d64e4956afaafd23db9f04c776d445f59fe94f54bdae8f0/orjson-3.11.4-cp314-cp314-win_amd64.whl", hash = "sha256:0a54d6635fa3aaa438ae32e8570b9f0de36f3f6562c308d2a2a452e8b0592db1", size = 131310, upload-time = "2025-10-24T15:50:14.46Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bf/def5e25d4d8bfce296a9a7c8248109bf58622c21618b590678f945a2c59c/orjson-3.11.4-cp314-cp314-win_arm64.whl", hash = "sha256:78b999999039db3cf58f6d230f524f04f75f129ba3d1ca2ed121f8657e575d3d", size = 126151, upload-time = "2025-10-24T15:50:15.878Z" }, ] [[package]] name = "packaging" version = "23.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fb/2b/9b9c33ffed44ee921d0967086d653047286054117d584f1b1a7c22ceaf7b/packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", size = 146714 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/2b/9b9c33ffed44ee921d0967086d653047286054117d584f1b1a7c22ceaf7b/packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", size = 146714, upload-time = "2023-10-01T13:50:05.279Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7", size = 53011 }, + { url = "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7", size = 53011, upload-time = "2023-10-01T13:50:03.745Z" }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "pillow" version = "10.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/74/ad3d526f3bf7b6d3f408b73fde271ec69dfac8b81341a318ce825f2b3812/pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", size = 46555059 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/74/ad3d526f3bf7b6d3f408b73fde271ec69dfac8b81341a318ce825f2b3812/pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", size = 46555059, upload-time = "2024-07-01T09:48:43.583Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/69/a31cccd538ca0b5272be2a38347f8839b97a14be104ea08b0db92f749c74/pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", size = 3509271 }, - { url = "https://files.pythonhosted.org/packages/9a/9e/4143b907be8ea0bce215f2ae4f7480027473f8b61fcedfda9d851082a5d2/pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", size = 3375658 }, - { url = "https://files.pythonhosted.org/packages/8a/25/1fc45761955f9359b1169aa75e241551e74ac01a09f487adaaf4c3472d11/pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", size = 4332075 }, - { url = "https://files.pythonhosted.org/packages/5e/dd/425b95d0151e1d6c951f45051112394f130df3da67363b6bc75dc4c27aba/pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", size = 4444808 }, - { url = "https://files.pythonhosted.org/packages/b1/84/9a15cc5726cbbfe7f9f90bfb11f5d028586595907cd093815ca6644932e3/pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", size = 4356290 }, - { url = "https://files.pythonhosted.org/packages/b5/5b/6651c288b08df3b8c1e2f8c1152201e0b25d240e22ddade0f1e242fc9fa0/pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", size = 4525163 }, - { url = "https://files.pythonhosted.org/packages/07/8b/34854bf11a83c248505c8cb0fcf8d3d0b459a2246c8809b967963b6b12ae/pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", size = 4463100 }, - { url = "https://files.pythonhosted.org/packages/78/63/0632aee4e82476d9cbe5200c0cdf9ba41ee04ed77887432845264d81116d/pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", size = 4592880 }, - { url = "https://files.pythonhosted.org/packages/df/56/b8663d7520671b4398b9d97e1ed9f583d4afcbefbda3c6188325e8c297bd/pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", size = 2235218 }, - { url = "https://files.pythonhosted.org/packages/f4/72/0203e94a91ddb4a9d5238434ae6c1ca10e610e8487036132ea9bf806ca2a/pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", size = 2554487 }, - { url = "https://files.pythonhosted.org/packages/bd/52/7e7e93d7a6e4290543f17dc6f7d3af4bd0b3dd9926e2e8a35ac2282bc5f4/pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1", size = 2243219 }, - { url = "https://files.pythonhosted.org/packages/a7/62/c9449f9c3043c37f73e7487ec4ef0c03eb9c9afc91a92b977a67b3c0bbc5/pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", size = 3509265 }, - { url = "https://files.pythonhosted.org/packages/f4/5f/491dafc7bbf5a3cc1845dc0430872e8096eb9e2b6f8161509d124594ec2d/pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", size = 3375655 }, - { url = "https://files.pythonhosted.org/packages/73/d5/c4011a76f4207a3c151134cd22a1415741e42fa5ddecec7c0182887deb3d/pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", size = 4340304 }, - { url = "https://files.pythonhosted.org/packages/ac/10/c67e20445a707f7a610699bba4fe050583b688d8cd2d202572b257f46600/pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", size = 4452804 }, - { url = "https://files.pythonhosted.org/packages/a9/83/6523837906d1da2b269dee787e31df3b0acb12e3d08f024965a3e7f64665/pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", size = 4365126 }, - { url = "https://files.pythonhosted.org/packages/ba/e5/8c68ff608a4203085158cff5cc2a3c534ec384536d9438c405ed6370d080/pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", size = 4533541 }, - { url = "https://files.pythonhosted.org/packages/f4/7c/01b8dbdca5bc6785573f4cee96e2358b0918b7b2c7b60d8b6f3abf87a070/pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", size = 4471616 }, - { url = "https://files.pythonhosted.org/packages/c8/57/2899b82394a35a0fbfd352e290945440e3b3785655a03365c0ca8279f351/pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", size = 4600802 }, - { url = "https://files.pythonhosted.org/packages/4d/d7/a44f193d4c26e58ee5d2d9db3d4854b2cfb5b5e08d360a5e03fe987c0086/pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", size = 2235213 }, - { url = "https://files.pythonhosted.org/packages/c1/d0/5866318eec2b801cdb8c82abf190c8343d8a1cd8bf5a0c17444a6f268291/pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", size = 2554498 }, - { url = "https://files.pythonhosted.org/packages/d4/c8/310ac16ac2b97e902d9eb438688de0d961660a87703ad1561fd3dfbd2aa0/pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", size = 2243219 }, - { url = "https://files.pythonhosted.org/packages/05/cb/0353013dc30c02a8be34eb91d25e4e4cf594b59e5a55ea1128fde1e5f8ea/pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", size = 3509350 }, - { url = "https://files.pythonhosted.org/packages/e7/cf/5c558a0f247e0bf9cec92bff9b46ae6474dd736f6d906315e60e4075f737/pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", size = 3374980 }, - { url = "https://files.pythonhosted.org/packages/84/48/6e394b86369a4eb68b8a1382c78dc092245af517385c086c5094e3b34428/pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", size = 4343799 }, - { url = "https://files.pythonhosted.org/packages/3b/f3/a8c6c11fa84b59b9df0cd5694492da8c039a24cd159f0f6918690105c3be/pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", size = 4459973 }, - { url = "https://files.pythonhosted.org/packages/7d/1b/c14b4197b80150fb64453585247e6fb2e1d93761fa0fa9cf63b102fde822/pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", size = 4370054 }, - { url = "https://files.pythonhosted.org/packages/55/77/40daddf677897a923d5d33329acd52a2144d54a9644f2a5422c028c6bf2d/pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", size = 4539484 }, - { url = "https://files.pythonhosted.org/packages/40/54/90de3e4256b1207300fb2b1d7168dd912a2fb4b2401e439ba23c2b2cabde/pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", size = 4477375 }, - { url = "https://files.pythonhosted.org/packages/13/24/1bfba52f44193860918ff7c93d03d95e3f8748ca1de3ceaf11157a14cf16/pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", size = 4608773 }, - { url = "https://files.pythonhosted.org/packages/55/04/5e6de6e6120451ec0c24516c41dbaf80cce1b6451f96561235ef2429da2e/pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", size = 2235690 }, - { url = "https://files.pythonhosted.org/packages/74/0a/d4ce3c44bca8635bd29a2eab5aa181b654a734a29b263ca8efe013beea98/pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", size = 2554951 }, - { url = "https://files.pythonhosted.org/packages/b5/ca/184349ee40f2e92439be9b3502ae6cfc43ac4b50bc4fc6b3de7957563894/pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", size = 2243427 }, - { url = "https://files.pythonhosted.org/packages/c3/00/706cebe7c2c12a6318aabe5d354836f54adff7156fd9e1bd6c89f4ba0e98/pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", size = 3525685 }, - { url = "https://files.pythonhosted.org/packages/cf/76/f658cbfa49405e5ecbfb9ba42d07074ad9792031267e782d409fd8fe7c69/pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", size = 3374883 }, - { url = "https://files.pythonhosted.org/packages/46/2b/99c28c4379a85e65378211971c0b430d9c7234b1ec4d59b2668f6299e011/pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", size = 4339837 }, - { url = "https://files.pythonhosted.org/packages/f1/74/b1ec314f624c0c43711fdf0d8076f82d9d802afd58f1d62c2a86878e8615/pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", size = 4455562 }, - { url = "https://files.pythonhosted.org/packages/4a/2a/4b04157cb7b9c74372fa867096a1607e6fedad93a44deeff553ccd307868/pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", size = 4366761 }, - { url = "https://files.pythonhosted.org/packages/ac/7b/8f1d815c1a6a268fe90481232c98dd0e5fa8c75e341a75f060037bd5ceae/pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", size = 4536767 }, - { url = "https://files.pythonhosted.org/packages/e5/77/05fa64d1f45d12c22c314e7b97398ffb28ef2813a485465017b7978b3ce7/pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", size = 4477989 }, - { url = "https://files.pythonhosted.org/packages/12/63/b0397cfc2caae05c3fb2f4ed1b4fc4fc878f0243510a7a6034ca59726494/pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", size = 4610255 }, - { url = "https://files.pythonhosted.org/packages/7b/f9/cfaa5082ca9bc4a6de66ffe1c12c2d90bf09c309a5f52b27759a596900e7/pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", size = 2235603 }, - { url = "https://files.pythonhosted.org/packages/01/6a/30ff0eef6e0c0e71e55ded56a38d4859bf9d3634a94a88743897b5f96936/pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", size = 2554972 }, - { url = "https://files.pythonhosted.org/packages/48/2c/2e0a52890f269435eee38b21c8218e102c621fe8d8df8b9dd06fabf879ba/pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", size = 2243375 }, - { url = "https://files.pythonhosted.org/packages/38/30/095d4f55f3a053392f75e2eae45eba3228452783bab3d9a920b951ac495c/pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", size = 3493889 }, - { url = "https://files.pythonhosted.org/packages/f3/e8/4ff79788803a5fcd5dc35efdc9386af153569853767bff74540725b45863/pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", size = 3346160 }, - { url = "https://files.pythonhosted.org/packages/d7/ac/4184edd511b14f760c73f5bb8a5d6fd85c591c8aff7c2229677a355c4179/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", size = 3435020 }, - { url = "https://files.pythonhosted.org/packages/da/21/1749cd09160149c0a246a81d646e05f35041619ce76f6493d6a96e8d1103/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", size = 3490539 }, - { url = "https://files.pythonhosted.org/packages/b6/f5/f71fe1888b96083b3f6dfa0709101f61fc9e972c0c8d04e9d93ccef2a045/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", size = 3476125 }, - { url = "https://files.pythonhosted.org/packages/96/b9/c0362c54290a31866c3526848583a2f45a535aa9d725fd31e25d318c805f/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", size = 3579373 }, - { url = "https://files.pythonhosted.org/packages/52/3b/ce7a01026a7cf46e5452afa86f97a5e88ca97f562cafa76570178ab56d8d/pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", size = 2554661 }, + { url = "https://files.pythonhosted.org/packages/0e/69/a31cccd538ca0b5272be2a38347f8839b97a14be104ea08b0db92f749c74/pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", size = 3509271, upload-time = "2024-07-01T09:45:22.07Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9e/4143b907be8ea0bce215f2ae4f7480027473f8b61fcedfda9d851082a5d2/pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", size = 3375658, upload-time = "2024-07-01T09:45:25.292Z" }, + { url = "https://files.pythonhosted.org/packages/8a/25/1fc45761955f9359b1169aa75e241551e74ac01a09f487adaaf4c3472d11/pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", size = 4332075, upload-time = "2024-07-01T09:45:27.94Z" }, + { url = "https://files.pythonhosted.org/packages/5e/dd/425b95d0151e1d6c951f45051112394f130df3da67363b6bc75dc4c27aba/pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", size = 4444808, upload-time = "2024-07-01T09:45:30.305Z" }, + { url = "https://files.pythonhosted.org/packages/b1/84/9a15cc5726cbbfe7f9f90bfb11f5d028586595907cd093815ca6644932e3/pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", size = 4356290, upload-time = "2024-07-01T09:45:32.868Z" }, + { url = "https://files.pythonhosted.org/packages/b5/5b/6651c288b08df3b8c1e2f8c1152201e0b25d240e22ddade0f1e242fc9fa0/pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", size = 4525163, upload-time = "2024-07-01T09:45:35.279Z" }, + { url = "https://files.pythonhosted.org/packages/07/8b/34854bf11a83c248505c8cb0fcf8d3d0b459a2246c8809b967963b6b12ae/pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", size = 4463100, upload-time = "2024-07-01T09:45:37.74Z" }, + { url = "https://files.pythonhosted.org/packages/78/63/0632aee4e82476d9cbe5200c0cdf9ba41ee04ed77887432845264d81116d/pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", size = 4592880, upload-time = "2024-07-01T09:45:39.89Z" }, + { url = "https://files.pythonhosted.org/packages/df/56/b8663d7520671b4398b9d97e1ed9f583d4afcbefbda3c6188325e8c297bd/pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", size = 2235218, upload-time = "2024-07-01T09:45:42.771Z" }, + { url = "https://files.pythonhosted.org/packages/f4/72/0203e94a91ddb4a9d5238434ae6c1ca10e610e8487036132ea9bf806ca2a/pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", size = 2554487, upload-time = "2024-07-01T09:45:45.176Z" }, + { url = "https://files.pythonhosted.org/packages/bd/52/7e7e93d7a6e4290543f17dc6f7d3af4bd0b3dd9926e2e8a35ac2282bc5f4/pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1", size = 2243219, upload-time = "2024-07-01T09:45:47.274Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/c9449f9c3043c37f73e7487ec4ef0c03eb9c9afc91a92b977a67b3c0bbc5/pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", size = 3509265, upload-time = "2024-07-01T09:45:49.812Z" }, + { url = "https://files.pythonhosted.org/packages/f4/5f/491dafc7bbf5a3cc1845dc0430872e8096eb9e2b6f8161509d124594ec2d/pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", size = 3375655, upload-time = "2024-07-01T09:45:52.462Z" }, + { url = "https://files.pythonhosted.org/packages/73/d5/c4011a76f4207a3c151134cd22a1415741e42fa5ddecec7c0182887deb3d/pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", size = 4340304, upload-time = "2024-07-01T09:45:55.006Z" }, + { url = "https://files.pythonhosted.org/packages/ac/10/c67e20445a707f7a610699bba4fe050583b688d8cd2d202572b257f46600/pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", size = 4452804, upload-time = "2024-07-01T09:45:58.437Z" }, + { url = "https://files.pythonhosted.org/packages/a9/83/6523837906d1da2b269dee787e31df3b0acb12e3d08f024965a3e7f64665/pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", size = 4365126, upload-time = "2024-07-01T09:46:00.713Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e5/8c68ff608a4203085158cff5cc2a3c534ec384536d9438c405ed6370d080/pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", size = 4533541, upload-time = "2024-07-01T09:46:03.235Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7c/01b8dbdca5bc6785573f4cee96e2358b0918b7b2c7b60d8b6f3abf87a070/pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", size = 4471616, upload-time = "2024-07-01T09:46:05.356Z" }, + { url = "https://files.pythonhosted.org/packages/c8/57/2899b82394a35a0fbfd352e290945440e3b3785655a03365c0ca8279f351/pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", size = 4600802, upload-time = "2024-07-01T09:46:08.145Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d7/a44f193d4c26e58ee5d2d9db3d4854b2cfb5b5e08d360a5e03fe987c0086/pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", size = 2235213, upload-time = "2024-07-01T09:46:10.211Z" }, + { url = "https://files.pythonhosted.org/packages/c1/d0/5866318eec2b801cdb8c82abf190c8343d8a1cd8bf5a0c17444a6f268291/pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", size = 2554498, upload-time = "2024-07-01T09:46:12.685Z" }, + { url = "https://files.pythonhosted.org/packages/d4/c8/310ac16ac2b97e902d9eb438688de0d961660a87703ad1561fd3dfbd2aa0/pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", size = 2243219, upload-time = "2024-07-01T09:46:14.83Z" }, + { url = "https://files.pythonhosted.org/packages/05/cb/0353013dc30c02a8be34eb91d25e4e4cf594b59e5a55ea1128fde1e5f8ea/pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", size = 3509350, upload-time = "2024-07-01T09:46:17.177Z" }, + { url = "https://files.pythonhosted.org/packages/e7/cf/5c558a0f247e0bf9cec92bff9b46ae6474dd736f6d906315e60e4075f737/pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", size = 3374980, upload-time = "2024-07-01T09:46:19.169Z" }, + { url = "https://files.pythonhosted.org/packages/84/48/6e394b86369a4eb68b8a1382c78dc092245af517385c086c5094e3b34428/pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", size = 4343799, upload-time = "2024-07-01T09:46:21.883Z" }, + { url = "https://files.pythonhosted.org/packages/3b/f3/a8c6c11fa84b59b9df0cd5694492da8c039a24cd159f0f6918690105c3be/pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", size = 4459973, upload-time = "2024-07-01T09:46:24.321Z" }, + { url = "https://files.pythonhosted.org/packages/7d/1b/c14b4197b80150fb64453585247e6fb2e1d93761fa0fa9cf63b102fde822/pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", size = 4370054, upload-time = "2024-07-01T09:46:26.825Z" }, + { url = "https://files.pythonhosted.org/packages/55/77/40daddf677897a923d5d33329acd52a2144d54a9644f2a5422c028c6bf2d/pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", size = 4539484, upload-time = "2024-07-01T09:46:29.355Z" }, + { url = "https://files.pythonhosted.org/packages/40/54/90de3e4256b1207300fb2b1d7168dd912a2fb4b2401e439ba23c2b2cabde/pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", size = 4477375, upload-time = "2024-07-01T09:46:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/13/24/1bfba52f44193860918ff7c93d03d95e3f8748ca1de3ceaf11157a14cf16/pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", size = 4608773, upload-time = "2024-07-01T09:46:33.73Z" }, + { url = "https://files.pythonhosted.org/packages/55/04/5e6de6e6120451ec0c24516c41dbaf80cce1b6451f96561235ef2429da2e/pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", size = 2235690, upload-time = "2024-07-01T09:46:36.587Z" }, + { url = "https://files.pythonhosted.org/packages/74/0a/d4ce3c44bca8635bd29a2eab5aa181b654a734a29b263ca8efe013beea98/pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", size = 2554951, upload-time = "2024-07-01T09:46:38.777Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ca/184349ee40f2e92439be9b3502ae6cfc43ac4b50bc4fc6b3de7957563894/pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", size = 2243427, upload-time = "2024-07-01T09:46:43.15Z" }, + { url = "https://files.pythonhosted.org/packages/c3/00/706cebe7c2c12a6318aabe5d354836f54adff7156fd9e1bd6c89f4ba0e98/pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", size = 3525685, upload-time = "2024-07-01T09:46:45.194Z" }, + { url = "https://files.pythonhosted.org/packages/cf/76/f658cbfa49405e5ecbfb9ba42d07074ad9792031267e782d409fd8fe7c69/pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", size = 3374883, upload-time = "2024-07-01T09:46:47.331Z" }, + { url = "https://files.pythonhosted.org/packages/46/2b/99c28c4379a85e65378211971c0b430d9c7234b1ec4d59b2668f6299e011/pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", size = 4339837, upload-time = "2024-07-01T09:46:49.647Z" }, + { url = "https://files.pythonhosted.org/packages/f1/74/b1ec314f624c0c43711fdf0d8076f82d9d802afd58f1d62c2a86878e8615/pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", size = 4455562, upload-time = "2024-07-01T09:46:51.811Z" }, + { url = "https://files.pythonhosted.org/packages/4a/2a/4b04157cb7b9c74372fa867096a1607e6fedad93a44deeff553ccd307868/pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", size = 4366761, upload-time = "2024-07-01T09:46:53.961Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7b/8f1d815c1a6a268fe90481232c98dd0e5fa8c75e341a75f060037bd5ceae/pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", size = 4536767, upload-time = "2024-07-01T09:46:56.664Z" }, + { url = "https://files.pythonhosted.org/packages/e5/77/05fa64d1f45d12c22c314e7b97398ffb28ef2813a485465017b7978b3ce7/pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", size = 4477989, upload-time = "2024-07-01T09:46:58.977Z" }, + { url = "https://files.pythonhosted.org/packages/12/63/b0397cfc2caae05c3fb2f4ed1b4fc4fc878f0243510a7a6034ca59726494/pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", size = 4610255, upload-time = "2024-07-01T09:47:01.189Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f9/cfaa5082ca9bc4a6de66ffe1c12c2d90bf09c309a5f52b27759a596900e7/pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", size = 2235603, upload-time = "2024-07-01T09:47:03.918Z" }, + { url = "https://files.pythonhosted.org/packages/01/6a/30ff0eef6e0c0e71e55ded56a38d4859bf9d3634a94a88743897b5f96936/pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", size = 2554972, upload-time = "2024-07-01T09:47:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/48/2c/2e0a52890f269435eee38b21c8218e102c621fe8d8df8b9dd06fabf879ba/pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", size = 2243375, upload-time = "2024-07-01T09:47:09.065Z" }, + { url = "https://files.pythonhosted.org/packages/38/30/095d4f55f3a053392f75e2eae45eba3228452783bab3d9a920b951ac495c/pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", size = 3493889, upload-time = "2024-07-01T09:48:04.815Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e8/4ff79788803a5fcd5dc35efdc9386af153569853767bff74540725b45863/pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", size = 3346160, upload-time = "2024-07-01T09:48:07.206Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ac/4184edd511b14f760c73f5bb8a5d6fd85c591c8aff7c2229677a355c4179/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", size = 3435020, upload-time = "2024-07-01T09:48:09.66Z" }, + { url = "https://files.pythonhosted.org/packages/da/21/1749cd09160149c0a246a81d646e05f35041619ce76f6493d6a96e8d1103/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", size = 3490539, upload-time = "2024-07-01T09:48:12.529Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f5/f71fe1888b96083b3f6dfa0709101f61fc9e972c0c8d04e9d93ccef2a045/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", size = 3476125, upload-time = "2024-07-01T09:48:14.891Z" }, + { url = "https://files.pythonhosted.org/packages/96/b9/c0362c54290a31866c3526848583a2f45a535aa9d725fd31e25d318c805f/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", size = 3579373, upload-time = "2024-07-01T09:48:17.601Z" }, + { url = "https://files.pythonhosted.org/packages/52/3b/ce7a01026a7cf46e5452afa86f97a5e88ca97f562cafa76570178ab56d8d/pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", size = 2554661, upload-time = "2024-07-01T09:48:20.293Z" }, ] [[package]] name = "platformdirs" version = "4.3.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291 } +sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291, upload-time = "2025-03-19T20:36:10.989Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499 }, + { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499, upload-time = "2025-03-19T20:36:09.038Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] @@ -2067,83 +2130,83 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/c0/5e9c4d2a643a00a6f67578ef35485173de273a4567279e4f0c200c01386b/prettytable-3.9.0.tar.gz", hash = "sha256:f4ed94803c23073a90620b201965e5dc0bccf1760b7a7eaf3158cab8aaffdf34", size = 47874 } +sdist = { url = "https://files.pythonhosted.org/packages/e1/c0/5e9c4d2a643a00a6f67578ef35485173de273a4567279e4f0c200c01386b/prettytable-3.9.0.tar.gz", hash = "sha256:f4ed94803c23073a90620b201965e5dc0bccf1760b7a7eaf3158cab8aaffdf34", size = 47874, upload-time = "2023-09-11T14:04:14.548Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/81/316b6a55a0d1f327d04cc7b0ba9d04058cb62de6c3a4d4b0df280cbe3b0b/prettytable-3.9.0-py3-none-any.whl", hash = "sha256:a71292ab7769a5de274b146b276ce938786f56c31cf7cea88b6f3775d82fe8c8", size = 27772 }, + { url = "https://files.pythonhosted.org/packages/4d/81/316b6a55a0d1f327d04cc7b0ba9d04058cb62de6c3a4d4b0df280cbe3b0b/prettytable-3.9.0-py3-none-any.whl", hash = "sha256:a71292ab7769a5de274b146b276ce938786f56c31cf7cea88b6f3775d82fe8c8", size = 27772, upload-time = "2023-09-11T14:03:45.582Z" }, ] [[package]] name = "protobuf" version = "4.25.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/a5/05ea470f4e793c9408bc975ce1c6957447e3134ce7f7a58c13be8b2c216f/protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e", size = 380282 } +sdist = { url = "https://files.pythonhosted.org/packages/db/a5/05ea470f4e793c9408bc975ce1c6957447e3134ce7f7a58c13be8b2c216f/protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e", size = 380282, upload-time = "2024-01-10T19:37:42.958Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/2f/01f63896ddf22cbb0173ab51f54fde70b0208ca6c2f5e8416950977930e1/protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6", size = 392408 }, - { url = "https://files.pythonhosted.org/packages/c1/00/c3ae19cabb36cfabc94ff0b102aac21b471c9f91a1357f8aafffb9efe8e0/protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9", size = 413397 }, - { url = "https://files.pythonhosted.org/packages/b3/81/0017aefacf23273d4efd1154ef958a27eed9c177c4cc09d2d4ba398fb47f/protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d", size = 394159 }, - { url = "https://files.pythonhosted.org/packages/23/17/405ba44f60a693dfe96c7a18e843707cffa0fcfad80bd8fc4f227f499ea5/protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62", size = 293698 }, - { url = "https://files.pythonhosted.org/packages/81/9e/63501b8d5b4e40c7260049836bd15ec3270c936e83bc57b85e4603cc212c/protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020", size = 294609 }, - { url = "https://files.pythonhosted.org/packages/ff/52/5d23df1fe3b368133ec3e2436fb3dd4ccedf44c8d5ac7f4a88087c75180b/protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830", size = 156463 }, + { url = "https://files.pythonhosted.org/packages/36/2f/01f63896ddf22cbb0173ab51f54fde70b0208ca6c2f5e8416950977930e1/protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6", size = 392408, upload-time = "2024-01-10T19:37:23.466Z" }, + { url = "https://files.pythonhosted.org/packages/c1/00/c3ae19cabb36cfabc94ff0b102aac21b471c9f91a1357f8aafffb9efe8e0/protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9", size = 413397, upload-time = "2024-01-10T19:37:26.321Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/0017aefacf23273d4efd1154ef958a27eed9c177c4cc09d2d4ba398fb47f/protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d", size = 394159, upload-time = "2024-01-10T19:37:28.932Z" }, + { url = "https://files.pythonhosted.org/packages/23/17/405ba44f60a693dfe96c7a18e843707cffa0fcfad80bd8fc4f227f499ea5/protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62", size = 293698, upload-time = "2024-01-10T19:37:30.666Z" }, + { url = "https://files.pythonhosted.org/packages/81/9e/63501b8d5b4e40c7260049836bd15ec3270c936e83bc57b85e4603cc212c/protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020", size = 294609, upload-time = "2024-01-10T19:37:32.777Z" }, + { url = "https://files.pythonhosted.org/packages/ff/52/5d23df1fe3b368133ec3e2436fb3dd4ccedf44c8d5ac7f4a88087c75180b/protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830", size = 156463, upload-time = "2024-01-10T19:37:41.24Z" }, ] [[package]] name = "psutil" version = "5.9.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a0/d0/c9ae661a302931735237791f04cb7086ac244377f78692ba3b3eae3a9619/psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c", size = 498429 } +sdist = { url = "https://files.pythonhosted.org/packages/a0/d0/c9ae661a302931735237791f04cb7086ac244377f78692ba3b3eae3a9619/psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c", size = 498429, upload-time = "2023-12-17T11:25:21.22Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/63/86a4ccc640b4ee1193800f57bbd20b766853c0cdbdbb248a27cdfafe6cbf/psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e", size = 245972 }, - { url = "https://files.pythonhosted.org/packages/58/80/cc6666b3968646f2d94de66bbc63d701d501f4aa04de43dd7d1f5dc477dd/psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284", size = 282514 }, - { url = "https://files.pythonhosted.org/packages/be/fa/f1f626620e3b47e6237dcc64cb8cc1472f139e99422e5b9fa5bbcf457f48/psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe", size = 285469 }, - { url = "https://files.pythonhosted.org/packages/7c/b8/dc6ebfc030b47cccc5f5229eeb15e64142b4782796c3ce169ccd60b4d511/psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68", size = 248406 }, - { url = "https://files.pythonhosted.org/packages/50/28/92b74d95dd991c837813ffac0c79a581a3d129eb0fa7c1dd616d9901e0f3/psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414", size = 252245 }, - { url = "https://files.pythonhosted.org/packages/ba/8a/000d0e80156f0b96c55bda6c60f5ed6543d7b5e893ccab83117e50de1400/psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340", size = 246739 }, + { url = "https://files.pythonhosted.org/packages/6c/63/86a4ccc640b4ee1193800f57bbd20b766853c0cdbdbb248a27cdfafe6cbf/psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e", size = 245972, upload-time = "2023-12-17T11:25:48.202Z" }, + { url = "https://files.pythonhosted.org/packages/58/80/cc6666b3968646f2d94de66bbc63d701d501f4aa04de43dd7d1f5dc477dd/psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284", size = 282514, upload-time = "2023-12-17T11:25:51.371Z" }, + { url = "https://files.pythonhosted.org/packages/be/fa/f1f626620e3b47e6237dcc64cb8cc1472f139e99422e5b9fa5bbcf457f48/psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe", size = 285469, upload-time = "2023-12-17T11:25:54.25Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b8/dc6ebfc030b47cccc5f5229eeb15e64142b4782796c3ce169ccd60b4d511/psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68", size = 248406, upload-time = "2023-12-17T12:38:50.326Z" }, + { url = "https://files.pythonhosted.org/packages/50/28/92b74d95dd991c837813ffac0c79a581a3d129eb0fa7c1dd616d9901e0f3/psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414", size = 252245, upload-time = "2023-12-17T12:39:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8a/000d0e80156f0b96c55bda6c60f5ed6543d7b5e893ccab83117e50de1400/psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340", size = 246739, upload-time = "2023-12-17T11:25:57.305Z" }, ] [[package]] name = "pyclipper" version = "1.3.0.post6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/b2/550fe500e49c464d73fabcb8cb04d47e4885d6ca4cfc1f5b0a125a95b19a/pyclipper-1.3.0.post6.tar.gz", hash = "sha256:42bff0102fa7a7f2abdd795a2594654d62b786d0c6cd67b72d469114fdeb608c", size = 165909 } +sdist = { url = "https://files.pythonhosted.org/packages/4a/b2/550fe500e49c464d73fabcb8cb04d47e4885d6ca4cfc1f5b0a125a95b19a/pyclipper-1.3.0.post6.tar.gz", hash = "sha256:42bff0102fa7a7f2abdd795a2594654d62b786d0c6cd67b72d469114fdeb608c", size = 165909, upload-time = "2024-10-18T12:23:09.069Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/34/0dca299fe41e9a92e78735502fed5238a4ac734755e624488df9b2eeec46/pyclipper-1.3.0.post6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fa0f5e78cfa8262277bb3d0225537b3c2a90ef68fd90a229d5d24cf49955dcf4", size = 269504 }, - { url = "https://files.pythonhosted.org/packages/8a/5b/81528b08134b3c2abdfae821e1eff975c0703802d41974b02dfb2e101c55/pyclipper-1.3.0.post6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a01f182d8938c1dc515e8508ed2442f7eebd2c25c7d5cb29281f583c1a8008a4", size = 142599 }, - { url = "https://files.pythonhosted.org/packages/84/a4/3e304f6c0d000382cd54d4a1e5f0d8fc28e1ae97413a2ec1016a7b840319/pyclipper-1.3.0.post6-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:640f20975727994d4abacd07396f564e9e5665ba5cb66ceb36b300c281f84fa4", size = 912209 }, - { url = "https://files.pythonhosted.org/packages/f5/6a/28ec55cc3f972368b211fca017e081cf5a71009d1b8ec3559767cda5b289/pyclipper-1.3.0.post6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63002f6bb0f1efa87c0b81634cbb571066f237067e23707dabf746306c92ba5", size = 929511 }, - { url = "https://files.pythonhosted.org/packages/c4/56/c326f3454c5f30a31f58a5c3154d891fce58ad73ccbf1d3f4aacfcbd344d/pyclipper-1.3.0.post6-cp310-cp310-win32.whl", hash = "sha256:106b8622cd9fb07d80cbf9b1d752334c55839203bae962376a8c59087788af26", size = 100126 }, - { url = "https://files.pythonhosted.org/packages/f8/e6/f8239af6346848b20a3448c554782fe59298ab06c1d040490242dc7e3c26/pyclipper-1.3.0.post6-cp310-cp310-win_amd64.whl", hash = "sha256:9699e98862dadefd0bea2360c31fa61ca553c660cbf6fb44993acde1b959f58f", size = 110470 }, - { url = "https://files.pythonhosted.org/packages/50/a9/66ca5f252dcac93ca076698591b838ba17f9729591edf4b74fef7fbe1414/pyclipper-1.3.0.post6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4247e7c44b34c87acbf38f99d48fb1acaf5da4a2cf4dcd601a9b24d431be4ef", size = 270930 }, - { url = "https://files.pythonhosted.org/packages/59/fe/2ab5818b3504e179086e54a37ecc245525d069267b8c31b18ec3d0830cbf/pyclipper-1.3.0.post6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:851b3e58106c62a5534a1201295fe20c21714dee2eda68081b37ddb0367e6caa", size = 143411 }, - { url = "https://files.pythonhosted.org/packages/09/f7/b58794f643e033a6d14da7c70f517315c3072f3c5fccdf4232fa8c8090c1/pyclipper-1.3.0.post6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16cc1705a915896d2aff52131c427df02265631279eac849ebda766432714cc0", size = 951754 }, - { url = "https://files.pythonhosted.org/packages/c1/77/846a21957cd4ed266c36705ee340beaa923eb57d2bba013cfd7a5c417cfd/pyclipper-1.3.0.post6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace1f0753cf71c5c5f6488b8feef5dd0fa8b976ad86b24bb51f708f513df4aac", size = 969608 }, - { url = "https://files.pythonhosted.org/packages/c9/2b/580703daa6606d160caf596522d4cfdf62ae619b062a7ce6f905821a57e8/pyclipper-1.3.0.post6-cp311-cp311-win32.whl", hash = "sha256:dbc828641667142751b1127fd5c4291663490cf05689c85be4c5bcc89aaa236a", size = 100227 }, - { url = "https://files.pythonhosted.org/packages/17/4b/a4cda18e8556d913ff75052585eb0d658500596b5f97fe8401d05123d47b/pyclipper-1.3.0.post6-cp311-cp311-win_amd64.whl", hash = "sha256:1c03f1ae43b18ee07730c3c774cc3cf88a10c12a4b097239b33365ec24a0a14a", size = 110442 }, - { url = "https://files.pythonhosted.org/packages/fc/c8/197d9a1d8354922d24d11d22fb2e0cc1ebc182f8a30496b7ddbe89467ce1/pyclipper-1.3.0.post6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:6363b9d79ba1b5d8f32d1623e797c1e9f994600943402e68d5266067bdde173e", size = 270487 }, - { url = "https://files.pythonhosted.org/packages/8e/8e/eb14eadf054494ad81446e21c4ea163b941747610b0eb9051644395f567e/pyclipper-1.3.0.post6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:32cd7fb9c1c893eb87f82a072dbb5e26224ea7cebbad9dc306d67e1ac62dd229", size = 143469 }, - { url = "https://files.pythonhosted.org/packages/cf/e5/6c4a8df6e904c133bb4c5309d211d31c751db60cbd36a7250c02b05494a1/pyclipper-1.3.0.post6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3aab10e3c10ed8fa60c608fb87c040089b83325c937f98f06450cf9fcfdaf1d", size = 944206 }, - { url = "https://files.pythonhosted.org/packages/76/65/cb014acc41cd5bf6bbfa4671c7faffffb9cee01706642c2dec70c5209ac8/pyclipper-1.3.0.post6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58eae2ff92a8cae1331568df076c4c5775bf946afab0068b217f0cf8e188eb3c", size = 963797 }, - { url = "https://files.pythonhosted.org/packages/80/ec/b40cd81ab7598984167508a5369a2fa31a09fe3b3e3d0b73aa50e06d4b3f/pyclipper-1.3.0.post6-cp312-cp312-win32.whl", hash = "sha256:793b0aa54b914257aa7dc76b793dd4dcfb3c84011d48df7e41ba02b571616eaf", size = 99456 }, - { url = "https://files.pythonhosted.org/packages/24/3a/7d6292e3c94fb6b872d8d7e80d909dc527ee6b0af73b753c63fdde65a7da/pyclipper-1.3.0.post6-cp312-cp312-win_amd64.whl", hash = "sha256:d3f9da96f83b8892504923beb21a481cd4516c19be1d39eb57a92ef1c9a29548", size = 110278 }, - { url = "https://files.pythonhosted.org/packages/8c/b3/75232906bd13f869600d23bdb8fe6903cc899fa7e96981ae4c9b7d9c409e/pyclipper-1.3.0.post6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f129284d2c7bcd213d11c0f35e1ae506a1144ce4954e9d1734d63b120b0a1b58", size = 268254 }, - { url = "https://files.pythonhosted.org/packages/0b/db/35843050a3dd7586781497a21ca6c8d48111afb66061cb40c3d3c288596d/pyclipper-1.3.0.post6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:188fbfd1d30d02247f92c25ce856f5f3c75d841251f43367dbcf10935bc48f38", size = 142204 }, - { url = "https://files.pythonhosted.org/packages/7c/d7/1faa0ff35caa02cb32cb0583688cded3f38788f33e02bfe6461fbcc1bee1/pyclipper-1.3.0.post6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6d129d0c2587f2f5904d201a4021f859afbb45fada4261c9fdedb2205b09d23", size = 943835 }, - { url = "https://files.pythonhosted.org/packages/31/10/c0bf140bee2844e2c0617fdcc8a4e8daf98e71710046b06034e6f1963404/pyclipper-1.3.0.post6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c9c80b5c46eef38ba3f12dd818dc87f5f2a0853ba914b6f91b133232315f526", size = 962510 }, - { url = "https://files.pythonhosted.org/packages/85/6f/8c6afc49b51b1bf16d5903ecd5aee657cf88f52c83cb5fabf771deeba728/pyclipper-1.3.0.post6-cp313-cp313-win32.whl", hash = "sha256:b15113ec4fc423b58e9ae80aa95cf5a0802f02d8f02a98a46af3d7d66ff0cc0e", size = 98836 }, - { url = "https://files.pythonhosted.org/packages/d5/19/9ff4551b42f2068686c50c0d199072fa67aee57fc5cf86770cacf71efda3/pyclipper-1.3.0.post6-cp313-cp313-win_amd64.whl", hash = "sha256:e5ff68fa770ac654c7974fc78792978796f068bd274e95930c0691c31e192889", size = 109672 }, + { url = "https://files.pythonhosted.org/packages/b5/34/0dca299fe41e9a92e78735502fed5238a4ac734755e624488df9b2eeec46/pyclipper-1.3.0.post6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fa0f5e78cfa8262277bb3d0225537b3c2a90ef68fd90a229d5d24cf49955dcf4", size = 269504, upload-time = "2024-10-18T12:21:55.735Z" }, + { url = "https://files.pythonhosted.org/packages/8a/5b/81528b08134b3c2abdfae821e1eff975c0703802d41974b02dfb2e101c55/pyclipper-1.3.0.post6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a01f182d8938c1dc515e8508ed2442f7eebd2c25c7d5cb29281f583c1a8008a4", size = 142599, upload-time = "2024-10-18T12:21:57.401Z" }, + { url = "https://files.pythonhosted.org/packages/84/a4/3e304f6c0d000382cd54d4a1e5f0d8fc28e1ae97413a2ec1016a7b840319/pyclipper-1.3.0.post6-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:640f20975727994d4abacd07396f564e9e5665ba5cb66ceb36b300c281f84fa4", size = 912209, upload-time = "2024-10-18T12:21:59.408Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6a/28ec55cc3f972368b211fca017e081cf5a71009d1b8ec3559767cda5b289/pyclipper-1.3.0.post6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63002f6bb0f1efa87c0b81634cbb571066f237067e23707dabf746306c92ba5", size = 929511, upload-time = "2024-10-18T12:22:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c4/56/c326f3454c5f30a31f58a5c3154d891fce58ad73ccbf1d3f4aacfcbd344d/pyclipper-1.3.0.post6-cp310-cp310-win32.whl", hash = "sha256:106b8622cd9fb07d80cbf9b1d752334c55839203bae962376a8c59087788af26", size = 100126, upload-time = "2024-10-18T12:22:02.83Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e6/f8239af6346848b20a3448c554782fe59298ab06c1d040490242dc7e3c26/pyclipper-1.3.0.post6-cp310-cp310-win_amd64.whl", hash = "sha256:9699e98862dadefd0bea2360c31fa61ca553c660cbf6fb44993acde1b959f58f", size = 110470, upload-time = "2024-10-18T12:22:04.411Z" }, + { url = "https://files.pythonhosted.org/packages/50/a9/66ca5f252dcac93ca076698591b838ba17f9729591edf4b74fef7fbe1414/pyclipper-1.3.0.post6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4247e7c44b34c87acbf38f99d48fb1acaf5da4a2cf4dcd601a9b24d431be4ef", size = 270930, upload-time = "2024-10-18T12:22:06.066Z" }, + { url = "https://files.pythonhosted.org/packages/59/fe/2ab5818b3504e179086e54a37ecc245525d069267b8c31b18ec3d0830cbf/pyclipper-1.3.0.post6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:851b3e58106c62a5534a1201295fe20c21714dee2eda68081b37ddb0367e6caa", size = 143411, upload-time = "2024-10-18T12:22:07.598Z" }, + { url = "https://files.pythonhosted.org/packages/09/f7/b58794f643e033a6d14da7c70f517315c3072f3c5fccdf4232fa8c8090c1/pyclipper-1.3.0.post6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16cc1705a915896d2aff52131c427df02265631279eac849ebda766432714cc0", size = 951754, upload-time = "2024-10-18T12:22:08.966Z" }, + { url = "https://files.pythonhosted.org/packages/c1/77/846a21957cd4ed266c36705ee340beaa923eb57d2bba013cfd7a5c417cfd/pyclipper-1.3.0.post6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace1f0753cf71c5c5f6488b8feef5dd0fa8b976ad86b24bb51f708f513df4aac", size = 969608, upload-time = "2024-10-18T12:22:10.321Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2b/580703daa6606d160caf596522d4cfdf62ae619b062a7ce6f905821a57e8/pyclipper-1.3.0.post6-cp311-cp311-win32.whl", hash = "sha256:dbc828641667142751b1127fd5c4291663490cf05689c85be4c5bcc89aaa236a", size = 100227, upload-time = "2024-10-18T12:22:11.991Z" }, + { url = "https://files.pythonhosted.org/packages/17/4b/a4cda18e8556d913ff75052585eb0d658500596b5f97fe8401d05123d47b/pyclipper-1.3.0.post6-cp311-cp311-win_amd64.whl", hash = "sha256:1c03f1ae43b18ee07730c3c774cc3cf88a10c12a4b097239b33365ec24a0a14a", size = 110442, upload-time = "2024-10-18T12:22:13.121Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c8/197d9a1d8354922d24d11d22fb2e0cc1ebc182f8a30496b7ddbe89467ce1/pyclipper-1.3.0.post6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:6363b9d79ba1b5d8f32d1623e797c1e9f994600943402e68d5266067bdde173e", size = 270487, upload-time = "2024-10-18T12:22:14.852Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8e/eb14eadf054494ad81446e21c4ea163b941747610b0eb9051644395f567e/pyclipper-1.3.0.post6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:32cd7fb9c1c893eb87f82a072dbb5e26224ea7cebbad9dc306d67e1ac62dd229", size = 143469, upload-time = "2024-10-18T12:22:16.109Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e5/6c4a8df6e904c133bb4c5309d211d31c751db60cbd36a7250c02b05494a1/pyclipper-1.3.0.post6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3aab10e3c10ed8fa60c608fb87c040089b83325c937f98f06450cf9fcfdaf1d", size = 944206, upload-time = "2024-10-18T12:22:17.216Z" }, + { url = "https://files.pythonhosted.org/packages/76/65/cb014acc41cd5bf6bbfa4671c7faffffb9cee01706642c2dec70c5209ac8/pyclipper-1.3.0.post6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58eae2ff92a8cae1331568df076c4c5775bf946afab0068b217f0cf8e188eb3c", size = 963797, upload-time = "2024-10-18T12:22:18.881Z" }, + { url = "https://files.pythonhosted.org/packages/80/ec/b40cd81ab7598984167508a5369a2fa31a09fe3b3e3d0b73aa50e06d4b3f/pyclipper-1.3.0.post6-cp312-cp312-win32.whl", hash = "sha256:793b0aa54b914257aa7dc76b793dd4dcfb3c84011d48df7e41ba02b571616eaf", size = 99456, upload-time = "2024-10-18T12:22:20.084Z" }, + { url = "https://files.pythonhosted.org/packages/24/3a/7d6292e3c94fb6b872d8d7e80d909dc527ee6b0af73b753c63fdde65a7da/pyclipper-1.3.0.post6-cp312-cp312-win_amd64.whl", hash = "sha256:d3f9da96f83b8892504923beb21a481cd4516c19be1d39eb57a92ef1c9a29548", size = 110278, upload-time = "2024-10-18T12:22:21.178Z" }, + { url = "https://files.pythonhosted.org/packages/8c/b3/75232906bd13f869600d23bdb8fe6903cc899fa7e96981ae4c9b7d9c409e/pyclipper-1.3.0.post6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f129284d2c7bcd213d11c0f35e1ae506a1144ce4954e9d1734d63b120b0a1b58", size = 268254, upload-time = "2024-10-18T12:22:22.272Z" }, + { url = "https://files.pythonhosted.org/packages/0b/db/35843050a3dd7586781497a21ca6c8d48111afb66061cb40c3d3c288596d/pyclipper-1.3.0.post6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:188fbfd1d30d02247f92c25ce856f5f3c75d841251f43367dbcf10935bc48f38", size = 142204, upload-time = "2024-10-18T12:22:24.315Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d7/1faa0ff35caa02cb32cb0583688cded3f38788f33e02bfe6461fbcc1bee1/pyclipper-1.3.0.post6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6d129d0c2587f2f5904d201a4021f859afbb45fada4261c9fdedb2205b09d23", size = 943835, upload-time = "2024-10-18T12:22:26.233Z" }, + { url = "https://files.pythonhosted.org/packages/31/10/c0bf140bee2844e2c0617fdcc8a4e8daf98e71710046b06034e6f1963404/pyclipper-1.3.0.post6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c9c80b5c46eef38ba3f12dd818dc87f5f2a0853ba914b6f91b133232315f526", size = 962510, upload-time = "2024-10-18T12:22:27.573Z" }, + { url = "https://files.pythonhosted.org/packages/85/6f/8c6afc49b51b1bf16d5903ecd5aee657cf88f52c83cb5fabf771deeba728/pyclipper-1.3.0.post6-cp313-cp313-win32.whl", hash = "sha256:b15113ec4fc423b58e9ae80aa95cf5a0802f02d8f02a98a46af3d7d66ff0cc0e", size = 98836, upload-time = "2024-10-18T12:22:29.157Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/9ff4551b42f2068686c50c0d199072fa67aee57fc5cf86770cacf71efda3/pyclipper-1.3.0.post6-cp313-cp313-win_amd64.whl", hash = "sha256:e5ff68fa770ac654c7974fc78792978796f068bd274e95930c0691c31e192889", size = 109672, upload-time = "2024-10-18T12:22:30.411Z" }, ] [[package]] name = "pycparser" version = "2.21" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206", size = 170877 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206", size = 170877, upload-time = "2021-11-06T12:48:46.095Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", size = 118697 }, + { url = "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", size = 118697, upload-time = "2021-11-06T12:50:13.61Z" }, ] [[package]] name = "pydantic" -version = "2.11.7" +version = "2.12.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2151,142 +2214,173 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350 } +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782 }, + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, ] [[package]] name = "pydantic-core" -version = "2.33.2" +version = "2.41.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195 } +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817 }, - { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357 }, - { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011 }, - { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730 }, - { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178 }, - { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462 }, - { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652 }, - { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306 }, - { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720 }, - { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915 }, - { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884 }, - { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496 }, - { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019 }, - { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584 }, - { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071 }, - { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823 }, - { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792 }, - { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338 }, - { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998 }, - { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200 }, - { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890 }, - { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359 }, - { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883 }, - { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074 }, - { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538 }, - { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909 }, - { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786 }, - { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000 }, - { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996 }, - { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957 }, - { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199 }, - { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296 }, - { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109 }, - { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028 }, - { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044 }, - { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881 }, - { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034 }, - { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187 }, - { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628 }, - { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866 }, - { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894 }, - { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688 }, - { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808 }, - { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580 }, - { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859 }, - { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810 }, - { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498 }, - { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611 }, - { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924 }, - { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196 }, - { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389 }, - { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223 }, - { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473 }, - { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269 }, - { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162 }, - { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560 }, - { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777 }, - { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982 }, - { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412 }, - { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749 }, - { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527 }, - { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225 }, - { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490 }, - { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525 }, - { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446 }, - { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678 }, - { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200 }, - { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123 }, - { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852 }, - { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484 }, - { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896 }, - { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475 }, - { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013 }, - { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715 }, - { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757 }, + { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload-time = "2025-11-04T13:39:04.116Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload-time = "2025-11-04T13:39:06.055Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload-time = "2025-11-04T13:39:10.41Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload-time = "2025-11-04T13:39:12.244Z" }, + { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload-time = "2025-11-04T13:39:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload-time = "2025-11-04T13:39:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload-time = "2025-11-04T13:39:17.403Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload-time = "2025-11-04T13:39:19.351Z" }, + { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload-time = "2025-11-04T13:39:21Z" }, + { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload-time = "2025-11-04T13:39:22.606Z" }, + { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload-time = "2025-11-04T13:39:25.843Z" }, + { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload-time = "2025-11-04T13:39:27.92Z" }, + { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload-time = "2025-11-04T13:39:29.848Z" }, + { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, + { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, + { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, + { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, + { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, + { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, + { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, + { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, + { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, + { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload-time = "2025-11-04T13:43:02.058Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload-time = "2025-11-04T13:43:05.159Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload-time = "2025-11-04T13:43:08.116Z" }, + { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload-time = "2025-11-04T13:43:12.49Z" }, + { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload-time = "2025-11-04T13:43:15.431Z" }, + { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload-time = "2025-11-04T13:43:18.062Z" }, + { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload-time = "2025-11-04T13:43:20.679Z" }, + { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload-time = "2025-11-04T13:43:23.286Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, + { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, + { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, + { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, ] [[package]] name = "pydantic-settings" -version = "2.10.1" +version = "2.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/85/1ea668bbab3c50071ca613c6ab30047fb36ab0da1b92fa8f17bbc38fd36c/pydantic_settings-2.10.1.tar.gz", hash = "sha256:06f0062169818d0f5524420a360d632d5857b83cffd4d42fe29597807a1614ee", size = 172583 } +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/f0/427018098906416f580e3cf1366d3b1abfb408a0652e9f31600c24a1903c/pydantic_settings-2.10.1-py3-none-any.whl", hash = "sha256:a60952460b99cf661dc25c29c0ef171721f98bfcb52ef8d9ea4c943d7c8cc796", size = 45235 }, + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, ] [[package]] name = "pygments" version = "2.17.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/55/59/8bccf4157baf25e4aa5a0bb7fa3ba8600907de105ebc22b0c78cfbf6f565/pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367", size = 4827772 } +sdist = { url = "https://files.pythonhosted.org/packages/55/59/8bccf4157baf25e4aa5a0bb7fa3ba8600907de105ebc22b0c78cfbf6f565/pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367", size = 4827772, upload-time = "2023-11-21T20:43:53.875Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/9c/372fef8377a6e340b1704768d20daaded98bf13282b5327beb2e2fe2c7ef/pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", size = 1179756 }, + { url = "https://files.pythonhosted.org/packages/97/9c/372fef8377a6e340b1704768d20daaded98bf13282b5327beb2e2fe2c7ef/pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", size = 1179756, upload-time = "2023-11-21T20:43:49.423Z" }, ] [[package]] name = "pyparsing" version = "3.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/fe/65c989f70bd630b589adfbbcd6ed238af22319e90f059946c26b4835e44b/pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db", size = 884814 } +sdist = { url = "https://files.pythonhosted.org/packages/37/fe/65c989f70bd630b589adfbbcd6ed238af22319e90f059946c26b4835e44b/pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db", size = 884814, upload-time = "2023-07-30T15:07:02.617Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/92/8486ede85fcc088f1b3dba4ce92dd29d126fd96b0008ea213167940a2475/pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb", size = 103139 }, + { url = "https://files.pythonhosted.org/packages/39/92/8486ede85fcc088f1b3dba4ce92dd29d126fd96b0008ea213167940a2475/pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb", size = 103139, upload-time = "2023-07-30T15:06:59.829Z" }, ] [[package]] name = "pyreadline3" version = "3.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/86/3d61a61f36a0067874a00cb4dceb9028d34b6060e47828f7fc86fb9f7ee9/pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae", size = 86465 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/86/3d61a61f36a0067874a00cb4dceb9028d34b6060e47828f7fc86fb9f7ee9/pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae", size = 86465, upload-time = "2022-01-24T20:05:11.66Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/fc/a3c13ded7b3057680c8ae95a9b6cc83e63657c38e0005c400a5d018a33a7/pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb", size = 95203 }, + { url = "https://files.pythonhosted.org/packages/56/fc/a3c13ded7b3057680c8ae95a9b6cc83e63657c38e0005c400a5d018a33a7/pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb", size = 95203, upload-time = "2022-01-24T20:05:10.442Z" }, ] [[package]] name = "pytest" -version = "8.4.1" +version = "9.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -2297,48 +2391,49 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714 } +sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474 }, + { url = "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", size = 373668, upload-time = "2025-11-12T13:05:07.379Z" }, ] [[package]] name = "pytest-asyncio" -version = "1.1.0" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652 } +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157 }, + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] [[package]] name = "pytest-cov" -version = "6.2.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644 }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.1" +version = "3.15.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241 } +sdist = { url = "https://files.pythonhosted.org/packages/68/14/eb014d26be205d38ad5ad20d9a80f7d201472e08167f0bb4361e251084a9/pytest_mock-3.15.1.tar.gz", hash = "sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f", size = 34036, upload-time = "2025-09-16T16:37:27.081Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923 }, + { url = "https://files.pythonhosted.org/packages/5a/cc/06253936f4a7fa2e0f48dfe6d851d9c56df896a9ab09ac019d70b760619c/pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d", size = 10095, upload-time = "2025-09-16T16:37:25.734Z" }, ] [[package]] @@ -2348,18 +2443,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", size = 357324 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", size = 357324, upload-time = "2021-07-14T08:19:19.783Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9", size = 247702 }, + { url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9", size = 247702, upload-time = "2021-07-14T08:19:18.161Z" }, ] [[package]] name = "python-dotenv" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/31/06/1ef763af20d0572c032fa22882cfbfb005fba6e7300715a37840858c919e/python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", size = 37399 } +sdist = { url = "https://files.pythonhosted.org/packages/31/06/1ef763af20d0572c032fa22882cfbfb005fba6e7300715a37840858c919e/python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", size = 37399, upload-time = "2023-02-24T06:46:37.282Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/2f/62ea1c8b593f4e093cc1a7768f0d46112107e790c3e478532329e434f00b/python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a", size = 19482 }, + { url = "https://files.pythonhosted.org/packages/44/2f/62ea1c8b593f4e093cc1a7768f0d46112107e790c3e478532329e434f00b/python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a", size = 19482, upload-time = "2023-02-24T06:46:36.009Z" }, ] [[package]] @@ -2369,31 +2464,31 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "simple-websocket" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/0b/67295279b66835f9fa7a491650efcd78b20321c127036eef62c11a31e028/python_engineio-4.12.2.tar.gz", hash = "sha256:e7e712ffe1be1f6a05ee5f951e72d434854a32fcfc7f6e4d9d3cae24ec70defa", size = 91677 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/0b/67295279b66835f9fa7a491650efcd78b20321c127036eef62c11a31e028/python_engineio-4.12.2.tar.gz", hash = "sha256:e7e712ffe1be1f6a05ee5f951e72d434854a32fcfc7f6e4d9d3cae24ec70defa", size = 91677, upload-time = "2025-06-04T19:22:18.789Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/fa/df59acedf7bbb937f69174d00f921a7b93aa5a5f5c17d05296c814fff6fc/python_engineio-4.12.2-py3-none-any.whl", hash = "sha256:8218ab66950e179dfec4b4bbb30aecf3f5d86f5e58e6fc1aa7fde2c698b2804f", size = 59536 }, + { url = "https://files.pythonhosted.org/packages/0c/fa/df59acedf7bbb937f69174d00f921a7b93aa5a5f5c17d05296c814fff6fc/python_engineio-4.12.2-py3-none-any.whl", hash = "sha256:8218ab66950e179dfec4b4bbb30aecf3f5d86f5e58e6fc1aa7fde2c698b2804f", size = 59536, upload-time = "2025-06-04T19:22:16.916Z" }, ] [[package]] name = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, ] [[package]] name = "python-socketio" -version = "5.13.0" +version = "5.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "bidict" }, { name = "python-engineio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/21/1a/396d50ccf06ee539fa758ce5623b59a9cb27637fc4b2dc07ed08bf495e77/python_socketio-5.13.0.tar.gz", hash = "sha256:ac4e19a0302ae812e23b712ec8b6427ca0521f7c582d6abb096e36e24a263029", size = 121125 } +sdist = { url = "https://files.pythonhosted.org/packages/72/a8/5f7c805dd6d0d6cba91d3ea215b4b88889d1b99b71a53c932629daba53f1/python_socketio-5.15.0.tar.gz", hash = "sha256:d0403ababb59aa12fd5adcfc933a821113f27bd77761bc1c54aad2e3191a9b69", size = 126439, upload-time = "2025-11-22T18:50:21.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/32/b4fb8585d1be0f68bde7e110dffbcf354915f77ad8c778563f0ad9655c02/python_socketio-5.13.0-py3-none-any.whl", hash = "sha256:51f68d6499f2df8524668c24bcec13ba1414117cfb3a90115c559b601ab10caf", size = 77800 }, + { url = "https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl", hash = "sha256:e93363102f4da6d8e7a8872bf4908b866c40f070e716aa27132891e643e2687c", size = 79451, upload-time = "2025-11-22T18:50:19.416Z" }, ] [package.optional-dependencies] @@ -2402,63 +2497,72 @@ client = [ { name = "websocket-client" }, ] +[[package]] +name = "pytokens" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/8d/a762be14dae1c3bf280202ba3172020b2b0b4c537f94427435f19c413b72/pytokens-0.3.0.tar.gz", hash = "sha256:2f932b14ed08de5fcf0b391ace2642f858f1394c0857202959000b68ed7a458a", size = 17644, upload-time = "2025-11-05T13:36:35.34Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/25/d9db8be44e205a124f6c98bc0324b2bb149b7431c53877fc6d1038dddaf5/pytokens-0.3.0-py3-none-any.whl", hash = "sha256:95b2b5eaf832e469d141a378872480ede3f251a5a5041b8ec6e581d3ac71bbf3", size = 12195, upload-time = "2025-11-05T13:36:33.183Z" }, +] + [[package]] name = "pywin32" version = "306" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/dc/28c668097edfaf4eac4617ef7adf081b9cf50d254672fcf399a70f5efc41/pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d", size = 8506422 }, - { url = "https://files.pythonhosted.org/packages/d3/d6/891894edec688e72c2e308b3243fad98b4066e1839fd2fe78f04129a9d31/pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8", size = 9226392 }, - { url = "https://files.pythonhosted.org/packages/8b/1e/fc18ad83ca553e01b97aa8393ff10e33c1fb57801db05488b83282ee9913/pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407", size = 8507689 }, - { url = "https://files.pythonhosted.org/packages/7e/9e/ad6b1ae2a5ad1066dc509350e0fbf74d8d50251a51e420a2a8feaa0cecbd/pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e", size = 9227547 }, - { url = "https://files.pythonhosted.org/packages/91/20/f744bff1da8f43388498503634378dbbefbe493e65675f2cc52f7185c2c2/pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a", size = 10388324 }, - { url = "https://files.pythonhosted.org/packages/14/91/17e016d5923e178346aabda3dfec6629d1a26efe587d19667542105cf0a6/pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b", size = 8507705 }, - { url = "https://files.pythonhosted.org/packages/83/1c/25b79fc3ec99b19b0a0730cc47356f7e2959863bf9f3cd314332bddb4f68/pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e", size = 9227429 }, - { url = "https://files.pythonhosted.org/packages/1c/43/e3444dc9a12f8365d9603c2145d16bf0a2f8180f343cf87be47f5579e547/pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040", size = 10388145 }, + { url = "https://files.pythonhosted.org/packages/08/dc/28c668097edfaf4eac4617ef7adf081b9cf50d254672fcf399a70f5efc41/pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d", size = 8506422, upload-time = "2023-03-26T03:27:46.303Z" }, + { url = "https://files.pythonhosted.org/packages/d3/d6/891894edec688e72c2e308b3243fad98b4066e1839fd2fe78f04129a9d31/pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8", size = 9226392, upload-time = "2023-03-26T03:27:53.591Z" }, + { url = "https://files.pythonhosted.org/packages/8b/1e/fc18ad83ca553e01b97aa8393ff10e33c1fb57801db05488b83282ee9913/pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407", size = 8507689, upload-time = "2023-03-25T23:50:08.499Z" }, + { url = "https://files.pythonhosted.org/packages/7e/9e/ad6b1ae2a5ad1066dc509350e0fbf74d8d50251a51e420a2a8feaa0cecbd/pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e", size = 9227547, upload-time = "2023-03-25T23:50:20.331Z" }, + { url = "https://files.pythonhosted.org/packages/91/20/f744bff1da8f43388498503634378dbbefbe493e65675f2cc52f7185c2c2/pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a", size = 10388324, upload-time = "2023-03-25T23:50:30.904Z" }, + { url = "https://files.pythonhosted.org/packages/14/91/17e016d5923e178346aabda3dfec6629d1a26efe587d19667542105cf0a6/pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b", size = 8507705, upload-time = "2023-03-25T23:50:40.279Z" }, + { url = "https://files.pythonhosted.org/packages/83/1c/25b79fc3ec99b19b0a0730cc47356f7e2959863bf9f3cd314332bddb4f68/pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e", size = 9227429, upload-time = "2023-03-25T23:50:50.222Z" }, + { url = "https://files.pythonhosted.org/packages/1c/43/e3444dc9a12f8365d9603c2145d16bf0a2f8180f343cf87be47f5579e547/pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040", size = 10388145, upload-time = "2023-03-25T23:51:01.401Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] @@ -2468,46 +2572,46 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/33/1a3683fc9a4bd64d8ccc0290da75c8f042184a1a49c146d28398414d3341/pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226", size = 1402339 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/33/1a3683fc9a4bd64d8ccc0290da75c8f042184a1a49c146d28398414d3341/pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226", size = 1402339, upload-time = "2023-12-05T07:34:47.976Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/f4/901edb48b2b2c00ad73de0db2ee76e24ce5903ef815ad0ad10e14555d989/pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4", size = 1872310 }, - { url = "https://files.pythonhosted.org/packages/5e/46/2de69c7c79fd78bf4c22a9e8165fa6312f5d49410f1be6ddab51a6fe7236/pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0", size = 1249619 }, - { url = "https://files.pythonhosted.org/packages/d1/f5/d6b9755713843bf9701ae86bf6fd97ec294a52cf2af719cd14fdf9392f65/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e", size = 897360 }, - { url = "https://files.pythonhosted.org/packages/7c/88/c1aef8820f12e710d136024d231e70e24684a01314aa1814f0758960ba01/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872", size = 1156959 }, - { url = "https://files.pythonhosted.org/packages/82/1b/b25d2c4ac3b4dae238c98e63395dbb88daf11968b168948d3c6289c3e95c/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d", size = 1100585 }, - { url = "https://files.pythonhosted.org/packages/67/bf/6bc0977acd934b66eacab79cec303ecf08ae4a6150d57c628aa919615488/pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75", size = 1109267 }, - { url = "https://files.pythonhosted.org/packages/64/fb/4f07424e56c6a5fb47306d9ba744c3c250250c2e7272f9c81efbf8daaccf/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6", size = 1431853 }, - { url = "https://files.pythonhosted.org/packages/a2/10/2b88c1d4beb59a1d45c13983c4b7c5dcd6ef7988db3c03d23b0cabc5adca/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979", size = 1766212 }, - { url = "https://files.pythonhosted.org/packages/bc/ab/c9a22eacfd5bd82620501ae426a3dd6ffa374ac335b21e54209d7a93d3fb/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08", size = 1653737 }, - { url = "https://files.pythonhosted.org/packages/d6/e5/71bd89e47eedb7ebec31ef9a49dcdb0517dbbb063bd5de363980a6911eb1/pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886", size = 906288 }, - { url = "https://files.pythonhosted.org/packages/9d/5f/2defc8a579e8b5679d92720ab3a4cb93e3a77d923070bf4c1a103d3ae478/pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6", size = 1170923 }, - { url = "https://files.pythonhosted.org/packages/35/de/7579518bc58cebf92568b48e354a702fb52525d0fab166dc544f2a0615dc/pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c", size = 1870360 }, - { url = "https://files.pythonhosted.org/packages/ce/f9/58b6cc9a110b1832f666fa6b5a67dc4d520fabfc680ca87a8167b2061d5d/pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1", size = 1249008 }, - { url = "https://files.pythonhosted.org/packages/bc/4a/ac6469c01813cb3652ab4e30ec4a37815cc9949afc18af33f64e2ec704aa/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348", size = 904394 }, - { url = "https://files.pythonhosted.org/packages/77/b7/8cee519b11bdd3f76c1a6eb537ab13c1bfef2964d725717705c86f524e4c/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642", size = 1161453 }, - { url = "https://files.pythonhosted.org/packages/b6/1d/c35a956a44b333b064ae1b1c588c2dfa0e01b7ec90884c1972bfcef119c3/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840", size = 1105501 }, - { url = "https://files.pythonhosted.org/packages/18/d1/b3d1e985318ed7287737ea9e6b6e21748cc7c89accc2443347cd2c8d5f0f/pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d", size = 1109513 }, - { url = "https://files.pythonhosted.org/packages/14/9b/341cdfb47440069010101403298dc24d449150370c6cb322e73bfa1949bd/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b", size = 1433541 }, - { url = "https://files.pythonhosted.org/packages/fa/52/c6d4e76e020c554e965459d41a98201b4d45277a288648f53a4e5a2429cc/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b", size = 1766133 }, - { url = "https://files.pythonhosted.org/packages/1d/6d/0cbd8dd5b8979fd6b9cf1852ed067b9d2cd6fa0c09c3bafe6874d2d2e03c/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3", size = 1653636 }, - { url = "https://files.pythonhosted.org/packages/f5/af/d90eed9cf3840685d54d4a35d5f9e242a8a48b5410d41146f14c1e098302/pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097", size = 904865 }, - { url = "https://files.pythonhosted.org/packages/20/d2/09443dc73053ad01c846d7fb77e09fe9d93c09d4e900215f3c8b7b56bfec/pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9", size = 1171332 }, - { url = "https://files.pythonhosted.org/packages/6e/f0/d71cf69dc039c9adc8b625efc3bad3684f3660a570e47f0f0c64df787b41/pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a", size = 1871111 }, - { url = "https://files.pythonhosted.org/packages/68/62/d365773edf56ad71993579ee574105f02f83530caf600ebf28bea15d88d0/pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e", size = 1248844 }, - { url = "https://files.pythonhosted.org/packages/72/55/cc3163e20f40615a49245fa7041badec6103e8ee7e482dbb0feea00a7b84/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27", size = 899373 }, - { url = "https://files.pythonhosted.org/packages/40/aa/ae292bd85deda637230970bbc53c1dc53696a99e82fc7cd6d373ec173853/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30", size = 1160901 }, - { url = "https://files.pythonhosted.org/packages/93/b7/6e291eafbbbc66d0e87658dd21383ec2b4ab35edcfb283902c580a6db76f/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee", size = 1101147 }, - { url = "https://files.pythonhosted.org/packages/3a/f1/e296d5a507eac519d1fe1382851b1a4575f690bc2b2d2c8eca2ed7e4bd1f/pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537", size = 1105315 }, - { url = "https://files.pythonhosted.org/packages/56/63/5c2abb556ab4cf013d98e01782d5bd642238a0ed9b019e965a7d7e957f56/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181", size = 1427747 }, - { url = "https://files.pythonhosted.org/packages/b1/71/5dba5f6b12ef54fb977c9b9279075e151c04fc0dd6851e9663d9e66b593f/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe", size = 1762221 }, - { url = "https://files.pythonhosted.org/packages/cf/49/54d7e8bb3df82a3509325b11491d33450dc91580d4826b62fa5e554bb9cf/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737", size = 1649505 }, - { url = "https://files.pythonhosted.org/packages/34/14/58e5037229bc37963e2ce804c2c075a3a541e3f84bf1c231e7c9779d36f1/pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d", size = 954891 }, - { url = "https://files.pythonhosted.org/packages/2c/2d/04fab685ef3a8e6e955220fd2a54dc99efaee960a88675bf5c92cd277164/pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7", size = 1252773 }, - { url = "https://files.pythonhosted.org/packages/6b/fe/ed38fe12c540bafc1cae32c3ff638e9df32528f5cf91b5e400e6a8f5b3ec/pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05", size = 963654 }, - { url = "https://files.pythonhosted.org/packages/44/97/a760a2dff0672c408f22f726f2ea10a7a516ffa5001ca5a3641e355a45f9/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8", size = 609436 }, - { url = "https://files.pythonhosted.org/packages/41/81/ace39daa19c78b2f4fc12ef217d9d5f1ac658d5828d692bbbb68240cd55b/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e", size = 843396 }, - { url = "https://files.pythonhosted.org/packages/4c/43/150b0b203f5461a9aeadaa925c55167e2b4215c9322b6911a64360d2243e/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4", size = 800856 }, - { url = "https://files.pythonhosted.org/packages/5f/91/a618b56aaabe40dddcd25db85624d7408768fd32f5bfcf81bc0af5b1ce75/pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d", size = 413836 }, + { url = "https://files.pythonhosted.org/packages/5e/f4/901edb48b2b2c00ad73de0db2ee76e24ce5903ef815ad0ad10e14555d989/pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4", size = 1872310, upload-time = "2023-12-05T07:48:13.713Z" }, + { url = "https://files.pythonhosted.org/packages/5e/46/2de69c7c79fd78bf4c22a9e8165fa6312f5d49410f1be6ddab51a6fe7236/pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0", size = 1249619, upload-time = "2023-12-05T07:50:38.691Z" }, + { url = "https://files.pythonhosted.org/packages/d1/f5/d6b9755713843bf9701ae86bf6fd97ec294a52cf2af719cd14fdf9392f65/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e", size = 897360, upload-time = "2023-12-05T07:42:26.268Z" }, + { url = "https://files.pythonhosted.org/packages/7c/88/c1aef8820f12e710d136024d231e70e24684a01314aa1814f0758960ba01/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872", size = 1156959, upload-time = "2023-12-05T07:44:29.904Z" }, + { url = "https://files.pythonhosted.org/packages/82/1b/b25d2c4ac3b4dae238c98e63395dbb88daf11968b168948d3c6289c3e95c/pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d", size = 1100585, upload-time = "2023-12-05T07:45:05.518Z" }, + { url = "https://files.pythonhosted.org/packages/67/bf/6bc0977acd934b66eacab79cec303ecf08ae4a6150d57c628aa919615488/pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75", size = 1109267, upload-time = "2023-12-05T07:39:51.21Z" }, + { url = "https://files.pythonhosted.org/packages/64/fb/4f07424e56c6a5fb47306d9ba744c3c250250c2e7272f9c81efbf8daaccf/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6", size = 1431853, upload-time = "2023-12-05T07:41:09.261Z" }, + { url = "https://files.pythonhosted.org/packages/a2/10/2b88c1d4beb59a1d45c13983c4b7c5dcd6ef7988db3c03d23b0cabc5adca/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979", size = 1766212, upload-time = "2023-12-05T07:49:05.926Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ab/c9a22eacfd5bd82620501ae426a3dd6ffa374ac335b21e54209d7a93d3fb/pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08", size = 1653737, upload-time = "2023-12-05T07:49:09.096Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e5/71bd89e47eedb7ebec31ef9a49dcdb0517dbbb063bd5de363980a6911eb1/pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886", size = 906288, upload-time = "2023-12-05T07:42:05.509Z" }, + { url = "https://files.pythonhosted.org/packages/9d/5f/2defc8a579e8b5679d92720ab3a4cb93e3a77d923070bf4c1a103d3ae478/pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6", size = 1170923, upload-time = "2023-12-05T07:44:54.296Z" }, + { url = "https://files.pythonhosted.org/packages/35/de/7579518bc58cebf92568b48e354a702fb52525d0fab166dc544f2a0615dc/pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c", size = 1870360, upload-time = "2023-12-05T07:48:16.153Z" }, + { url = "https://files.pythonhosted.org/packages/ce/f9/58b6cc9a110b1832f666fa6b5a67dc4d520fabfc680ca87a8167b2061d5d/pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1", size = 1249008, upload-time = "2023-12-05T07:50:40.442Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4a/ac6469c01813cb3652ab4e30ec4a37815cc9949afc18af33f64e2ec704aa/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348", size = 904394, upload-time = "2023-12-05T07:42:27.815Z" }, + { url = "https://files.pythonhosted.org/packages/77/b7/8cee519b11bdd3f76c1a6eb537ab13c1bfef2964d725717705c86f524e4c/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642", size = 1161453, upload-time = "2023-12-05T07:44:32.003Z" }, + { url = "https://files.pythonhosted.org/packages/b6/1d/c35a956a44b333b064ae1b1c588c2dfa0e01b7ec90884c1972bfcef119c3/pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840", size = 1105501, upload-time = "2023-12-05T07:45:07.18Z" }, + { url = "https://files.pythonhosted.org/packages/18/d1/b3d1e985318ed7287737ea9e6b6e21748cc7c89accc2443347cd2c8d5f0f/pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d", size = 1109513, upload-time = "2023-12-05T07:39:53.338Z" }, + { url = "https://files.pythonhosted.org/packages/14/9b/341cdfb47440069010101403298dc24d449150370c6cb322e73bfa1949bd/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b", size = 1433541, upload-time = "2023-12-05T07:41:10.786Z" }, + { url = "https://files.pythonhosted.org/packages/fa/52/c6d4e76e020c554e965459d41a98201b4d45277a288648f53a4e5a2429cc/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b", size = 1766133, upload-time = "2023-12-05T07:49:11.204Z" }, + { url = "https://files.pythonhosted.org/packages/1d/6d/0cbd8dd5b8979fd6b9cf1852ed067b9d2cd6fa0c09c3bafe6874d2d2e03c/pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3", size = 1653636, upload-time = "2023-12-05T07:49:13.787Z" }, + { url = "https://files.pythonhosted.org/packages/f5/af/d90eed9cf3840685d54d4a35d5f9e242a8a48b5410d41146f14c1e098302/pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097", size = 904865, upload-time = "2023-12-05T07:42:07.189Z" }, + { url = "https://files.pythonhosted.org/packages/20/d2/09443dc73053ad01c846d7fb77e09fe9d93c09d4e900215f3c8b7b56bfec/pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9", size = 1171332, upload-time = "2023-12-05T07:44:56.111Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f0/d71cf69dc039c9adc8b625efc3bad3684f3660a570e47f0f0c64df787b41/pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a", size = 1871111, upload-time = "2023-12-05T07:48:17.868Z" }, + { url = "https://files.pythonhosted.org/packages/68/62/d365773edf56ad71993579ee574105f02f83530caf600ebf28bea15d88d0/pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e", size = 1248844, upload-time = "2023-12-05T07:50:42.922Z" }, + { url = "https://files.pythonhosted.org/packages/72/55/cc3163e20f40615a49245fa7041badec6103e8ee7e482dbb0feea00a7b84/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27", size = 899373, upload-time = "2023-12-05T07:42:29.595Z" }, + { url = "https://files.pythonhosted.org/packages/40/aa/ae292bd85deda637230970bbc53c1dc53696a99e82fc7cd6d373ec173853/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30", size = 1160901, upload-time = "2023-12-05T07:44:33.819Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/6e291eafbbbc66d0e87658dd21383ec2b4ab35edcfb283902c580a6db76f/pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee", size = 1101147, upload-time = "2023-12-05T07:45:10.058Z" }, + { url = "https://files.pythonhosted.org/packages/3a/f1/e296d5a507eac519d1fe1382851b1a4575f690bc2b2d2c8eca2ed7e4bd1f/pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537", size = 1105315, upload-time = "2023-12-05T07:39:55.851Z" }, + { url = "https://files.pythonhosted.org/packages/56/63/5c2abb556ab4cf013d98e01782d5bd642238a0ed9b019e965a7d7e957f56/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181", size = 1427747, upload-time = "2023-12-05T07:41:13.219Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/5dba5f6b12ef54fb977c9b9279075e151c04fc0dd6851e9663d9e66b593f/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe", size = 1762221, upload-time = "2023-12-05T07:49:16.352Z" }, + { url = "https://files.pythonhosted.org/packages/cf/49/54d7e8bb3df82a3509325b11491d33450dc91580d4826b62fa5e554bb9cf/pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737", size = 1649505, upload-time = "2023-12-05T07:49:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/34/14/58e5037229bc37963e2ce804c2c075a3a541e3f84bf1c231e7c9779d36f1/pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d", size = 954891, upload-time = "2023-12-05T07:42:09.208Z" }, + { url = "https://files.pythonhosted.org/packages/2c/2d/04fab685ef3a8e6e955220fd2a54dc99efaee960a88675bf5c92cd277164/pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7", size = 1252773, upload-time = "2023-12-05T07:44:58.16Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fe/ed38fe12c540bafc1cae32c3ff638e9df32528f5cf91b5e400e6a8f5b3ec/pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05", size = 963654, upload-time = "2023-12-05T07:47:03.874Z" }, + { url = "https://files.pythonhosted.org/packages/44/97/a760a2dff0672c408f22f726f2ea10a7a516ffa5001ca5a3641e355a45f9/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8", size = 609436, upload-time = "2023-12-05T07:42:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/41/81/ace39daa19c78b2f4fc12ef217d9d5f1ac658d5828d692bbbb68240cd55b/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e", size = 843396, upload-time = "2023-12-05T07:44:43.727Z" }, + { url = "https://files.pythonhosted.org/packages/4c/43/150b0b203f5461a9aeadaa925c55167e2b4215c9322b6911a64360d2243e/pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4", size = 800856, upload-time = "2023-12-05T07:45:21.117Z" }, + { url = "https://files.pythonhosted.org/packages/5f/91/a618b56aaabe40dddcd25db85624d7408768fd32f5bfcf81bc0af5b1ce75/pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d", size = 413836, upload-time = "2023-12-05T07:53:22.583Z" }, ] [[package]] @@ -2521,14 +2625,14 @@ dependencies = [ { name = "scikit-learn", version = "1.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/2d/bab8babd9dc9a9e4df6eb115540cee4322c1a74078fb6f3b3ebc452a22b3/qudida-0.0.4.tar.gz", hash = "sha256:db198e2887ab0c9aa0023e565afbff41dfb76b361f85fd5e13f780d75ba18cc8", size = 3100 } +sdist = { url = "https://files.pythonhosted.org/packages/3e/2d/bab8babd9dc9a9e4df6eb115540cee4322c1a74078fb6f3b3ebc452a22b3/qudida-0.0.4.tar.gz", hash = "sha256:db198e2887ab0c9aa0023e565afbff41dfb76b361f85fd5e13f780d75ba18cc8", size = 3100, upload-time = "2021-08-09T16:47:55.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/a1/a5f4bebaa31d109003909809d88aeb0d4b201463a9ea29308d9e4f9e7655/qudida-0.0.4-py3-none-any.whl", hash = "sha256:4519714c40cd0f2e6c51e1735edae8f8b19f4efe1f33be13e9d644ca5f736dd6", size = 3478 }, + { url = "https://files.pythonhosted.org/packages/f0/a1/a5f4bebaa31d109003909809d88aeb0d4b201463a9ea29308d9e4f9e7655/qudida-0.0.4-py3-none-any.whl", hash = "sha256:4519714c40cd0f2e6c51e1735edae8f8b19f4efe1f33be13e9d644ca5f736dd6", size = 3478, upload-time = "2021-08-09T16:47:54.637Z" }, ] [[package]] name = "rapidocr" -version = "3.4.0" +version = "3.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorlog" }, @@ -2544,7 +2648,7 @@ dependencies = [ { name = "tqdm" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/e4/09ec2657421f1f23eec6b40ecbee77bbf3ff053c1483d8f2ed62d285bcf3/rapidocr-3.4.0-py3-none-any.whl", hash = "sha256:08d72f4c3a566bc76ac5c8d65d1e1c39550222b3b41b73aef976914ce80f48db", size = 15055924 }, + { url = "https://files.pythonhosted.org/packages/3c/83/5b8c8075954c5b61d938b8954710d986134c4ca7c32a841ad7d8c844cf6c/rapidocr-3.4.2-py3-none-any.whl", hash = "sha256:17845fa8cc9a20a935111e59482f2214598bba1547000cfd960d8924dd4522a5", size = 15056674, upload-time = "2025-10-11T14:43:00.296Z" }, ] [[package]] @@ -2557,22 +2661,22 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, ] [[package]] name = "rich" -version = "14.1.0" +version = "14.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368 }, + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] [[package]] @@ -2585,9 +2689,9 @@ dependencies = [ { name = "ruamel-yaml" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/db/76b40afe343f8a8c5222300da425e0dace30ce639a94776468b1d157311b/rknn_toolkit_lite2-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:821e80c95e6838308c133915660b1a6ae78bb8d079b2cbbd46a02dae61192d33", size = 559386 }, - { url = "https://files.pythonhosted.org/packages/c1/3d/e80e1742420f62cb628d40a8bf547d6f7c9dbe4e13dcb7b7e7c0b5620e74/rknn_toolkit_lite2-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bda74f1179e15fccb8726054a24898982522784b65bb340b20146955d254e800", size = 569160 }, - { url = "https://files.pythonhosted.org/packages/ff/db/64c756f3f06b219e92ff4f0fd4e000870ee49f214d505ff01c8b0275e26d/rknn_toolkit_lite2-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1e4ec691fed900c0e6fde5e7d8eeba17f806aa45092b63b361ee775e2c1b50e", size = 527458 }, + { url = "https://files.pythonhosted.org/packages/ab/db/76b40afe343f8a8c5222300da425e0dace30ce639a94776468b1d157311b/rknn_toolkit_lite2-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:821e80c95e6838308c133915660b1a6ae78bb8d079b2cbbd46a02dae61192d33", size = 559386, upload-time = "2025-04-09T09:39:54.414Z" }, + { url = "https://files.pythonhosted.org/packages/c1/3d/e80e1742420f62cb628d40a8bf547d6f7c9dbe4e13dcb7b7e7c0b5620e74/rknn_toolkit_lite2-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bda74f1179e15fccb8726054a24898982522784b65bb340b20146955d254e800", size = 569160, upload-time = "2025-04-09T09:39:56.149Z" }, + { url = "https://files.pythonhosted.org/packages/ff/db/64c756f3f06b219e92ff4f0fd4e000870ee49f214d505ff01c8b0275e26d/rknn_toolkit_lite2-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1e4ec691fed900c0e6fde5e7d8eeba17f806aa45092b63b361ee775e2c1b50e", size = 527458, upload-time = "2025-04-09T09:39:58.881Z" }, ] [[package]] @@ -2597,79 +2701,79 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447 } +sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447, upload-time = "2025-01-06T14:08:51.334Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1", size = 117729 }, + { url = "https://files.pythonhosted.org/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1", size = 117729, upload-time = "2025-01-06T14:08:47.471Z" }, ] [[package]] name = "ruamel-yaml-clib" version = "0.2.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315 } +sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315, upload-time = "2024-10-20T10:10:56.22Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301 }, - { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728 }, - { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230 }, - { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, - { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, - { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, - { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, - { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, - { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, - { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, - { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480 }, - { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068 }, - { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, - { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, - { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, - { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, - { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, - { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, - { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, - { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362 }, - { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118 }, - { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, - { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, - { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, - { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, - { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, - { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, - { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011 }, - { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488 }, - { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066 }, - { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785 }, - { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017 }, - { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270 }, - { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059 }, - { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583 }, - { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190 }, + { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301, upload-time = "2024-10-20T10:12:35.876Z" }, + { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728, upload-time = "2024-10-20T10:12:37.858Z" }, + { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230, upload-time = "2024-10-20T10:12:39.457Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712, upload-time = "2024-10-20T10:12:41.119Z" }, + { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936, upload-time = "2024-10-21T11:26:37.419Z" }, + { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580, upload-time = "2024-10-21T11:26:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393, upload-time = "2024-12-11T19:58:13.873Z" }, + { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326, upload-time = "2024-10-20T10:12:42.967Z" }, + { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079, upload-time = "2024-10-20T10:12:44.117Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224, upload-time = "2024-10-20T10:12:45.162Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480, upload-time = "2024-10-20T10:12:46.758Z" }, + { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068, upload-time = "2024-10-20T10:12:48.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012, upload-time = "2024-10-20T10:12:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352, upload-time = "2024-10-21T11:26:41.438Z" }, + { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344, upload-time = "2024-10-21T11:26:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498, upload-time = "2024-12-11T19:58:15.592Z" }, + { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205, upload-time = "2024-10-20T10:12:52.865Z" }, + { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185, upload-time = "2024-10-20T10:12:54.652Z" }, + { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433, upload-time = "2024-10-20T10:12:55.657Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362, upload-time = "2024-10-20T10:12:57.155Z" }, + { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118, upload-time = "2024-10-20T10:12:58.501Z" }, + { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497, upload-time = "2024-10-20T10:13:00.211Z" }, + { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042, upload-time = "2024-10-21T11:26:46.038Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831, upload-time = "2024-10-21T11:26:47.487Z" }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692, upload-time = "2024-12-11T19:58:17.252Z" }, + { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777, upload-time = "2024-10-20T10:13:01.395Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523, upload-time = "2024-10-20T10:13:02.768Z" }, + { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011, upload-time = "2024-10-20T10:13:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488, upload-time = "2024-10-20T10:13:05.906Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066, upload-time = "2024-10-20T10:13:07.26Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785, upload-time = "2024-10-20T10:13:08.504Z" }, + { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017, upload-time = "2024-10-21T11:26:48.866Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270, upload-time = "2024-10-21T11:26:50.213Z" }, + { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059, upload-time = "2024-12-11T19:58:18.846Z" }, + { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583, upload-time = "2024-10-20T10:13:09.658Z" }, + { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190, upload-time = "2024-10-20T10:13:10.66Z" }, ] [[package]] name = "ruff" -version = "0.12.11" +version = "0.14.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103 } +sdist = { url = "https://files.pythonhosted.org/packages/52/f0/62b5a1a723fe183650109407fa56abb433b00aa1c0b9ba555f9c4efec2c6/ruff-0.14.6.tar.gz", hash = "sha256:6f0c742ca6a7783a736b867a263b9a7a80a45ce9bee391eeda296895f1b4e1cc", size = 5669501, upload-time = "2025-11-21T14:26:17.903Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885 }, - { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364 }, - { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111 }, - { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060 }, - { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848 }, - { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288 }, - { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633 }, - { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430 }, - { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133 }, - { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082 }, - { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490 }, - { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928 }, - { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513 }, - { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154 }, - { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653 }, - { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270 }, - { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600 }, - { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290 }, + { url = "https://files.pythonhosted.org/packages/67/d2/7dd544116d107fffb24a0064d41a5d2ed1c9d6372d142f9ba108c8e39207/ruff-0.14.6-py3-none-linux_armv6l.whl", hash = "sha256:d724ac2f1c240dbd01a2ae98db5d1d9a5e1d9e96eba999d1c48e30062df578a3", size = 13326119, upload-time = "2025-11-21T14:25:24.2Z" }, + { url = "https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004", size = 13526007, upload-time = "2025-11-21T14:25:26.906Z" }, + { url = "https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332", size = 12676572, upload-time = "2025-11-21T14:25:29.826Z" }, + { url = "https://files.pythonhosted.org/packages/76/a4/f319e87759949062cfee1b26245048e92e2acce900ad3a909285f9db1859/ruff-0.14.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a8e7b9d73d8728b68f632aa8e824ef041d068d231d8dbc7808532d3629a6bef", size = 13140745, upload-time = "2025-11-21T14:25:32.788Z" }, + { url = "https://files.pythonhosted.org/packages/95/d3/248c1efc71a0a8ed4e8e10b4b2266845d7dfc7a0ab64354afe049eaa1310/ruff-0.14.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d50d45d4553a3ebcbd33e7c5e0fe6ca4aafd9a9122492de357205c2c48f00775", size = 13076486, upload-time = "2025-11-21T14:25:35.601Z" }, + { url = "https://files.pythonhosted.org/packages/a5/19/b68d4563fe50eba4b8c92aa842149bb56dd24d198389c0ed12e7faff4f7d/ruff-0.14.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:118548dd121f8a21bfa8ab2c5b80e5b4aed67ead4b7567790962554f38e598ce", size = 13727563, upload-time = "2025-11-21T14:25:38.514Z" }, + { url = "https://files.pythonhosted.org/packages/47/ac/943169436832d4b0e867235abbdb57ce3a82367b47e0280fa7b4eabb7593/ruff-0.14.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57256efafbfefcb8748df9d1d766062f62b20150691021f8ab79e2d919f7c11f", size = 15199755, upload-time = "2025-11-21T14:25:41.516Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b9/288bb2399860a36d4bb0541cb66cce3c0f4156aaff009dc8499be0c24bf2/ruff-0.14.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff18134841e5c68f8e5df1999a64429a02d5549036b394fafbe410f886e1989d", size = 14850608, upload-time = "2025-11-21T14:25:44.428Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b1/a0d549dd4364e240f37e7d2907e97ee80587480d98c7799d2d8dc7a2f605/ruff-0.14.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c4b7ec1e66a105d5c27bd57fa93203637d66a26d10ca9809dc7fc18ec58440", size = 14118754, upload-time = "2025-11-21T14:25:47.214Z" }, + { url = "https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105", size = 13949214, upload-time = "2025-11-21T14:25:50.002Z" }, + { url = "https://files.pythonhosted.org/packages/12/27/4dad6c6a77fede9560b7df6802b1b697e97e49ceabe1f12baf3ea20862e9/ruff-0.14.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:16a33af621c9c523b1ae006b1b99b159bf5ac7e4b1f20b85b2572455018e0821", size = 14106112, upload-time = "2025-11-21T14:25:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/6a/db/23e322d7177873eaedea59a7932ca5084ec5b7e20cb30f341ab594130a71/ruff-0.14.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1432ab6e1ae2dc565a7eea707d3b03a0c234ef401482a6f1621bc1f427c2ff55", size = 13035010, upload-time = "2025-11-21T14:25:55.536Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9c/20e21d4d69dbb35e6a1df7691e02f363423658a20a2afacf2a2c011800dc/ruff-0.14.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c55cfbbe7abb61eb914bfd20683d14cdfb38a6d56c6c66efa55ec6570ee4e71", size = 13054082, upload-time = "2025-11-21T14:25:58.625Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/906ee6a0464c3125c8d673c589771a974965c2be1a1e28b5c3b96cb6ef88/ruff-0.14.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:efea3c0f21901a685fff4befda6d61a1bf4cb43de16da87e8226a281d614350b", size = 13303354, upload-time = "2025-11-21T14:26:01.816Z" }, + { url = "https://files.pythonhosted.org/packages/4c/58/60577569e198d56922b7ead07b465f559002b7b11d53f40937e95067ca1c/ruff-0.14.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:344d97172576d75dc6afc0e9243376dbe1668559c72de1864439c4fc95f78185", size = 14054487, upload-time = "2025-11-21T14:26:05.058Z" }, + { url = "https://files.pythonhosted.org/packages/67/0b/8e4e0639e4cc12547f41cb771b0b44ec8225b6b6a93393176d75fe6f7d40/ruff-0.14.6-py3-none-win32.whl", hash = "sha256:00169c0c8b85396516fdd9ce3446c7ca20c2a8f90a77aa945ba6b8f2bfe99e85", size = 13013361, upload-time = "2025-11-21T14:26:08.152Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl", hash = "sha256:390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9", size = 14432087, upload-time = "2025-11-21T14:26:10.891Z" }, + { url = "https://files.pythonhosted.org/packages/a5/1f/93f9b0fad9470e4c829a5bb678da4012f0c710d09331b860ee555216f4ea/ruff-0.14.6-py3-none-win_arm64.whl", hash = "sha256:d43c81fbeae52cfa8728d8766bbf46ee4298c888072105815b392da70ca836b2", size = 13520930, upload-time = "2025-11-21T14:26:13.951Z" }, ] [[package]] @@ -2687,23 +2791,23 @@ dependencies = [ { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "tifffile" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/65/c1/a49da20845f0f0e1afbb1c2586d406dc0acb84c26ae293bad6d7e7f718bc/scikit_image-0.22.0.tar.gz", hash = "sha256:018d734df1d2da2719087d15f679d19285fce97cd37695103deadfaef2873236", size = 22685018 } +sdist = { url = "https://files.pythonhosted.org/packages/65/c1/a49da20845f0f0e1afbb1c2586d406dc0acb84c26ae293bad6d7e7f718bc/scikit_image-0.22.0.tar.gz", hash = "sha256:018d734df1d2da2719087d15f679d19285fce97cd37695103deadfaef2873236", size = 22685018, upload-time = "2023-10-03T21:36:34.274Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/8c/381ae42b37cf3e9e99a1deb3ffe76ca5ff5dd18ffa368293476164507fad/scikit_image-0.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74ec5c1d4693506842cc7c9487c89d8fc32aed064e9363def7af08b8f8cbb31d", size = 13905039 }, - { url = "https://files.pythonhosted.org/packages/16/06/4bfba08f5cce26d5070bb2cf4e3f9f479480978806355d1c5bea6f26a17c/scikit_image-0.22.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:a05ae4fe03d802587ed8974e900b943275548cde6a6807b785039d63e9a7a5ff", size = 13279212 }, - { url = "https://files.pythonhosted.org/packages/74/57/dbf744ca00eea2a09b1848c9dec28a43978c16dc049b1fba949cb050bedf/scikit_image-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a92dca3d95b1301442af055e196a54b5a5128c6768b79fc0a4098f1d662dee6", size = 14091779 }, - { url = "https://files.pythonhosted.org/packages/f1/6c/49f5a0ce8ddcdbdac5ac69c129654938cc6de0a936303caa6cad495ceb2a/scikit_image-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3663d063d8bf2fb9bdfb0ca967b9ee3b6593139c860c7abc2d2351a8a8863938", size = 14682042 }, - { url = "https://files.pythonhosted.org/packages/86/f0/18895318109f9b508f2310f136922e455a453550826a8240b412063c2528/scikit_image-0.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:ebdbdc901bae14dab637f8d5c99f6d5cc7aaf4a3b6f4003194e003e9f688a6fc", size = 24492345 }, - { url = "https://files.pythonhosted.org/packages/9f/d9/dc99e527d1a0050f0353d2fff3548273b4df6151884806e324f26572fd6b/scikit_image-0.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95d6da2d8a44a36ae04437c76d32deb4e3c993ffc846b394b9949fd8ded73cb2", size = 13883619 }, - { url = "https://files.pythonhosted.org/packages/80/37/7670020b112ff9a47e49b1e36f438d000db5b632aab8a8fd7e6be545d065/scikit_image-0.22.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:2c6ef454a85f569659b813ac2a93948022b0298516b757c9c6c904132be327e2", size = 13264761 }, - { url = "https://files.pythonhosted.org/packages/ad/85/dadf1194793ac1c895370f3ed048bb91dda083775b42e11d9672a50494d5/scikit_image-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87872f067444ee90a00dd49ca897208308645382e8a24bd3e76f301af2352cd", size = 14070710 }, - { url = "https://files.pythonhosted.org/packages/d4/34/e27bf2bfe7b52b884b49bd71ea91ff81e4737246735ee5ea383314c31876/scikit_image-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5c378db54e61b491b9edeefff87e49fcf7fdf729bb93c777d7a5f15d36f743e", size = 14664172 }, - { url = "https://files.pythonhosted.org/packages/ce/d0/a3f60c9f57ed295b3076e4acdb29a37bbd8823452562ab2ad51b03d6f377/scikit_image-0.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:2bcb74adb0634258a67f66c2bb29978c9a3e222463e003b67ba12056c003971b", size = 24491321 }, - { url = "https://files.pythonhosted.org/packages/da/a4/b0b69bde4d6360e801d647691591dc9967a25a18a4c63ecf7f87d94e3fac/scikit_image-0.22.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:003ca2274ac0fac252280e7179ff986ff783407001459ddea443fe7916e38cff", size = 13968808 }, - { url = "https://files.pythonhosted.org/packages/e4/65/3c0f77e7a9bae100a8f7f5cebde410fca1a3cf64e1ecdd343666e27b11d4/scikit_image-0.22.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:cf3c0c15b60ae3e557a0c7575fbd352f0c3ce0afca562febfe3ab80efbeec0e9", size = 13323763 }, - { url = "https://files.pythonhosted.org/packages/4a/ed/7faf9f7a55d5b3095d33990a85603b66866cce2a608b27f0e1487d70a451/scikit_image-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5b23908dd4d120e6aecb1ed0277563e8cbc8d6c0565bdc4c4c6475d53608452", size = 13877233 }, - { url = "https://files.pythonhosted.org/packages/ae/9d/09d06f36ce71fa276e1d9453fb4b04250a7038292b13b8c273a5a1a8f7c0/scikit_image-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be79d7493f320a964f8fcf603121595ba82f84720de999db0fcca002266a549a", size = 14954814 }, - { url = "https://files.pythonhosted.org/packages/dc/35/e6327ae498c6f557cb0a7c3fc284effe7958d2d1c43fb61cd77804fc2c4f/scikit_image-0.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:722b970aa5da725dca55252c373b18bbea7858c1cdb406e19f9b01a4a73b30b2", size = 25004857 }, + { url = "https://files.pythonhosted.org/packages/9c/8c/381ae42b37cf3e9e99a1deb3ffe76ca5ff5dd18ffa368293476164507fad/scikit_image-0.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74ec5c1d4693506842cc7c9487c89d8fc32aed064e9363def7af08b8f8cbb31d", size = 13905039, upload-time = "2023-10-03T21:35:27.279Z" }, + { url = "https://files.pythonhosted.org/packages/16/06/4bfba08f5cce26d5070bb2cf4e3f9f479480978806355d1c5bea6f26a17c/scikit_image-0.22.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:a05ae4fe03d802587ed8974e900b943275548cde6a6807b785039d63e9a7a5ff", size = 13279212, upload-time = "2023-10-03T21:35:30.864Z" }, + { url = "https://files.pythonhosted.org/packages/74/57/dbf744ca00eea2a09b1848c9dec28a43978c16dc049b1fba949cb050bedf/scikit_image-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a92dca3d95b1301442af055e196a54b5a5128c6768b79fc0a4098f1d662dee6", size = 14091779, upload-time = "2023-10-03T21:35:34.273Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6c/49f5a0ce8ddcdbdac5ac69c129654938cc6de0a936303caa6cad495ceb2a/scikit_image-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3663d063d8bf2fb9bdfb0ca967b9ee3b6593139c860c7abc2d2351a8a8863938", size = 14682042, upload-time = "2023-10-03T21:35:37.787Z" }, + { url = "https://files.pythonhosted.org/packages/86/f0/18895318109f9b508f2310f136922e455a453550826a8240b412063c2528/scikit_image-0.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:ebdbdc901bae14dab637f8d5c99f6d5cc7aaf4a3b6f4003194e003e9f688a6fc", size = 24492345, upload-time = "2023-10-03T21:35:41.122Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d9/dc99e527d1a0050f0353d2fff3548273b4df6151884806e324f26572fd6b/scikit_image-0.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95d6da2d8a44a36ae04437c76d32deb4e3c993ffc846b394b9949fd8ded73cb2", size = 13883619, upload-time = "2023-10-03T21:35:44.88Z" }, + { url = "https://files.pythonhosted.org/packages/80/37/7670020b112ff9a47e49b1e36f438d000db5b632aab8a8fd7e6be545d065/scikit_image-0.22.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:2c6ef454a85f569659b813ac2a93948022b0298516b757c9c6c904132be327e2", size = 13264761, upload-time = "2023-10-03T21:35:48.865Z" }, + { url = "https://files.pythonhosted.org/packages/ad/85/dadf1194793ac1c895370f3ed048bb91dda083775b42e11d9672a50494d5/scikit_image-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87872f067444ee90a00dd49ca897208308645382e8a24bd3e76f301af2352cd", size = 14070710, upload-time = "2023-10-03T21:35:51.711Z" }, + { url = "https://files.pythonhosted.org/packages/d4/34/e27bf2bfe7b52b884b49bd71ea91ff81e4737246735ee5ea383314c31876/scikit_image-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5c378db54e61b491b9edeefff87e49fcf7fdf729bb93c777d7a5f15d36f743e", size = 14664172, upload-time = "2023-10-03T21:35:55.752Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d0/a3f60c9f57ed295b3076e4acdb29a37bbd8823452562ab2ad51b03d6f377/scikit_image-0.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:2bcb74adb0634258a67f66c2bb29978c9a3e222463e003b67ba12056c003971b", size = 24491321, upload-time = "2023-10-03T21:35:58.847Z" }, + { url = "https://files.pythonhosted.org/packages/da/a4/b0b69bde4d6360e801d647691591dc9967a25a18a4c63ecf7f87d94e3fac/scikit_image-0.22.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:003ca2274ac0fac252280e7179ff986ff783407001459ddea443fe7916e38cff", size = 13968808, upload-time = "2023-10-03T21:36:02.526Z" }, + { url = "https://files.pythonhosted.org/packages/e4/65/3c0f77e7a9bae100a8f7f5cebde410fca1a3cf64e1ecdd343666e27b11d4/scikit_image-0.22.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:cf3c0c15b60ae3e557a0c7575fbd352f0c3ce0afca562febfe3ab80efbeec0e9", size = 13323763, upload-time = "2023-10-03T21:36:05.504Z" }, + { url = "https://files.pythonhosted.org/packages/4a/ed/7faf9f7a55d5b3095d33990a85603b66866cce2a608b27f0e1487d70a451/scikit_image-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5b23908dd4d120e6aecb1ed0277563e8cbc8d6c0565bdc4c4c6475d53608452", size = 13877233, upload-time = "2023-10-03T21:36:08.352Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/09d06f36ce71fa276e1d9453fb4b04250a7038292b13b8c273a5a1a8f7c0/scikit_image-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be79d7493f320a964f8fcf603121595ba82f84720de999db0fcca002266a549a", size = 14954814, upload-time = "2023-10-03T21:36:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/dc/35/e6327ae498c6f557cb0a7c3fc284effe7958d2d1c43fb61cd77804fc2c4f/scikit_image-0.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:722b970aa5da725dca55252c373b18bbea7858c1cdb406e19f9b01a4a73b30b2", size = 25004857, upload-time = "2023-10-03T21:36:15.457Z" }, ] [[package]] @@ -2721,23 +2825,23 @@ dependencies = [ { name = "scipy", version = "1.11.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "threadpoolctl", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/88/00/835e3d280fdd7784e76bdef91dd9487582d7951a7254f59fc8004fc8b213/scikit-learn-1.3.2.tar.gz", hash = "sha256:a2f54c76accc15a34bfb9066e6c7a56c1e7235dda5762b990792330b52ccfb05", size = 7510251 } +sdist = { url = "https://files.pythonhosted.org/packages/88/00/835e3d280fdd7784e76bdef91dd9487582d7951a7254f59fc8004fc8b213/scikit-learn-1.3.2.tar.gz", hash = "sha256:a2f54c76accc15a34bfb9066e6c7a56c1e7235dda5762b990792330b52ccfb05", size = 7510251, upload-time = "2023-10-23T13:47:55.287Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/53/570b55a6e10b8694ac1e3024d2df5cd443f1b4ff6d28430845da8b9019b3/scikit_learn-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e326c0eb5cf4d6ba40f93776a20e9a7a69524c4db0757e7ce24ba222471ee8a1", size = 10209999 }, - { url = "https://files.pythonhosted.org/packages/70/d0/50ace22129f79830e3cf682d0a2bd4843ef91573299d43112d52790163a8/scikit_learn-1.3.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:535805c2a01ccb40ca4ab7d081d771aea67e535153e35a1fd99418fcedd1648a", size = 9479353 }, - { url = "https://files.pythonhosted.org/packages/8f/46/fcc35ed7606c50d3072eae5a107a45cfa5b7f5fa8cc48610edd8cc8e8550/scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1215e5e58e9880b554b01187b8c9390bf4dc4692eedeaf542d3273f4785e342c", size = 10304705 }, - { url = "https://files.pythonhosted.org/packages/d0/0b/26ad95cf0b747be967b15fb71a06f5ac67aba0fd2f9cd174de6edefc4674/scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ee107923a623b9f517754ea2f69ea3b62fc898a3641766cb7deb2f2ce450161", size = 10827807 }, - { url = "https://files.pythonhosted.org/packages/69/8a/cf17d6443f5f537e099be81535a56ab68a473f9393fbffda38cd19899fc8/scikit_learn-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:35a22e8015048c628ad099da9df5ab3004cdbf81edc75b396fd0cff8699ac58c", size = 9255427 }, - { url = "https://files.pythonhosted.org/packages/08/5d/e5acecd6e99a6b656e42e7a7b18284e2f9c9f512e8ed6979e1e75d25f05f/scikit_learn-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6fb6bc98f234fda43163ddbe36df8bcde1d13ee176c6dc9b92bb7d3fc842eb66", size = 10116376 }, - { url = "https://files.pythonhosted.org/packages/40/c6/2e91eefb757822e70d351e02cc38d07c137212ae7c41ac12746415b4860a/scikit_learn-1.3.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:18424efee518a1cde7b0b53a422cde2f6625197de6af36da0b57ec502f126157", size = 9383415 }, - { url = "https://files.pythonhosted.org/packages/fa/fd/b3637639e73bb72b12803c5245f2a7299e09b2acd85a0f23937c53369a1c/scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3271552a5eb16f208a6f7f617b8cc6d1f137b52c8a1ef8edf547db0259b2c9fb", size = 10279163 }, - { url = "https://files.pythonhosted.org/packages/0c/2a/d3ff6091406bc2207e0adb832ebd15e40ac685811c7e2e3b432bfd969b71/scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4144a5004a676d5022b798d9e573b05139e77f271253a4703eed295bde0433", size = 10884422 }, - { url = "https://files.pythonhosted.org/packages/4e/ba/ce9bd1cd4953336a0e213b29cb80bb11816f2a93de8c99f88ef0b446ad0c/scikit_learn-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:67f37d708f042a9b8d59551cf94d30431e01374e00dc2645fa186059c6c5d78b", size = 9207060 }, - { url = "https://files.pythonhosted.org/packages/26/7e/2c3b82c8c29aa384c8bf859740419278627d2cdd0050db503c8840e72477/scikit_learn-1.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8db94cd8a2e038b37a80a04df8783e09caac77cbe052146432e67800e430c028", size = 9979322 }, - { url = "https://files.pythonhosted.org/packages/cf/fc/6c52ffeb587259b6b893b7cac268f1eb1b5426bcce1aa20e53523bfe6944/scikit_learn-1.3.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:61a6efd384258789aa89415a410dcdb39a50e19d3d8410bd29be365bcdd512d5", size = 9270688 }, - { url = "https://files.pythonhosted.org/packages/e5/a7/6f4ae76f72ae9de162b97acbf1f53acbe404c555f968d13da21e4112a002/scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb06f8dce3f5ddc5dee1715a9b9f19f20d295bed8e3cd4fa51e1d050347de525", size = 10280398 }, - { url = "https://files.pythonhosted.org/packages/5d/b7/ee35904c07a0666784349529412fbb9814a56382b650d30fd9d6be5e5054/scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b2de18d86f630d68fe1f87af690d451388bb186480afc719e5f770590c2ef6c", size = 10796478 }, - { url = "https://files.pythonhosted.org/packages/fe/6b/db949ed5ac367987b1f250f070f340b7715d22f0c9c965bdf07de6ca75a3/scikit_learn-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:0402638c9a7c219ee52c94cbebc8fcb5eb9fe9c773717965c1f4185588ad3107", size = 9133979 }, + { url = "https://files.pythonhosted.org/packages/0d/53/570b55a6e10b8694ac1e3024d2df5cd443f1b4ff6d28430845da8b9019b3/scikit_learn-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e326c0eb5cf4d6ba40f93776a20e9a7a69524c4db0757e7ce24ba222471ee8a1", size = 10209999, upload-time = "2023-10-23T13:46:30.373Z" }, + { url = "https://files.pythonhosted.org/packages/70/d0/50ace22129f79830e3cf682d0a2bd4843ef91573299d43112d52790163a8/scikit_learn-1.3.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:535805c2a01ccb40ca4ab7d081d771aea67e535153e35a1fd99418fcedd1648a", size = 9479353, upload-time = "2023-10-23T13:46:34.368Z" }, + { url = "https://files.pythonhosted.org/packages/8f/46/fcc35ed7606c50d3072eae5a107a45cfa5b7f5fa8cc48610edd8cc8e8550/scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1215e5e58e9880b554b01187b8c9390bf4dc4692eedeaf542d3273f4785e342c", size = 10304705, upload-time = "2023-10-23T13:46:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/d0/0b/26ad95cf0b747be967b15fb71a06f5ac67aba0fd2f9cd174de6edefc4674/scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ee107923a623b9f517754ea2f69ea3b62fc898a3641766cb7deb2f2ce450161", size = 10827807, upload-time = "2023-10-23T13:46:41.59Z" }, + { url = "https://files.pythonhosted.org/packages/69/8a/cf17d6443f5f537e099be81535a56ab68a473f9393fbffda38cd19899fc8/scikit_learn-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:35a22e8015048c628ad099da9df5ab3004cdbf81edc75b396fd0cff8699ac58c", size = 9255427, upload-time = "2023-10-23T13:46:44.826Z" }, + { url = "https://files.pythonhosted.org/packages/08/5d/e5acecd6e99a6b656e42e7a7b18284e2f9c9f512e8ed6979e1e75d25f05f/scikit_learn-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6fb6bc98f234fda43163ddbe36df8bcde1d13ee176c6dc9b92bb7d3fc842eb66", size = 10116376, upload-time = "2023-10-23T13:46:48.147Z" }, + { url = "https://files.pythonhosted.org/packages/40/c6/2e91eefb757822e70d351e02cc38d07c137212ae7c41ac12746415b4860a/scikit_learn-1.3.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:18424efee518a1cde7b0b53a422cde2f6625197de6af36da0b57ec502f126157", size = 9383415, upload-time = "2023-10-23T13:46:51.324Z" }, + { url = "https://files.pythonhosted.org/packages/fa/fd/b3637639e73bb72b12803c5245f2a7299e09b2acd85a0f23937c53369a1c/scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3271552a5eb16f208a6f7f617b8cc6d1f137b52c8a1ef8edf547db0259b2c9fb", size = 10279163, upload-time = "2023-10-23T13:46:54.642Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/d3ff6091406bc2207e0adb832ebd15e40ac685811c7e2e3b432bfd969b71/scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4144a5004a676d5022b798d9e573b05139e77f271253a4703eed295bde0433", size = 10884422, upload-time = "2023-10-23T13:46:58.087Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ba/ce9bd1cd4953336a0e213b29cb80bb11816f2a93de8c99f88ef0b446ad0c/scikit_learn-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:67f37d708f042a9b8d59551cf94d30431e01374e00dc2645fa186059c6c5d78b", size = 9207060, upload-time = "2023-10-23T13:47:00.948Z" }, + { url = "https://files.pythonhosted.org/packages/26/7e/2c3b82c8c29aa384c8bf859740419278627d2cdd0050db503c8840e72477/scikit_learn-1.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8db94cd8a2e038b37a80a04df8783e09caac77cbe052146432e67800e430c028", size = 9979322, upload-time = "2023-10-23T13:47:03.977Z" }, + { url = "https://files.pythonhosted.org/packages/cf/fc/6c52ffeb587259b6b893b7cac268f1eb1b5426bcce1aa20e53523bfe6944/scikit_learn-1.3.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:61a6efd384258789aa89415a410dcdb39a50e19d3d8410bd29be365bcdd512d5", size = 9270688, upload-time = "2023-10-23T13:47:07.316Z" }, + { url = "https://files.pythonhosted.org/packages/e5/a7/6f4ae76f72ae9de162b97acbf1f53acbe404c555f968d13da21e4112a002/scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb06f8dce3f5ddc5dee1715a9b9f19f20d295bed8e3cd4fa51e1d050347de525", size = 10280398, upload-time = "2023-10-23T13:47:10.796Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b7/ee35904c07a0666784349529412fbb9814a56382b650d30fd9d6be5e5054/scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b2de18d86f630d68fe1f87af690d451388bb186480afc719e5f770590c2ef6c", size = 10796478, upload-time = "2023-10-23T13:47:14.077Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6b/db949ed5ac367987b1f250f070f340b7715d22f0c9c965bdf07de6ca75a3/scikit_learn-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:0402638c9a7c219ee52c94cbebc8fcb5eb9fe9c773717965c1f4185588ad3107", size = 9133979, upload-time = "2023-10-23T13:47:17.389Z" }, ] [[package]] @@ -2764,33 +2868,33 @@ dependencies = [ { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "threadpoolctl", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445 } +sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445, upload-time = "2025-07-18T08:01:54.5Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/74/88/0dd5be14ef19f2d80a77780be35a33aa94e8a3b3223d80bee8892a7832b4/scikit_learn-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:406204dd4004f0517f0b23cf4b28c6245cbd51ab1b6b78153bc784def214946d", size = 9338868 }, - { url = "https://files.pythonhosted.org/packages/fd/52/3056b6adb1ac58a0bc335fc2ed2fcf599974d908855e8cb0ca55f797593c/scikit_learn-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16af2e44164f05d04337fd1fc3ae7c4ea61fd9b0d527e22665346336920fe0e1", size = 8655943 }, - { url = "https://files.pythonhosted.org/packages/fb/a4/e488acdece6d413f370a9589a7193dac79cd486b2e418d3276d6ea0b9305/scikit_learn-1.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2f2e78e56a40c7587dea9a28dc4a49500fa2ead366869418c66f0fd75b80885c", size = 9652056 }, - { url = "https://files.pythonhosted.org/packages/18/41/bceacec1285b94eb9e4659b24db46c23346d7e22cf258d63419eb5dec6f7/scikit_learn-1.7.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b62b76ad408a821475b43b7bb90a9b1c9a4d8d125d505c2df0539f06d6e631b1", size = 9473691 }, - { url = "https://files.pythonhosted.org/packages/12/7b/e1ae4b7e1dd85c4ca2694ff9cc4a9690970fd6150d81b975e6c5c6f8ee7c/scikit_learn-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:9963b065677a4ce295e8ccdee80a1dd62b37249e667095039adcd5bce6e90deb", size = 8900873 }, - { url = "https://files.pythonhosted.org/packages/b4/bd/a23177930abd81b96daffa30ef9c54ddbf544d3226b8788ce4c3ef1067b4/scikit_learn-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90c8494ea23e24c0fb371afc474618c1019dc152ce4a10e4607e62196113851b", size = 9334838 }, - { url = "https://files.pythonhosted.org/packages/8d/a1/d3a7628630a711e2ac0d1a482910da174b629f44e7dd8cfcd6924a4ef81a/scikit_learn-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bb870c0daf3bf3be145ec51df8ac84720d9972170786601039f024bf6d61a518", size = 8651241 }, - { url = "https://files.pythonhosted.org/packages/26/92/85ec172418f39474c1cd0221d611345d4f433fc4ee2fc68e01f524ccc4e4/scikit_learn-1.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40daccd1b5623f39e8943ab39735cadf0bdce80e67cdca2adcb5426e987320a8", size = 9718677 }, - { url = "https://files.pythonhosted.org/packages/df/ce/abdb1dcbb1d2b66168ec43b23ee0cee356b4cc4100ddee3943934ebf1480/scikit_learn-1.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30d1f413cfc0aa5a99132a554f1d80517563c34a9d3e7c118fde2d273c6fe0f7", size = 9511189 }, - { url = "https://files.pythonhosted.org/packages/b2/3b/47b5eaee01ef2b5a80ba3f7f6ecf79587cb458690857d4777bfd77371c6f/scikit_learn-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c711d652829a1805a95d7fe96654604a8f16eab5a9e9ad87b3e60173415cb650", size = 8914794 }, - { url = "https://files.pythonhosted.org/packages/cb/16/57f176585b35ed865f51b04117947fe20f130f78940c6477b6d66279c9c2/scikit_learn-1.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3cee419b49b5bbae8796ecd690f97aa412ef1674410c23fc3257c6b8b85b8087", size = 9260431 }, - { url = "https://files.pythonhosted.org/packages/67/4e/899317092f5efcab0e9bc929e3391341cec8fb0e816c4789686770024580/scikit_learn-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2fd8b8d35817b0d9ebf0b576f7d5ffbbabdb55536b0655a8aaae629d7ffd2e1f", size = 8637191 }, - { url = "https://files.pythonhosted.org/packages/f3/1b/998312db6d361ded1dd56b457ada371a8d8d77ca2195a7d18fd8a1736f21/scikit_learn-1.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:588410fa19a96a69763202f1d6b7b91d5d7a5d73be36e189bc6396bfb355bd87", size = 9486346 }, - { url = "https://files.pythonhosted.org/packages/ad/09/a2aa0b4e644e5c4ede7006748f24e72863ba2ae71897fecfd832afea01b4/scikit_learn-1.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3142f0abe1ad1d1c31a2ae987621e41f6b578144a911ff4ac94781a583adad7", size = 9290988 }, - { url = "https://files.pythonhosted.org/packages/15/fa/c61a787e35f05f17fc10523f567677ec4eeee5f95aa4798dbbbcd9625617/scikit_learn-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ddd9092c1bd469acab337d87930067c87eac6bd544f8d5027430983f1e1ae88", size = 8735568 }, - { url = "https://files.pythonhosted.org/packages/52/f8/e0533303f318a0f37b88300d21f79b6ac067188d4824f1047a37214ab718/scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae", size = 9213143 }, - { url = "https://files.pythonhosted.org/packages/71/f3/f1df377d1bdfc3e3e2adc9c119c238b182293e6740df4cbeac6de2cc3e23/scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10", size = 8591977 }, - { url = "https://files.pythonhosted.org/packages/99/72/c86a4cd867816350fe8dee13f30222340b9cd6b96173955819a5561810c5/scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309", size = 9436142 }, - { url = "https://files.pythonhosted.org/packages/e8/66/277967b29bd297538dc7a6ecfb1a7dce751beabd0d7f7a2233be7a4f7832/scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43", size = 9282996 }, - { url = "https://files.pythonhosted.org/packages/e2/47/9291cfa1db1dae9880420d1e07dbc7e8dd4a7cdbc42eaba22512e6bde958/scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11", size = 8707418 }, - { url = "https://files.pythonhosted.org/packages/61/95/45726819beccdaa34d3362ea9b2ff9f2b5d3b8bf721bd632675870308ceb/scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae", size = 9561466 }, - { url = "https://files.pythonhosted.org/packages/ee/1c/6f4b3344805de783d20a51eb24d4c9ad4b11a7f75c1801e6ec6d777361fd/scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c", size = 9040467 }, - { url = "https://files.pythonhosted.org/packages/6f/80/abe18fe471af9f1d181904203d62697998b27d9b62124cd281d740ded2f9/scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e", size = 9532052 }, - { url = "https://files.pythonhosted.org/packages/14/82/b21aa1e0c4cee7e74864d3a5a721ab8fcae5ca55033cb6263dca297ed35b/scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7", size = 9361575 }, - { url = "https://files.pythonhosted.org/packages/f2/20/f4777fcd5627dc6695fa6b92179d0edb7a3ac1b91bcd9a1c7f64fa7ade23/scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5", size = 9277310 }, + { url = "https://files.pythonhosted.org/packages/74/88/0dd5be14ef19f2d80a77780be35a33aa94e8a3b3223d80bee8892a7832b4/scikit_learn-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:406204dd4004f0517f0b23cf4b28c6245cbd51ab1b6b78153bc784def214946d", size = 9338868, upload-time = "2025-07-18T08:01:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/fd/52/3056b6adb1ac58a0bc335fc2ed2fcf599974d908855e8cb0ca55f797593c/scikit_learn-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16af2e44164f05d04337fd1fc3ae7c4ea61fd9b0d527e22665346336920fe0e1", size = 8655943, upload-time = "2025-07-18T08:01:02.974Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a4/e488acdece6d413f370a9589a7193dac79cd486b2e418d3276d6ea0b9305/scikit_learn-1.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2f2e78e56a40c7587dea9a28dc4a49500fa2ead366869418c66f0fd75b80885c", size = 9652056, upload-time = "2025-07-18T08:01:04.978Z" }, + { url = "https://files.pythonhosted.org/packages/18/41/bceacec1285b94eb9e4659b24db46c23346d7e22cf258d63419eb5dec6f7/scikit_learn-1.7.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b62b76ad408a821475b43b7bb90a9b1c9a4d8d125d505c2df0539f06d6e631b1", size = 9473691, upload-time = "2025-07-18T08:01:07.006Z" }, + { url = "https://files.pythonhosted.org/packages/12/7b/e1ae4b7e1dd85c4ca2694ff9cc4a9690970fd6150d81b975e6c5c6f8ee7c/scikit_learn-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:9963b065677a4ce295e8ccdee80a1dd62b37249e667095039adcd5bce6e90deb", size = 8900873, upload-time = "2025-07-18T08:01:09.332Z" }, + { url = "https://files.pythonhosted.org/packages/b4/bd/a23177930abd81b96daffa30ef9c54ddbf544d3226b8788ce4c3ef1067b4/scikit_learn-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90c8494ea23e24c0fb371afc474618c1019dc152ce4a10e4607e62196113851b", size = 9334838, upload-time = "2025-07-18T08:01:11.239Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a1/d3a7628630a711e2ac0d1a482910da174b629f44e7dd8cfcd6924a4ef81a/scikit_learn-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bb870c0daf3bf3be145ec51df8ac84720d9972170786601039f024bf6d61a518", size = 8651241, upload-time = "2025-07-18T08:01:13.234Z" }, + { url = "https://files.pythonhosted.org/packages/26/92/85ec172418f39474c1cd0221d611345d4f433fc4ee2fc68e01f524ccc4e4/scikit_learn-1.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40daccd1b5623f39e8943ab39735cadf0bdce80e67cdca2adcb5426e987320a8", size = 9718677, upload-time = "2025-07-18T08:01:15.649Z" }, + { url = "https://files.pythonhosted.org/packages/df/ce/abdb1dcbb1d2b66168ec43b23ee0cee356b4cc4100ddee3943934ebf1480/scikit_learn-1.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30d1f413cfc0aa5a99132a554f1d80517563c34a9d3e7c118fde2d273c6fe0f7", size = 9511189, upload-time = "2025-07-18T08:01:18.013Z" }, + { url = "https://files.pythonhosted.org/packages/b2/3b/47b5eaee01ef2b5a80ba3f7f6ecf79587cb458690857d4777bfd77371c6f/scikit_learn-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c711d652829a1805a95d7fe96654604a8f16eab5a9e9ad87b3e60173415cb650", size = 8914794, upload-time = "2025-07-18T08:01:20.357Z" }, + { url = "https://files.pythonhosted.org/packages/cb/16/57f176585b35ed865f51b04117947fe20f130f78940c6477b6d66279c9c2/scikit_learn-1.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3cee419b49b5bbae8796ecd690f97aa412ef1674410c23fc3257c6b8b85b8087", size = 9260431, upload-time = "2025-07-18T08:01:22.77Z" }, + { url = "https://files.pythonhosted.org/packages/67/4e/899317092f5efcab0e9bc929e3391341cec8fb0e816c4789686770024580/scikit_learn-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2fd8b8d35817b0d9ebf0b576f7d5ffbbabdb55536b0655a8aaae629d7ffd2e1f", size = 8637191, upload-time = "2025-07-18T08:01:24.731Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1b/998312db6d361ded1dd56b457ada371a8d8d77ca2195a7d18fd8a1736f21/scikit_learn-1.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:588410fa19a96a69763202f1d6b7b91d5d7a5d73be36e189bc6396bfb355bd87", size = 9486346, upload-time = "2025-07-18T08:01:26.713Z" }, + { url = "https://files.pythonhosted.org/packages/ad/09/a2aa0b4e644e5c4ede7006748f24e72863ba2ae71897fecfd832afea01b4/scikit_learn-1.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3142f0abe1ad1d1c31a2ae987621e41f6b578144a911ff4ac94781a583adad7", size = 9290988, upload-time = "2025-07-18T08:01:28.938Z" }, + { url = "https://files.pythonhosted.org/packages/15/fa/c61a787e35f05f17fc10523f567677ec4eeee5f95aa4798dbbbcd9625617/scikit_learn-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ddd9092c1bd469acab337d87930067c87eac6bd544f8d5027430983f1e1ae88", size = 8735568, upload-time = "2025-07-18T08:01:30.936Z" }, + { url = "https://files.pythonhosted.org/packages/52/f8/e0533303f318a0f37b88300d21f79b6ac067188d4824f1047a37214ab718/scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae", size = 9213143, upload-time = "2025-07-18T08:01:32.942Z" }, + { url = "https://files.pythonhosted.org/packages/71/f3/f1df377d1bdfc3e3e2adc9c119c238b182293e6740df4cbeac6de2cc3e23/scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10", size = 8591977, upload-time = "2025-07-18T08:01:34.967Z" }, + { url = "https://files.pythonhosted.org/packages/99/72/c86a4cd867816350fe8dee13f30222340b9cd6b96173955819a5561810c5/scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309", size = 9436142, upload-time = "2025-07-18T08:01:37.397Z" }, + { url = "https://files.pythonhosted.org/packages/e8/66/277967b29bd297538dc7a6ecfb1a7dce751beabd0d7f7a2233be7a4f7832/scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43", size = 9282996, upload-time = "2025-07-18T08:01:39.721Z" }, + { url = "https://files.pythonhosted.org/packages/e2/47/9291cfa1db1dae9880420d1e07dbc7e8dd4a7cdbc42eaba22512e6bde958/scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11", size = 8707418, upload-time = "2025-07-18T08:01:42.124Z" }, + { url = "https://files.pythonhosted.org/packages/61/95/45726819beccdaa34d3362ea9b2ff9f2b5d3b8bf721bd632675870308ceb/scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae", size = 9561466, upload-time = "2025-07-18T08:01:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1c/6f4b3344805de783d20a51eb24d4c9ad4b11a7f75c1801e6ec6d777361fd/scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c", size = 9040467, upload-time = "2025-07-18T08:01:46.671Z" }, + { url = "https://files.pythonhosted.org/packages/6f/80/abe18fe471af9f1d181904203d62697998b27d9b62124cd281d740ded2f9/scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e", size = 9532052, upload-time = "2025-07-18T08:01:48.676Z" }, + { url = "https://files.pythonhosted.org/packages/14/82/b21aa1e0c4cee7e74864d3a5a721ab8fcae5ca55033cb6263dca297ed35b/scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7", size = 9361575, upload-time = "2025-07-18T08:01:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/f4777fcd5627dc6695fa6b92179d0edb7a3ac1b91bcd9a1c7f64fa7ade23/scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5", size = 9277310, upload-time = "2025-07-18T08:01:52.547Z" }, ] [[package]] @@ -2805,26 +2909,26 @@ resolution-markers = [ dependencies = [ { name = "numpy", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/1f/91144ba78dccea567a6466262922786ffc97be1e9b06ed9574ef0edc11e1/scipy-1.11.4.tar.gz", hash = "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa", size = 56336202 } +sdist = { url = "https://files.pythonhosted.org/packages/6e/1f/91144ba78dccea567a6466262922786ffc97be1e9b06ed9574ef0edc11e1/scipy-1.11.4.tar.gz", hash = "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa", size = 56336202, upload-time = "2023-11-18T21:06:08.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/c6/a32add319475d21f89733c034b99c81b3a7c6c7c19f96f80c7ca3ff1bbd4/scipy-1.11.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710", size = 37293259 }, - { url = "https://files.pythonhosted.org/packages/de/0d/4fa68303568c70fd56fbf40668b6c6807cfee4cad975f07d80bdd26d013e/scipy-1.11.4-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41", size = 29760656 }, - { url = "https://files.pythonhosted.org/packages/13/e5/8012be7857db6cbbbdbeea8a154dbacdfae845e95e1e19c028e82236d4a0/scipy-1.11.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4", size = 32922489 }, - { url = "https://files.pythonhosted.org/packages/e0/9e/80e2205d138960a49caea391f3710600895dd8292b6868dc9aff7aa593f9/scipy-1.11.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56", size = 36442040 }, - { url = "https://files.pythonhosted.org/packages/69/60/30a9c3fbe5066a3a93eefe3e2d44553df13587e6f792e1bff20dfed3d17e/scipy-1.11.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446", size = 36643257 }, - { url = "https://files.pythonhosted.org/packages/f8/ec/b46756f80e3f4c5f0989f6e4492c2851f156d9c239d554754a3c8cffd4e2/scipy-1.11.4-cp310-cp310-win_amd64.whl", hash = "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3", size = 44149285 }, - { url = "https://files.pythonhosted.org/packages/b8/f2/1aefbd5e54ebd8c6163ccf7f73e5d17bc8cb38738d312befc524fce84bb4/scipy-1.11.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be", size = 37159197 }, - { url = "https://files.pythonhosted.org/packages/4b/48/20e77ddb1f473d4717a7d4d3fc8d15557f406f7708496054c59f635b7734/scipy-1.11.4-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8", size = 29675057 }, - { url = "https://files.pythonhosted.org/packages/75/2e/a781862190d0e7e76afa74752ef363488a9a9d6ea86e46d5e5506cee8df6/scipy-1.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c", size = 32882747 }, - { url = "https://files.pythonhosted.org/packages/6b/d4/d62ce38ba00dc67d7ec4ec5cc19d36958d8ed70e63778715ad626bcbc796/scipy-1.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff", size = 36402732 }, - { url = "https://files.pythonhosted.org/packages/88/86/827b56aea1ed04adbb044a675672a73c84d81076a350092bbfcfc1ae723b/scipy-1.11.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993", size = 36622138 }, - { url = "https://files.pythonhosted.org/packages/43/d0/f3cd75b62e1b90f48dbf091261b2fc7ceec14a700e308c50f6a69c83d337/scipy-1.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd", size = 44095631 }, - { url = "https://files.pythonhosted.org/packages/df/64/8a690570485b636da614acff35fd725fcbc487f8b1fa9bdb12871b77412f/scipy-1.11.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6", size = 37053653 }, - { url = "https://files.pythonhosted.org/packages/5e/43/abf331745a7e5f4af51f13d40e2a72f516048db41ecbcf3ac6f86ada54a3/scipy-1.11.4-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d", size = 29641601 }, - { url = "https://files.pythonhosted.org/packages/47/9b/62d0ec086dd2871009da8769c504bec6e39b80f4c182c6ead0fcebd8b323/scipy-1.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4", size = 32272137 }, - { url = "https://files.pythonhosted.org/packages/08/77/f90f7306d755ac68bd159c50bb86fffe38400e533e8c609dd8484bd0f172/scipy-1.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79", size = 35777534 }, - { url = "https://files.pythonhosted.org/packages/00/de/b9f6938090c37b5092969ba1c67118e9114e8e6ef9d197251671444e839c/scipy-1.11.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660", size = 35963721 }, - { url = "https://files.pythonhosted.org/packages/c6/a1/357e4cd43af2748e1e0407ae0e9a5ea8aaaa6b702833c81be11670dcbad8/scipy-1.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97", size = 43730653 }, + { url = "https://files.pythonhosted.org/packages/34/c6/a32add319475d21f89733c034b99c81b3a7c6c7c19f96f80c7ca3ff1bbd4/scipy-1.11.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710", size = 37293259, upload-time = "2023-11-18T21:01:18.805Z" }, + { url = "https://files.pythonhosted.org/packages/de/0d/4fa68303568c70fd56fbf40668b6c6807cfee4cad975f07d80bdd26d013e/scipy-1.11.4-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41", size = 29760656, upload-time = "2023-11-18T21:01:41.815Z" }, + { url = "https://files.pythonhosted.org/packages/13/e5/8012be7857db6cbbbdbeea8a154dbacdfae845e95e1e19c028e82236d4a0/scipy-1.11.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4", size = 32922489, upload-time = "2023-11-18T21:01:50.637Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9e/80e2205d138960a49caea391f3710600895dd8292b6868dc9aff7aa593f9/scipy-1.11.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56", size = 36442040, upload-time = "2023-11-18T21:02:00.119Z" }, + { url = "https://files.pythonhosted.org/packages/69/60/30a9c3fbe5066a3a93eefe3e2d44553df13587e6f792e1bff20dfed3d17e/scipy-1.11.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446", size = 36643257, upload-time = "2023-11-18T21:02:06.798Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ec/b46756f80e3f4c5f0989f6e4492c2851f156d9c239d554754a3c8cffd4e2/scipy-1.11.4-cp310-cp310-win_amd64.whl", hash = "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3", size = 44149285, upload-time = "2023-11-18T21:02:15.592Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f2/1aefbd5e54ebd8c6163ccf7f73e5d17bc8cb38738d312befc524fce84bb4/scipy-1.11.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be", size = 37159197, upload-time = "2023-11-18T21:02:21.959Z" }, + { url = "https://files.pythonhosted.org/packages/4b/48/20e77ddb1f473d4717a7d4d3fc8d15557f406f7708496054c59f635b7734/scipy-1.11.4-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8", size = 29675057, upload-time = "2023-11-18T21:02:28.169Z" }, + { url = "https://files.pythonhosted.org/packages/75/2e/a781862190d0e7e76afa74752ef363488a9a9d6ea86e46d5e5506cee8df6/scipy-1.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c", size = 32882747, upload-time = "2023-11-18T21:02:33.683Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d4/d62ce38ba00dc67d7ec4ec5cc19d36958d8ed70e63778715ad626bcbc796/scipy-1.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff", size = 36402732, upload-time = "2023-11-18T21:02:39.762Z" }, + { url = "https://files.pythonhosted.org/packages/88/86/827b56aea1ed04adbb044a675672a73c84d81076a350092bbfcfc1ae723b/scipy-1.11.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993", size = 36622138, upload-time = "2023-11-18T21:02:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/43/d0/f3cd75b62e1b90f48dbf091261b2fc7ceec14a700e308c50f6a69c83d337/scipy-1.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd", size = 44095631, upload-time = "2023-11-18T21:02:52.859Z" }, + { url = "https://files.pythonhosted.org/packages/df/64/8a690570485b636da614acff35fd725fcbc487f8b1fa9bdb12871b77412f/scipy-1.11.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6", size = 37053653, upload-time = "2023-11-18T21:03:00.107Z" }, + { url = "https://files.pythonhosted.org/packages/5e/43/abf331745a7e5f4af51f13d40e2a72f516048db41ecbcf3ac6f86ada54a3/scipy-1.11.4-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d", size = 29641601, upload-time = "2023-11-18T21:03:06.708Z" }, + { url = "https://files.pythonhosted.org/packages/47/9b/62d0ec086dd2871009da8769c504bec6e39b80f4c182c6ead0fcebd8b323/scipy-1.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4", size = 32272137, upload-time = "2023-11-18T21:03:14.877Z" }, + { url = "https://files.pythonhosted.org/packages/08/77/f90f7306d755ac68bd159c50bb86fffe38400e533e8c609dd8484bd0f172/scipy-1.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79", size = 35777534, upload-time = "2023-11-18T21:03:21.451Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/b9f6938090c37b5092969ba1c67118e9114e8e6ef9d197251671444e839c/scipy-1.11.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660", size = 35963721, upload-time = "2023-11-18T21:03:27.85Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a1/357e4cd43af2748e1e0407ae0e9a5ea8aaaa6b702833c81be11670dcbad8/scipy-1.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97", size = 43730653, upload-time = "2023-11-18T21:03:34.758Z" }, ] [[package]] @@ -2848,71 +2952,71 @@ resolution-markers = [ dependencies = [ { name = "numpy", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861 } +sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/91/812adc6f74409b461e3a5fa97f4f74c769016919203138a3bf6fc24ba4c5/scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030", size = 36552519 }, - { url = "https://files.pythonhosted.org/packages/47/18/8e355edcf3b71418d9e9f9acd2708cc3a6c27e8f98fde0ac34b8a0b45407/scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7", size = 28638010 }, - { url = "https://files.pythonhosted.org/packages/d9/eb/e931853058607bdfbc11b86df19ae7a08686121c203483f62f1ecae5989c/scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77", size = 20909790 }, - { url = "https://files.pythonhosted.org/packages/45/0c/be83a271d6e96750cd0be2e000f35ff18880a46f05ce8b5d3465dc0f7a2a/scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe", size = 23513352 }, - { url = "https://files.pythonhosted.org/packages/7c/bf/fe6eb47e74f762f933cca962db7f2c7183acfdc4483bd1c3813cfe83e538/scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b", size = 33534643 }, - { url = "https://files.pythonhosted.org/packages/bb/ba/63f402e74875486b87ec6506a4f93f6d8a0d94d10467280f3d9d7837ce3a/scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7", size = 35376776 }, - { url = "https://files.pythonhosted.org/packages/c3/b4/04eb9d39ec26a1b939689102da23d505ea16cdae3dbb18ffc53d1f831044/scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958", size = 35698906 }, - { url = "https://files.pythonhosted.org/packages/04/d6/bb5468da53321baeb001f6e4e0d9049eadd175a4a497709939128556e3ec/scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39", size = 38129275 }, - { url = "https://files.pythonhosted.org/packages/c4/94/994369978509f227cba7dfb9e623254d0d5559506fe994aef4bea3ed469c/scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596", size = 38644572 }, - { url = "https://files.pythonhosted.org/packages/f8/d9/ec4864f5896232133f51382b54a08de91a9d1af7a76dfa372894026dfee2/scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c", size = 36575194 }, - { url = "https://files.pythonhosted.org/packages/5c/6d/40e81ecfb688e9d25d34a847dca361982a6addf8e31f0957b1a54fbfa994/scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04", size = 28594590 }, - { url = "https://files.pythonhosted.org/packages/0e/37/9f65178edfcc629377ce9a64fc09baebea18c80a9e57ae09a52edf84880b/scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919", size = 20866458 }, - { url = "https://files.pythonhosted.org/packages/2c/7b/749a66766871ea4cb1d1ea10f27004db63023074c22abed51f22f09770e0/scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921", size = 23539318 }, - { url = "https://files.pythonhosted.org/packages/c4/db/8d4afec60eb833a666434d4541a3151eedbf2494ea6d4d468cbe877f00cd/scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725", size = 33292899 }, - { url = "https://files.pythonhosted.org/packages/51/1e/79023ca3bbb13a015d7d2757ecca3b81293c663694c35d6541b4dca53e98/scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618", size = 35162637 }, - { url = "https://files.pythonhosted.org/packages/b6/49/0648665f9c29fdaca4c679182eb972935b3b4f5ace41d323c32352f29816/scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d", size = 35490507 }, - { url = "https://files.pythonhosted.org/packages/62/8f/66cbb9d6bbb18d8c658f774904f42a92078707a7c71e5347e8bf2f52bb89/scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119", size = 37923998 }, - { url = "https://files.pythonhosted.org/packages/14/c3/61f273ae550fbf1667675701112e380881905e28448c080b23b5a181df7c/scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a", size = 38508060 }, - { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717 }, - { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009 }, - { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942 }, - { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507 }, - { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040 }, - { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096 }, - { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328 }, - { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921 }, - { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462 }, - { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832 }, - { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084 }, - { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098 }, - { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858 }, - { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311 }, - { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542 }, - { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665 }, - { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210 }, - { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661 }, - { url = "https://files.pythonhosted.org/packages/81/ea/84d481a5237ed223bd3d32d6e82d7a6a96e34756492666c260cef16011d1/scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318", size = 36525921 }, - { url = "https://files.pythonhosted.org/packages/4e/9f/d9edbdeff9f3a664807ae3aea383e10afaa247e8e6255e6d2aa4515e8863/scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc", size = 28564152 }, - { url = "https://files.pythonhosted.org/packages/3b/95/8125bcb1fe04bc267d103e76516243e8d5e11229e6b306bda1024a5423d1/scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8", size = 20836028 }, - { url = "https://files.pythonhosted.org/packages/77/9c/bf92e215701fc70bbcd3d14d86337cf56a9b912a804b9c776a269524a9e9/scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e", size = 23489666 }, - { url = "https://files.pythonhosted.org/packages/5e/00/5e941d397d9adac41b02839011594620d54d99488d1be5be755c00cde9ee/scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0", size = 33358318 }, - { url = "https://files.pythonhosted.org/packages/0e/87/8db3aa10dde6e3e8e7eb0133f24baa011377d543f5b19c71469cf2648026/scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b", size = 35185724 }, - { url = "https://files.pythonhosted.org/packages/89/b4/6ab9ae443216807622bcff02690262d8184078ea467efee2f8c93288a3b1/scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731", size = 35554335 }, - { url = "https://files.pythonhosted.org/packages/9c/9a/d0e9dc03c5269a1afb60661118296a32ed5d2c24298af61b676c11e05e56/scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3", size = 37960310 }, - { url = "https://files.pythonhosted.org/packages/5e/00/c8f3130a50521a7977874817ca89e0599b1b4ee8e938bad8ae798a0e1f0d/scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19", size = 39319239 }, - { url = "https://files.pythonhosted.org/packages/f2/f2/1ca3eda54c3a7e4c92f6acef7db7b3a057deb135540d23aa6343ef8ad333/scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65", size = 36939460 }, - { url = "https://files.pythonhosted.org/packages/80/30/98c2840b293a132400c0940bb9e140171dcb8189588619048f42b2ce7b4f/scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2", size = 29093322 }, - { url = "https://files.pythonhosted.org/packages/c1/e6/1e6e006e850622cf2a039b62d1a6ddc4497d4851e58b68008526f04a9a00/scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d", size = 21365329 }, - { url = "https://files.pythonhosted.org/packages/8e/02/72a5aa5b820589dda9a25e329ca752842bfbbaf635e36bc7065a9b42216e/scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695", size = 23897544 }, - { url = "https://files.pythonhosted.org/packages/2b/dc/7122d806a6f9eb8a33532982234bed91f90272e990f414f2830cfe656e0b/scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86", size = 33442112 }, - { url = "https://files.pythonhosted.org/packages/24/39/e383af23564daa1021a5b3afbe0d8d6a68ec639b943661841f44ac92de85/scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff", size = 35286594 }, - { url = "https://files.pythonhosted.org/packages/95/47/1a0b0aff40c3056d955f38b0df5d178350c3d74734ec54f9c68d23910be5/scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4", size = 35665080 }, - { url = "https://files.pythonhosted.org/packages/64/df/ce88803e9ed6e27fe9b9abefa157cf2c80e4fa527cf17ee14be41f790ad4/scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3", size = 38050306 }, - { url = "https://files.pythonhosted.org/packages/6e/6c/a76329897a7cae4937d403e623aa6aaea616a0bb5b36588f0b9d1c9a3739/scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998", size = 39427705 }, + { url = "https://files.pythonhosted.org/packages/da/91/812adc6f74409b461e3a5fa97f4f74c769016919203138a3bf6fc24ba4c5/scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030", size = 36552519, upload-time = "2025-07-27T16:26:29.658Z" }, + { url = "https://files.pythonhosted.org/packages/47/18/8e355edcf3b71418d9e9f9acd2708cc3a6c27e8f98fde0ac34b8a0b45407/scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7", size = 28638010, upload-time = "2025-07-27T16:26:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/d9/eb/e931853058607bdfbc11b86df19ae7a08686121c203483f62f1ecae5989c/scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77", size = 20909790, upload-time = "2025-07-27T16:26:43.93Z" }, + { url = "https://files.pythonhosted.org/packages/45/0c/be83a271d6e96750cd0be2e000f35ff18880a46f05ce8b5d3465dc0f7a2a/scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe", size = 23513352, upload-time = "2025-07-27T16:26:50.017Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bf/fe6eb47e74f762f933cca962db7f2c7183acfdc4483bd1c3813cfe83e538/scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b", size = 33534643, upload-time = "2025-07-27T16:26:57.503Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ba/63f402e74875486b87ec6506a4f93f6d8a0d94d10467280f3d9d7837ce3a/scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7", size = 35376776, upload-time = "2025-07-27T16:27:06.639Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b4/04eb9d39ec26a1b939689102da23d505ea16cdae3dbb18ffc53d1f831044/scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958", size = 35698906, upload-time = "2025-07-27T16:27:14.943Z" }, + { url = "https://files.pythonhosted.org/packages/04/d6/bb5468da53321baeb001f6e4e0d9049eadd175a4a497709939128556e3ec/scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39", size = 38129275, upload-time = "2025-07-27T16:27:23.873Z" }, + { url = "https://files.pythonhosted.org/packages/c4/94/994369978509f227cba7dfb9e623254d0d5559506fe994aef4bea3ed469c/scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596", size = 38644572, upload-time = "2025-07-27T16:27:32.637Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d9/ec4864f5896232133f51382b54a08de91a9d1af7a76dfa372894026dfee2/scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c", size = 36575194, upload-time = "2025-07-27T16:27:41.321Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6d/40e81ecfb688e9d25d34a847dca361982a6addf8e31f0957b1a54fbfa994/scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04", size = 28594590, upload-time = "2025-07-27T16:27:49.204Z" }, + { url = "https://files.pythonhosted.org/packages/0e/37/9f65178edfcc629377ce9a64fc09baebea18c80a9e57ae09a52edf84880b/scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919", size = 20866458, upload-time = "2025-07-27T16:27:54.98Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7b/749a66766871ea4cb1d1ea10f27004db63023074c22abed51f22f09770e0/scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921", size = 23539318, upload-time = "2025-07-27T16:28:01.604Z" }, + { url = "https://files.pythonhosted.org/packages/c4/db/8d4afec60eb833a666434d4541a3151eedbf2494ea6d4d468cbe877f00cd/scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725", size = 33292899, upload-time = "2025-07-27T16:28:09.147Z" }, + { url = "https://files.pythonhosted.org/packages/51/1e/79023ca3bbb13a015d7d2757ecca3b81293c663694c35d6541b4dca53e98/scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618", size = 35162637, upload-time = "2025-07-27T16:28:17.535Z" }, + { url = "https://files.pythonhosted.org/packages/b6/49/0648665f9c29fdaca4c679182eb972935b3b4f5ace41d323c32352f29816/scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d", size = 35490507, upload-time = "2025-07-27T16:28:25.705Z" }, + { url = "https://files.pythonhosted.org/packages/62/8f/66cbb9d6bbb18d8c658f774904f42a92078707a7c71e5347e8bf2f52bb89/scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119", size = 37923998, upload-time = "2025-07-27T16:28:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/14/c3/61f273ae550fbf1667675701112e380881905e28448c080b23b5a181df7c/scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a", size = 38508060, upload-time = "2025-07-27T16:28:43.242Z" }, + { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, + { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, + { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, + { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, + { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, + { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, + { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, + { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, + { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, + { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, + { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/ea/84d481a5237ed223bd3d32d6e82d7a6a96e34756492666c260cef16011d1/scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318", size = 36525921, upload-time = "2025-07-27T16:30:30.081Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9f/d9edbdeff9f3a664807ae3aea383e10afaa247e8e6255e6d2aa4515e8863/scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc", size = 28564152, upload-time = "2025-07-27T16:30:35.336Z" }, + { url = "https://files.pythonhosted.org/packages/3b/95/8125bcb1fe04bc267d103e76516243e8d5e11229e6b306bda1024a5423d1/scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8", size = 20836028, upload-time = "2025-07-27T16:30:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/77/9c/bf92e215701fc70bbcd3d14d86337cf56a9b912a804b9c776a269524a9e9/scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e", size = 23489666, upload-time = "2025-07-27T16:30:43.663Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/5e941d397d9adac41b02839011594620d54d99488d1be5be755c00cde9ee/scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0", size = 33358318, upload-time = "2025-07-27T16:30:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/8db3aa10dde6e3e8e7eb0133f24baa011377d543f5b19c71469cf2648026/scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b", size = 35185724, upload-time = "2025-07-27T16:30:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/89/b4/6ab9ae443216807622bcff02690262d8184078ea467efee2f8c93288a3b1/scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731", size = 35554335, upload-time = "2025-07-27T16:30:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/9c/9a/d0e9dc03c5269a1afb60661118296a32ed5d2c24298af61b676c11e05e56/scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3", size = 37960310, upload-time = "2025-07-27T16:31:06.151Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/c8f3130a50521a7977874817ca89e0599b1b4ee8e938bad8ae798a0e1f0d/scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19", size = 39319239, upload-time = "2025-07-27T16:31:59.942Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f2/1ca3eda54c3a7e4c92f6acef7db7b3a057deb135540d23aa6343ef8ad333/scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65", size = 36939460, upload-time = "2025-07-27T16:31:11.865Z" }, + { url = "https://files.pythonhosted.org/packages/80/30/98c2840b293a132400c0940bb9e140171dcb8189588619048f42b2ce7b4f/scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2", size = 29093322, upload-time = "2025-07-27T16:31:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e6/1e6e006e850622cf2a039b62d1a6ddc4497d4851e58b68008526f04a9a00/scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d", size = 21365329, upload-time = "2025-07-27T16:31:21.188Z" }, + { url = "https://files.pythonhosted.org/packages/8e/02/72a5aa5b820589dda9a25e329ca752842bfbbaf635e36bc7065a9b42216e/scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695", size = 23897544, upload-time = "2025-07-27T16:31:25.408Z" }, + { url = "https://files.pythonhosted.org/packages/2b/dc/7122d806a6f9eb8a33532982234bed91f90272e990f414f2830cfe656e0b/scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86", size = 33442112, upload-time = "2025-07-27T16:31:30.62Z" }, + { url = "https://files.pythonhosted.org/packages/24/39/e383af23564daa1021a5b3afbe0d8d6a68ec639b943661841f44ac92de85/scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff", size = 35286594, upload-time = "2025-07-27T16:31:36.112Z" }, + { url = "https://files.pythonhosted.org/packages/95/47/1a0b0aff40c3056d955f38b0df5d178350c3d74734ec54f9c68d23910be5/scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4", size = 35665080, upload-time = "2025-07-27T16:31:42.025Z" }, + { url = "https://files.pythonhosted.org/packages/64/df/ce88803e9ed6e27fe9b9abefa157cf2c80e4fa527cf17ee14be41f790ad4/scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3", size = 38050306, upload-time = "2025-07-27T16:31:48.109Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6c/a76329897a7cae4937d403e623aa6aaea616a0bb5b36588f0b9d1c9a3739/scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998", size = 39427705, upload-time = "2025-07-27T16:31:53.96Z" }, ] [[package]] name = "setuptools" version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958 } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486 }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[package]] @@ -2922,48 +3026,48 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422, upload-time = "2025-05-19T11:04:41.265Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/fa/f18025c95b86116dd8f1ec58cab078bd59ab51456b448136ca27463be533/shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6", size = 1825117 }, - { url = "https://files.pythonhosted.org/packages/c7/65/46b519555ee9fb851234288be7c78be11e6260995281071d13abf2c313d0/shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099", size = 1628541 }, - { url = "https://files.pythonhosted.org/packages/29/51/0b158a261df94e33505eadfe737db9531f346dfa60850945ad25fd4162f1/shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d", size = 2948453 }, - { url = "https://files.pythonhosted.org/packages/a9/4f/6c9bb4bd7b1a14d7051641b9b479ad2a643d5cbc382bcf5bd52fd0896974/shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a", size = 3057029 }, - { url = "https://files.pythonhosted.org/packages/89/0b/ad1b0af491d753a83ea93138eee12a4597f763ae12727968d05934fe7c78/shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd", size = 3894342 }, - { url = "https://files.pythonhosted.org/packages/7d/96/73232c5de0b9fdf0ec7ddfc95c43aaf928740e87d9f168bff0e928d78c6d/shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b", size = 4056766 }, - { url = "https://files.pythonhosted.org/packages/43/cc/eec3c01f754f5b3e0c47574b198f9deb70465579ad0dad0e1cef2ce9e103/shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f", size = 1523744 }, - { url = "https://files.pythonhosted.org/packages/50/fc/a7187e6dadb10b91e66a9e715d28105cde6489e1017cce476876185a43da/shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6", size = 1703061 }, - { url = "https://files.pythonhosted.org/packages/19/97/2df985b1e03f90c503796ad5ecd3d9ed305123b64d4ccb54616b30295b29/shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7", size = 1819368 }, - { url = "https://files.pythonhosted.org/packages/56/17/504518860370f0a28908b18864f43d72f03581e2b6680540ca668f07aa42/shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea", size = 1625362 }, - { url = "https://files.pythonhosted.org/packages/36/a1/9677337d729b79fce1ef3296aac6b8ef4743419086f669e8a8070eff8f40/shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7", size = 2999005 }, - { url = "https://files.pythonhosted.org/packages/a2/17/e09357274699c6e012bbb5a8ea14765a4d5860bb658df1931c9f90d53bd3/shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753", size = 3108489 }, - { url = "https://files.pythonhosted.org/packages/17/5d/93a6c37c4b4e9955ad40834f42b17260ca74ecf36df2e81bb14d12221b90/shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647", size = 3945727 }, - { url = "https://files.pythonhosted.org/packages/a3/1a/ad696648f16fd82dd6bfcca0b3b8fbafa7aacc13431c7fc4c9b49e481681/shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0", size = 4109311 }, - { url = "https://files.pythonhosted.org/packages/d4/38/150dd245beab179ec0d4472bf6799bf18f21b1efbef59ac87de3377dbf1c/shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab", size = 1522982 }, - { url = "https://files.pythonhosted.org/packages/93/5b/842022c00fbb051083c1c85430f3bb55565b7fd2d775f4f398c0ba8052ce/shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93", size = 1703872 }, - { url = "https://files.pythonhosted.org/packages/fb/64/9544dc07dfe80a2d489060791300827c941c451e2910f7364b19607ea352/shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43", size = 1833021 }, - { url = "https://files.pythonhosted.org/packages/07/aa/fb5f545e72e89b6a0f04a0effda144f5be956c9c312c7d4e00dfddbddbcf/shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad", size = 1643018 }, - { url = "https://files.pythonhosted.org/packages/03/46/61e03edba81de729f09d880ce7ae5c1af873a0814206bbfb4402ab5c3388/shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9", size = 2986417 }, - { url = "https://files.pythonhosted.org/packages/1f/1e/83ec268ab8254a446b4178b45616ab5822d7b9d2b7eb6e27cf0b82f45601/shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef", size = 3098224 }, - { url = "https://files.pythonhosted.org/packages/f1/44/0c21e7717c243e067c9ef8fa9126de24239f8345a5bba9280f7bb9935959/shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1", size = 3925982 }, - { url = "https://files.pythonhosted.org/packages/15/50/d3b4e15fefc103a0eb13d83bad5f65cd6e07a5d8b2ae920e767932a247d1/shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d", size = 4089122 }, - { url = "https://files.pythonhosted.org/packages/bd/05/9a68f27fc6110baeedeeebc14fd86e73fa38738c5b741302408fb6355577/shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8", size = 1522437 }, - { url = "https://files.pythonhosted.org/packages/bc/e9/a4560e12b9338842a1f82c9016d2543eaa084fce30a1ca11991143086b57/shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a", size = 1703479 }, - { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107 }, - { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355 }, - { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871 }, - { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830 }, - { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961 }, - { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623 }, - { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916 }, - { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746 }, - { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482 }, - { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256 }, - { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614 }, - { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542 }, - { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961 }, - { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514 }, - { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607 }, - { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061 }, + { url = "https://files.pythonhosted.org/packages/82/fa/f18025c95b86116dd8f1ec58cab078bd59ab51456b448136ca27463be533/shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6", size = 1825117, upload-time = "2025-05-19T11:03:43.547Z" }, + { url = "https://files.pythonhosted.org/packages/c7/65/46b519555ee9fb851234288be7c78be11e6260995281071d13abf2c313d0/shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099", size = 1628541, upload-time = "2025-05-19T11:03:45.162Z" }, + { url = "https://files.pythonhosted.org/packages/29/51/0b158a261df94e33505eadfe737db9531f346dfa60850945ad25fd4162f1/shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d", size = 2948453, upload-time = "2025-05-19T11:03:46.681Z" }, + { url = "https://files.pythonhosted.org/packages/a9/4f/6c9bb4bd7b1a14d7051641b9b479ad2a643d5cbc382bcf5bd52fd0896974/shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a", size = 3057029, upload-time = "2025-05-19T11:03:48.346Z" }, + { url = "https://files.pythonhosted.org/packages/89/0b/ad1b0af491d753a83ea93138eee12a4597f763ae12727968d05934fe7c78/shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd", size = 3894342, upload-time = "2025-05-19T11:03:49.602Z" }, + { url = "https://files.pythonhosted.org/packages/7d/96/73232c5de0b9fdf0ec7ddfc95c43aaf928740e87d9f168bff0e928d78c6d/shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b", size = 4056766, upload-time = "2025-05-19T11:03:51.252Z" }, + { url = "https://files.pythonhosted.org/packages/43/cc/eec3c01f754f5b3e0c47574b198f9deb70465579ad0dad0e1cef2ce9e103/shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f", size = 1523744, upload-time = "2025-05-19T11:03:52.624Z" }, + { url = "https://files.pythonhosted.org/packages/50/fc/a7187e6dadb10b91e66a9e715d28105cde6489e1017cce476876185a43da/shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6", size = 1703061, upload-time = "2025-05-19T11:03:54.695Z" }, + { url = "https://files.pythonhosted.org/packages/19/97/2df985b1e03f90c503796ad5ecd3d9ed305123b64d4ccb54616b30295b29/shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7", size = 1819368, upload-time = "2025-05-19T11:03:55.937Z" }, + { url = "https://files.pythonhosted.org/packages/56/17/504518860370f0a28908b18864f43d72f03581e2b6680540ca668f07aa42/shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea", size = 1625362, upload-time = "2025-05-19T11:03:57.06Z" }, + { url = "https://files.pythonhosted.org/packages/36/a1/9677337d729b79fce1ef3296aac6b8ef4743419086f669e8a8070eff8f40/shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7", size = 2999005, upload-time = "2025-05-19T11:03:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/a2/17/e09357274699c6e012bbb5a8ea14765a4d5860bb658df1931c9f90d53bd3/shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753", size = 3108489, upload-time = "2025-05-19T11:04:00.059Z" }, + { url = "https://files.pythonhosted.org/packages/17/5d/93a6c37c4b4e9955ad40834f42b17260ca74ecf36df2e81bb14d12221b90/shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647", size = 3945727, upload-time = "2025-05-19T11:04:01.786Z" }, + { url = "https://files.pythonhosted.org/packages/a3/1a/ad696648f16fd82dd6bfcca0b3b8fbafa7aacc13431c7fc4c9b49e481681/shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0", size = 4109311, upload-time = "2025-05-19T11:04:03.134Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/150dd245beab179ec0d4472bf6799bf18f21b1efbef59ac87de3377dbf1c/shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab", size = 1522982, upload-time = "2025-05-19T11:04:05.217Z" }, + { url = "https://files.pythonhosted.org/packages/93/5b/842022c00fbb051083c1c85430f3bb55565b7fd2d775f4f398c0ba8052ce/shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93", size = 1703872, upload-time = "2025-05-19T11:04:06.791Z" }, + { url = "https://files.pythonhosted.org/packages/fb/64/9544dc07dfe80a2d489060791300827c941c451e2910f7364b19607ea352/shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43", size = 1833021, upload-time = "2025-05-19T11:04:08.022Z" }, + { url = "https://files.pythonhosted.org/packages/07/aa/fb5f545e72e89b6a0f04a0effda144f5be956c9c312c7d4e00dfddbddbcf/shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad", size = 1643018, upload-time = "2025-05-19T11:04:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/03/46/61e03edba81de729f09d880ce7ae5c1af873a0814206bbfb4402ab5c3388/shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9", size = 2986417, upload-time = "2025-05-19T11:04:10.56Z" }, + { url = "https://files.pythonhosted.org/packages/1f/1e/83ec268ab8254a446b4178b45616ab5822d7b9d2b7eb6e27cf0b82f45601/shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef", size = 3098224, upload-time = "2025-05-19T11:04:11.903Z" }, + { url = "https://files.pythonhosted.org/packages/f1/44/0c21e7717c243e067c9ef8fa9126de24239f8345a5bba9280f7bb9935959/shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1", size = 3925982, upload-time = "2025-05-19T11:04:13.224Z" }, + { url = "https://files.pythonhosted.org/packages/15/50/d3b4e15fefc103a0eb13d83bad5f65cd6e07a5d8b2ae920e767932a247d1/shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d", size = 4089122, upload-time = "2025-05-19T11:04:14.477Z" }, + { url = "https://files.pythonhosted.org/packages/bd/05/9a68f27fc6110baeedeeebc14fd86e73fa38738c5b741302408fb6355577/shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8", size = 1522437, upload-time = "2025-05-19T11:04:16.203Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e9/a4560e12b9338842a1f82c9016d2543eaa084fce30a1ca11991143086b57/shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a", size = 1703479, upload-time = "2025-05-19T11:04:18.497Z" }, + { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107, upload-time = "2025-05-19T11:04:19.736Z" }, + { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355, upload-time = "2025-05-19T11:04:21.035Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871, upload-time = "2025-05-19T11:04:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830, upload-time = "2025-05-19T11:04:23.997Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961, upload-time = "2025-05-19T11:04:25.702Z" }, + { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623, upload-time = "2025-05-19T11:04:27.171Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916, upload-time = "2025-05-19T11:04:28.405Z" }, + { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746, upload-time = "2025-05-19T11:04:29.643Z" }, + { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482, upload-time = "2025-05-19T11:04:30.852Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256, upload-time = "2025-05-19T11:04:32.068Z" }, + { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614, upload-time = "2025-05-19T11:04:33.7Z" }, + { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542, upload-time = "2025-05-19T11:04:34.952Z" }, + { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961, upload-time = "2025-05-19T11:04:36.32Z" }, + { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514, upload-time = "2025-05-19T11:04:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607, upload-time = "2025-05-19T11:04:38.925Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061, upload-time = "2025-05-19T11:04:40.082Z" }, ] [[package]] @@ -2973,27 +3077,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wsproto" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b0/d4/bfa032f961103eba93de583b161f0e6a5b63cebb8f2c7d0c6e6efe1e3d2e/simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4", size = 17300 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/d4/bfa032f961103eba93de583b161f0e6a5b63cebb8f2c7d0c6e6efe1e3d2e/simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4", size = 17300, upload-time = "2024-10-10T22:39:31.412Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c", size = 13842 }, + { url = "https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c", size = 13842, upload-time = "2024-10-10T22:39:29.645Z" }, ] [[package]] name = "six" version = "1.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041, upload-time = "2021-05-05T14:18:18.379Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053, upload-time = "2021-05-05T14:18:17.237Z" }, ] [[package]] name = "sniffio" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/50/d49c388cae4ec10e8109b1b833fd265511840706808576df3ada99ecb0ac/sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", size = 17103 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/50/d49c388cae4ec10e8109b1b833fd265511840706808576df3ada99ecb0ac/sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", size = 17103, upload-time = "2022-09-01T12:31:36.968Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/a0/5dba8ed157b0136607c7f2151db695885606968d1fae123dc3391e0cfdbf/sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384", size = 10165 }, + { url = "https://files.pythonhosted.org/packages/c3/a0/5dba8ed157b0136607c7f2151db695885606968d1fae123dc3391e0cfdbf/sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384", size = 10165, upload-time = "2022-09-01T12:31:34.186Z" }, ] [[package]] @@ -3003,9 +3107,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/da/1fb4bdb72ae12b834becd7e1e7e47001d32f91ec0ce8d7bc1b618d9f0bd9/starlette-0.41.2.tar.gz", hash = "sha256:9834fd799d1a87fd346deb76158668cfa0b0d56f85caefe8268e2d97c3468b62", size = 2573867 } +sdist = { url = "https://files.pythonhosted.org/packages/3e/da/1fb4bdb72ae12b834becd7e1e7e47001d32f91ec0ce8d7bc1b618d9f0bd9/starlette-0.41.2.tar.gz", hash = "sha256:9834fd799d1a87fd346deb76158668cfa0b0d56f85caefe8268e2d97c3468b62", size = 2573867, upload-time = "2024-10-27T08:20:02.818Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/43/f185bfd0ca1d213beb4293bed51d92254df23d8ceaf6c0e17146d508a776/starlette-0.41.2-py3-none-any.whl", hash = "sha256:fbc189474b4731cf30fcef52f18a8d070e3f3b46c6a04c97579e85e6ffca942d", size = 73259 }, + { url = "https://files.pythonhosted.org/packages/54/43/f185bfd0ca1d213beb4293bed51d92254df23d8ceaf6c0e17146d508a776/starlette-0.41.2-py3-none-any.whl", hash = "sha256:fbc189474b4731cf30fcef52f18a8d070e3f3b46c6a04c97579e85e6ffca942d", size = 73259, upload-time = "2024-10-27T08:20:00.052Z" }, ] [[package]] @@ -3015,18 +3119,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mpmath" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e5/57/3485a1a3dff51bfd691962768b14310dae452431754bfc091250be50dd29/sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8", size = 6722203 } +sdist = { url = "https://files.pythonhosted.org/packages/e5/57/3485a1a3dff51bfd691962768b14310dae452431754bfc091250be50dd29/sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8", size = 6722203, upload-time = "2023-05-10T18:23:00.378Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/05/e6600db80270777c4a64238a98d442f0fd07cc8915be2a1c16da7f2b9e74/sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5", size = 5742435 }, + { url = "https://files.pythonhosted.org/packages/d2/05/e6600db80270777c4a64238a98d442f0fd07cc8915be2a1c16da7f2b9e74/sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5", size = 5742435, upload-time = "2023-05-10T18:22:14.76Z" }, ] [[package]] name = "threadpoolctl" version = "3.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/8a/c05f7831beb32aff70f808766224f11c650f7edfd49b27a8fc6666107006/threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355", size = 36266 } +sdist = { url = "https://files.pythonhosted.org/packages/47/8a/c05f7831beb32aff70f808766224f11c650f7edfd49b27a8fc6666107006/threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355", size = 36266, upload-time = "2023-07-13T14:53:53.299Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/12/fd4dea011af9d69e1cad05c75f3f7202cdcbeac9b712eea58ca779a72865/threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032", size = 15539 }, + { url = "https://files.pythonhosted.org/packages/81/12/fd4dea011af9d69e1cad05c75f3f7202cdcbeac9b712eea58ca779a72865/threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032", size = 15539, upload-time = "2023-07-13T14:53:39.336Z" }, ] [[package]] @@ -3036,43 +3140,43 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/a4/6c0eadea1ccfcda27e6cce400c366098b5b082138a073f4252fe399f4148/tifffile-2023.12.9.tar.gz", hash = "sha256:9dd1da91180a6453018a241ff219e1905f169384355cd89c9ef4034c1b46cdb8", size = 353467 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/a4/6c0eadea1ccfcda27e6cce400c366098b5b082138a073f4252fe399f4148/tifffile-2023.12.9.tar.gz", hash = "sha256:9dd1da91180a6453018a241ff219e1905f169384355cd89c9ef4034c1b46cdb8", size = 353467, upload-time = "2023-12-09T20:46:29.203Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/a4/569fc717831969cf48bced350bdaf070cdeab06918d179429899e144358d/tifffile-2023.12.9-py3-none-any.whl", hash = "sha256:9b066e4b1a900891ea42ffd33dab8ba34c537935618b9893ddef42d7d422692f", size = 223627 }, + { url = "https://files.pythonhosted.org/packages/54/a4/569fc717831969cf48bced350bdaf070cdeab06918d179429899e144358d/tifffile-2023.12.9-py3-none-any.whl", hash = "sha256:9b066e4b1a900891ea42ffd33dab8ba34c537935618b9893ddef42d7d422692f", size = 223627, upload-time = "2023-12-09T20:46:26.569Z" }, ] [[package]] name = "tokenizers" -version = "0.21.4" +version = "0.22.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/2f/402986d0823f8d7ca139d969af2917fefaa9b947d1fb32f6168c509f2492/tokenizers-0.21.4.tar.gz", hash = "sha256:fa23f85fbc9a02ec5c6978da172cdcbac23498c3ca9f3645c5c68740ac007880", size = 351253 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/46/fb6854cec3278fbfa4a75b50232c77622bc517ac886156e6afbfa4d8fc6e/tokenizers-0.22.1.tar.gz", hash = "sha256:61de6522785310a309b3407bac22d99c4db5dba349935e99e4d15ea2226af2d9", size = 363123, upload-time = "2025-09-19T09:49:23.424Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/c6/fdb6f72bf6454f52eb4a2510be7fb0f614e541a2554d6210e370d85efff4/tokenizers-0.21.4-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ccc10a7c3bcefe0f242867dc914fc1226ee44321eb618cfe3019b5df3400133", size = 2863987 }, - { url = "https://files.pythonhosted.org/packages/8d/a6/28975479e35ddc751dc1ddc97b9b69bf7fcf074db31548aab37f8116674c/tokenizers-0.21.4-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:5e2f601a8e0cd5be5cc7506b20a79112370b9b3e9cb5f13f68ab11acd6ca7d60", size = 2732457 }, - { url = "https://files.pythonhosted.org/packages/aa/8f/24f39d7b5c726b7b0be95dca04f344df278a3fe3a4deb15a975d194cbb32/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b376f5a1aee67b4d29032ee85511bbd1b99007ec735f7f35c8a2eb104eade5", size = 3012624 }, - { url = "https://files.pythonhosted.org/packages/58/47/26358925717687a58cb74d7a508de96649544fad5778f0cd9827398dc499/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2107ad649e2cda4488d41dfd031469e9da3fcbfd6183e74e4958fa729ffbf9c6", size = 2939681 }, - { url = "https://files.pythonhosted.org/packages/99/6f/cc300fea5db2ab5ddc2c8aea5757a27b89c84469899710c3aeddc1d39801/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c73012da95afafdf235ba80047699df4384fdc481527448a078ffd00e45a7d9", size = 3247445 }, - { url = "https://files.pythonhosted.org/packages/be/bf/98cb4b9c3c4afd8be89cfa6423704337dc20b73eb4180397a6e0d456c334/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f23186c40395fc390d27f519679a58023f368a0aad234af145e0f39ad1212732", size = 3428014 }, - { url = "https://files.pythonhosted.org/packages/75/c7/96c1cc780e6ca7f01a57c13235dd05b7bc1c0f3588512ebe9d1331b5f5ae/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc88bb34e23a54cc42713d6d98af5f1bf79c07653d24fe984d2d695ba2c922a2", size = 3193197 }, - { url = "https://files.pythonhosted.org/packages/f2/90/273b6c7ec78af547694eddeea9e05de771278bd20476525ab930cecaf7d8/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51b7eabb104f46c1c50b486520555715457ae833d5aee9ff6ae853d1130506ff", size = 3115426 }, - { url = "https://files.pythonhosted.org/packages/91/43/c640d5a07e95f1cf9d2c92501f20a25f179ac53a4f71e1489a3dcfcc67ee/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:714b05b2e1af1288bd1bc56ce496c4cebb64a20d158ee802887757791191e6e2", size = 9089127 }, - { url = "https://files.pythonhosted.org/packages/44/a1/dd23edd6271d4dca788e5200a807b49ec3e6987815cd9d0a07ad9c96c7c2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1340ff877ceedfa937544b7d79f5b7becf33a4cfb58f89b3b49927004ef66f78", size = 9055243 }, - { url = "https://files.pythonhosted.org/packages/21/2b/b410d6e9021c4b7ddb57248304dc817c4d4970b73b6ee343674914701197/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3c1f4317576e465ac9ef0d165b247825a2a4078bcd01cba6b54b867bdf9fdd8b", size = 9298237 }, - { url = "https://files.pythonhosted.org/packages/b7/0a/42348c995c67e2e6e5c89ffb9cfd68507cbaeb84ff39c49ee6e0a6dd0fd2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c212aa4e45ec0bb5274b16b6f31dd3f1c41944025c2358faaa5782c754e84c24", size = 9461980 }, - { url = "https://files.pythonhosted.org/packages/3d/d3/dacccd834404cd71b5c334882f3ba40331ad2120e69ded32cf5fda9a7436/tokenizers-0.21.4-cp39-abi3-win32.whl", hash = "sha256:6c42a930bc5f4c47f4ea775c91de47d27910881902b0f20e4990ebe045a415d0", size = 2329871 }, - { url = "https://files.pythonhosted.org/packages/41/f2/fd673d979185f5dcbac4be7d09461cbb99751554ffb6718d0013af8604cb/tokenizers-0.21.4-cp39-abi3-win_amd64.whl", hash = "sha256:475d807a5c3eb72c59ad9b5fcdb254f6e17f53dfcbb9903233b0dfa9c943b597", size = 2507568 }, + { url = "https://files.pythonhosted.org/packages/bf/33/f4b2d94ada7ab297328fc671fed209368ddb82f965ec2224eb1892674c3a/tokenizers-0.22.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59fdb013df17455e5f950b4b834a7b3ee2e0271e6378ccb33aa74d178b513c73", size = 3069318, upload-time = "2025-09-19T09:49:11.848Z" }, + { url = "https://files.pythonhosted.org/packages/1c/58/2aa8c874d02b974990e89ff95826a4852a8b2a273c7d1b4411cdd45a4565/tokenizers-0.22.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d4e484f7b0827021ac5f9f71d4794aaef62b979ab7608593da22b1d2e3c4edc", size = 2926478, upload-time = "2025-09-19T09:49:09.759Z" }, + { url = "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a", size = 3256994, upload-time = "2025-09-19T09:48:56.701Z" }, + { url = "https://files.pythonhosted.org/packages/71/0b/fbfecf42f67d9b7b80fde4aabb2b3110a97fac6585c9470b5bff103a80cb/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38201f15cdb1f8a6843e6563e6e79f4abd053394992b9bbdf5213ea3469b4ae7", size = 3153141, upload-time = "2025-09-19T09:48:59.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/a9/b38f4e74e0817af8f8ef925507c63c6ae8171e3c4cb2d5d4624bf58fca69/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1cbe5454c9a15df1b3443c726063d930c16f047a3cc724b9e6e1a91140e5a21", size = 3508049, upload-time = "2025-09-19T09:49:05.868Z" }, + { url = "https://files.pythonhosted.org/packages/d2/48/dd2b3dac46bb9134a88e35d72e1aa4869579eacc1a27238f1577270773ff/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7d094ae6312d69cc2a872b54b91b309f4f6fbce871ef28eb27b52a98e4d0214", size = 3710730, upload-time = "2025-09-19T09:49:01.832Z" }, + { url = "https://files.pythonhosted.org/packages/93/0e/ccabc8d16ae4ba84a55d41345207c1e2ea88784651a5a487547d80851398/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afd7594a56656ace95cdd6df4cca2e4059d294c5cfb1679c57824b605556cb2f", size = 3412560, upload-time = "2025-09-19T09:49:03.867Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c6/dc3a0db5a6766416c32c034286d7c2d406da1f498e4de04ab1b8959edd00/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ef6063d7a84994129732b47e7915e8710f27f99f3a3260b8a38fc7ccd083f4", size = 3250221, upload-time = "2025-09-19T09:49:07.664Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a6/2c8486eef79671601ff57b093889a345dd3d576713ef047776015dc66de7/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba0a64f450b9ef412c98f6bcd2a50c6df6e2443b560024a09fa6a03189726879", size = 9345569, upload-time = "2025-09-19T09:49:14.214Z" }, + { url = "https://files.pythonhosted.org/packages/6b/16/32ce667f14c35537f5f605fe9bea3e415ea1b0a646389d2295ec348d5657/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:331d6d149fa9c7d632cde4490fb8bbb12337fa3a0232e77892be656464f4b446", size = 9271599, upload-time = "2025-09-19T09:49:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/51/7c/a5f7898a3f6baa3fc2685c705e04c98c1094c523051c805cdd9306b8f87e/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:607989f2ea68a46cb1dfbaf3e3aabdf3f21d8748312dbeb6263d1b3b66c5010a", size = 9533862, upload-time = "2025-09-19T09:49:19.146Z" }, + { url = "https://files.pythonhosted.org/packages/36/65/7e75caea90bc73c1dd8d40438adf1a7bc26af3b8d0a6705ea190462506e1/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a0f307d490295717726598ef6fa4f24af9d484809223bbc253b201c740a06390", size = 9681250, upload-time = "2025-09-19T09:49:21.501Z" }, + { url = "https://files.pythonhosted.org/packages/30/2c/959dddef581b46e6209da82df3b78471e96260e2bc463f89d23b1bf0e52a/tokenizers-0.22.1-cp39-abi3-win32.whl", hash = "sha256:b5120eed1442765cd90b903bb6cfef781fd8fe64e34ccaecbae4c619b7b12a82", size = 2472003, upload-time = "2025-09-19T09:49:27.089Z" }, + { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, ] [[package]] name = "tomli" version = "2.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164, upload-time = "2022-02-08T10:54:04.006Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, + { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757, upload-time = "2022-02-08T10:54:02.017Z" }, ] [[package]] @@ -3082,101 +3186,101 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/00/6a9b3aedb0b60a80995ade30f718f1a9902612f22a1aaf531c85a02987f7/tqdm-4.66.3.tar.gz", hash = "sha256:23097a41eba115ba99ecae40d06444c15d1c0c698d527a01c6c8bd1c5d0647e5", size = 169551 } +sdist = { url = "https://files.pythonhosted.org/packages/03/00/6a9b3aedb0b60a80995ade30f718f1a9902612f22a1aaf531c85a02987f7/tqdm-4.66.3.tar.gz", hash = "sha256:23097a41eba115ba99ecae40d06444c15d1c0c698d527a01c6c8bd1c5d0647e5", size = 169551, upload-time = "2024-05-02T21:44:05.084Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/ad/7d47bbf2cae78ff79f29db0bed5016ec9c56b212a93fca624bb88b551a7c/tqdm-4.66.3-py3-none-any.whl", hash = "sha256:4f41d54107ff9a223dca80b53efe4fb654c67efaba7f47bada3ee9d50e05bd53", size = 78374 }, + { url = "https://files.pythonhosted.org/packages/d1/ad/7d47bbf2cae78ff79f29db0bed5016ec9c56b212a93fca624bb88b551a7c/tqdm-4.66.3-py3-none-any.whl", hash = "sha256:4f41d54107ff9a223dca80b53efe4fb654c67efaba7f47bada3ee9d50e05bd53", size = 78374, upload-time = "2024-05-02T21:44:01.541Z" }, ] [[package]] name = "types-pyyaml" -version = "6.0.12.20250822" +version = "6.0.12.20250915" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/49/85/90a442e538359ab5c9e30de415006fb22567aa4301c908c09f19e42975c2/types_pyyaml-6.0.12.20250822.tar.gz", hash = "sha256:259f1d93079d335730a9db7cff2bcaf65d7e04b4a56b5927d49a612199b59413", size = 17481 } +sdist = { url = "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz", hash = "sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3", size = 17522, upload-time = "2025-09-15T03:01:00.728Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/8e/8f0aca667c97c0d76024b37cffa39e76e2ce39ca54a38f285a64e6ae33ba/types_pyyaml-6.0.12.20250822-py3-none-any.whl", hash = "sha256:1fe1a5e146aa315483592d292b72a172b65b946a6d98aa6ddd8e4aa838ab7098", size = 20314 }, + { url = "https://files.pythonhosted.org/packages/bd/e0/1eed384f02555dde685fff1a1ac805c1c7dcb6dd019c916fe659b1c1f9ec/types_pyyaml-6.0.12.20250915-py3-none-any.whl", hash = "sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6", size = 20338, upload-time = "2025-09-15T03:00:59.218Z" }, ] [[package]] name = "types-requests" -version = "2.32.4.20250809" +version = "2.32.4.20250913" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/b0/9355adb86ec84d057fea765e4c49cce592aaf3d5117ce5609a95a7fc3dac/types_requests-2.32.4.20250809.tar.gz", hash = "sha256:d8060de1c8ee599311f56ff58010fb4902f462a1470802cf9f6ed27bc46c4df3", size = 23027 } +sdist = { url = "https://files.pythonhosted.org/packages/36/27/489922f4505975b11de2b5ad07b4fe1dca0bca9be81a703f26c5f3acfce5/types_requests-2.32.4.20250913.tar.gz", hash = "sha256:abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d", size = 23113, upload-time = "2025-09-13T02:40:02.309Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/6f/ec0012be842b1d888d46884ac5558fd62aeae1f0ec4f7a581433d890d4b5/types_requests-2.32.4.20250809-py3-none-any.whl", hash = "sha256:f73d1832fb519ece02c85b1f09d5f0dd3108938e7d47e7f94bbfa18a6782b163", size = 20644 }, + { url = "https://files.pythonhosted.org/packages/2a/20/9a227ea57c1285986c4cf78400d0a91615d25b24e257fd9e2969606bdfae/types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1", size = 20658, upload-time = "2025-09-13T02:40:01.115Z" }, ] [[package]] name = "types-setuptools" version = "80.9.0.20250822" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/bd/1e5f949b7cb740c9f0feaac430e301b8f1c5f11a81e26324299ea671a237/types_setuptools-80.9.0.20250822.tar.gz", hash = "sha256:070ea7716968ec67a84c7f7768d9952ff24d28b65b6594797a464f1b3066f965", size = 41296 } +sdist = { url = "https://files.pythonhosted.org/packages/19/bd/1e5f949b7cb740c9f0feaac430e301b8f1c5f11a81e26324299ea671a237/types_setuptools-80.9.0.20250822.tar.gz", hash = "sha256:070ea7716968ec67a84c7f7768d9952ff24d28b65b6594797a464f1b3066f965", size = 41296, upload-time = "2025-08-22T03:02:08.771Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/2d/475bf15c1cdc172e7a0d665b6e373ebfb1e9bf734d3f2f543d668b07a142/types_setuptools-80.9.0.20250822-py3-none-any.whl", hash = "sha256:53bf881cb9d7e46ed12c76ef76c0aaf28cfe6211d3fab12e0b83620b1a8642c3", size = 63179 }, + { url = "https://files.pythonhosted.org/packages/b6/2d/475bf15c1cdc172e7a0d665b6e373ebfb1e9bf734d3f2f543d668b07a142/types_setuptools-80.9.0.20250822-py3-none-any.whl", hash = "sha256:53bf881cb9d7e46ed12c76ef76c0aaf28cfe6211d3fab12e0b83620b1a8642c3", size = 63179, upload-time = "2025-08-22T03:02:07.643Z" }, ] [[package]] name = "types-simplejson" version = "3.20.0.20250822" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/6b/96d43a90cd202bd552cdd871858a11c138fe5ef11aeb4ed8e8dc51389257/types_simplejson-3.20.0.20250822.tar.gz", hash = "sha256:2b0bfd57a6beed3b932fd2c3c7f8e2f48a7df3978c9bba43023a32b3741a95b0", size = 10608 } +sdist = { url = "https://files.pythonhosted.org/packages/df/6b/96d43a90cd202bd552cdd871858a11c138fe5ef11aeb4ed8e8dc51389257/types_simplejson-3.20.0.20250822.tar.gz", hash = "sha256:2b0bfd57a6beed3b932fd2c3c7f8e2f48a7df3978c9bba43023a32b3741a95b0", size = 10608, upload-time = "2025-08-22T03:03:35.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/9f/8e2c9e6aee9a2ff34f2ffce6ccd9c26edeef6dfd366fde611dc2e2c00ab9/types_simplejson-3.20.0.20250822-py3-none-any.whl", hash = "sha256:b5e63ae220ac7a1b0bb9af43b9cb8652237c947981b2708b0c776d3b5d8fa169", size = 10417 }, + { url = "https://files.pythonhosted.org/packages/3c/9f/8e2c9e6aee9a2ff34f2ffce6ccd9c26edeef6dfd366fde611dc2e2c00ab9/types_simplejson-3.20.0.20250822-py3-none-any.whl", hash = "sha256:b5e63ae220ac7a1b0bb9af43b9cb8652237c947981b2708b0c776d3b5d8fa169", size = 10417, upload-time = "2025-08-22T03:03:34.485Z" }, ] [[package]] name = "types-ujson" version = "5.10.0.20250822" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/bd/d372d44534f84864a96c19a7059d9b4d29db8541828b8b9dc3040f7a46d0/types_ujson-5.10.0.20250822.tar.gz", hash = "sha256:0a795558e1f78532373cf3f03f35b1f08bc60d52d924187b97995ee3597ba006", size = 8437 } +sdist = { url = "https://files.pythonhosted.org/packages/5c/bd/d372d44534f84864a96c19a7059d9b4d29db8541828b8b9dc3040f7a46d0/types_ujson-5.10.0.20250822.tar.gz", hash = "sha256:0a795558e1f78532373cf3f03f35b1f08bc60d52d924187b97995ee3597ba006", size = 8437, upload-time = "2025-08-22T03:02:19.433Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/f2/d812543c350674d8b3f6e17c8922248ee3bb752c2a76f64beb8c538b40cf/types_ujson-5.10.0.20250822-py3-none-any.whl", hash = "sha256:3e9e73a6dc62ccc03449d9ac2c580cd1b7a8e4873220db498f7dd056754be080", size = 7657 }, + { url = "https://files.pythonhosted.org/packages/d7/f2/d812543c350674d8b3f6e17c8922248ee3bb752c2a76f64beb8c538b40cf/types_ujson-5.10.0.20250822-py3-none-any.whl", hash = "sha256:3e9e73a6dc62ccc03449d9ac2c580cd1b7a8e4873220db498f7dd056754be080", size = 7657, upload-time = "2025-08-22T03:02:18.699Z" }, ] [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] name = "urllib3" version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/36/dd/a6b232f449e1bc71802a5b7950dc3675d32c6dbc2a1bd6d71f065551adb6/urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54", size = 263900 } +sdist = { url = "https://files.pythonhosted.org/packages/36/dd/a6b232f449e1bc71802a5b7950dc3675d32c6dbc2a1bd6d71f065551adb6/urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54", size = 263900, upload-time = "2023-11-13T12:29:45.049Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/94/c31f58c7a7f470d5665935262ebd7455c7e4c7782eb525658d3dbf4b9403/urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", size = 104579 }, + { url = "https://files.pythonhosted.org/packages/96/94/c31f58c7a7f470d5665935262ebd7455c7e4c7782eb525658d3dbf4b9403/urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", size = 104579, upload-time = "2023-11-13T12:29:42.719Z" }, ] [[package]] name = "uvicorn" -version = "0.35.0" +version = "0.38.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473 } +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406 }, + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, ] [package.optional-dependencies] @@ -3194,26 +3298,26 @@ standard = [ name = "uvloop" version = "0.19.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/16/728cc5dde368e6eddb299c5aec4d10eaf25335a5af04e8c0abd68e2e9d32/uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", size = 2318492 } +sdist = { url = "https://files.pythonhosted.org/packages/9c/16/728cc5dde368e6eddb299c5aec4d10eaf25335a5af04e8c0abd68e2e9d32/uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", size = 2318492, upload-time = "2023-10-22T22:03:57.665Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/c2/27bf858a576b1fa35b5c2c2029c8cec424a8789e87545ed2f25466d1f21d/uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", size = 1443484 }, - { url = "https://files.pythonhosted.org/packages/4e/35/05b6064b93f4113412d1fd92bdcb6018607e78ae94d1712e63e533f9b2fa/uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", size = 793850 }, - { url = "https://files.pythonhosted.org/packages/aa/56/b62ab4e10458ce96bb30c98d327c127f989d3bb4ef899e4c410c739f7ef6/uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", size = 3418601 }, - { url = "https://files.pythonhosted.org/packages/ab/ed/12729fba5e3b7e02ee70b3ea230b88e60a50375cf63300db22607694d2f0/uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", size = 3416731 }, - { url = "https://files.pythonhosted.org/packages/a2/23/80381a2d728d2a0c36e2eef202f5b77428990004d8fbdd3865558ff49fa5/uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", size = 4128572 }, - { url = "https://files.pythonhosted.org/packages/6b/23/1ee41a15e1ad15182e2bd12cbfd37bcb6802f01d6bbcaddf6ca136cbb308/uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", size = 4129235 }, - { url = "https://files.pythonhosted.org/packages/41/2a/608ad69f27f51280098abee440c33e921d3ad203e2c86f7262e241e49c99/uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", size = 1357681 }, - { url = "https://files.pythonhosted.org/packages/13/00/d0923d66d80c8717983493a4d7af747ce47f1c2147d82df057a846ba6bff/uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", size = 746421 }, - { url = "https://files.pythonhosted.org/packages/1f/c7/e494c367b0c6e6453f9bed5a78548f5b2ff49add36302cd915a91d347d88/uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", size = 3481000 }, - { url = "https://files.pythonhosted.org/packages/86/cc/1829b3f740e4cb1baefff8240a1c6fc8db9e3caac7b93169aec7d4386069/uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", size = 3476361 }, - { url = "https://files.pythonhosted.org/packages/7a/4c/ca87e8f5a30629ffa2038c20907c8ab455c5859ff10e810227b76e60d927/uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", size = 4169571 }, - { url = "https://files.pythonhosted.org/packages/d2/a9/f947a00c47b1c87c937cac2423243a41ba08f0fb76d04eb0d1d170606e0a/uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", size = 4170459 }, - { url = "https://files.pythonhosted.org/packages/85/57/6736733bb0e86a4b5380d04082463b289c0baecaa205934ba81e8a1d5ea4/uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", size = 1355376 }, - { url = "https://files.pythonhosted.org/packages/eb/0c/51339463da912ed34b48d470538d98a91660749b2db56902f23db9b42fdd/uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", size = 745031 }, - { url = "https://files.pythonhosted.org/packages/e6/fc/f0daaf19f5b2116a2d26eb9f98c4a45084aea87bf03c33bcca7aa1ff36e5/uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", size = 4077630 }, - { url = "https://files.pythonhosted.org/packages/fd/96/fdc318ffe82ae567592b213ec2fcd8ecedd927b5da068cf84d56b28c51a4/uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", size = 4159957 }, - { url = "https://files.pythonhosted.org/packages/71/bc/092068ae7fc16dcf20f3e389126ba7800cee75ffba83f78bf1d167aee3cd/uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", size = 4014951 }, - { url = "https://files.pythonhosted.org/packages/a6/f2/6ce1e73933eb038c89f929e26042e64b2cb8d4453410153eed14918ca9a8/uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", size = 4100911 }, + { url = "https://files.pythonhosted.org/packages/36/c2/27bf858a576b1fa35b5c2c2029c8cec424a8789e87545ed2f25466d1f21d/uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", size = 1443484, upload-time = "2023-10-22T22:02:54.169Z" }, + { url = "https://files.pythonhosted.org/packages/4e/35/05b6064b93f4113412d1fd92bdcb6018607e78ae94d1712e63e533f9b2fa/uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", size = 793850, upload-time = "2023-10-22T22:02:56.311Z" }, + { url = "https://files.pythonhosted.org/packages/aa/56/b62ab4e10458ce96bb30c98d327c127f989d3bb4ef899e4c410c739f7ef6/uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", size = 3418601, upload-time = "2023-10-22T22:02:58.717Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ed/12729fba5e3b7e02ee70b3ea230b88e60a50375cf63300db22607694d2f0/uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", size = 3416731, upload-time = "2023-10-22T22:03:01.043Z" }, + { url = "https://files.pythonhosted.org/packages/a2/23/80381a2d728d2a0c36e2eef202f5b77428990004d8fbdd3865558ff49fa5/uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", size = 4128572, upload-time = "2023-10-22T22:03:02.874Z" }, + { url = "https://files.pythonhosted.org/packages/6b/23/1ee41a15e1ad15182e2bd12cbfd37bcb6802f01d6bbcaddf6ca136cbb308/uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", size = 4129235, upload-time = "2023-10-22T22:03:05.361Z" }, + { url = "https://files.pythonhosted.org/packages/41/2a/608ad69f27f51280098abee440c33e921d3ad203e2c86f7262e241e49c99/uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", size = 1357681, upload-time = "2023-10-22T22:03:07.158Z" }, + { url = "https://files.pythonhosted.org/packages/13/00/d0923d66d80c8717983493a4d7af747ce47f1c2147d82df057a846ba6bff/uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", size = 746421, upload-time = "2023-10-22T22:03:09.4Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c7/e494c367b0c6e6453f9bed5a78548f5b2ff49add36302cd915a91d347d88/uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", size = 3481000, upload-time = "2023-10-22T22:03:11.755Z" }, + { url = "https://files.pythonhosted.org/packages/86/cc/1829b3f740e4cb1baefff8240a1c6fc8db9e3caac7b93169aec7d4386069/uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", size = 3476361, upload-time = "2023-10-22T22:03:13.841Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4c/ca87e8f5a30629ffa2038c20907c8ab455c5859ff10e810227b76e60d927/uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", size = 4169571, upload-time = "2023-10-22T22:03:15.618Z" }, + { url = "https://files.pythonhosted.org/packages/d2/a9/f947a00c47b1c87c937cac2423243a41ba08f0fb76d04eb0d1d170606e0a/uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", size = 4170459, upload-time = "2023-10-22T22:03:17.988Z" }, + { url = "https://files.pythonhosted.org/packages/85/57/6736733bb0e86a4b5380d04082463b289c0baecaa205934ba81e8a1d5ea4/uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", size = 1355376, upload-time = "2023-10-22T22:03:20.075Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0c/51339463da912ed34b48d470538d98a91660749b2db56902f23db9b42fdd/uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", size = 745031, upload-time = "2023-10-22T22:03:21.404Z" }, + { url = "https://files.pythonhosted.org/packages/e6/fc/f0daaf19f5b2116a2d26eb9f98c4a45084aea87bf03c33bcca7aa1ff36e5/uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", size = 4077630, upload-time = "2023-10-22T22:03:23.568Z" }, + { url = "https://files.pythonhosted.org/packages/fd/96/fdc318ffe82ae567592b213ec2fcd8ecedd927b5da068cf84d56b28c51a4/uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", size = 4159957, upload-time = "2023-10-22T22:03:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/71/bc/092068ae7fc16dcf20f3e389126ba7800cee75ffba83f78bf1d167aee3cd/uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", size = 4014951, upload-time = "2023-10-22T22:03:27.055Z" }, + { url = "https://files.pythonhosted.org/packages/a6/f2/6ce1e73933eb038c89f929e26042e64b2cb8d4453410153eed14918ca9a8/uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", size = 4100911, upload-time = "2023-10-22T22:03:29.39Z" }, ] [[package]] @@ -3223,115 +3327,115 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/79/0ee412e1228aaf6f9568aa180b43cb482472de52560fbd7c283c786534af/watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3", size = 37098 } +sdist = { url = "https://files.pythonhosted.org/packages/66/79/0ee412e1228aaf6f9568aa180b43cb482472de52560fbd7c283c786534af/watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3", size = 37098, upload-time = "2023-10-13T13:06:39.809Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/85/ea2a035b7d86bf0a29ee1c32bc2df8ad4da77e6602806e679d9735ff28cb/watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa", size = 428182 }, - { url = "https://files.pythonhosted.org/packages/b5/e5/240e5eb3ff0ee3da3b028ac5be2019c407bdd0f3fdb02bd75fdf3bd10aff/watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e", size = 418275 }, - { url = "https://files.pythonhosted.org/packages/5b/79/ecd0dfb04443a1900cd3952d7ea6493bf655c2db9a0d3736a5d98a15da39/watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03", size = 1379785 }, - { url = "https://files.pythonhosted.org/packages/41/0e/3333b986b1889bb71f0e44b3fac0591824a679619b8b8ddd70ff8858edc4/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124", size = 1349374 }, - { url = "https://files.pythonhosted.org/packages/18/c4/ad5ad16cad900a29aaa792e0ed121ff70d76f74062b051661090d88c6dfd/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab", size = 1348033 }, - { url = "https://files.pythonhosted.org/packages/4e/d2/769254ff04ba88ceb179a6e892606ac4da17338eb010e85ca7a9c3339234/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303", size = 1464393 }, - { url = "https://files.pythonhosted.org/packages/14/d0/662800e778ca20e7664dd5df57751aa79ef18b6abb92224b03c8c2e852a6/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d", size = 1542953 }, - { url = "https://files.pythonhosted.org/packages/f7/4b/b90dcdc3bbaf3bb2db733e1beea2d01566b601c15fcf8e71dfcc8686c097/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c", size = 1346961 }, - { url = "https://files.pythonhosted.org/packages/92/ff/75cc1b30c5abcad13a2a72e75625ec619c7a393028a111d7d24dba578d5e/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9", size = 1464393 }, - { url = "https://files.pythonhosted.org/packages/9a/65/12cbeb363bf220482a559c48107edfd87f09248f55e1ac315a36c2098a0f/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9", size = 1463409 }, - { url = "https://files.pythonhosted.org/packages/f2/08/92e28867c66f0d9638bb131feca739057efc48dbcd391fd7f0a55507e470/watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293", size = 268101 }, - { url = "https://files.pythonhosted.org/packages/4b/ea/80527adf1ad51488a96fc201715730af5879f4dfeccb5e2069ff82d890d4/watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235", size = 279675 }, - { url = "https://files.pythonhosted.org/packages/57/b9/2667286003dd305b81d3a3aa824d3dfc63dacbf2a96faae09e72d953c430/watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7", size = 428210 }, - { url = "https://files.pythonhosted.org/packages/a3/87/6793ac60d2e20c9c1883aec7431c2e7b501ee44a839f6da1b747c13baa23/watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef", size = 418196 }, - { url = "https://files.pythonhosted.org/packages/5d/12/e1d1d220c5b99196eea38c9a878964f30a2b55ec9d72fd713191725b35e8/watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586", size = 1380287 }, - { url = "https://files.pythonhosted.org/packages/0e/cf/126f0a8683f326d190c3539a769e45e747a80a5fcbf797de82e738c946ae/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317", size = 1349653 }, - { url = "https://files.pythonhosted.org/packages/20/6e/6cffd795ec65dbc82f15d95b73d3042c1ddaffc4dd25f6c8240bfcf0640f/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b", size = 1348844 }, - { url = "https://files.pythonhosted.org/packages/d5/2a/f9633279d8937ad84c532997405dd106fa6100e8d2b83e364f1c87561f96/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1", size = 1464343 }, - { url = "https://files.pythonhosted.org/packages/d7/49/9b2199bbf3c89e7c8dd795fced9dac29f201be8a28a5df0c8ff625737df6/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d", size = 1542858 }, - { url = "https://files.pythonhosted.org/packages/35/e0/e8a9c1fe30e98c5b3507ad381abc4d9ee2c3b9c0ae62ffe9c164a5838186/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7", size = 1347464 }, - { url = "https://files.pythonhosted.org/packages/ba/66/873739dd7defdfaee4b880114de9463fae18ba13ae2ddd784806b0ee33b6/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0", size = 1464343 }, - { url = "https://files.pythonhosted.org/packages/bd/51/d7539aa258d8f0e5d7b870af8b9b8964b4f88a1e4517eeb8a2efb838e9b3/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365", size = 1463338 }, - { url = "https://files.pythonhosted.org/packages/ee/92/219c539a2a93b6870fa7b84eace946983126b20a7e15c6c034d8d0472682/watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400", size = 267658 }, - { url = "https://files.pythonhosted.org/packages/f3/dc/2a8a447b783f5059c4bf7a6bad8fe59375a5a9ce872774763b25c21c2860/watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe", size = 280113 }, - { url = "https://files.pythonhosted.org/packages/22/15/e4085181cf0210a6ec6eb29fee0c6088de867ee33d81555076a4a2726e8b/watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078", size = 268688 }, - { url = "https://files.pythonhosted.org/packages/a1/fd/2f009eb17809afd32a143b442856628585c9ce3a9c6d5c1841e44e35a16c/watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a", size = 426902 }, - { url = "https://files.pythonhosted.org/packages/e0/62/a2605f212a136e06f2d056ee7491ede9935ba0f1d5ceafd1f7da2a0c8625/watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1", size = 417300 }, - { url = "https://files.pythonhosted.org/packages/69/0e/29f158fa22eb2cc1f188b5ec20fb5c0a64eb801e3901ad5b7ad546cbaed0/watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a", size = 1378126 }, - { url = "https://files.pythonhosted.org/packages/e8/f3/c67865cb5a174201c52d34e870cc7956b8408ee83ce9a02909d6a2a93a14/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915", size = 1348275 }, - { url = "https://files.pythonhosted.org/packages/d7/eb/b6f1184d1c7b9670f5bd1e184e4c221ecf25fd817cf2fcac6adc387882b5/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360", size = 1347255 }, - { url = "https://files.pythonhosted.org/packages/c8/27/e534e4b3fe739f4bf8bd5dc4c26cbc5d3baa427125d8ef78a6556acd6ff4/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6", size = 1462845 }, - { url = "https://files.pythonhosted.org/packages/b0/ba/a0d1c1c55f75e7e47c8f79f2314f7ec670b5177596f6d27764aecc7048cd/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7", size = 1528957 }, - { url = "https://files.pythonhosted.org/packages/1c/3a/4e38518c4dff58090c01fc8cc051fa08ac9ae00b361c855075809b0058ce/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c", size = 1345542 }, - { url = "https://files.pythonhosted.org/packages/9f/b7/783097f8137a710d5cd9ccbfcd92e4b453d38dab05cfcb5dbd2c587752e5/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235", size = 1462238 }, - { url = "https://files.pythonhosted.org/packages/6b/4c/b741eb38f2c408ae9c5a25235f6506b1dda43486ae0fdb4c462ef75bce11/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7", size = 1462406 }, - { url = "https://files.pythonhosted.org/packages/77/e4/8d2b3c67364671b0e1c0ce383895a5415f45ecb3e8586982deff4a8e85c9/watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3", size = 266789 }, - { url = "https://files.pythonhosted.org/packages/da/f2/6b1de38aeb21eb9dac1ae6a1ee4521566e79690117032036c737cfab52fa/watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094", size = 280292 }, - { url = "https://files.pythonhosted.org/packages/5a/a5/7aba9435beb863c2490bae3173a45f42044ac7a48155d3dd42ab49cfae45/watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6", size = 268026 }, - { url = "https://files.pythonhosted.org/packages/62/66/7463ceb43eabc6deaa795c7969ff4d4fd938de54e655035483dfd1e97c84/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994", size = 429092 }, - { url = "https://files.pythonhosted.org/packages/fe/a3/42686af3a089f34aba35c39abac852869661938dae7025c1a0580dfe0fbf/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f", size = 419188 }, - { url = "https://files.pythonhosted.org/packages/37/17/4825999346f15d650f4c69093efa64fb040fbff4f706a20e8c4745f64070/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c", size = 1350366 }, - { url = "https://files.pythonhosted.org/packages/70/76/8d124e14cf51af4d6bba926c7473f253c6efd1539ba62577f079a2d71537/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc", size = 1346270 }, + { url = "https://files.pythonhosted.org/packages/6e/85/ea2a035b7d86bf0a29ee1c32bc2df8ad4da77e6602806e679d9735ff28cb/watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa", size = 428182, upload-time = "2023-10-13T13:04:34.803Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e5/240e5eb3ff0ee3da3b028ac5be2019c407bdd0f3fdb02bd75fdf3bd10aff/watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e", size = 418275, upload-time = "2023-10-13T13:04:36.632Z" }, + { url = "https://files.pythonhosted.org/packages/5b/79/ecd0dfb04443a1900cd3952d7ea6493bf655c2db9a0d3736a5d98a15da39/watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03", size = 1379785, upload-time = "2023-10-13T13:04:38.641Z" }, + { url = "https://files.pythonhosted.org/packages/41/0e/3333b986b1889bb71f0e44b3fac0591824a679619b8b8ddd70ff8858edc4/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124", size = 1349374, upload-time = "2023-10-13T13:04:41.711Z" }, + { url = "https://files.pythonhosted.org/packages/18/c4/ad5ad16cad900a29aaa792e0ed121ff70d76f74062b051661090d88c6dfd/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab", size = 1348033, upload-time = "2023-10-13T13:04:43.324Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d2/769254ff04ba88ceb179a6e892606ac4da17338eb010e85ca7a9c3339234/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303", size = 1464393, upload-time = "2023-10-13T13:04:44.818Z" }, + { url = "https://files.pythonhosted.org/packages/14/d0/662800e778ca20e7664dd5df57751aa79ef18b6abb92224b03c8c2e852a6/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d", size = 1542953, upload-time = "2023-10-13T13:04:46.714Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4b/b90dcdc3bbaf3bb2db733e1beea2d01566b601c15fcf8e71dfcc8686c097/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c", size = 1346961, upload-time = "2023-10-13T13:04:48.072Z" }, + { url = "https://files.pythonhosted.org/packages/92/ff/75cc1b30c5abcad13a2a72e75625ec619c7a393028a111d7d24dba578d5e/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9", size = 1464393, upload-time = "2023-10-13T13:04:49.638Z" }, + { url = "https://files.pythonhosted.org/packages/9a/65/12cbeb363bf220482a559c48107edfd87f09248f55e1ac315a36c2098a0f/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9", size = 1463409, upload-time = "2023-10-13T13:04:51.762Z" }, + { url = "https://files.pythonhosted.org/packages/f2/08/92e28867c66f0d9638bb131feca739057efc48dbcd391fd7f0a55507e470/watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293", size = 268101, upload-time = "2023-10-13T13:04:53.78Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ea/80527adf1ad51488a96fc201715730af5879f4dfeccb5e2069ff82d890d4/watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235", size = 279675, upload-time = "2023-10-13T13:04:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/2667286003dd305b81d3a3aa824d3dfc63dacbf2a96faae09e72d953c430/watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7", size = 428210, upload-time = "2023-10-13T13:04:56.894Z" }, + { url = "https://files.pythonhosted.org/packages/a3/87/6793ac60d2e20c9c1883aec7431c2e7b501ee44a839f6da1b747c13baa23/watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef", size = 418196, upload-time = "2023-10-13T13:04:58.19Z" }, + { url = "https://files.pythonhosted.org/packages/5d/12/e1d1d220c5b99196eea38c9a878964f30a2b55ec9d72fd713191725b35e8/watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586", size = 1380287, upload-time = "2023-10-13T13:04:59.923Z" }, + { url = "https://files.pythonhosted.org/packages/0e/cf/126f0a8683f326d190c3539a769e45e747a80a5fcbf797de82e738c946ae/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317", size = 1349653, upload-time = "2023-10-13T13:05:01.622Z" }, + { url = "https://files.pythonhosted.org/packages/20/6e/6cffd795ec65dbc82f15d95b73d3042c1ddaffc4dd25f6c8240bfcf0640f/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b", size = 1348844, upload-time = "2023-10-13T13:05:03.805Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2a/f9633279d8937ad84c532997405dd106fa6100e8d2b83e364f1c87561f96/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1", size = 1464343, upload-time = "2023-10-13T13:05:05.248Z" }, + { url = "https://files.pythonhosted.org/packages/d7/49/9b2199bbf3c89e7c8dd795fced9dac29f201be8a28a5df0c8ff625737df6/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d", size = 1542858, upload-time = "2023-10-13T13:05:06.791Z" }, + { url = "https://files.pythonhosted.org/packages/35/e0/e8a9c1fe30e98c5b3507ad381abc4d9ee2c3b9c0ae62ffe9c164a5838186/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7", size = 1347464, upload-time = "2023-10-13T13:05:08.622Z" }, + { url = "https://files.pythonhosted.org/packages/ba/66/873739dd7defdfaee4b880114de9463fae18ba13ae2ddd784806b0ee33b6/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0", size = 1464343, upload-time = "2023-10-13T13:05:10.584Z" }, + { url = "https://files.pythonhosted.org/packages/bd/51/d7539aa258d8f0e5d7b870af8b9b8964b4f88a1e4517eeb8a2efb838e9b3/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365", size = 1463338, upload-time = "2023-10-13T13:05:12.671Z" }, + { url = "https://files.pythonhosted.org/packages/ee/92/219c539a2a93b6870fa7b84eace946983126b20a7e15c6c034d8d0472682/watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400", size = 267658, upload-time = "2023-10-13T13:05:13.972Z" }, + { url = "https://files.pythonhosted.org/packages/f3/dc/2a8a447b783f5059c4bf7a6bad8fe59375a5a9ce872774763b25c21c2860/watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe", size = 280113, upload-time = "2023-10-13T13:05:15.289Z" }, + { url = "https://files.pythonhosted.org/packages/22/15/e4085181cf0210a6ec6eb29fee0c6088de867ee33d81555076a4a2726e8b/watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078", size = 268688, upload-time = "2023-10-13T13:05:17.144Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fd/2f009eb17809afd32a143b442856628585c9ce3a9c6d5c1841e44e35a16c/watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a", size = 426902, upload-time = "2023-10-13T13:05:18.828Z" }, + { url = "https://files.pythonhosted.org/packages/e0/62/a2605f212a136e06f2d056ee7491ede9935ba0f1d5ceafd1f7da2a0c8625/watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1", size = 417300, upload-time = "2023-10-13T13:05:20.116Z" }, + { url = "https://files.pythonhosted.org/packages/69/0e/29f158fa22eb2cc1f188b5ec20fb5c0a64eb801e3901ad5b7ad546cbaed0/watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a", size = 1378126, upload-time = "2023-10-13T13:05:21.508Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f3/c67865cb5a174201c52d34e870cc7956b8408ee83ce9a02909d6a2a93a14/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915", size = 1348275, upload-time = "2023-10-13T13:05:22.995Z" }, + { url = "https://files.pythonhosted.org/packages/d7/eb/b6f1184d1c7b9670f5bd1e184e4c221ecf25fd817cf2fcac6adc387882b5/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360", size = 1347255, upload-time = "2023-10-13T13:05:24.618Z" }, + { url = "https://files.pythonhosted.org/packages/c8/27/e534e4b3fe739f4bf8bd5dc4c26cbc5d3baa427125d8ef78a6556acd6ff4/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6", size = 1462845, upload-time = "2023-10-13T13:05:26.531Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ba/a0d1c1c55f75e7e47c8f79f2314f7ec670b5177596f6d27764aecc7048cd/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7", size = 1528957, upload-time = "2023-10-13T13:05:28.365Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3a/4e38518c4dff58090c01fc8cc051fa08ac9ae00b361c855075809b0058ce/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c", size = 1345542, upload-time = "2023-10-13T13:05:29.862Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b7/783097f8137a710d5cd9ccbfcd92e4b453d38dab05cfcb5dbd2c587752e5/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235", size = 1462238, upload-time = "2023-10-13T13:05:32.245Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4c/b741eb38f2c408ae9c5a25235f6506b1dda43486ae0fdb4c462ef75bce11/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7", size = 1462406, upload-time = "2023-10-13T13:05:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/77/e4/8d2b3c67364671b0e1c0ce383895a5415f45ecb3e8586982deff4a8e85c9/watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3", size = 266789, upload-time = "2023-10-13T13:05:35.606Z" }, + { url = "https://files.pythonhosted.org/packages/da/f2/6b1de38aeb21eb9dac1ae6a1ee4521566e79690117032036c737cfab52fa/watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094", size = 280292, upload-time = "2023-10-13T13:05:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a5/7aba9435beb863c2490bae3173a45f42044ac7a48155d3dd42ab49cfae45/watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6", size = 268026, upload-time = "2023-10-13T13:05:38.591Z" }, + { url = "https://files.pythonhosted.org/packages/62/66/7463ceb43eabc6deaa795c7969ff4d4fd938de54e655035483dfd1e97c84/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994", size = 429092, upload-time = "2023-10-13T13:06:21.419Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a3/42686af3a089f34aba35c39abac852869661938dae7025c1a0580dfe0fbf/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f", size = 419188, upload-time = "2023-10-13T13:06:22.934Z" }, + { url = "https://files.pythonhosted.org/packages/37/17/4825999346f15d650f4c69093efa64fb040fbff4f706a20e8c4745f64070/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c", size = 1350366, upload-time = "2023-10-13T13:06:24.254Z" }, + { url = "https://files.pythonhosted.org/packages/70/76/8d124e14cf51af4d6bba926c7473f253c6efd1539ba62577f079a2d71537/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc", size = 1346270, upload-time = "2023-10-13T13:06:25.742Z" }, ] [[package]] name = "wcwidth" version = "0.2.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, ] [[package]] name = "websocket-client" version = "1.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, ] [[package]] name = "websockets" version = "12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2e/62/7a7874b7285413c954a4cca3c11fd851f11b2fe5b4ae2d9bee4f6d9bdb10/websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", size = 104994 } +sdist = { url = "https://files.pythonhosted.org/packages/2e/62/7a7874b7285413c954a4cca3c11fd851f11b2fe5b4ae2d9bee4f6d9bdb10/websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", size = 104994, upload-time = "2023-10-21T14:21:11.88Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/b9/360b86ded0920a93bff0db4e4b0aa31370b0208ca240b2e98d62aad8d082/websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", size = 124025 }, - { url = "https://files.pythonhosted.org/packages/bb/d3/1eca0d8fb6f0665c96f0dc7c0d0ec8aa1a425e8c003e0c18e1451f65d177/websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", size = 121261 }, - { url = "https://files.pythonhosted.org/packages/4e/e1/f6c3ecf7f1bfd9209e13949db027d7fdea2faf090c69b5f2d17d1d796d96/websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", size = 121328 }, - { url = "https://files.pythonhosted.org/packages/74/4d/f88eeceb23cb587c4aeca779e3f356cf54817af2368cb7f2bd41f93c8360/websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", size = 130925 }, - { url = "https://files.pythonhosted.org/packages/16/17/f63d9ee6ffd9afbeea021d5950d6e8db84cd4aead306c6c2ca523805699e/websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", size = 129930 }, - { url = "https://files.pythonhosted.org/packages/9a/12/c7a7504f5bf74d6ee0533f6fc7d30d8f4b79420ab179d1df2484b07602eb/websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", size = 130245 }, - { url = "https://files.pythonhosted.org/packages/e4/6a/3600c7771eb31116d2e77383d7345618b37bb93709d041e328c08e2a8eb3/websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", size = 134966 }, - { url = "https://files.pythonhosted.org/packages/22/26/df77c4b7538caebb78c9b97f43169ef742a4f445e032a5ea1aaef88f8f46/websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", size = 134196 }, - { url = "https://files.pythonhosted.org/packages/e5/18/18ce9a4a08203c8d0d3d561e3ea4f453daf32f099601fc831e60c8a9b0f2/websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", size = 134822 }, - { url = "https://files.pythonhosted.org/packages/45/51/1f823a341fc20a880e67ae62f6c38c4880a24a4b60fbe544a38f516f39a1/websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", size = 124454 }, - { url = "https://files.pythonhosted.org/packages/41/b0/5ec054cfcf23adfc88d39359b85e81d043af8a141e3ac8ce40f45a5ce5f4/websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", size = 124974 }, - { url = "https://files.pythonhosted.org/packages/02/73/9c1e168a2e7fdf26841dc98f5f5502e91dea47428da7690a08101f616169/websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", size = 124047 }, - { url = "https://files.pythonhosted.org/packages/e4/2d/9a683359ad2ed11b2303a7a94800db19c61d33fa3bde271df09e99936022/websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", size = 121282 }, - { url = "https://files.pythonhosted.org/packages/95/aa/75fa3b893142d6d98a48cb461169bd268141f2da8bfca97392d6462a02eb/websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", size = 121325 }, - { url = "https://files.pythonhosted.org/packages/6e/a4/51a25e591d645df71ee0dc3a2c880b28e5514c00ce752f98a40a87abcd1e/websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", size = 131502 }, - { url = "https://files.pythonhosted.org/packages/cd/ea/0ceeea4f5b87398fe2d9f5bcecfa00a1bcd542e2bfcac2f2e5dd612c4e9e/websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", size = 130491 }, - { url = "https://files.pythonhosted.org/packages/e3/05/f52a60b66d9faf07a4f7d71dc056bffafe36a7e98c4eb5b78f04fe6e4e85/websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", size = 130872 }, - { url = "https://files.pythonhosted.org/packages/ac/4e/c7361b2d7b964c40fea924d64881145164961fcd6c90b88b7e3ab2c4f431/websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", size = 136318 }, - { url = "https://files.pythonhosted.org/packages/0a/31/337bf35ae5faeaf364c9cddec66681cdf51dc4414ee7a20f92a18e57880f/websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", size = 135594 }, - { url = "https://files.pythonhosted.org/packages/95/aa/1ac767825c96f9d7e43c4c95683757d4ef28cf11fa47a69aca42428d3e3a/websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", size = 136191 }, - { url = "https://files.pythonhosted.org/packages/28/4b/344ec5cfeb6bc417da097f8253607c3aed11d9a305fb58346f506bf556d8/websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", size = 124453 }, - { url = "https://files.pythonhosted.org/packages/d1/40/6b169cd1957476374f51f4486a3e85003149e62a14e6b78a958c2222337a/websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", size = 124971 }, - { url = "https://files.pythonhosted.org/packages/a9/6d/23cc898647c8a614a0d9ca703695dd04322fb5135096a20c2684b7c852b6/websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", size = 124061 }, - { url = "https://files.pythonhosted.org/packages/39/34/364f30fdf1a375e4002a26ee3061138d1571dfda6421126127d379d13930/websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", size = 121296 }, - { url = "https://files.pythonhosted.org/packages/2e/00/96ae1c9dcb3bc316ef683f2febd8c97dde9f254dc36c3afc65c7645f734c/websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", size = 121326 }, - { url = "https://files.pythonhosted.org/packages/af/f1/bba1e64430685dd456c1a1fd6b0c791ae33104967b928aefeff261761e8d/websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", size = 131807 }, - { url = "https://files.pythonhosted.org/packages/62/3b/98ee269712f37d892b93852ce07b3e6d7653160ca4c0d4f8c8663f8021f8/websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", size = 130751 }, - { url = "https://files.pythonhosted.org/packages/f1/00/d6f01ca2b191f8b0808e4132ccd2e7691f0453cbd7d0f72330eb97453c3a/websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", size = 131176 }, - { url = "https://files.pythonhosted.org/packages/af/9c/703ff3cd8109dcdee6152bae055d852ebaa7750117760ded697ab836cbcf/websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", size = 136246 }, - { url = "https://files.pythonhosted.org/packages/0b/a5/1a38fb85a456b9dc874ec984f3ff34f6550eafd17a3da28753cd3c1628e8/websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", size = 135466 }, - { url = "https://files.pythonhosted.org/packages/3c/98/1261f289dff7e65a38d59d2f591de6ed0a2580b729aebddec033c4d10881/websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", size = 136083 }, - { url = "https://files.pythonhosted.org/packages/a9/1c/f68769fba63ccb9c13fe0a25b616bd5aebeef1c7ddebc2ccc32462fb784d/websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", size = 124460 }, - { url = "https://files.pythonhosted.org/packages/20/52/8915f51f9aaef4e4361c89dd6cf69f72a0159f14e0d25026c81b6ad22525/websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", size = 124985 }, - { url = "https://files.pythonhosted.org/packages/43/8b/554a8a8bb6da9dd1ce04c44125e2192af7b7beebf6e3dbfa5d0e285cc20f/websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", size = 121110 }, - { url = "https://files.pythonhosted.org/packages/b0/8e/58b8812940d746ad74d395fb069497255cb5ef50748dfab1e8b386b1f339/websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", size = 123216 }, - { url = "https://files.pythonhosted.org/packages/81/ee/272cb67ace1786ce6d9f39d47b3c55b335e8b75dd1972a7967aad39178b6/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", size = 122821 }, - { url = "https://files.pythonhosted.org/packages/a8/03/387fc902b397729df166763e336f4e5cec09fe7b9d60f442542c94a21be1/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", size = 122768 }, - { url = "https://files.pythonhosted.org/packages/50/f0/5939fbc9bc1979d79a774ce5b7c4b33c0cefe99af22fb70f7462d0919640/websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", size = 125009 }, - { url = "https://files.pythonhosted.org/packages/79/4d/9cc401e7b07e80532ebc8c8e993f42541534da9e9249c59ee0139dcb0352/websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", size = 118370 }, + { url = "https://files.pythonhosted.org/packages/b1/b9/360b86ded0920a93bff0db4e4b0aa31370b0208ca240b2e98d62aad8d082/websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", size = 124025, upload-time = "2023-10-21T14:19:28.387Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d3/1eca0d8fb6f0665c96f0dc7c0d0ec8aa1a425e8c003e0c18e1451f65d177/websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", size = 121261, upload-time = "2023-10-21T14:19:30.203Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e1/f6c3ecf7f1bfd9209e13949db027d7fdea2faf090c69b5f2d17d1d796d96/websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", size = 121328, upload-time = "2023-10-21T14:19:31.765Z" }, + { url = "https://files.pythonhosted.org/packages/74/4d/f88eeceb23cb587c4aeca779e3f356cf54817af2368cb7f2bd41f93c8360/websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", size = 130925, upload-time = "2023-10-21T14:19:33.36Z" }, + { url = "https://files.pythonhosted.org/packages/16/17/f63d9ee6ffd9afbeea021d5950d6e8db84cd4aead306c6c2ca523805699e/websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", size = 129930, upload-time = "2023-10-21T14:19:35.109Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/c7a7504f5bf74d6ee0533f6fc7d30d8f4b79420ab179d1df2484b07602eb/websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", size = 130245, upload-time = "2023-10-21T14:19:36.761Z" }, + { url = "https://files.pythonhosted.org/packages/e4/6a/3600c7771eb31116d2e77383d7345618b37bb93709d041e328c08e2a8eb3/websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", size = 134966, upload-time = "2023-10-21T14:19:38.481Z" }, + { url = "https://files.pythonhosted.org/packages/22/26/df77c4b7538caebb78c9b97f43169ef742a4f445e032a5ea1aaef88f8f46/websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", size = 134196, upload-time = "2023-10-21T14:19:40.264Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/18ce9a4a08203c8d0d3d561e3ea4f453daf32f099601fc831e60c8a9b0f2/websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", size = 134822, upload-time = "2023-10-21T14:19:41.836Z" }, + { url = "https://files.pythonhosted.org/packages/45/51/1f823a341fc20a880e67ae62f6c38c4880a24a4b60fbe544a38f516f39a1/websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", size = 124454, upload-time = "2023-10-21T14:19:43.639Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/5ec054cfcf23adfc88d39359b85e81d043af8a141e3ac8ce40f45a5ce5f4/websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", size = 124974, upload-time = "2023-10-21T14:19:44.934Z" }, + { url = "https://files.pythonhosted.org/packages/02/73/9c1e168a2e7fdf26841dc98f5f5502e91dea47428da7690a08101f616169/websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", size = 124047, upload-time = "2023-10-21T14:19:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/e4/2d/9a683359ad2ed11b2303a7a94800db19c61d33fa3bde271df09e99936022/websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", size = 121282, upload-time = "2023-10-21T14:19:47.739Z" }, + { url = "https://files.pythonhosted.org/packages/95/aa/75fa3b893142d6d98a48cb461169bd268141f2da8bfca97392d6462a02eb/websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", size = 121325, upload-time = "2023-10-21T14:19:49.4Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a4/51a25e591d645df71ee0dc3a2c880b28e5514c00ce752f98a40a87abcd1e/websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", size = 131502, upload-time = "2023-10-21T14:19:50.683Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ea/0ceeea4f5b87398fe2d9f5bcecfa00a1bcd542e2bfcac2f2e5dd612c4e9e/websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", size = 130491, upload-time = "2023-10-21T14:19:51.835Z" }, + { url = "https://files.pythonhosted.org/packages/e3/05/f52a60b66d9faf07a4f7d71dc056bffafe36a7e98c4eb5b78f04fe6e4e85/websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", size = 130872, upload-time = "2023-10-21T14:19:53.071Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4e/c7361b2d7b964c40fea924d64881145164961fcd6c90b88b7e3ab2c4f431/websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", size = 136318, upload-time = "2023-10-21T14:19:54.41Z" }, + { url = "https://files.pythonhosted.org/packages/0a/31/337bf35ae5faeaf364c9cddec66681cdf51dc4414ee7a20f92a18e57880f/websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", size = 135594, upload-time = "2023-10-21T14:19:55.982Z" }, + { url = "https://files.pythonhosted.org/packages/95/aa/1ac767825c96f9d7e43c4c95683757d4ef28cf11fa47a69aca42428d3e3a/websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", size = 136191, upload-time = "2023-10-21T14:19:57.349Z" }, + { url = "https://files.pythonhosted.org/packages/28/4b/344ec5cfeb6bc417da097f8253607c3aed11d9a305fb58346f506bf556d8/websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", size = 124453, upload-time = "2023-10-21T14:19:59.11Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/6b169cd1957476374f51f4486a3e85003149e62a14e6b78a958c2222337a/websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", size = 124971, upload-time = "2023-10-21T14:20:00.243Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6d/23cc898647c8a614a0d9ca703695dd04322fb5135096a20c2684b7c852b6/websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", size = 124061, upload-time = "2023-10-21T14:20:02.221Z" }, + { url = "https://files.pythonhosted.org/packages/39/34/364f30fdf1a375e4002a26ee3061138d1571dfda6421126127d379d13930/websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", size = 121296, upload-time = "2023-10-21T14:20:03.591Z" }, + { url = "https://files.pythonhosted.org/packages/2e/00/96ae1c9dcb3bc316ef683f2febd8c97dde9f254dc36c3afc65c7645f734c/websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", size = 121326, upload-time = "2023-10-21T14:20:04.956Z" }, + { url = "https://files.pythonhosted.org/packages/af/f1/bba1e64430685dd456c1a1fd6b0c791ae33104967b928aefeff261761e8d/websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", size = 131807, upload-time = "2023-10-21T14:20:06.153Z" }, + { url = "https://files.pythonhosted.org/packages/62/3b/98ee269712f37d892b93852ce07b3e6d7653160ca4c0d4f8c8663f8021f8/websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", size = 130751, upload-time = "2023-10-21T14:20:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/f1/00/d6f01ca2b191f8b0808e4132ccd2e7691f0453cbd7d0f72330eb97453c3a/websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", size = 131176, upload-time = "2023-10-21T14:20:09.212Z" }, + { url = "https://files.pythonhosted.org/packages/af/9c/703ff3cd8109dcdee6152bae055d852ebaa7750117760ded697ab836cbcf/websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", size = 136246, upload-time = "2023-10-21T14:20:10.423Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a5/1a38fb85a456b9dc874ec984f3ff34f6550eafd17a3da28753cd3c1628e8/websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", size = 135466, upload-time = "2023-10-21T14:20:11.826Z" }, + { url = "https://files.pythonhosted.org/packages/3c/98/1261f289dff7e65a38d59d2f591de6ed0a2580b729aebddec033c4d10881/websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", size = 136083, upload-time = "2023-10-21T14:20:13.451Z" }, + { url = "https://files.pythonhosted.org/packages/a9/1c/f68769fba63ccb9c13fe0a25b616bd5aebeef1c7ddebc2ccc32462fb784d/websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", size = 124460, upload-time = "2023-10-21T14:20:14.719Z" }, + { url = "https://files.pythonhosted.org/packages/20/52/8915f51f9aaef4e4361c89dd6cf69f72a0159f14e0d25026c81b6ad22525/websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", size = 124985, upload-time = "2023-10-21T14:20:15.817Z" }, + { url = "https://files.pythonhosted.org/packages/43/8b/554a8a8bb6da9dd1ce04c44125e2192af7b7beebf6e3dbfa5d0e285cc20f/websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", size = 121110, upload-time = "2023-10-21T14:20:48.335Z" }, + { url = "https://files.pythonhosted.org/packages/b0/8e/58b8812940d746ad74d395fb069497255cb5ef50748dfab1e8b386b1f339/websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", size = 123216, upload-time = "2023-10-21T14:20:50.083Z" }, + { url = "https://files.pythonhosted.org/packages/81/ee/272cb67ace1786ce6d9f39d47b3c55b335e8b75dd1972a7967aad39178b6/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", size = 122821, upload-time = "2023-10-21T14:20:51.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/03/387fc902b397729df166763e336f4e5cec09fe7b9d60f442542c94a21be1/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", size = 122768, upload-time = "2023-10-21T14:20:52.59Z" }, + { url = "https://files.pythonhosted.org/packages/50/f0/5939fbc9bc1979d79a774ce5b7c4b33c0cefe99af22fb70f7462d0919640/websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", size = 125009, upload-time = "2023-10-21T14:20:54.419Z" }, + { url = "https://files.pythonhosted.org/packages/79/4d/9cc401e7b07e80532ebc8c8e993f42541534da9e9249c59ee0139dcb0352/websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", size = 118370, upload-time = "2023-10-21T14:21:10.075Z" }, ] [[package]] @@ -3341,9 +3445,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/02/51/2e0fc149e7a810d300422ab543f87f2bcf64d985eb6f1228c4efd6e4f8d4/werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18", size = 803342 } +sdist = { url = "https://files.pythonhosted.org/packages/02/51/2e0fc149e7a810d300422ab543f87f2bcf64d985eb6f1228c4efd6e4f8d4/werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18", size = 803342, upload-time = "2024-05-05T23:10:31.999Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/6e/e792999e816d19d7fcbfa94c730936750036d65656a76a5a688b57a656c4/werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8", size = 227274 }, + { url = "https://files.pythonhosted.org/packages/9d/6e/e792999e816d19d7fcbfa94c730936750036d65656a76a5a688b57a656c4/werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8", size = 227274, upload-time = "2024-05-05T23:10:29.567Z" }, ] [[package]] @@ -3353,9 +3457,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/4a/44d3c295350d776427904d73c189e10aeae66d7f555bb2feee16d1e4ba5a/wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", size = 53425 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/4a/44d3c295350d776427904d73c189e10aeae66d7f555bb2feee16d1e4ba5a/wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", size = 53425, upload-time = "2022-08-23T19:58:21.447Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736", size = 24226 }, + { url = "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736", size = 24226, upload-time = "2022-08-23T19:58:19.96Z" }, ] [[package]] @@ -3365,9 +3469,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/c2/427f1867bb96555d1d34342f1dd97f8c420966ab564d58d18469a1db8736/zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd", size = 17350 } +sdist = { url = "https://files.pythonhosted.org/packages/46/c2/427f1867bb96555d1d34342f1dd97f8c420966ab564d58d18469a1db8736/zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd", size = 17350, upload-time = "2023-06-23T06:28:35.709Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/42/f8dbc2b9ad59e927940325a22d6d3931d630c3644dae7e2369ef5d9ba230/zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26", size = 6824 }, + { url = "https://files.pythonhosted.org/packages/fe/42/f8dbc2b9ad59e927940325a22d6d3931d630c3644dae7e2369ef5d9ba230/zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26", size = 6824, upload-time = "2023-06-23T06:28:32.652Z" }, ] [[package]] @@ -3377,24 +3481,24 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/03/6b85c1df2dca1b9acca38b423d1e226d8ffdf30ebd78bcb398c511de8b54/zope.interface-6.1.tar.gz", hash = "sha256:2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309", size = 293914 } +sdist = { url = "https://files.pythonhosted.org/packages/87/03/6b85c1df2dca1b9acca38b423d1e226d8ffdf30ebd78bcb398c511de8b54/zope.interface-6.1.tar.gz", hash = "sha256:2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309", size = 293914, upload-time = "2023-10-05T11:24:38.943Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/ec/c1e7ce928dc10bfe02c6da7e964342d941aaf168f96f8084636167ea50d2/zope.interface-6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:43b576c34ef0c1f5a4981163b551a8781896f2a37f71b8655fd20b5af0386abb", size = 202417 }, - { url = "https://files.pythonhosted.org/packages/f7/0b/12f269ad049fc40a7a3ab85445d7855b6bc6f1e774c5ca9dd6f5c32becb3/zope.interface-6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67be3ca75012c6e9b109860820a8b6c9a84bfb036fbd1076246b98e56951ca92", size = 202528 }, - { url = "https://files.pythonhosted.org/packages/7f/85/3a35144509eb4a5a2208b48ae8d116a969d67de62cc6513d85602144d9cd/zope.interface-6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9bc671626281f6045ad61d93a60f52fd5e8209b1610972cf0ef1bbe6d808e3", size = 247532 }, - { url = "https://files.pythonhosted.org/packages/50/d6/6176aaa1f6588378f5a5a4a9c6ad50a36824e902b2f844ca8de7f1b0c4a7/zope.interface-6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe81def9cf3e46f16ce01d9bfd8bea595e06505e51b7baf45115c77352675fd", size = 241703 }, - { url = "https://files.pythonhosted.org/packages/4f/20/94d4f221989b4bbdd09004b2afb329958e776b7015b7ea8bc915327e195a/zope.interface-6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dc998f6de015723196a904045e5a2217f3590b62ea31990672e31fbc5370b41", size = 247078 }, - { url = "https://files.pythonhosted.org/packages/97/7e/b790b4ab9605010816a91df26a715f163e228d60eb36c947c3118fb65190/zope.interface-6.1-cp310-cp310-win_amd64.whl", hash = "sha256:239a4a08525c080ff833560171d23b249f7f4d17fcbf9316ef4159f44997616f", size = 204155 }, - { url = "https://files.pythonhosted.org/packages/4a/0b/1d8817b8a3631384a26ff7faa4c1f3e6726f7e4950c3442721cfef2c95eb/zope.interface-6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ffdaa5290422ac0f1688cb8adb1b94ca56cee3ad11f29f2ae301df8aecba7d1", size = 202441 }, - { url = "https://files.pythonhosted.org/packages/3e/1f/43557bb2b6e8537002a5a26af9b899171e26ddfcdf17a00ff729b00c036b/zope.interface-6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34c15ca9248f2e095ef2e93af2d633358c5f048c49fbfddf5fdfc47d5e263736", size = 202530 }, - { url = "https://files.pythonhosted.org/packages/37/a1/5d2b265f4b7371630cad5873d0873965e35ca3de993d11b9336c720f7259/zope.interface-6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b012d023b4fb59183909b45d7f97fb493ef7a46d2838a5e716e3155081894605", size = 249584 }, - { url = "https://files.pythonhosted.org/packages/8b/6d/547bfa7465e5b296adba0aff5c7ace1150f2a9e429fbf6c33d6618275162/zope.interface-6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97806e9ca3651588c1baaebb8d0c5ee3db95430b612db354c199b57378312ee8", size = 243737 }, - { url = "https://files.pythonhosted.org/packages/db/5f/46946b588c43eb28efe0e46f4cf455b1ed8b2d1ea62a21b0001c6610662f/zope.interface-6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fddbab55a2473f1d3b8833ec6b7ac31e8211b0aa608df5ab09ce07f3727326de", size = 249104 }, - { url = "https://files.pythonhosted.org/packages/6c/9c/9d3c0e7e5362ea59da3c42b3b2b9fc073db433a0fe3bc6cae0809ccec395/zope.interface-6.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0da79117952a9a41253696ed3e8b560a425197d4e41634a23b1507efe3273f1", size = 204155 }, - { url = "https://files.pythonhosted.org/packages/3c/91/68a0bbc97c2554f87d39572091954e94d043bcd83897cd6a779ca85cb5cc/zope.interface-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8bb9c990ca9027b4214fa543fd4025818dc95f8b7abce79d61dc8a2112b561a", size = 202757 }, - { url = "https://files.pythonhosted.org/packages/e1/84/850092a8ab7e87a3ea615daf3f822f7196c52592e3e92f264621b4cfe5a2/zope.interface-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b51b64432eed4c0744241e9ce5c70dcfecac866dff720e746d0a9c82f371dfa7", size = 202654 }, - { url = "https://files.pythonhosted.org/packages/57/23/508f7f79619ae4e025f5b264a9283efc3c805ed4c0ad75cb28c091179ced/zope.interface-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa6fd016e9644406d0a61313e50348c706e911dca29736a3266fc9e28ec4ca6d", size = 254400 }, - { url = "https://files.pythonhosted.org/packages/7c/0d/db0ccf0d12767015f23b302aebe98d5eca218aaadc70c2e3908b85fecd2a/zope.interface-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c8cf55261e15590065039696607f6c9c1aeda700ceee40c70478552d323b3ff", size = 248853 }, - { url = "https://files.pythonhosted.org/packages/fd/4f/8e80173ebcdefe0ff4164444c22b171cf8bd72533026befc2adf079f3ac8/zope.interface-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e30506bcb03de8983f78884807e4fd95d8db6e65b69257eea05d13d519b83ac0", size = 255127 }, - { url = "https://files.pythonhosted.org/packages/0f/d5/81f9789311d9773a02ed048af7452fc6cedce059748dba956c1dc040340a/zope.interface-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:e33e86fd65f369f10608b08729c8f1c92ec7e0e485964670b4d2633a4812d36b", size = 204268 }, + { url = "https://files.pythonhosted.org/packages/3c/ec/c1e7ce928dc10bfe02c6da7e964342d941aaf168f96f8084636167ea50d2/zope.interface-6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:43b576c34ef0c1f5a4981163b551a8781896f2a37f71b8655fd20b5af0386abb", size = 202417, upload-time = "2023-10-05T11:24:25.141Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0b/12f269ad049fc40a7a3ab85445d7855b6bc6f1e774c5ca9dd6f5c32becb3/zope.interface-6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67be3ca75012c6e9b109860820a8b6c9a84bfb036fbd1076246b98e56951ca92", size = 202528, upload-time = "2023-10-05T11:24:27.336Z" }, + { url = "https://files.pythonhosted.org/packages/7f/85/3a35144509eb4a5a2208b48ae8d116a969d67de62cc6513d85602144d9cd/zope.interface-6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9bc671626281f6045ad61d93a60f52fd5e8209b1610972cf0ef1bbe6d808e3", size = 247532, upload-time = "2023-10-05T11:49:20.587Z" }, + { url = "https://files.pythonhosted.org/packages/50/d6/6176aaa1f6588378f5a5a4a9c6ad50a36824e902b2f844ca8de7f1b0c4a7/zope.interface-6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe81def9cf3e46f16ce01d9bfd8bea595e06505e51b7baf45115c77352675fd", size = 241703, upload-time = "2023-10-05T11:25:33.542Z" }, + { url = "https://files.pythonhosted.org/packages/4f/20/94d4f221989b4bbdd09004b2afb329958e776b7015b7ea8bc915327e195a/zope.interface-6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dc998f6de015723196a904045e5a2217f3590b62ea31990672e31fbc5370b41", size = 247078, upload-time = "2023-10-05T11:25:48.235Z" }, + { url = "https://files.pythonhosted.org/packages/97/7e/b790b4ab9605010816a91df26a715f163e228d60eb36c947c3118fb65190/zope.interface-6.1-cp310-cp310-win_amd64.whl", hash = "sha256:239a4a08525c080ff833560171d23b249f7f4d17fcbf9316ef4159f44997616f", size = 204155, upload-time = "2023-10-05T11:37:56.715Z" }, + { url = "https://files.pythonhosted.org/packages/4a/0b/1d8817b8a3631384a26ff7faa4c1f3e6726f7e4950c3442721cfef2c95eb/zope.interface-6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ffdaa5290422ac0f1688cb8adb1b94ca56cee3ad11f29f2ae301df8aecba7d1", size = 202441, upload-time = "2023-10-05T11:24:20.414Z" }, + { url = "https://files.pythonhosted.org/packages/3e/1f/43557bb2b6e8537002a5a26af9b899171e26ddfcdf17a00ff729b00c036b/zope.interface-6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34c15ca9248f2e095ef2e93af2d633358c5f048c49fbfddf5fdfc47d5e263736", size = 202530, upload-time = "2023-10-05T11:24:22.975Z" }, + { url = "https://files.pythonhosted.org/packages/37/a1/5d2b265f4b7371630cad5873d0873965e35ca3de993d11b9336c720f7259/zope.interface-6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b012d023b4fb59183909b45d7f97fb493ef7a46d2838a5e716e3155081894605", size = 249584, upload-time = "2023-10-05T11:49:22.978Z" }, + { url = "https://files.pythonhosted.org/packages/8b/6d/547bfa7465e5b296adba0aff5c7ace1150f2a9e429fbf6c33d6618275162/zope.interface-6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97806e9ca3651588c1baaebb8d0c5ee3db95430b612db354c199b57378312ee8", size = 243737, upload-time = "2023-10-05T11:25:35.439Z" }, + { url = "https://files.pythonhosted.org/packages/db/5f/46946b588c43eb28efe0e46f4cf455b1ed8b2d1ea62a21b0001c6610662f/zope.interface-6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fddbab55a2473f1d3b8833ec6b7ac31e8211b0aa608df5ab09ce07f3727326de", size = 249104, upload-time = "2023-10-05T11:25:51.355Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9c/9d3c0e7e5362ea59da3c42b3b2b9fc073db433a0fe3bc6cae0809ccec395/zope.interface-6.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0da79117952a9a41253696ed3e8b560a425197d4e41634a23b1507efe3273f1", size = 204155, upload-time = "2023-10-05T11:39:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/3c/91/68a0bbc97c2554f87d39572091954e94d043bcd83897cd6a779ca85cb5cc/zope.interface-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8bb9c990ca9027b4214fa543fd4025818dc95f8b7abce79d61dc8a2112b561a", size = 202757, upload-time = "2023-10-05T11:25:05.865Z" }, + { url = "https://files.pythonhosted.org/packages/e1/84/850092a8ab7e87a3ea615daf3f822f7196c52592e3e92f264621b4cfe5a2/zope.interface-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b51b64432eed4c0744241e9ce5c70dcfecac866dff720e746d0a9c82f371dfa7", size = 202654, upload-time = "2023-10-05T11:25:08.347Z" }, + { url = "https://files.pythonhosted.org/packages/57/23/508f7f79619ae4e025f5b264a9283efc3c805ed4c0ad75cb28c091179ced/zope.interface-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa6fd016e9644406d0a61313e50348c706e911dca29736a3266fc9e28ec4ca6d", size = 254400, upload-time = "2023-10-05T11:49:25.326Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0d/db0ccf0d12767015f23b302aebe98d5eca218aaadc70c2e3908b85fecd2a/zope.interface-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c8cf55261e15590065039696607f6c9c1aeda700ceee40c70478552d323b3ff", size = 248853, upload-time = "2023-10-05T11:25:37.37Z" }, + { url = "https://files.pythonhosted.org/packages/fd/4f/8e80173ebcdefe0ff4164444c22b171cf8bd72533026befc2adf079f3ac8/zope.interface-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e30506bcb03de8983f78884807e4fd95d8db6e65b69257eea05d13d519b83ac0", size = 255127, upload-time = "2023-10-05T11:25:53.819Z" }, + { url = "https://files.pythonhosted.org/packages/0f/d5/81f9789311d9773a02ed048af7452fc6cedce059748dba956c1dc040340a/zope.interface-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:e33e86fd65f369f10608b08729c8f1c92ec7e0e485964670b4d2633a4812d36b", size = 204268, upload-time = "2023-10-05T11:41:22.778Z" }, ] diff --git a/mise.toml b/mise.toml index cf3b86c6cc..0b61f3c26a 100644 --- a/mise.toml +++ b/mise.toml @@ -1,11 +1,12 @@ experimental_monorepo_root = true [tools] -node = "24.11.0" +node = "24.11.1" flutter = "3.35.7" -pnpm = "10.20.0" -terragrunt = "0.91.2" -opentofu = "1.10.6" +pnpm = "10.24.0" +terragrunt = "0.93.10" +opentofu = "1.10.7" +java = "25.0.1" [tools."github:CQLabs/homebrew-dcm"] version = "1.30.0" diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt index e6cf92f573..d3282f4dfd 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt @@ -89,7 +89,10 @@ data class PlatformAsset ( val height: Long? = null, val durationInSeconds: Long, val orientation: Long, - val isFavorite: Boolean + val isFavorite: Boolean, + val adjustmentTime: Long? = null, + val latitude: Double? = null, + val longitude: Double? = null ) { companion object { @@ -104,7 +107,10 @@ data class PlatformAsset ( val durationInSeconds = pigeonVar_list[7] as Long val orientation = pigeonVar_list[8] as Long val isFavorite = pigeonVar_list[9] as Boolean - return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite) + val adjustmentTime = pigeonVar_list[10] as Long? + val latitude = pigeonVar_list[11] as Double? + val longitude = pigeonVar_list[12] as Double? + return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite, adjustmentTime, latitude, longitude) } } fun toList(): List { @@ -119,6 +125,9 @@ data class PlatformAsset ( durationInSeconds, orientation, isFavorite, + adjustmentTime, + latitude, + longitude, ) } override fun equals(other: Any?): Boolean { diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt index b1e9dd7d44..b374ef50f0 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt @@ -4,7 +4,6 @@ import android.annotation.SuppressLint import android.content.ContentUris import android.content.Context import android.database.Cursor -import android.net.Uri import android.os.Bundle import android.provider.MediaStore import android.util.Base64 diff --git a/mobile/android/fastlane/Fastfile b/mobile/android/fastlane/Fastfile index 6b9ce07465..b2e6c568c2 100644 --- a/mobile/android/fastlane/Fastfile +++ b/mobile/android/fastlane/Fastfile @@ -35,8 +35,8 @@ platform :android do task: 'bundle', build_type: 'Release', properties: { - "android.injected.version.code" => 3026, - "android.injected.version.name" => "2.2.3", + "android.injected.version.code" => 3028, + "android.injected.version.name" => "2.3.1", } ) upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab') diff --git a/mobile/drift_schemas/main/drift_schema_v14.json b/mobile/drift_schemas/main/drift_schema_v14.json new file mode 100644 index 0000000000..40a1af8423 --- /dev/null +++ b/mobile/drift_schemas/main/drift_schema_v14.json @@ -0,0 +1 @@ +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":true},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"user_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"email","getter_name":"email","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"has_profile_image","getter_name":"hasProfileImage","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"has_profile_image\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"has_profile_image\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"profile_changed_at","getter_name":"profileChangedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"avatar_color","getter_name":"avatarColor","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AvatarColor.values)","dart_type_name":"AvatarColor"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":1,"references":[0],"type":"table","data":{"name":"remote_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"local_date_time","getter_name":"localDateTime","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"thumb_hash","getter_name":"thumbHash","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"live_photo_video_id","getter_name":"livePhotoVideoId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"visibility","getter_name":"visibility","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetVisibility.values)","dart_type_name":"AssetVisibility"}},{"name":"stack_id","getter_name":"stackId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"library_id","getter_name":"libraryId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":2,"references":[0],"type":"table","data":{"name":"stack_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"primary_asset_id","getter_name":"primaryAssetId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":3,"references":[],"type":"table","data":{"name":"local_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"adjustment_time","getter_name":"adjustmentTime","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"latitude","getter_name":"latitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"longitude","getter_name":"longitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":4,"references":[0,1],"type":"table","data":{"name":"remote_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('\\'\\'')","default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"thumbnail_asset_id","getter_name":"thumbnailAssetId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"is_activity_enabled","getter_name":"isActivityEnabled","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_activity_enabled\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_activity_enabled\" IN (0, 1))"},"default_dart":"const CustomExpression('1')","default_client_dart":null,"dsl_features":[]},{"name":"order","getter_name":"order","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumAssetOrder.values)","dart_type_name":"AlbumAssetOrder"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":5,"references":[4],"type":"table","data":{"name":"local_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"backup_selection","getter_name":"backupSelection","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(BackupSelection.values)","dart_type_name":"BackupSelection"}},{"name":"is_ios_shared_album","getter_name":"isIosSharedAlbum","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_ios_shared_album\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_ios_shared_album\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"linked_remote_album_id","getter_name":"linkedRemoteAlbumId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"marker","getter_name":"marker_","moor_type":"bool","nullable":true,"customConstraints":null,"defaultConstraints":"CHECK (\"marker\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"marker\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":6,"references":[3,5],"type":"table","data":{"name":"local_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"marker","getter_name":"marker_","moor_type":"bool","nullable":true,"customConstraints":null,"defaultConstraints":"CHECK (\"marker\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"marker\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":7,"references":[3],"type":"index","data":{"on":3,"name":"idx_local_asset_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)","unique":false,"columns":[]}},{"id":8,"references":[1],"type":"index","data":{"on":1,"name":"idx_remote_asset_owner_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)","unique":false,"columns":[]}},{"id":9,"references":[1],"type":"index","data":{"on":1,"name":"UQ_remote_assets_owner_checksum","sql":"CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum\nON remote_asset_entity (owner_id, checksum)\nWHERE (library_id IS NULL);\n","unique":true,"columns":[]}},{"id":10,"references":[1],"type":"index","data":{"on":1,"name":"UQ_remote_assets_owner_library_checksum","sql":"CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum\nON remote_asset_entity (owner_id, library_id, checksum)\nWHERE (library_id IS NOT NULL);\n","unique":true,"columns":[]}},{"id":11,"references":[1],"type":"index","data":{"on":1,"name":"idx_remote_asset_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)","unique":false,"columns":[]}},{"id":12,"references":[],"type":"table","data":{"name":"auth_user_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"email","getter_name":"email","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_admin","getter_name":"isAdmin","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_admin\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_admin\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"has_profile_image","getter_name":"hasProfileImage","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"has_profile_image\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"has_profile_image\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"profile_changed_at","getter_name":"profileChangedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"avatar_color","getter_name":"avatarColor","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AvatarColor.values)","dart_type_name":"AvatarColor"}},{"name":"quota_size_in_bytes","getter_name":"quotaSizeInBytes","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"quota_usage_in_bytes","getter_name":"quotaUsageInBytes","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"pin_code","getter_name":"pinCode","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":13,"references":[0],"type":"table","data":{"name":"user_metadata_entity","was_declared_in_moor":false,"columns":[{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"key","getter_name":"key","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(UserMetadataKey.values)","dart_type_name":"UserMetadataKey"}},{"name":"value","getter_name":"value","moor_type":"blob","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"userMetadataConverter","dart_type_name":"Map"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["user_id","key"]}},{"id":14,"references":[0],"type":"table","data":{"name":"partner_entity","was_declared_in_moor":false,"columns":[{"name":"shared_by_id","getter_name":"sharedById","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"shared_with_id","getter_name":"sharedWithId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"in_timeline","getter_name":"inTimeline","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"in_timeline\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"in_timeline\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["shared_by_id","shared_with_id"]}},{"id":15,"references":[1],"type":"table","data":{"name":"remote_exif_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"city","getter_name":"city","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"state","getter_name":"state","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"country","getter_name":"country","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"date_time_original","getter_name":"dateTimeOriginal","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"exposure_time","getter_name":"exposureTime","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"f_number","getter_name":"fNumber","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"file_size","getter_name":"fileSize","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"focal_length","getter_name":"focalLength","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"latitude","getter_name":"latitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"longitude","getter_name":"longitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"iso","getter_name":"iso","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"make","getter_name":"make","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"model","getter_name":"model","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"lens","getter_name":"lens","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"time_zone","getter_name":"timeZone","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"rating","getter_name":"rating","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"projection_type","getter_name":"projectionType","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id"]}},{"id":16,"references":[1,4],"type":"table","data":{"name":"remote_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":17,"references":[4,0],"type":"table","data":{"name":"remote_album_user_entity","was_declared_in_moor":false,"columns":[{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"role","getter_name":"role","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumUserRole.values)","dart_type_name":"AlbumUserRole"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["album_id","user_id"]}},{"id":18,"references":[0],"type":"table","data":{"name":"memory_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(MemoryTypeEnum.values)","dart_type_name":"MemoryTypeEnum"}},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_saved","getter_name":"isSaved","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_saved\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_saved\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"memory_at","getter_name":"memoryAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"seen_at","getter_name":"seenAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"show_at","getter_name":"showAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"hide_at","getter_name":"hideAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":19,"references":[1,18],"type":"table","data":{"name":"memory_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"memory_id","getter_name":"memoryId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES memory_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES memory_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","memory_id"]}},{"id":20,"references":[0],"type":"table","data":{"name":"person_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"face_asset_id","getter_name":"faceAssetId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_hidden","getter_name":"isHidden","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_hidden\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_hidden\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"color","getter_name":"color","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"birth_date","getter_name":"birthDate","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":21,"references":[1,20],"type":"table","data":{"name":"asset_face_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"person_id","getter_name":"personId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES person_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES person_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"image_width","getter_name":"imageWidth","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"image_height","getter_name":"imageHeight","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_x1","getter_name":"boundingBoxX1","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_y1","getter_name":"boundingBoxY1","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_x2","getter_name":"boundingBoxX2","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_y2","getter_name":"boundingBoxY2","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"source_type","getter_name":"sourceType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":22,"references":[],"type":"table","data":{"name":"store_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"string_value","getter_name":"stringValue","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"int_value","getter_name":"intValue","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":23,"references":[],"type":"table","data":{"name":"trashed_local_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id","album_id"]}},{"id":24,"references":[15],"type":"index","data":{"on":15,"name":"idx_lat_lng","sql":"CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)","unique":false,"columns":[]}},{"id":25,"references":[23],"type":"index","data":{"on":23,"name":"idx_trashed_local_asset_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)","unique":false,"columns":[]}},{"id":26,"references":[23],"type":"index","data":{"on":23,"name":"idx_trashed_local_asset_album","sql":"CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)","unique":false,"columns":[]}}]} \ No newline at end of file diff --git a/mobile/ios/Runner/Sync/Messages.g.swift b/mobile/ios/Runner/Sync/Messages.g.swift index bbe18e7375..c1cc98014b 100644 --- a/mobile/ios/Runner/Sync/Messages.g.swift +++ b/mobile/ios/Runner/Sync/Messages.g.swift @@ -140,6 +140,9 @@ struct PlatformAsset: Hashable { var durationInSeconds: Int64 var orientation: Int64 var isFavorite: Bool + var adjustmentTime: Int64? = nil + var latitude: Double? = nil + var longitude: Double? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -154,6 +157,9 @@ struct PlatformAsset: Hashable { let durationInSeconds = pigeonVar_list[7] as! Int64 let orientation = pigeonVar_list[8] as! Int64 let isFavorite = pigeonVar_list[9] as! Bool + let adjustmentTime: Int64? = nilOrValue(pigeonVar_list[10]) + let latitude: Double? = nilOrValue(pigeonVar_list[11]) + let longitude: Double? = nilOrValue(pigeonVar_list[12]) return PlatformAsset( id: id, @@ -165,7 +171,10 @@ struct PlatformAsset: Hashable { height: height, durationInSeconds: durationInSeconds, orientation: orientation, - isFavorite: isFavorite + isFavorite: isFavorite, + adjustmentTime: adjustmentTime, + latitude: latitude, + longitude: longitude ) } func toList() -> [Any?] { @@ -180,6 +189,9 @@ struct PlatformAsset: Hashable { durationInSeconds, orientation, isFavorite, + adjustmentTime, + latitude, + longitude, ] } static func == (lhs: PlatformAsset, rhs: PlatformAsset) -> Bool { diff --git a/mobile/ios/Runner/Sync/PHAssetExtensions.swift b/mobile/ios/Runner/Sync/PHAssetExtensions.swift index 2b1ef6ac88..f555d75bd0 100644 --- a/mobile/ios/Runner/Sync/PHAssetExtensions.swift +++ b/mobile/ios/Runner/Sync/PHAssetExtensions.swift @@ -12,7 +12,10 @@ extension PHAsset { height: Int64(pixelHeight), durationInSeconds: Int64(duration), orientation: 0, - isFavorite: isFavorite + isFavorite: isFavorite, + adjustmentTime: adjustmentTimestamp, + latitude: location?.coordinate.latitude, + longitude: location?.coordinate.longitude ) } @@ -23,6 +26,13 @@ extension PHAsset { var filename: String? { return value(forKey: "filename") as? String } + + var adjustmentTimestamp: Int64? { + if let date = value(forKey: "adjustmentTimestamp") as? Date { + return Int64(date.timeIntervalSince1970) + } + return nil + } // This method is expected to be slow as it goes through the asset resources to fetch the originalFilename var originalFilename: String? { diff --git a/mobile/lib/constants/constants.dart b/mobile/lib/constants/constants.dart index 8d4636bbe1..cc408548d2 100644 --- a/mobile/lib/constants/constants.dart +++ b/mobile/lib/constants/constants.dart @@ -50,7 +50,7 @@ const double kUploadStatusCanceled = -2.0; const int kMinMonthsToEnableScrubberSnap = 12; -const String kImmichAppStoreLink = "https://apps.apple.com/app/immich/id6449244941"; +const String kImmichAppStoreLink = "https://apps.apple.com/app/immich/id1613945652"; const String kImmichPlayStoreLink = "https://play.google.com/store/apps/details?id=app.alextran.immich"; const String kImmichLatestRelease = "https://github.com/immich-app/immich/releases/latest"; diff --git a/mobile/lib/domain/models/asset/local_asset.model.dart b/mobile/lib/domain/models/asset/local_asset.model.dart index 6f2f4c06ba..ba64cc40b8 100644 --- a/mobile/lib/domain/models/asset/local_asset.model.dart +++ b/mobile/lib/domain/models/asset/local_asset.model.dart @@ -5,6 +5,10 @@ class LocalAsset extends BaseAsset { final String? remoteAssetId; final int orientation; + final DateTime? adjustmentTime; + final double? latitude; + final double? longitude; + const LocalAsset({ required this.id, String? remoteId, @@ -19,6 +23,9 @@ class LocalAsset extends BaseAsset { super.isFavorite = false, super.livePhotoVideoId, this.orientation = 0, + this.adjustmentTime, + this.latitude, + this.longitude, }) : remoteAssetId = remoteId; @override @@ -33,6 +40,8 @@ class LocalAsset extends BaseAsset { @override String get heroTag => '${id}_${remoteId ?? checksum}'; + bool get hasCoordinates => latitude != null && longitude != null && latitude != 0 && longitude != 0; + @override String toString() { return '''LocalAsset { @@ -47,6 +56,9 @@ class LocalAsset extends BaseAsset { remoteId: ${remoteId ?? ""} isFavorite: $isFavorite, orientation: $orientation, + adjustmentTime: $adjustmentTime, + latitude: ${latitude ?? ""}, + longitude: ${longitude ?? ""}, }'''; } @@ -55,11 +67,23 @@ class LocalAsset extends BaseAsset { bool operator ==(Object other) { if (other is! LocalAsset) return false; if (identical(this, other)) return true; - return super == other && id == other.id && orientation == other.orientation; + return super == other && + id == other.id && + orientation == other.orientation && + adjustmentTime == other.adjustmentTime && + latitude == other.latitude && + longitude == other.longitude; } @override - int get hashCode => super.hashCode ^ id.hashCode ^ remoteId.hashCode ^ orientation.hashCode; + int get hashCode => + super.hashCode ^ + id.hashCode ^ + remoteId.hashCode ^ + orientation.hashCode ^ + adjustmentTime.hashCode ^ + latitude.hashCode ^ + longitude.hashCode; LocalAsset copyWith({ String? id, @@ -74,6 +98,9 @@ class LocalAsset extends BaseAsset { int? durationInSeconds, bool? isFavorite, int? orientation, + DateTime? adjustmentTime, + double? latitude, + double? longitude, }) { return LocalAsset( id: id ?? this.id, @@ -88,6 +115,9 @@ class LocalAsset extends BaseAsset { durationInSeconds: durationInSeconds ?? this.durationInSeconds, isFavorite: isFavorite ?? this.isFavorite, orientation: orientation ?? this.orientation, + adjustmentTime: adjustmentTime ?? this.adjustmentTime, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, ); } } diff --git a/mobile/lib/domain/models/events.model.dart b/mobile/lib/domain/models/events.model.dart new file mode 100644 index 0000000000..b3ab756414 --- /dev/null +++ b/mobile/lib/domain/models/events.model.dart @@ -0,0 +1,32 @@ +import 'package:immich_mobile/domain/utils/event_stream.dart'; + +// Timeline Events +class TimelineReloadEvent extends Event { + const TimelineReloadEvent(); +} + +class ScrollToTopEvent extends Event { + const ScrollToTopEvent(); +} + +class ScrollToDateEvent extends Event { + final DateTime date; + + const ScrollToDateEvent(this.date); +} + +// Asset Viewer Events +class ViewerOpenBottomSheetEvent extends Event { + final bool activitiesMode; + const ViewerOpenBottomSheetEvent({this.activitiesMode = false}); +} + +class ViewerReloadAssetEvent extends Event { + const ViewerReloadAssetEvent(); +} + +// Multi-Select Events +class MultiSelectToggleEvent extends Event { + final bool isEnabled; + const MultiSelectToggleEvent(this.isEnabled); +} diff --git a/mobile/lib/domain/models/exif.model.dart b/mobile/lib/domain/models/exif.model.dart index 6e94c44650..46e2352ac8 100644 --- a/mobile/lib/domain/models/exif.model.dart +++ b/mobile/lib/domain/models/exif.model.dart @@ -3,8 +3,6 @@ class ExifInfo { final int? fileSize; final String? description; final bool isFlipped; - final double? width; - final double? height; final String? orientation; final String? timeZone; final DateTime? dateTimeOriginal; @@ -39,15 +37,13 @@ class ExifInfo { String get fNumber => f == null ? "" : f!.toStringAsFixed(1); - String get focalLength => mm == null ? "" : mm!.toStringAsFixed(1); + String get focalLength => mm == null ? "" : mm!.toStringAsFixed(3); const ExifInfo({ this.assetId, this.fileSize, this.description, this.orientation, - this.width, - this.height, this.timeZone, this.dateTimeOriginal, this.isFlipped = false, @@ -72,8 +68,6 @@ class ExifInfo { return other.fileSize == fileSize && other.description == description && other.isFlipped == isFlipped && - other.width == width && - other.height == height && other.orientation == orientation && other.timeZone == timeZone && other.dateTimeOriginal == dateTimeOriginal && @@ -98,8 +92,6 @@ class ExifInfo { description.hashCode ^ orientation.hashCode ^ isFlipped.hashCode ^ - width.hashCode ^ - height.hashCode ^ timeZone.hashCode ^ dateTimeOriginal.hashCode ^ latitude.hashCode ^ @@ -123,8 +115,6 @@ class ExifInfo { fileSize: ${fileSize ?? 'NA'}, description: ${description ?? 'NA'}, orientation: ${orientation ?? 'NA'}, -width: ${width ?? 'NA'}, -height: ${height ?? 'NA'}, isFlipped: $isFlipped, timeZone: ${timeZone ?? 'NA'}, dateTimeOriginal: ${dateTimeOriginal ?? 'NA'}, diff --git a/mobile/lib/domain/models/store.model.dart b/mobile/lib/domain/models/store.model.dart index 0650fc44f0..ae0112acb3 100644 --- a/mobile/lib/domain/models/store.model.dart +++ b/mobile/lib/domain/models/store.model.dart @@ -71,7 +71,8 @@ enum StoreKey { readonlyModeEnabled._(138), autoPlayVideo._(139), - viewerQuickActionOrder._(140), + albumGridView._(140), + viewerQuickActionOrder._(141), // Experimental stuff photoManagerCustomFilter._(1000), diff --git a/mobile/lib/domain/models/timeline.model.dart b/mobile/lib/domain/models/timeline.model.dart index d4cc5ab5c6..c531fa4a94 100644 --- a/mobile/lib/domain/models/timeline.model.dart +++ b/mobile/lib/domain/models/timeline.model.dart @@ -1,5 +1,3 @@ -import 'package:immich_mobile/domain/utils/event_stream.dart'; - enum GroupAssetsBy { day, month, auto, none } enum HeaderType { none, month, day, monthAndDay } @@ -31,17 +29,3 @@ class TimeBucket extends Bucket { @override int get hashCode => super.hashCode ^ date.hashCode; } - -class TimelineReloadEvent extends Event { - const TimelineReloadEvent(); -} - -class ScrollToTopEvent extends Event { - const ScrollToTopEvent(); -} - -class ScrollToDateEvent extends Event { - final DateTime date; - - const ScrollToDateEvent(this.date); -} diff --git a/mobile/lib/domain/services/asset.service.dart b/mobile/lib/domain/services/asset.service.dart index 7f8ade313c..3d8fddc9b7 100644 --- a/mobile/lib/domain/services/asset.service.dart +++ b/mobile/lib/domain/services/asset.service.dart @@ -65,8 +65,8 @@ class AssetService { if (asset.hasRemote) { final exif = await getExif(asset); isFlipped = ExifDtoConverter.isOrientationFlipped(exif?.orientation); - width = exif?.width ?? asset.width?.toDouble(); - height = exif?.height ?? asset.height?.toDouble(); + width = asset.width?.toDouble(); + height = asset.height?.toDouble(); } else if (asset is LocalAsset) { isFlipped = CurrentPlatform.isAndroid && (asset.orientation == 90 || asset.orientation == 270); width = asset.width?.toDouble(); @@ -75,6 +75,20 @@ class AssetService { isFlipped = false; } + if (width == null || height == null) { + if (asset.hasRemote) { + final id = asset is LocalAsset ? asset.remoteId! : (asset as RemoteAsset).id; + final remoteAsset = await _remoteAssetRepository.get(id); + width = remoteAsset?.width?.toDouble(); + height = remoteAsset?.height?.toDouble(); + } else { + final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!; + final localAsset = await _localAssetRepository.get(id); + width = localAsset?.width?.toDouble(); + height = localAsset?.height?.toDouble(); + } + } + final orientedWidth = isFlipped ? height : width; final orientedHeight = isFlipped ? width : height; if (orientedWidth != null && orientedHeight != null && orientedHeight > 0) { diff --git a/mobile/lib/domain/services/background_worker.service.dart b/mobile/lib/domain/services/background_worker.service.dart index 28c87293f9..8a237f801a 100644 --- a/mobile/lib/domain/services/background_worker.service.dart +++ b/mobile/lib/domain/services/background_worker.service.dart @@ -177,6 +177,12 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { } Future _cleanup() async { + await runZonedGuarded(_handleCleanup, (error, stack) { + dPrint(() => "Error during background worker cleanup: $error, $stack"); + }); + } + + Future _handleCleanup() async { // If ref is null, it means the service was never initialized properly if (_isCleanedUp || _ref == null) { return; @@ -186,11 +192,16 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { _isCleanedUp = true; final backgroundSyncManager = _ref?.read(backgroundSyncProvider); final nativeSyncApi = _ref?.read(nativeSyncApiProvider); + + await _drift.close(); + await _driftLogger.close(); + _ref?.dispose(); _ref = null; _cancellationToken.cancel(); _logger.info("Cleaning up background worker"); + final cleanupFutures = [ nativeSyncApi?.cancelHashing(), workerManagerPatch.dispose().catchError((_) async { @@ -199,8 +210,7 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { }), LogService.I.dispose(), Store.dispose(), - _drift.close(), - _driftLogger.close(), + backgroundSyncManager?.cancel(), ]; diff --git a/mobile/lib/domain/services/local_sync.service.dart b/mobile/lib/domain/services/local_sync.service.dart index 5cbae9c5a1..c49ac49cce 100644 --- a/mobile/lib/domain/services/local_sync.service.dart +++ b/mobile/lib/domain/services/local_sync.service.dart @@ -286,11 +286,23 @@ class LocalSyncService { } bool _assetsEqual(LocalAsset a, LocalAsset b) { - return a.updatedAt.isAtSameMomentAs(b.updatedAt) && + if (CurrentPlatform.isAndroid) { + return a.updatedAt.isAtSameMomentAs(b.updatedAt) && + a.createdAt.isAtSameMomentAs(b.createdAt) && + a.width == b.width && + a.height == b.height && + a.durationInSeconds == b.durationInSeconds; + } + + final firstAdjustment = a.adjustmentTime?.millisecondsSinceEpoch ?? 0; + final secondAdjustment = b.adjustmentTime?.millisecondsSinceEpoch ?? 0; + return firstAdjustment == secondAdjustment && a.createdAt.isAtSameMomentAs(b.createdAt) && a.width == b.width && a.height == b.height && - a.durationInSeconds == b.durationInSeconds; + a.durationInSeconds == b.durationInSeconds && + a.latitude == b.latitude && + a.longitude == b.longitude; } bool _albumsEqual(LocalAlbum a, LocalAlbum b) { @@ -363,18 +375,21 @@ extension on Iterable { } } -extension on PlatformAsset { +extension PlatformToLocalAsset on PlatformAsset { LocalAsset toLocalAsset() => LocalAsset( id: id, name: name, checksum: null, type: AssetType.values.elementAtOrNull(type) ?? AssetType.other, createdAt: tryFromSecondsSinceEpoch(createdAt, isUtc: true) ?? DateTime.timestamp(), - updatedAt: tryFromSecondsSinceEpoch(createdAt, isUtc: true) ?? DateTime.timestamp(), + updatedAt: tryFromSecondsSinceEpoch(updatedAt, isUtc: true) ?? DateTime.timestamp(), width: width, height: height, durationInSeconds: durationInSeconds, isFavorite: isFavorite, orientation: orientation, + adjustmentTime: tryFromSecondsSinceEpoch(adjustmentTime, isUtc: true), + latitude: latitude, + longitude: longitude, ); } diff --git a/mobile/lib/domain/services/remote_album.service.dart b/mobile/lib/domain/services/remote_album.service.dart index 67e91188e2..68c72255b0 100644 --- a/mobile/lib/domain/services/remote_album.service.dart +++ b/mobile/lib/domain/services/remote_album.service.dart @@ -7,6 +7,7 @@ import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/repositories/drift_album_api_repository.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; class RemoteAlbumService { final DriftRemoteAlbumRepository _repository; @@ -32,16 +33,16 @@ class RemoteAlbumService { Future> sortAlbums( List albums, - RemoteAlbumSortMode sortMode, { + AlbumSortMode sortMode, { bool isReverse = false, }) async { final List sorted = switch (sortMode) { - RemoteAlbumSortMode.created => albums.sortedBy((album) => album.createdAt), - RemoteAlbumSortMode.title => albums.sortedBy((album) => album.name), - RemoteAlbumSortMode.lastModified => albums.sortedBy((album) => album.updatedAt), - RemoteAlbumSortMode.assetCount => albums.sortedBy((album) => album.assetCount), - RemoteAlbumSortMode.mostRecent => await _sortByNewestAsset(albums), - RemoteAlbumSortMode.mostOldest => await _sortByOldestAsset(albums), + AlbumSortMode.created => albums.sortedBy((album) => album.createdAt), + AlbumSortMode.title => albums.sortedBy((album) => album.name), + AlbumSortMode.lastModified => albums.sortedBy((album) => album.updatedAt), + AlbumSortMode.assetCount => albums.sortedBy((album) => album.assetCount), + AlbumSortMode.mostRecent => await _sortByNewestAsset(albums), + AlbumSortMode.mostOldest => await _sortByOldestAsset(albums), }; return (isReverse ? sorted.reversed : sorted).toList(); @@ -211,16 +212,3 @@ class RemoteAlbumService { return sorted.reversed.toList(); } } - -enum RemoteAlbumSortMode { - title("library_page_sort_title"), - assetCount("library_page_sort_asset_count"), - lastModified("library_page_sort_last_modified"), - created("library_page_sort_created"), - mostRecent("sort_newest"), - mostOldest("sort_oldest"); - - final String key; - - const RemoteAlbumSortMode(this.key); -} diff --git a/mobile/lib/domain/services/timeline.service.dart b/mobile/lib/domain/services/timeline.service.dart index 9537fe667a..96630f1eba 100644 --- a/mobile/lib/domain/services/timeline.service.dart +++ b/mobile/lib/domain/services/timeline.service.dart @@ -4,6 +4,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/setting.model.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/services/setting.service.dart'; diff --git a/mobile/lib/extensions/asset_extensions.dart b/mobile/lib/extensions/asset_extensions.dart index 22d5d5030a..a8ca7ef2aa 100644 --- a/mobile/lib/extensions/asset_extensions.dart +++ b/mobile/lib/extensions/asset_extensions.dart @@ -1,5 +1,5 @@ import 'package:immich_mobile/entities/asset.entity.dart'; -import 'package:timezone/timezone.dart'; +import 'package:immich_mobile/utils/timezone.dart'; extension TZExtension on Asset { /// Returns the created time of the asset from the exif info (if available) or from @@ -7,24 +7,11 @@ extension TZExtension on Asset { /// the timezone offset in [Duration] (DateTime, Duration) getTZAdjustedTimeAndOffset() { DateTime dt = fileCreatedAt.toLocal(); + if (exifInfo?.dateTimeOriginal != null) { - dt = exifInfo!.dateTimeOriginal!; - if (exifInfo?.timeZone != null) { - dt = dt.toUtc(); - try { - final location = getLocation(exifInfo!.timeZone!); - dt = TZDateTime.from(dt, location); - } on LocationNotFoundException { - RegExp re = RegExp(r'^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$', caseSensitive: false); - final m = re.firstMatch(exifInfo!.timeZone!); - if (m != null) { - final duration = Duration(hours: int.parse(m.group(1) ?? '0'), minutes: int.parse(m.group(2) ?? '0')); - dt = dt.add(duration); - return (dt, duration); - } - } - } + return applyTimezoneOffset(dateTime: exifInfo!.dateTimeOriginal!, timeZone: exifInfo?.timeZone); } + return (dt, dt.timeZoneOffset); } } diff --git a/mobile/lib/infrastructure/entities/exif.entity.dart b/mobile/lib/infrastructure/entities/exif.entity.dart index 9c7f9e9975..2dbe05b9d7 100644 --- a/mobile/lib/infrastructure/entities/exif.entity.dart +++ b/mobile/lib/infrastructure/entities/exif.entity.dart @@ -165,8 +165,7 @@ extension RemoteExifEntityDataDomainEx on RemoteExifEntityData { f: fNumber?.toDouble(), mm: focalLength?.toDouble(), lens: lens, - width: width?.toDouble(), - height: height?.toDouble(), isFlipped: ExifDtoConverter.isOrientationFlipped(orientation), + exposureSeconds: ExifDtoConverter.exposureTimeToSeconds(exposureTime), ); } diff --git a/mobile/lib/infrastructure/entities/local_asset.entity.dart b/mobile/lib/infrastructure/entities/local_asset.entity.dart index 8b253f83a3..d2455b744e 100644 --- a/mobile/lib/infrastructure/entities/local_asset.entity.dart +++ b/mobile/lib/infrastructure/entities/local_asset.entity.dart @@ -16,6 +16,12 @@ class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin { IntColumn get orientation => integer().withDefault(const Constant(0))(); + DateTimeColumn get adjustmentTime => dateTime().nullable()(); + + RealColumn get latitude => real().nullable()(); + + RealColumn get longitude => real().nullable()(); + @override Set get primaryKey => {id}; } @@ -34,5 +40,8 @@ extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData { width: width, remoteId: remoteId, orientation: orientation, + adjustmentTime: adjustmentTime, + latitude: latitude, + longitude: longitude, ); } diff --git a/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart b/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart index d0fe742463..22219b1e6e 100644 --- a/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart +++ b/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart @@ -21,6 +21,9 @@ typedef $$LocalAssetEntityTableCreateCompanionBuilder = i0.Value checksum, i0.Value isFavorite, i0.Value orientation, + i0.Value adjustmentTime, + i0.Value latitude, + i0.Value longitude, }); typedef $$LocalAssetEntityTableUpdateCompanionBuilder = i1.LocalAssetEntityCompanion Function({ @@ -35,6 +38,9 @@ typedef $$LocalAssetEntityTableUpdateCompanionBuilder = i0.Value checksum, i0.Value isFavorite, i0.Value orientation, + i0.Value adjustmentTime, + i0.Value latitude, + i0.Value longitude, }); class $$LocalAssetEntityTableFilterComposer @@ -101,6 +107,21 @@ class $$LocalAssetEntityTableFilterComposer column: $table.orientation, builder: (column) => i0.ColumnFilters(column), ); + + i0.ColumnFilters get adjustmentTime => $composableBuilder( + column: $table.adjustmentTime, + builder: (column) => i0.ColumnFilters(column), + ); + + i0.ColumnFilters get latitude => $composableBuilder( + column: $table.latitude, + builder: (column) => i0.ColumnFilters(column), + ); + + i0.ColumnFilters get longitude => $composableBuilder( + column: $table.longitude, + builder: (column) => i0.ColumnFilters(column), + ); } class $$LocalAssetEntityTableOrderingComposer @@ -166,6 +187,21 @@ class $$LocalAssetEntityTableOrderingComposer column: $table.orientation, builder: (column) => i0.ColumnOrderings(column), ); + + i0.ColumnOrderings get adjustmentTime => $composableBuilder( + column: $table.adjustmentTime, + builder: (column) => i0.ColumnOrderings(column), + ); + + i0.ColumnOrderings get latitude => $composableBuilder( + column: $table.latitude, + builder: (column) => i0.ColumnOrderings(column), + ); + + i0.ColumnOrderings get longitude => $composableBuilder( + column: $table.longitude, + builder: (column) => i0.ColumnOrderings(column), + ); } class $$LocalAssetEntityTableAnnotationComposer @@ -215,6 +251,17 @@ class $$LocalAssetEntityTableAnnotationComposer column: $table.orientation, builder: (column) => column, ); + + i0.GeneratedColumn get adjustmentTime => $composableBuilder( + column: $table.adjustmentTime, + builder: (column) => column, + ); + + i0.GeneratedColumn get latitude => + $composableBuilder(column: $table.latitude, builder: (column) => column); + + i0.GeneratedColumn get longitude => + $composableBuilder(column: $table.longitude, builder: (column) => column); } class $$LocalAssetEntityTableTableManager @@ -268,6 +315,9 @@ class $$LocalAssetEntityTableTableManager i0.Value checksum = const i0.Value.absent(), i0.Value isFavorite = const i0.Value.absent(), i0.Value orientation = const i0.Value.absent(), + i0.Value adjustmentTime = const i0.Value.absent(), + i0.Value latitude = const i0.Value.absent(), + i0.Value longitude = const i0.Value.absent(), }) => i1.LocalAssetEntityCompanion( name: name, type: type, @@ -280,6 +330,9 @@ class $$LocalAssetEntityTableTableManager checksum: checksum, isFavorite: isFavorite, orientation: orientation, + adjustmentTime: adjustmentTime, + latitude: latitude, + longitude: longitude, ), createCompanionCallback: ({ @@ -294,6 +347,9 @@ class $$LocalAssetEntityTableTableManager i0.Value checksum = const i0.Value.absent(), i0.Value isFavorite = const i0.Value.absent(), i0.Value orientation = const i0.Value.absent(), + i0.Value adjustmentTime = const i0.Value.absent(), + i0.Value latitude = const i0.Value.absent(), + i0.Value longitude = const i0.Value.absent(), }) => i1.LocalAssetEntityCompanion.insert( name: name, type: type, @@ -306,6 +362,9 @@ class $$LocalAssetEntityTableTableManager checksum: checksum, isFavorite: isFavorite, orientation: orientation, + adjustmentTime: adjustmentTime, + latitude: latitude, + longitude: longitude, ), withReferenceMapper: (p0) => p0 .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) @@ -473,6 +532,39 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity requiredDuringInsert: false, defaultValue: const i4.Constant(0), ); + static const i0.VerificationMeta _adjustmentTimeMeta = + const i0.VerificationMeta('adjustmentTime'); + @override + late final i0.GeneratedColumn adjustmentTime = + i0.GeneratedColumn( + 'adjustment_time', + aliasedName, + true, + type: i0.DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + static const i0.VerificationMeta _latitudeMeta = const i0.VerificationMeta( + 'latitude', + ); + @override + late final i0.GeneratedColumn latitude = i0.GeneratedColumn( + 'latitude', + aliasedName, + true, + type: i0.DriftSqlType.double, + requiredDuringInsert: false, + ); + static const i0.VerificationMeta _longitudeMeta = const i0.VerificationMeta( + 'longitude', + ); + @override + late final i0.GeneratedColumn longitude = i0.GeneratedColumn( + 'longitude', + aliasedName, + true, + type: i0.DriftSqlType.double, + requiredDuringInsert: false, + ); @override List get $columns => [ name, @@ -486,6 +578,9 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity checksum, isFavorite, orientation, + adjustmentTime, + latitude, + longitude, ]; @override String get aliasedName => _alias ?? actualTableName; @@ -566,6 +661,27 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity ), ); } + if (data.containsKey('adjustment_time')) { + context.handle( + _adjustmentTimeMeta, + adjustmentTime.isAcceptableOrUnknown( + data['adjustment_time']!, + _adjustmentTimeMeta, + ), + ); + } + if (data.containsKey('latitude')) { + context.handle( + _latitudeMeta, + latitude.isAcceptableOrUnknown(data['latitude']!, _latitudeMeta), + ); + } + if (data.containsKey('longitude')) { + context.handle( + _longitudeMeta, + longitude.isAcceptableOrUnknown(data['longitude']!, _longitudeMeta), + ); + } return context; } @@ -624,6 +740,18 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity i0.DriftSqlType.int, data['${effectivePrefix}orientation'], )!, + adjustmentTime: attachedDatabase.typeMapping.read( + i0.DriftSqlType.dateTime, + data['${effectivePrefix}adjustment_time'], + ), + latitude: attachedDatabase.typeMapping.read( + i0.DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + i0.DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), ); } @@ -653,6 +781,9 @@ class LocalAssetEntityData extends i0.DataClass final String? checksum; final bool isFavorite; final int orientation; + final DateTime? adjustmentTime; + final double? latitude; + final double? longitude; const LocalAssetEntityData({ required this.name, required this.type, @@ -665,6 +796,9 @@ class LocalAssetEntityData extends i0.DataClass this.checksum, required this.isFavorite, required this.orientation, + this.adjustmentTime, + this.latitude, + this.longitude, }); @override Map toColumns(bool nullToAbsent) { @@ -692,6 +826,15 @@ class LocalAssetEntityData extends i0.DataClass } map['is_favorite'] = i0.Variable(isFavorite); map['orientation'] = i0.Variable(orientation); + if (!nullToAbsent || adjustmentTime != null) { + map['adjustment_time'] = i0.Variable(adjustmentTime); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = i0.Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = i0.Variable(longitude); + } return map; } @@ -714,6 +857,9 @@ class LocalAssetEntityData extends i0.DataClass checksum: serializer.fromJson(json['checksum']), isFavorite: serializer.fromJson(json['isFavorite']), orientation: serializer.fromJson(json['orientation']), + adjustmentTime: serializer.fromJson(json['adjustmentTime']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), ); } @override @@ -733,6 +879,9 @@ class LocalAssetEntityData extends i0.DataClass 'checksum': serializer.toJson(checksum), 'isFavorite': serializer.toJson(isFavorite), 'orientation': serializer.toJson(orientation), + 'adjustmentTime': serializer.toJson(adjustmentTime), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), }; } @@ -748,6 +897,9 @@ class LocalAssetEntityData extends i0.DataClass i0.Value checksum = const i0.Value.absent(), bool? isFavorite, int? orientation, + i0.Value adjustmentTime = const i0.Value.absent(), + i0.Value latitude = const i0.Value.absent(), + i0.Value longitude = const i0.Value.absent(), }) => i1.LocalAssetEntityData( name: name ?? this.name, type: type ?? this.type, @@ -762,6 +914,11 @@ class LocalAssetEntityData extends i0.DataClass checksum: checksum.present ? checksum.value : this.checksum, isFavorite: isFavorite ?? this.isFavorite, orientation: orientation ?? this.orientation, + adjustmentTime: adjustmentTime.present + ? adjustmentTime.value + : this.adjustmentTime, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, ); LocalAssetEntityData copyWithCompanion(i1.LocalAssetEntityCompanion data) { return LocalAssetEntityData( @@ -782,6 +939,11 @@ class LocalAssetEntityData extends i0.DataClass orientation: data.orientation.present ? data.orientation.value : this.orientation, + adjustmentTime: data.adjustmentTime.present + ? data.adjustmentTime.value + : this.adjustmentTime, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, ); } @@ -798,7 +960,10 @@ class LocalAssetEntityData extends i0.DataClass ..write('id: $id, ') ..write('checksum: $checksum, ') ..write('isFavorite: $isFavorite, ') - ..write('orientation: $orientation') + ..write('orientation: $orientation, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') ..write(')')) .toString(); } @@ -816,6 +981,9 @@ class LocalAssetEntityData extends i0.DataClass checksum, isFavorite, orientation, + adjustmentTime, + latitude, + longitude, ); @override bool operator ==(Object other) => @@ -831,7 +999,10 @@ class LocalAssetEntityData extends i0.DataClass other.id == this.id && other.checksum == this.checksum && other.isFavorite == this.isFavorite && - other.orientation == this.orientation); + other.orientation == this.orientation && + other.adjustmentTime == this.adjustmentTime && + other.latitude == this.latitude && + other.longitude == this.longitude); } class LocalAssetEntityCompanion @@ -847,6 +1018,9 @@ class LocalAssetEntityCompanion final i0.Value checksum; final i0.Value isFavorite; final i0.Value orientation; + final i0.Value adjustmentTime; + final i0.Value latitude; + final i0.Value longitude; const LocalAssetEntityCompanion({ this.name = const i0.Value.absent(), this.type = const i0.Value.absent(), @@ -859,6 +1033,9 @@ class LocalAssetEntityCompanion this.checksum = const i0.Value.absent(), this.isFavorite = const i0.Value.absent(), this.orientation = const i0.Value.absent(), + this.adjustmentTime = const i0.Value.absent(), + this.latitude = const i0.Value.absent(), + this.longitude = const i0.Value.absent(), }); LocalAssetEntityCompanion.insert({ required String name, @@ -872,6 +1049,9 @@ class LocalAssetEntityCompanion this.checksum = const i0.Value.absent(), this.isFavorite = const i0.Value.absent(), this.orientation = const i0.Value.absent(), + this.adjustmentTime = const i0.Value.absent(), + this.latitude = const i0.Value.absent(), + this.longitude = const i0.Value.absent(), }) : name = i0.Value(name), type = i0.Value(type), id = i0.Value(id); @@ -887,6 +1067,9 @@ class LocalAssetEntityCompanion i0.Expression? checksum, i0.Expression? isFavorite, i0.Expression? orientation, + i0.Expression? adjustmentTime, + i0.Expression? latitude, + i0.Expression? longitude, }) { return i0.RawValuesInsertable({ if (name != null) 'name': name, @@ -900,6 +1083,9 @@ class LocalAssetEntityCompanion if (checksum != null) 'checksum': checksum, if (isFavorite != null) 'is_favorite': isFavorite, if (orientation != null) 'orientation': orientation, + if (adjustmentTime != null) 'adjustment_time': adjustmentTime, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, }); } @@ -915,6 +1101,9 @@ class LocalAssetEntityCompanion i0.Value? checksum, i0.Value? isFavorite, i0.Value? orientation, + i0.Value? adjustmentTime, + i0.Value? latitude, + i0.Value? longitude, }) { return i1.LocalAssetEntityCompanion( name: name ?? this.name, @@ -928,6 +1117,9 @@ class LocalAssetEntityCompanion checksum: checksum ?? this.checksum, isFavorite: isFavorite ?? this.isFavorite, orientation: orientation ?? this.orientation, + adjustmentTime: adjustmentTime ?? this.adjustmentTime, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, ); } @@ -969,6 +1161,15 @@ class LocalAssetEntityCompanion if (orientation.present) { map['orientation'] = i0.Variable(orientation.value); } + if (adjustmentTime.present) { + map['adjustment_time'] = i0.Variable(adjustmentTime.value); + } + if (latitude.present) { + map['latitude'] = i0.Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = i0.Variable(longitude.value); + } return map; } @@ -985,7 +1186,10 @@ class LocalAssetEntityCompanion ..write('id: $id, ') ..write('checksum: $checksum, ') ..write('isFavorite: $isFavorite, ') - ..write('orientation: $orientation') + ..write('orientation: $orientation, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') ..write(')')) .toString(); } diff --git a/mobile/lib/infrastructure/repositories/db.repository.dart b/mobile/lib/infrastructure/repositories/db.repository.dart index 548aa2e384..b42aa31550 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.dart @@ -10,7 +10,6 @@ import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'; import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart'; import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart'; -import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/memory.entity.dart'; import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/partner.entity.dart'; @@ -21,6 +20,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.d import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/stack.entity.dart'; import 'package:immich_mobile/infrastructure/entities/store.entity.dart'; +import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.steps.dart'; @@ -95,7 +95,7 @@ class Drift extends $Drift implements IDatabaseRepository { } @override - int get schemaVersion => 13; + int get schemaVersion => 14; @override MigrationStrategy get migration => MigrationStrategy( @@ -185,6 +185,11 @@ class Drift extends $Drift implements IDatabaseRepository { await m.createIndex(v13.idxTrashedLocalAssetChecksum); await m.createIndex(v13.idxTrashedLocalAssetAlbum); }, + from13To14: (m, v14) async { + await m.addColumn(v14.localAssetEntity, v14.localAssetEntity.adjustmentTime); + await m.addColumn(v14.localAssetEntity, v14.localAssetEntity.latitude); + await m.addColumn(v14.localAssetEntity, v14.localAssetEntity.longitude); + }, ), ); diff --git a/mobile/lib/infrastructure/repositories/db.repository.steps.dart b/mobile/lib/infrastructure/repositories/db.repository.steps.dart index f2d87a7f83..21a3db5274 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.steps.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.steps.dart @@ -5485,6 +5485,462 @@ i1.GeneratedColumn _column_95(String aliasedName) => false, type: i1.DriftSqlType.string, ); + +final class Schema14 extends i0.VersionedSchema { + Schema14({required super.database}) : super(version: 14); + @override + late final List entities = [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAssetChecksum, + idxRemoteAssetOwnerChecksum, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + trashedLocalAssetEntity, + idxLatLng, + idxTrashedLocalAssetChecksum, + idxTrashedLocalAssetAlbum, + ]; + late final Shape20 userEntity = Shape20( + source: i0.VersionedTable( + entityName: 'user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_3, + _column_84, + _column_85, + _column_91, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape17 remoteAssetEntity = Shape17( + source: i0.VersionedTable( + entityName: 'remote_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_1, + _column_8, + _column_9, + _column_5, + _column_10, + _column_11, + _column_12, + _column_0, + _column_13, + _column_14, + _column_15, + _column_16, + _column_17, + _column_18, + _column_19, + _column_20, + _column_21, + _column_86, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape3 stackEntity = Shape3( + source: i0.VersionedTable( + entityName: 'stack_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [_column_0, _column_9, _column_5, _column_15, _column_75], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape24 localAssetEntity = Shape24( + source: i0.VersionedTable( + entityName: 'local_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_1, + _column_8, + _column_9, + _column_5, + _column_10, + _column_11, + _column_12, + _column_0, + _column_22, + _column_14, + _column_23, + _column_96, + _column_46, + _column_47, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape9 remoteAlbumEntity = Shape9( + source: i0.VersionedTable( + entityName: 'remote_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_56, + _column_9, + _column_5, + _column_15, + _column_57, + _column_58, + _column_59, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape19 localAlbumEntity = Shape19( + source: i0.VersionedTable( + entityName: 'local_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_5, + _column_31, + _column_32, + _column_90, + _column_33, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape22 localAlbumAssetEntity = Shape22( + source: i0.VersionedTable( + entityName: 'local_album_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, album_id)'], + columns: [_column_34, _column_35, _column_33], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxLocalAssetChecksum = i1.Index( + 'idx_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)', + ); + final i1.Index idxRemoteAssetOwnerChecksum = i1.Index( + 'idx_remote_asset_owner_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)', + ); + final i1.Index uQRemoteAssetsOwnerChecksum = i1.Index( + 'UQ_remote_assets_owner_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)', + ); + final i1.Index uQRemoteAssetsOwnerLibraryChecksum = i1.Index( + 'UQ_remote_assets_owner_library_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)', + ); + final i1.Index idxRemoteAssetChecksum = i1.Index( + 'idx_remote_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)', + ); + late final Shape21 authUserEntity = Shape21( + source: i0.VersionedTable( + entityName: 'auth_user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_3, + _column_2, + _column_84, + _column_85, + _column_92, + _column_93, + _column_7, + _column_94, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape4 userMetadataEntity = Shape4( + source: i0.VersionedTable( + entityName: 'user_metadata_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(user_id, "key")'], + columns: [_column_25, _column_26, _column_27], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape5 partnerEntity = Shape5( + source: i0.VersionedTable( + entityName: 'partner_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'], + columns: [_column_28, _column_29, _column_30], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape8 remoteExifEntity = Shape8( + source: i0.VersionedTable( + entityName: 'remote_exif_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id)'], + columns: [ + _column_36, + _column_37, + _column_38, + _column_39, + _column_40, + _column_41, + _column_11, + _column_10, + _column_42, + _column_43, + _column_44, + _column_45, + _column_46, + _column_47, + _column_48, + _column_49, + _column_50, + _column_51, + _column_52, + _column_53, + _column_54, + _column_55, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape7 remoteAlbumAssetEntity = Shape7( + source: i0.VersionedTable( + entityName: 'remote_album_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, album_id)'], + columns: [_column_36, _column_60], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape10 remoteAlbumUserEntity = Shape10( + source: i0.VersionedTable( + entityName: 'remote_album_user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(album_id, user_id)'], + columns: [_column_60, _column_25, _column_61], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape11 memoryEntity = Shape11( + source: i0.VersionedTable( + entityName: 'memory_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_9, + _column_5, + _column_18, + _column_15, + _column_8, + _column_62, + _column_63, + _column_64, + _column_65, + _column_66, + _column_67, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape12 memoryAssetEntity = Shape12( + source: i0.VersionedTable( + entityName: 'memory_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, memory_id)'], + columns: [_column_36, _column_68], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape14 personEntity = Shape14( + source: i0.VersionedTable( + entityName: 'person_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_9, + _column_5, + _column_15, + _column_1, + _column_69, + _column_71, + _column_72, + _column_73, + _column_74, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape15 assetFaceEntity = Shape15( + source: i0.VersionedTable( + entityName: 'asset_face_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_36, + _column_76, + _column_77, + _column_78, + _column_79, + _column_80, + _column_81, + _column_82, + _column_83, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape18 storeEntity = Shape18( + source: i0.VersionedTable( + entityName: 'store_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [_column_87, _column_88, _column_89], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape23 trashedLocalAssetEntity = Shape23( + source: i0.VersionedTable( + entityName: 'trashed_local_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id, album_id)'], + columns: [ + _column_1, + _column_8, + _column_9, + _column_5, + _column_10, + _column_11, + _column_12, + _column_0, + _column_95, + _column_22, + _column_14, + _column_23, + ], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxLatLng = i1.Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); + final i1.Index idxTrashedLocalAssetChecksum = i1.Index( + 'idx_trashed_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)', + ); + final i1.Index idxTrashedLocalAssetAlbum = i1.Index( + 'idx_trashed_local_asset_album', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)', + ); +} + +class Shape24 extends i0.VersionedTable { + Shape24({required super.source, required super.alias}) : super.aliased(); + i1.GeneratedColumn get name => + columnsByName['name']! as i1.GeneratedColumn; + i1.GeneratedColumn get type => + columnsByName['type']! as i1.GeneratedColumn; + i1.GeneratedColumn get createdAt => + columnsByName['created_at']! as i1.GeneratedColumn; + i1.GeneratedColumn get updatedAt => + columnsByName['updated_at']! as i1.GeneratedColumn; + i1.GeneratedColumn get width => + columnsByName['width']! as i1.GeneratedColumn; + i1.GeneratedColumn get height => + columnsByName['height']! as i1.GeneratedColumn; + i1.GeneratedColumn get durationInSeconds => + columnsByName['duration_in_seconds']! as i1.GeneratedColumn; + i1.GeneratedColumn get id => + columnsByName['id']! as i1.GeneratedColumn; + i1.GeneratedColumn get checksum => + columnsByName['checksum']! as i1.GeneratedColumn; + i1.GeneratedColumn get isFavorite => + columnsByName['is_favorite']! as i1.GeneratedColumn; + i1.GeneratedColumn get orientation => + columnsByName['orientation']! as i1.GeneratedColumn; + i1.GeneratedColumn get adjustmentTime => + columnsByName['adjustment_time']! as i1.GeneratedColumn; + i1.GeneratedColumn get latitude => + columnsByName['latitude']! as i1.GeneratedColumn; + i1.GeneratedColumn get longitude => + columnsByName['longitude']! as i1.GeneratedColumn; +} + +i1.GeneratedColumn _column_96(String aliasedName) => + i1.GeneratedColumn( + 'adjustment_time', + aliasedName, + true, + type: i1.DriftSqlType.dateTime, + ); i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, @@ -5498,6 +5954,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema11 schema) from10To11, required Future Function(i1.Migrator m, Schema12 schema) from11To12, required Future Function(i1.Migrator m, Schema13 schema) from12To13, + required Future Function(i1.Migrator m, Schema14 schema) from13To14, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -5561,6 +6018,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from12To13(migrator, schema); return 13; + case 13: + final schema = Schema14(database: database); + final migrator = i1.Migrator(database, schema); + await from13To14(migrator, schema); + return 14; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -5580,6 +6042,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema11 schema) from10To11, required Future Function(i1.Migrator m, Schema12 schema) from11To12, required Future Function(i1.Migrator m, Schema13 schema) from12To13, + required Future Function(i1.Migrator m, Schema14 schema) from13To14, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( from1To2: from1To2, @@ -5594,5 +6057,6 @@ i1.OnUpgrade stepByStep({ from10To11: from10To11, from11To12: from11To12, from12To13: from12To13, + from13To14: from13To14, ), ); diff --git a/mobile/lib/infrastructure/repositories/local_album.repository.dart b/mobile/lib/infrastructure/repositories/local_album.repository.dart index 63259bc62b..9d4c9bc496 100644 --- a/mobile/lib/infrastructure/repositories/local_album.repository.dart +++ b/mobile/lib/infrastructure/repositories/local_album.repository.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:drift/drift.dart'; import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; @@ -244,7 +246,56 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository { return query.map((row) => row.readTable(_db.localAssetEntity).toDto()).get(); } - Future _upsertAssets(Iterable localAssets) { + Future Function(Iterable) get _upsertAssets => + CurrentPlatform.isIOS ? _upsertAssetsDarwin : _upsertAssetsAndroid; + + Future _upsertAssetsDarwin(Iterable localAssets) async { + if (localAssets.isEmpty) { + return Future.value(); + } + + // Reset checksum if asset changed + await _db.batch((batch) async { + for (final asset in localAssets) { + final companion = LocalAssetEntityCompanion( + checksum: const Value(null), + adjustmentTime: Value(asset.adjustmentTime), + ); + batch.update( + _db.localAssetEntity, + companion, + where: (row) => row.id.equals(asset.id) & row.adjustmentTime.isNotExp(Variable(asset.adjustmentTime)), + ); + } + }); + + return _db.batch((batch) async { + for (final asset in localAssets) { + final companion = LocalAssetEntityCompanion.insert( + name: asset.name, + type: asset.type, + createdAt: Value(asset.createdAt), + updatedAt: Value(asset.updatedAt), + width: Value(asset.width), + height: Value(asset.height), + durationInSeconds: Value(asset.durationInSeconds), + id: asset.id, + orientation: Value(asset.orientation), + isFavorite: Value(asset.isFavorite), + latitude: Value(asset.latitude), + longitude: Value(asset.longitude), + adjustmentTime: Value(asset.adjustmentTime), + ); + batch.insert<$LocalAssetEntityTable, LocalAssetEntityData>( + _db.localAssetEntity, + companion.copyWith(checksum: const Value(null)), + onConflict: DoUpdate((old) => companion), + ); + } + }); + } + + Future _upsertAssetsAndroid(Iterable localAssets) async { if (localAssets.isEmpty) { return Future.value(); } @@ -260,8 +311,8 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository { height: Value(asset.height), durationInSeconds: Value(asset.durationInSeconds), id: asset.id, - orientation: Value(asset.orientation), checksum: const Value(null), + orientation: Value(asset.orientation), isFavorite: Value(asset.isFavorite), ); batch.insert<$LocalAssetEntityTable, LocalAssetEntityData>( diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index 8e087f836f..5ab1844571 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -219,8 +219,6 @@ class SyncStreamRepository extends DriftDatabaseRepository { country: Value(exif.country), dateTimeOriginal: Value(exif.dateTimeOriginal), description: Value(exif.description), - height: Value(exif.exifImageHeight), - width: Value(exif.exifImageWidth), exposureTime: Value(exif.exposureTime), fNumber: Value(exif.fNumber), fileSize: Value(exif.fileSizeInByte), @@ -244,6 +242,16 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); + + await _db.batch((batch) { + for (final exif in data) { + batch.update( + _db.remoteAssetEntity, + RemoteAssetEntityCompanion(width: Value(exif.exifImageWidth), height: Value(exif.exifImageHeight)), + where: (row) => row.id.equals(exif.assetId), + ); + } + }); } catch (error, stack) { _logger.severe('Error: updateAssetsExifV1 - $debugLabel', error, stack); rethrow; diff --git a/mobile/lib/infrastructure/repositories/timeline.repository.dart b/mobile/lib/infrastructure/repositories/timeline.repository.dart index 1fc0ee43e5..d21e1e905b 100644 --- a/mobile/lib/infrastructure/repositories/timeline.repository.dart +++ b/mobile/lib/infrastructure/repositories/timeline.repository.dart @@ -265,7 +265,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { row.deletedAt.isNull() & row.isFavorite.equals(true) & row.ownerId.equals(userId) & - row.visibility.equalsValue(AssetVisibility.timeline), + (row.visibility.equalsValue(AssetVisibility.timeline) | row.visibility.equalsValue(AssetVisibility.archive)), groupBy: groupBy, origin: TimelineOrigin.favorite, ); diff --git a/mobile/lib/infrastructure/utils/exif.converter.dart b/mobile/lib/infrastructure/utils/exif.converter.dart index eb9945f454..50639e8e42 100644 --- a/mobile/lib/infrastructure/utils/exif.converter.dart +++ b/mobile/lib/infrastructure/utils/exif.converter.dart @@ -22,7 +22,7 @@ abstract final class ExifDtoConverter { f: dto.fNumber?.toDouble(), mm: dto.focalLength?.toDouble(), iso: dto.iso?.toInt(), - exposureSeconds: _exposureTimeToSeconds(dto.exposureTime), + exposureSeconds: exposureTimeToSeconds(dto.exposureTime), ); } @@ -36,15 +36,15 @@ abstract final class ExifDtoConverter { return isRotated90CW || isRotated270CW; } - static double? _exposureTimeToSeconds(String? s) { - if (s == null) { + static double? exposureTimeToSeconds(String? second) { + if (second == null) { return null; } - double? value = double.tryParse(s); + double? value = double.tryParse(second); if (value != null) { return value; } - final parts = s.split("/"); + final parts = second.split("/"); if (parts.length == 2) { final numerator = double.tryParse(parts.firstOrNull ?? "-"); final denominator = double.tryParse(parts.lastOrNull ?? "-"); diff --git a/mobile/lib/pages/backup/drift_backup_asset_detail.page.dart b/mobile/lib/pages/backup/drift_backup_asset_detail.page.dart index f3fdccc329..36d51c5624 100644 --- a/mobile/lib/pages/backup/drift_backup_asset_detail.page.dart +++ b/mobile/lib/pages/backup/drift_backup_asset_detail.page.dart @@ -3,7 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; diff --git a/mobile/lib/pages/common/settings.page.dart b/mobile/lib/pages/common/settings.page.dart index 0fe2ccec09..86c80253dc 100644 --- a/mobile/lib/pages/common/settings.page.dart +++ b/mobile/lib/pages/common/settings.page.dart @@ -58,7 +58,7 @@ class SettingsPage extends StatelessWidget { context.locale; return Scaffold( appBar: AppBar(centerTitle: false, title: const Text('settings').tr()), - body: context.isMobile ? const SafeArea(child: _MobileLayout()) : const SafeArea(child: _TabletLayout()), + body: context.isMobile ? const _MobileLayout() : const _TabletLayout(), ); } } @@ -89,11 +89,7 @@ class _MobileLayout extends StatelessWidget { ], ) .toList(); - return ListView( - physics: const ClampingScrollPhysics(), - padding: const EdgeInsets.only(top: 10.0, bottom: 16), - children: [...settings], - ); + return ListView(padding: const EdgeInsets.only(top: 10.0, bottom: 16), children: [...settings]); } } diff --git a/mobile/lib/pages/common/tab_shell.page.dart b/mobile/lib/pages/common/tab_shell.page.dart index bbb567bd3b..2fdcec4054 100644 --- a/mobile/lib/pages/common/tab_shell.page.dart +++ b/mobile/lib/pages/common/tab_shell.page.dart @@ -5,7 +5,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/constants.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/presentation/pages/search/paginated_search.provider.dart'; @@ -16,7 +16,6 @@ import 'package:immich_mobile/providers/infrastructure/people.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; import 'package:immich_mobile/providers/search/search_input_focus.provider.dart'; import 'package:immich_mobile/providers/tab.provider.dart'; -import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/routing/router.dart'; @RoutePage() diff --git a/mobile/lib/pages/search/map/map_location_picker.page.dart b/mobile/lib/pages/search/map/map_location_picker.page.dart index 94e6627c98..a2c927c6bd 100644 --- a/mobile/lib/pages/search/map/map_location_picker.page.dart +++ b/mobile/lib/pages/search/map/map_location_picker.page.dart @@ -49,7 +49,7 @@ class MapLocationPickerPage extends HookConsumerWidget { var currentLatLng = LatLng(currentLocation.latitude, currentLocation.longitude); selectedLatLng.value = currentLatLng; - await controller.value?.animateCamera(CameraUpdate.newLatLng(currentLatLng)); + await controller.value?.animateCamera(CameraUpdate.newLatLngZoom(currentLatLng, 12)); } return MapThemeOverride( @@ -66,7 +66,10 @@ class MapLocationPickerPage extends HookConsumerWidget { borderRadius: BorderRadius.only(bottomLeft: Radius.circular(40), bottomRight: Radius.circular(40)), ), child: MapLibreMap( - initialCameraPosition: CameraPosition(target: initialLatLng, zoom: 12), + initialCameraPosition: CameraPosition( + target: initialLatLng, + zoom: (initialLatLng.latitude == 0 && initialLatLng.longitude == 0) ? 1 : 12, + ), styleString: style, onMapCreated: (mapController) => controller.value = mapController, onStyleLoadedCallback: onStyleLoaded, diff --git a/mobile/lib/platform/native_sync_api.g.dart b/mobile/lib/platform/native_sync_api.g.dart index 34ed7a5e2b..1c3b4b083e 100644 --- a/mobile/lib/platform/native_sync_api.g.dart +++ b/mobile/lib/platform/native_sync_api.g.dart @@ -41,6 +41,9 @@ class PlatformAsset { required this.durationInSeconds, required this.orientation, required this.isFavorite, + this.adjustmentTime, + this.latitude, + this.longitude, }); String id; @@ -63,8 +66,28 @@ class PlatformAsset { bool isFavorite; + int? adjustmentTime; + + double? latitude; + + double? longitude; + List _toList() { - return [id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite]; + return [ + id, + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + orientation, + isFavorite, + adjustmentTime, + latitude, + longitude, + ]; } Object encode() { @@ -84,6 +107,9 @@ class PlatformAsset { durationInSeconds: result[7]! as int, orientation: result[8]! as int, isFavorite: result[9]! as bool, + adjustmentTime: result[10] as int?, + latitude: result[11] as double?, + longitude: result[12] as double?, ); } diff --git a/mobile/lib/presentation/pages/drift_asset_troubleshoot.page.dart b/mobile/lib/presentation/pages/drift_asset_troubleshoot.page.dart index 7a899f4e72..2b7034770b 100644 --- a/mobile/lib/presentation/pages/drift_asset_troubleshoot.page.dart +++ b/mobile/lib/presentation/pages/drift_asset_troubleshoot.page.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; +import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; @RoutePage() @@ -129,6 +130,15 @@ class _AssetPropertiesSectionState extends ConsumerState<_AssetPropertiesSection properties.insert(4, _PropertyItem(label: 'Orientation', value: asset.orientation.toString())); final albums = await ref.read(assetServiceProvider).getSourceAlbums(asset.id); properties.add(_PropertyItem(label: 'Album', value: albums.map((a) => a.name).join(', '))); + if (CurrentPlatform.isIOS) { + properties.add(_PropertyItem(label: 'Adjustment Time', value: asset.adjustmentTime?.toString())); + } + properties.add( + _PropertyItem( + label: 'GPS Coordinates', + value: asset.hasCoordinates ? '${asset.latitude}, ${asset.longitude}' : null, + ), + ); } Future _addRemoteAssetProperties(RemoteAsset asset) async { @@ -161,8 +171,6 @@ class _AssetPropertiesSectionState extends ConsumerState<_AssetPropertiesSection value: exif.fileSize != null ? '${(exif.fileSize! / 1024 / 1024).toStringAsFixed(2)} MB' : null, ), _PropertyItem(label: 'Description', value: exif.description), - _PropertyItem(label: 'EXIF Width', value: exif.width?.toString()), - _PropertyItem(label: 'EXIF Height', value: exif.height?.toString()), _PropertyItem(label: 'Date Taken', value: exif.dateTimeOriginal?.toString()), _PropertyItem(label: 'Time Zone', value: exif.timeZone), _PropertyItem(label: 'Camera Make', value: exif.make), diff --git a/mobile/lib/presentation/pages/drift_memory.page.dart b/mobile/lib/presentation/pages/drift_memory.page.dart index 55e5d24ecb..9042f2f1f5 100644 --- a/mobile/lib/presentation/pages/drift_memory.page.dart +++ b/mobile/lib/presentation/pages/drift_memory.page.dart @@ -24,6 +24,16 @@ class DriftMemoryPage extends HookConsumerWidget { const DriftMemoryPage({required this.memories, required this.memoryIndex, super.key}); + static void setMemory(WidgetRef ref, DriftMemory memory) { + if (memory.assets.isNotEmpty) { + ref.read(currentAssetNotifier.notifier).setAsset(memory.assets.first); + + if (memory.assets.first.isVideo) { + ref.read(videoPlaybackValueProvider.notifier).reset(); + } + } + } + @override Widget build(BuildContext context, WidgetRef ref) { final currentMemory = useState(memories[memoryIndex]); @@ -202,6 +212,10 @@ class DriftMemoryPage extends HookConsumerWidget { if (pageNumber < memories.length) { currentMemoryIndex.value = pageNumber; currentMemory.value = memories[pageNumber]; + + WidgetsBinding.instance.addPostFrameCallback((_) { + DriftMemoryPage.setMemory(ref, memories[pageNumber]); + }); } currentAssetPage.value = 0; diff --git a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart index 9155d82753..71fedf1258 100644 --- a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart @@ -77,6 +77,7 @@ class AddActionButton extends ConsumerWidget { color: context.themeData.scaffoldBackgroundColor, position: _menuPosition(context), items: items, + popUpAnimationStyle: AnimationStyle.noAnimation, ); if (selected == null) { diff --git a/mobile/lib/presentation/widgets/action_buttons/archive_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/archive_action_button.widget.dart index 290a19f584..4ba877bcba 100644 --- a/mobile/lib/presentation/widgets/action_buttons/archive_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/archive_action_button.widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/base_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/base_action_button.widget.dart index 5ec6c8bc54..b62398c03e 100644 --- a/mobile/lib/presentation/widgets/action_buttons/base_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/base_action_button.widget.dart @@ -38,6 +38,29 @@ class BaseActionButton extends StatelessWidget { ); } + if (context.findAncestorWidgetOfExactType() != null) { + final theme = context.themeData; + final textStyle = theme.textTheme.bodyMedium; + final defaultTextColor = theme.colorScheme.onSurfaceVariant; + final effectiveStyle = (textStyle ?? theme.textTheme.bodyMedium)?.copyWith( + color: (textStyle?.color ?? defaultTextColor), + ); + final effectiveIconColor = iconColor ?? theme.iconTheme.color ?? theme.colorScheme.onSurfaceVariant; + + return MenuItemButton( + style: MenuItemButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), + visualDensity: const VisualDensity(vertical: -2.5), + ), + trailingIcon: Icon(iconData, size: 18, color: effectiveIconColor), + onPressed: onPressed, + child: Align( + alignment: Alignment.centerLeft, + child: Text(label, style: effectiveStyle), + ), + ); + } + return ConstrainedBox( constraints: BoxConstraints(maxWidth: maxWidth), child: MaterialButton( diff --git a/mobile/lib/presentation/widgets/action_buttons/delete_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/delete_action_button.widget.dart index 723700af55..8b82e5c839 100644 --- a/mobile/lib/presentation/widgets/action_buttons/delete_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/delete_action_button.widget.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart index 3cd939aeb6..5d8ea8671c 100644 --- a/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/delete_permanent_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/delete_permanent_action_button.widget.dart index 4979df904c..a0191e2407 100644 --- a/mobile/lib/presentation/widgets/action_buttons/delete_permanent_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/delete_permanent_action_button.widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/move_to_lock_folder_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/move_to_lock_folder_action_button.widget.dart index ddc83cb383..20d391c4a6 100644 --- a/mobile/lib/presentation/widgets/action_buttons/move_to_lock_folder_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/move_to_lock_folder_action_button.widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/trash_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/trash_action_button.widget.dart index df8f544601..a78ff2ccd8 100644 --- a/mobile/lib/presentation/widgets/action_buttons/trash_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/trash_action_button.widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/unarchive_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/unarchive_action_button.widget.dart index 8b04a1b05d..32147a194f 100644 --- a/mobile/lib/presentation/widgets/action_buttons/unarchive_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/unarchive_action_button.widget.dart @@ -9,8 +9,8 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_bu import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; // used to allow performing unarchive action from different sources (without duplicating code) Future performUnArchiveAction(BuildContext context, WidgetRef ref, {required ActionSource source}) async { diff --git a/mobile/lib/presentation/widgets/album/album_selector.widget.dart b/mobile/lib/presentation/widgets/album/album_selector.widget.dart index 0d5b9a7636..4110966e57 100644 --- a/mobile/lib/presentation/widgets/album/album_selector.widget.dart +++ b/mobile/lib/presentation/widgets/album/album_selector.widget.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; @@ -17,6 +16,9 @@ import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart' import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; +import 'package:immich_mobile/providers/app_settings.provider.dart'; +import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/album_filter.utils.dart'; import 'package:immich_mobile/widgets/common/confirm_dialog.dart'; @@ -45,14 +47,28 @@ class _AlbumSelectorState extends ConsumerState { List shownAlbums = []; AlbumFilter filter = AlbumFilter(query: "", mode: QuickFilterMode.all); - AlbumSort sort = AlbumSort(mode: RemoteAlbumSortMode.lastModified, isReverse: true); + AlbumSort sort = AlbumSort(mode: AlbumSortMode.lastModified, isReverse: true); @override void initState() { super.initState(); - // Load albums when component mounts WidgetsBinding.instance.addPostFrameCallback((_) { + final appSettings = ref.read(appSettingsServiceProvider); + final savedSortMode = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortOrder); + final savedIsReverse = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortReverse); + final savedIsGrid = appSettings.getSetting(AppSettingsEnum.albumGridView); + + final albumSortMode = AlbumSortMode.values.firstWhere( + (e) => e.storeIndex == savedSortMode, + orElse: () => AlbumSortMode.lastModified, + ); + + setState(() { + sort = AlbumSort(mode: albumSortMode, isReverse: savedIsReverse); + isGrid = savedIsGrid; + }); + ref.read(remoteAlbumProvider.notifier).refresh(); }); @@ -82,6 +98,7 @@ class _AlbumSelectorState extends ConsumerState { setState(() { isGrid = !isGrid; }); + ref.read(appSettingsServiceProvider).setSetting(AppSettingsEnum.albumGridView, isGrid); } void changeFilter(QuickFilterMode mode) { @@ -97,6 +114,10 @@ class _AlbumSelectorState extends ConsumerState { this.sort = sort; }); + final appSettings = ref.read(appSettingsServiceProvider); + await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortOrder, sort.mode.storeIndex); + await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortReverse, sort.isReverse); + await sortAlbums(); } @@ -181,6 +202,8 @@ class _AlbumSelectorState extends ConsumerState { onToggleViewMode: toggleViewMode, onSortChanged: changeSort, controller: menuController, + currentSortMode: sort.mode, + currentIsReverse: sort.isReverse, ), isGrid ? _AlbumGrid(albums: shownAlbums, userId: userId, onAlbumSelected: widget.onAlbumSelected) @@ -192,21 +215,46 @@ class _AlbumSelectorState extends ConsumerState { } class _SortButton extends ConsumerStatefulWidget { - const _SortButton(this.onSortChanged, {this.controller}); + const _SortButton( + this.onSortChanged, { + required this.initialSortMode, + required this.initialIsReverse, + this.controller, + }); final Future Function(AlbumSort) onSortChanged; final MenuController? controller; + final AlbumSortMode initialSortMode; + final bool initialIsReverse; @override ConsumerState<_SortButton> createState() => _SortButtonState(); } class _SortButtonState extends ConsumerState<_SortButton> { - RemoteAlbumSortMode albumSortOption = RemoteAlbumSortMode.lastModified; - bool albumSortIsReverse = true; + late AlbumSortMode albumSortOption; + late bool albumSortIsReverse; bool isSorting = false; - Future onMenuTapped(RemoteAlbumSortMode sortMode) async { + @override + void initState() { + super.initState(); + albumSortOption = widget.initialSortMode; + albumSortIsReverse = widget.initialIsReverse; + } + + @override + void didUpdateWidget(_SortButton oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.initialSortMode != widget.initialSortMode || oldWidget.initialIsReverse != widget.initialIsReverse) { + setState(() { + albumSortOption = widget.initialSortMode; + albumSortIsReverse = widget.initialIsReverse; + }); + } + } + + Future onMenuTapped(AlbumSortMode sortMode) async { final selected = albumSortOption == sortMode; // Switch direction if (selected) { @@ -240,7 +288,7 @@ class _SortButtonState extends ConsumerState<_SortButton> { padding: const WidgetStatePropertyAll(EdgeInsets.all(4)), ), consumeOutsideTap: true, - menuChildren: RemoteAlbumSortMode.values + menuChildren: AlbumSortMode.values .map( (sortMode) => MenuItemButton( leadingIcon: albumSortOption == sortMode @@ -269,7 +317,7 @@ class _SortButtonState extends ConsumerState<_SortButton> { ), ), child: Text( - sortMode.key.t(context: context), + sortMode.label.t(context: context), style: context.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w600, color: albumSortOption == sortMode @@ -298,7 +346,7 @@ class _SortButtonState extends ConsumerState<_SortButton> { : const Icon(Icons.keyboard_arrow_up_rounded), ), Text( - albumSortOption.key.t(context: context), + albumSortOption.label.t(context: context), style: context.textTheme.bodyLarge?.copyWith( fontWeight: FontWeight.w500, color: context.colorScheme.onSurface.withAlpha(225), @@ -465,6 +513,8 @@ class _QuickSortAndViewMode extends StatelessWidget { required this.isGrid, required this.onToggleViewMode, required this.onSortChanged, + required this.currentSortMode, + required this.currentIsReverse, this.controller, }); @@ -472,6 +522,8 @@ class _QuickSortAndViewMode extends StatelessWidget { final VoidCallback onToggleViewMode; final MenuController? controller; final Future Function(AlbumSort) onSortChanged; + final AlbumSortMode currentSortMode; + final bool currentIsReverse; @override Widget build(BuildContext context) { @@ -481,7 +533,12 @@ class _QuickSortAndViewMode extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _SortButton(onSortChanged, controller: controller), + _SortButton( + onSortChanged, + controller: controller, + initialSortMode: currentSortMode, + initialIsReverse: currentIsReverse, + ), IconButton( icon: Icon(isGrid ? Icons.view_list_outlined : Icons.grid_view_outlined, size: 24), onPressed: onToggleViewMode, diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart index 50c4347301..70eb6699aa 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart @@ -7,7 +7,7 @@ import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.state.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.state.dart index d0fb1f8ba0..36e5bf67d9 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.state.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.state.dart @@ -1,17 +1,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_controls_provider.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -class ViewerOpenBottomSheetEvent extends Event { - final bool activitiesMode; - const ViewerOpenBottomSheetEvent({this.activitiesMode = false}); -} - -class ViewerReloadAssetEvent extends Event { - const ViewerReloadAssetEvent(); -} - class AssetViewerState { final int backgroundOpacity; final bool showingBottomSheet; diff --git a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart index d29e09a247..80840d94b4 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart @@ -4,20 +4,20 @@ import 'package:auto_route/auto_route.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/domain/models/setting.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/extensions/duration_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/album/album_tile.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet/sheet_location_details.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet/sheet_people_details.widget.dart'; +import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; -import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; @@ -30,6 +30,7 @@ import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/action_button.utils.dart'; import 'package:immich_mobile/utils/bytes_units.dart'; +import 'package:immich_mobile/utils/timezone.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; const _kSeparator = ' • '; @@ -86,19 +87,27 @@ class AssetDetailBottomSheet extends ConsumerWidget { class _AssetDetailBottomSheet extends ConsumerWidget { const _AssetDetailBottomSheet(); - String _getDateTime(BuildContext ctx, BaseAsset asset) { - final dateTime = asset.createdAt.toLocal(); + String _getDateTime(BuildContext ctx, BaseAsset asset, ExifInfo? exifInfo) { + DateTime dateTime = asset.createdAt.toLocal(); + Duration timeZoneOffset = dateTime.timeZoneOffset; + + // Use EXIF timezone information if available (matching web app behavior) + if (exifInfo?.dateTimeOriginal != null) { + (dateTime, timeZoneOffset) = applyTimezoneOffset( + dateTime: exifInfo!.dateTimeOriginal!, + timeZone: exifInfo.timeZone, + ); + } + final date = DateFormat.yMMMEd(ctx.locale.toLanguageTag()).format(dateTime); final time = DateFormat.jm(ctx.locale.toLanguageTag()).format(dateTime); - final timezone = dateTime.timeZoneOffset.isNegative - ? 'UTC-${dateTime.timeZoneOffset.inHours.abs().toString().padLeft(2, '0')}:${(dateTime.timeZoneOffset.inMinutes.abs() % 60).toString().padLeft(2, '0')}' - : 'UTC+${dateTime.timeZoneOffset.inHours.toString().padLeft(2, '0')}:${(dateTime.timeZoneOffset.inMinutes.abs() % 60).toString().padLeft(2, '0')}'; + final timezone = 'GMT${timeZoneOffset.formatAsOffset()}'; return '$date$_kSeparator$time $timezone'; } String _getFileInfo(BaseAsset asset, ExifInfo? exifInfo) { - final height = asset.height ?? exifInfo?.height; - final width = asset.width ?? exifInfo?.width; + final height = asset.height; + final width = asset.width; final resolution = (width != null && height != null) ? "${width.toInt()} x ${height.toInt()}" : null; final fileSize = exifInfo?.fileSize != null ? formatBytes(exifInfo!.fileSize!) : null; @@ -181,7 +190,7 @@ class _AssetDetailBottomSheet extends ConsumerWidget { spacing: 12, children: [ if (albums.isNotEmpty) - _SheetTile( + SheetTile( title: 'appears_in'.t(context: context).toUpperCase(), titleStyle: context.textTheme.labelMedium?.copyWith( color: context.textTheme.labelMedium?.color?.withAlpha(200), @@ -233,7 +242,7 @@ class _AssetDetailBottomSheet extends ConsumerWidget { future: assetMediaRepository.getOriginalFilename(asset.id), builder: (context, snapshot) { final displayName = snapshot.data ?? asset.name; - return _SheetTile( + return SheetTile( title: displayName, titleStyle: context.textTheme.labelLarge, leading: Icon( @@ -242,15 +251,15 @@ class _AssetDetailBottomSheet extends ConsumerWidget { color: context.textTheme.labelLarge?.color, ), subtitle: _getFileInfo(asset, exifInfo), - subtitleStyle: context.textTheme.bodyMedium?.copyWith( - color: context.textTheme.bodyMedium?.color?.withAlpha(155), + subtitleStyle: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), ), ); }, ); } else { // For remote assets, use the name directly - return _SheetTile( + return SheetTile( title: asset.name, titleStyle: context.textTheme.labelLarge, leading: Icon( @@ -259,8 +268,8 @@ class _AssetDetailBottomSheet extends ConsumerWidget { color: context.textTheme.labelLarge?.color, ), subtitle: _getFileInfo(asset, exifInfo), - subtitleStyle: context.textTheme.bodyMedium?.copyWith( - color: context.textTheme.bodyMedium?.color?.withAlpha(155), + subtitleStyle: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), ), ); } @@ -269,9 +278,9 @@ class _AssetDetailBottomSheet extends ConsumerWidget { return SliverList.list( children: [ // Asset Date and Time - _SheetTile( - title: _getDateTime(context, asset), - titleStyle: context.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w600), + SheetTile( + title: _getDateTime(context, asset, exifInfo), + titleStyle: context.textTheme.labelLarge, trailing: asset.hasRemote && isOwner ? const Icon(Icons.edit, size: 18) : null, onTap: asset.hasRemote && isOwner ? () async => await _editDateTime(context, ref) : null, ), @@ -279,8 +288,8 @@ class _AssetDetailBottomSheet extends ConsumerWidget { const SheetPeopleDetails(), const SheetLocationDetails(), // Details header - _SheetTile( - title: 'exif_bottom_sheet_details'.t(context: context), + SheetTile( + title: 'details'.t(context: context).toUpperCase(), titleStyle: context.textTheme.labelMedium?.copyWith( color: context.textTheme.labelMedium?.color?.withAlpha(200), fontWeight: FontWeight.w600, @@ -289,29 +298,33 @@ class _AssetDetailBottomSheet extends ConsumerWidget { // File info buildFileInfoTile(), // Camera info - if (cameraTitle != null) - _SheetTile( + if (cameraTitle != null) ...[ + const SizedBox(height: 16), + SheetTile( title: cameraTitle, titleStyle: context.textTheme.labelLarge, leading: Icon(Icons.camera_alt_outlined, size: 24, color: context.textTheme.labelLarge?.color), subtitle: _getCameraInfoSubtitle(exifInfo), - subtitleStyle: context.textTheme.bodyMedium?.copyWith( - color: context.textTheme.bodyMedium?.color?.withAlpha(155), + subtitleStyle: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), ), ), + ], // Lens info - if (lensTitle != null) - _SheetTile( + if (lensTitle != null) ...[ + const SizedBox(height: 16), + SheetTile( title: lensTitle, titleStyle: context.textTheme.labelLarge, leading: Icon(Icons.camera_outlined, size: 24, color: context.textTheme.labelLarge?.color), subtitle: _getLensInfoSubtitle(exifInfo), - subtitleStyle: context.textTheme.bodyMedium?.copyWith( - color: context.textTheme.bodyMedium?.color?.withAlpha(155), + subtitleStyle: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), ), ), + ], // Appears in (Albums) - _buildAppearsInList(ref, context), + Padding(padding: const EdgeInsets.only(top: 16.0), child: _buildAppearsInList(ref, context)), // padding at the bottom to avoid cut-off const SizedBox(height: 100), ], @@ -319,77 +332,6 @@ class _AssetDetailBottomSheet extends ConsumerWidget { } } -class _SheetTile extends ConsumerWidget { - final String title; - final Widget? leading; - final Widget? trailing; - final String? subtitle; - final TextStyle? titleStyle; - final TextStyle? subtitleStyle; - final VoidCallback? onTap; - - const _SheetTile({ - required this.title, - this.titleStyle, - this.leading, - this.subtitle, - this.subtitleStyle, - this.trailing, - this.onTap, - }); - - void copyTitle(BuildContext context, WidgetRef ref) { - Clipboard.setData(ClipboardData(text: title)); - ImmichToast.show( - context: context, - msg: 'copied_to_clipboard'.t(context: context), - toastType: ToastType.info, - ); - ref.read(hapticFeedbackProvider.notifier).selectionClick(); - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final Widget titleWidget; - if (leading == null) { - titleWidget = LimitedBox( - maxWidth: double.infinity, - child: Text(title, style: titleStyle), - ); - } else { - titleWidget = Container( - width: double.infinity, - padding: const EdgeInsets.only(left: 15), - child: Text(title, style: titleStyle), - ); - } - - final Widget? subtitleWidget; - if (leading == null && subtitle != null) { - subtitleWidget = Text(subtitle!, style: subtitleStyle); - } else if (leading != null && subtitle != null) { - subtitleWidget = Padding( - padding: const EdgeInsets.only(left: 15), - child: Text(subtitle!, style: subtitleStyle), - ); - } else { - subtitleWidget = null; - } - - return ListTile( - dense: true, - visualDensity: VisualDensity.compact, - title: GestureDetector(onLongPress: () => copyTitle(context, ref), child: titleWidget), - titleAlignment: ListTileTitleAlignment.center, - leading: leading, - trailing: trailing, - contentPadding: leading == null ? null : const EdgeInsets.only(left: 25), - subtitle: subtitleWidget, - onTap: onTap, - ); - } -} - class _SheetAssetDescription extends ConsumerStatefulWidget { final ExifInfo exif; final bool isEditable; diff --git a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet/sheet_location_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet/sheet_location_details.widget.dart index ab57ea4d8b..4edd6855a8 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet/sheet_location_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet/sheet_location_details.widget.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; +import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/widgets/asset_viewer/detail_panel/exif_map.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; @@ -16,8 +19,6 @@ class SheetLocationDetails extends ConsumerStatefulWidget { } class _SheetLocationDetailsState extends ConsumerState { - BaseAsset? asset; - ExifInfo? exifInfo; MapLibreMapController? _mapController; String? _getLocationName(ExifInfo? exifInfo) { @@ -39,14 +40,11 @@ class _SheetLocationDetailsState extends ConsumerState { } void _onExifChanged(AsyncValue? previous, AsyncValue current) { - asset = ref.read(currentAssetNotifier); - setState(() { - exifInfo = current.valueOrNull; - final hasCoordinates = exifInfo?.hasCoordinates ?? false; - if (exifInfo != null && hasCoordinates) { - _mapController?.moveCamera(CameraUpdate.newLatLng(LatLng(exifInfo!.latitude!, exifInfo!.longitude!))); - } - }); + final currentExif = current.valueOrNull; + + if (currentExif != null && currentExif.hasCoordinates) { + _mapController?.moveCamera(CameraUpdate.newLatLng(LatLng(currentExif.latitude!, currentExif.longitude!))); + } } @override @@ -55,45 +53,71 @@ class _SheetLocationDetailsState extends ConsumerState { ref.listenManual(currentAssetExifProvider, _onExifChanged, fireImmediately: true); } + void editLocation() async { + await ref.read(actionProvider.notifier).editLocation(ActionSource.viewer, context); + } + @override Widget build(BuildContext context) { + final asset = ref.watch(currentAssetNotifier); + final exifInfo = ref.watch(currentAssetExifProvider).valueOrNull; final hasCoordinates = exifInfo?.hasCoordinates ?? false; - // Guard no lat/lng - if (!hasCoordinates || (asset != null && asset is LocalAsset && asset!.hasRemote)) { + // Guard local assets + if (asset != null && asset is LocalAsset && asset.hasRemote) { return const SizedBox.shrink(); } - final remoteId = asset is LocalAsset ? (asset as LocalAsset).remoteId : (asset as RemoteAsset).id; + final remoteId = asset is LocalAsset ? asset.remoteId : (asset as RemoteAsset).id; final locationName = _getLocationName(exifInfo); - final coordinates = "${exifInfo!.latitude!.toStringAsFixed(4)}, ${exifInfo!.longitude!.toStringAsFixed(4)}"; + final coordinates = "${exifInfo?.latitude?.toStringAsFixed(4)}, ${exifInfo?.longitude?.toStringAsFixed(4)}"; return Padding( - padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: context.isMobile ? 16.0 : 56.0), + padding: const EdgeInsets.only(bottom: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text( - "exif_bottom_sheet_location".t(context: context), - style: context.textTheme.labelMedium?.copyWith( - color: context.textTheme.labelMedium?.color?.withAlpha(200), - fontWeight: FontWeight.w600, + SheetTile( + title: 'location'.t(context: context).toUpperCase(), + titleStyle: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), + fontWeight: FontWeight.w600, + ), + trailing: hasCoordinates ? const Icon(Icons.edit_location_alt, size: 20) : null, + onTap: editLocation, + ), + if (hasCoordinates) + Padding( + padding: EdgeInsets.symmetric(horizontal: context.isMobile ? 16.0 : 56.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ExifMap(exifInfo: exifInfo!, markerId: remoteId, onMapCreated: _onMapCreated), + const SizedBox(height: 16), + if (locationName != null) + Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: Text(locationName, style: context.textTheme.labelLarge), + ), + Text( + coordinates, + style: context.textTheme.labelMedium?.copyWith( + color: context.textTheme.labelMedium?.color?.withAlpha(200), + ), + ), + ], ), ), - ), - ExifMap(exifInfo: exifInfo!, markerId: remoteId, onMapCreated: _onMapCreated), - const SizedBox(height: 15), - if (locationName != null) - Padding( - padding: const EdgeInsets.only(bottom: 4.0), - child: Text(locationName, style: context.textTheme.labelLarge), + if (!hasCoordinates) + SheetTile( + title: "add_a_location".t(context: context), + titleStyle: context.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w600, + color: context.primaryColor, + ), + leading: const Icon(Icons.location_off), + onTap: editLocation, ), - Text( - coordinates, - style: context.textTheme.labelMedium?.copyWith(color: context.textTheme.labelMedium?.color?.withAlpha(150)), - ), ], ), ); diff --git a/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart new file mode 100644 index 0000000000..2af68e1ff0 --- /dev/null +++ b/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; +import 'package:immich_mobile/widgets/common/immich_toast.dart'; + +class SheetTile extends ConsumerWidget { + final String title; + final Widget? leading; + final Widget? trailing; + final String? subtitle; + final TextStyle? titleStyle; + final TextStyle? subtitleStyle; + final VoidCallback? onTap; + + const SheetTile({ + super.key, + required this.title, + this.titleStyle, + this.leading, + this.subtitle, + this.subtitleStyle, + this.trailing, + this.onTap, + }); + + void copyTitle(BuildContext context, WidgetRef ref) { + Clipboard.setData(ClipboardData(text: title)); + ImmichToast.show( + context: context, + msg: 'copied_to_clipboard'.t(context: context), + toastType: ToastType.info, + ); + ref.read(hapticFeedbackProvider.notifier).selectionClick(); + } + + @override + Widget build(BuildContext context, WidgetRef ref) { + final Widget titleWidget; + if (leading == null) { + titleWidget = LimitedBox( + maxWidth: double.infinity, + child: Text(title, style: titleStyle), + ); + } else { + titleWidget = Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 15, right: 15), + child: Text(title, style: titleStyle), + ); + } + + final Widget? subtitleWidget; + if (leading == null && subtitle != null) { + subtitleWidget = Text(subtitle!, style: subtitleStyle); + } else if (leading != null && subtitle != null) { + subtitleWidget = Padding( + padding: const EdgeInsets.only(left: 15), + child: Text(subtitle!, style: subtitleStyle), + ); + } else { + subtitleWidget = null; + } + + return ListTile( + dense: true, + visualDensity: VisualDensity.compact, + title: GestureDetector(onLongPress: () => copyTitle(context, ref), child: titleWidget), + titleAlignment: ListTileTitleAlignment.center, + leading: leading, + trailing: trailing, + contentPadding: leading == null ? null : const EdgeInsets.only(left: 25), + subtitle: subtitleWidget, + onTap: onTap, + ); + } +} diff --git a/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart index ab88dffab4..918ed8a223 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; @@ -14,6 +14,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/favorite_actio import 'package:immich_mobile/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; +import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart'; import 'package:immich_mobile/providers/activity.provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; @@ -89,12 +90,12 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget { if (asset.hasRemote && isOwner && asset.isFavorite) const UnFavoriteActionButton(source: ActionSource.viewer, menuItem: true), if (asset.isMotionPhoto) const MotionPhotoActionButton(menuItem: true), - const _KebabMenu(), + const ViewerKebabMenu(), ]; final lockedViewActions = [ if (isCasting || (asset.hasRemote)) const CastActionButton(menuItem: true), - const _KebabMenu(), + const ViewerKebabMenu(), ]; return IgnorePointer( @@ -122,20 +123,6 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget { Size get preferredSize => const Size.fromHeight(60.0); } -class _KebabMenu extends ConsumerWidget { - const _KebabMenu(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return IconButton( - onPressed: () { - EventStream.shared.emit(const ViewerOpenBottomSheetEvent()); - }, - icon: const Icon(Icons.more_vert_rounded), - ); - } -} - class _AppBarBackButton extends ConsumerWidget { const _AppBarBackButton(); diff --git a/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart new file mode 100644 index 0000000000..b228c0331b --- /dev/null +++ b/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart @@ -0,0 +1,53 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; +import 'package:immich_mobile/domain/utils/event_stream.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; +import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; + +class ViewerKebabMenu extends ConsumerWidget { + const ViewerKebabMenu({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final asset = ref.watch(currentAssetNotifier); + if (asset == null) { + return const SizedBox.shrink(); + } + + final theme = context.themeData; + final menuChildren = [ + BaseActionButton( + label: 'open_bottom_sheet_info'.tr(), + iconData: Icons.info_outline, + onPressed: () => EventStream.shared.emit(const ViewerOpenBottomSheetEvent()), + ), + ]; + + return MenuAnchor( + style: MenuStyle( + backgroundColor: WidgetStatePropertyAll(theme.scaffoldBackgroundColor), + elevation: const WidgetStatePropertyAll(4), + shape: const WidgetStatePropertyAll( + RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))), + ), + padding: const WidgetStatePropertyAll(EdgeInsets.symmetric(vertical: 2)), + ), + menuChildren: menuChildren, + builder: (context, controller, child) { + return IconButton( + icon: const Icon(Icons.more_vert_rounded), + onPressed: () { + if (controller.isOpen) { + controller.close(); + } else { + controller.open(); + } + }, + ); + }, + ); + } +} diff --git a/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart b/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart index 8d374f74ff..ae4cfbd1c6 100644 --- a/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart +++ b/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart @@ -143,11 +143,13 @@ class BackupToggleButtonState extends ConsumerState with Sin Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text( - "enable_backup".t(context: context), - style: context.textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - color: context.primaryColor, + Flexible( + child: Text( + "enable_backup".t(context: context), + style: context.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + color: context.primaryColor, + ), ), ), ], diff --git a/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart b/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart index f067bc6bf3..b514f9f0a5 100644 --- a/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart +++ b/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart @@ -3,8 +3,8 @@ import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/routing/router.dart'; diff --git a/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart b/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart index b2c61c7488..e85a6c05f8 100644 --- a/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart +++ b/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart @@ -3,10 +3,9 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/presentation/pages/drift_memory.page.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; -import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart'; import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/memory.provider.dart'; import 'package:immich_mobile/routing/router.dart'; @@ -31,16 +30,9 @@ class DriftMemoryLane extends ConsumerWidget { overlayColor: WidgetStateProperty.all(Colors.white.withValues(alpha: 0.1)), onTap: (index) { ref.read(hapticFeedbackProvider.notifier).heavyImpact(); - if (memories[index].assets.isNotEmpty) { - final asset = memories[index].assets[0]; - ref.read(currentAssetNotifier.notifier).setAsset(asset); - - if (asset.isVideo) { - ref.read(videoPlaybackValueProvider.notifier).reset(); - } + DriftMemoryPage.setMemory(ref, memories[index]); } - context.pushRoute(DriftMemoryRoute(memories: memories, memoryIndex: index)); }, children: memories diff --git a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart index 70dd15bf7f..5868de92aa 100644 --- a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart +++ b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/setting.model.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; diff --git a/mobile/lib/providers/app_life_cycle.provider.dart b/mobile/lib/providers/app_life_cycle.provider.dart index 6d0c0acb0d..4b1bf3e809 100644 --- a/mobile/lib/providers/app_life_cycle.provider.dart +++ b/mobile/lib/providers/app_life_cycle.provider.dart @@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; +import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/models/backup/backup_state.model.dart'; import 'package:immich_mobile/providers/album/album.provider.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; @@ -150,7 +151,7 @@ class AppLifeCycleNotifier extends StateNotifier { try { bool syncSuccess = false; await Future.wait([ - _safeRun(backgroundManager.syncLocal(), "syncLocal"), + _safeRun(backgroundManager.syncLocal(full: CurrentPlatform.isAndroid ? true : false), "syncLocal"), _safeRun(backgroundManager.syncRemote().then((success) => syncSuccess = success), "syncRemote"), ]); if (syncSuccess) { diff --git a/mobile/lib/providers/infrastructure/action.provider.dart b/mobile/lib/providers/infrastructure/action.provider.dart index 9467f63483..d4d850d8c1 100644 --- a/mobile/lib/providers/infrastructure/action.provider.dart +++ b/mobile/lib/providers/infrastructure/action.provider.dart @@ -264,9 +264,8 @@ class ActionNotifier extends Notifier { } Future deleteLocal(ActionSource source, BuildContext context) async { - // Always perform the operation if there is only one merged asset final assets = _getAssets(source); - bool? backedUpOnly = assets.length == 1 && assets.first.storage == AssetState.merged + bool? backedUpOnly = assets.every((asset) => asset.storage == AssetState.merged) ? true : await showDialog( context: context, @@ -302,6 +301,13 @@ class ActionNotifier extends Notifier { return null; } + // This must be called since editing location + // does not update the currentAsset which means + // the exif provider will not be refreshed automatically + if (source == ActionSource.viewer) { + ref.invalidate(currentAssetExifProvider); + } + return ActionResult(count: ids.length, success: true); } catch (error, stack) { _logger.severe('Failed to edit location for assets', error, stack); diff --git a/mobile/lib/providers/infrastructure/remote_album.provider.dart b/mobile/lib/providers/infrastructure/remote_album.provider.dart index 38ba52dc56..e3cffeb093 100644 --- a/mobile/lib/providers/infrastructure/remote_album.provider.dart +++ b/mobile/lib/providers/infrastructure/remote_album.provider.dart @@ -5,6 +5,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; import 'package:logging/logging.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -70,7 +71,7 @@ class RemoteAlbumNotifier extends Notifier { Future> sortAlbums( List albums, - RemoteAlbumSortMode sortMode, { + AlbumSortMode sortMode, { bool isReverse = false, }) async { return await _remoteAlbumService.sortAlbums(albums, sortMode, isReverse: isReverse); diff --git a/mobile/lib/providers/timeline/multiselect.provider.dart b/mobile/lib/providers/timeline/multiselect.provider.dart index 6949413cd9..0b3f7e610b 100644 --- a/mobile/lib/providers/timeline/multiselect.provider.dart +++ b/mobile/lib/providers/timeline/multiselect.provider.dart @@ -2,7 +2,6 @@ import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; -import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; final multiSelectProvider = NotifierProvider( @@ -10,11 +9,6 @@ final multiSelectProvider = NotifierProvider selectedAssets; final Set lockedSelectionAssets; diff --git a/mobile/lib/routing/router.dart b/mobile/lib/routing/router.dart index abe7ac3fa2..30f43cf3b2 100644 --- a/mobile/lib/routing/router.dart +++ b/mobile/lib/routing/router.dart @@ -245,23 +245,15 @@ class AppRouter extends RootStackRouter { guards: [_authGuard, _duplicateGuard], transitionsBuilder: TransitionsBuilders.slideLeft, ), - CustomRoute(page: FolderRoute.page, guards: [_authGuard], transitionsBuilder: TransitionsBuilders.fadeIn), + AutoRoute(page: FolderRoute.page, guards: [_authGuard]), AutoRoute(page: PartnerDetailRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: PersonResultRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: AllPeopleRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: MemoryRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: MapRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: AlbumOptionsRoute.page, guards: [_authGuard, _duplicateGuard]), - CustomRoute( - page: TrashRoute.page, - guards: [_authGuard, _duplicateGuard], - transitionsBuilder: TransitionsBuilders.slideLeft, - ), - CustomRoute( - page: SharedLinkRoute.page, - guards: [_authGuard, _duplicateGuard], - transitionsBuilder: TransitionsBuilders.slideLeft, - ), + AutoRoute(page: TrashRoute.page, guards: [_authGuard, _duplicateGuard]), + AutoRoute(page: SharedLinkRoute.page, guards: [_authGuard, _duplicateGuard]), AutoRoute(page: SharedLinkEditRoute.page, guards: [_authGuard, _duplicateGuard]), CustomRoute( page: ActivitiesRoute.page, diff --git a/mobile/lib/services/action.service.dart b/mobile/lib/services/action.service.dart index 59b627ecc3..4261613a19 100644 --- a/mobile/lib/services/action.service.dart +++ b/mobile/lib/services/action.service.dart @@ -15,6 +15,7 @@ import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/repositories/download.repository.dart'; import 'package:immich_mobile/repositories/drift_album_api_repository.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/utils/timezone.dart'; import 'package:immich_mobile/widgets/common/date_time_picker.dart'; import 'package:immich_mobile/widgets/common/location_picker.dart'; import 'package:maplibre_gl/maplibre_gl.dart' as maplibre; @@ -175,9 +176,17 @@ class ActionService { } final exifData = await _remoteAssetRepository.getExif(assetId); - initialDate = asset.createdAt.toLocal(); - offset = initialDate.timeZoneOffset; - timeZone = exifData?.timeZone; + + // Use EXIF timezone information if available (matching web app and display behavior) + DateTime dt = asset.createdAt.toLocal(); + offset = dt.timeZoneOffset; + + if (exifData?.dateTimeOriginal != null) { + timeZone = exifData!.timeZone; + (dt, offset) = applyTimezoneOffset(dateTime: exifData.dateTimeOriginal!, timeZone: exifData.timeZone); + } + + initialDate = dt; } final dateTime = await showDateTimePicker( diff --git a/mobile/lib/services/app_settings.service.dart b/mobile/lib/services/app_settings.service.dart index 788562d50d..1c48d9e868 100644 --- a/mobile/lib/services/app_settings.service.dart +++ b/mobile/lib/services/app_settings.service.dart @@ -52,9 +52,10 @@ enum AppSettingsEnum { enableBackup(StoreKey.enableBackup, null, false), useCellularForUploadVideos(StoreKey.useWifiForUploadVideos, null, false), useCellularForUploadPhotos(StoreKey.useWifiForUploadPhotos, null, false), + readonlyModeEnabled(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false), + albumGridView(StoreKey.albumGridView, "albumGridView", false), backupRequireCharging(StoreKey.backupRequireCharging, null, false), - backupTriggerDelay(StoreKey.backupTriggerDelay, null, 30), - readonlyModeEnabled(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false); + backupTriggerDelay(StoreKey.backupTriggerDelay, null, 30); const AppSettingsEnum(this.storeKey, this.hiveKey, this.defaultValue); diff --git a/mobile/lib/utils/album_filter.utils.dart b/mobile/lib/utils/album_filter.utils.dart index 02142b1571..8f9363d4d9 100644 --- a/mobile/lib/utils/album_filter.utils.dart +++ b/mobile/lib/utils/album_filter.utils.dart @@ -1,5 +1,5 @@ -import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; class AlbumFilter { String? userId; @@ -14,12 +14,12 @@ class AlbumFilter { } class AlbumSort { - RemoteAlbumSortMode mode; + AlbumSortMode mode; bool isReverse; AlbumSort({required this.mode, this.isReverse = false}); - AlbumSort copyWith({RemoteAlbumSortMode? mode, bool? isReverse}) { + AlbumSort copyWith({AlbumSortMode? mode, bool? isReverse}) { return AlbumSort(mode: mode ?? this.mode, isReverse: isReverse ?? this.isReverse); } } diff --git a/mobile/lib/utils/migration.dart b/mobile/lib/utils/migration.dart index 2ed6d9549f..35cdc7addf 100644 --- a/mobile/lib/utils/migration.dart +++ b/mobile/lib/utils/migration.dart @@ -22,14 +22,16 @@ import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; +import 'package:immich_mobile/platform/native_sync_api.g.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; +import 'package:immich_mobile/utils/datetime_helpers.dart'; import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/diff.dart'; import 'package:isar/isar.dart'; // ignore: import_rule_photo_manager import 'package:photo_manager/photo_manager.dart'; -const int targetVersion = 17; +const int targetVersion = 19; Future migrateDatabaseIfNeeded(Isar db, Drift drift) async { final hasVersion = Store.tryGet(StoreKey.version) != null; @@ -63,7 +65,8 @@ Future migrateDatabaseIfNeeded(Isar db, Drift drift) async { await Store.populateCache(); } - await handleBetaMigration(version, await _isNewInstallation(db, drift), SyncStreamRepository(drift)); + final syncStreamRepository = SyncStreamRepository(drift); + await handleBetaMigration(version, await _isNewInstallation(db, drift), syncStreamRepository); if (version < 17 && Store.isBetaTimelineEnabled) { final delay = Store.get(StoreKey.backupTriggerDelay, AppSettingsEnum.backupTriggerDelay.defaultValue); @@ -72,6 +75,17 @@ Future migrateDatabaseIfNeeded(Isar db, Drift drift) async { } } + if (version < 18 && Store.isBetaTimelineEnabled) { + await syncStreamRepository.reset(); + await Store.put(StoreKey.shouldResetSync, true); + } + + if (version < 19 && Store.isBetaTimelineEnabled) { + if (!await _populateLocalAssetTime(drift)) { + return; + } + } + if (targetVersion >= 12) { await Store.put(StoreKey.version, targetVersion); return; @@ -215,6 +229,35 @@ Future _migrateDeviceAsset(Isar db) async { }); } +Future _populateLocalAssetTime(Drift db) async { + try { + final nativeApi = NativeSyncApi(); + final albums = await nativeApi.getAlbums(); + for (final album in albums) { + final assets = await nativeApi.getAssetsForAlbum(album.id); + await db.batch((batch) async { + for (final asset in assets) { + batch.update( + db.localAssetEntity, + LocalAssetEntityCompanion( + longitude: Value(asset.longitude), + latitude: Value(asset.latitude), + adjustmentTime: Value(tryFromSecondsSinceEpoch(asset.adjustmentTime, isUtc: true)), + updatedAt: Value(tryFromSecondsSinceEpoch(asset.updatedAt, isUtc: true) ?? DateTime.timestamp()), + ), + where: (t) => t.id.equals(asset.id), + ); + } + }); + } + + return true; + } catch (error) { + dPrint(() => "[MIGRATION] Error while populating asset time: $error"); + return false; + } +} + Future migrateDeviceAssetToSqlite(Isar db, Drift drift) async { try { final isarDeviceAssets = await db.deviceAssetEntitys.where().findAll(); diff --git a/mobile/lib/utils/timezone.dart b/mobile/lib/utils/timezone.dart new file mode 100644 index 0000000000..d75122062f --- /dev/null +++ b/mobile/lib/utils/timezone.dart @@ -0,0 +1,35 @@ +import 'package:timezone/timezone.dart'; + +/// Applies timezone conversion to a DateTime using EXIF timezone information. +/// +/// This function handles two timezone formats: +/// 1. Named timezone locations (e.g., "Asia/Hong_Kong") +/// 2. UTC offset format (e.g., "UTC+08:00", "UTC-05:00") +/// +/// Returns a tuple of (adjusted DateTime, timezone offset Duration) +(DateTime, Duration) applyTimezoneOffset({required DateTime dateTime, required String? timeZone}) { + DateTime dt = dateTime.toUtc(); + + if (timeZone == null) { + return (dt, dt.timeZoneOffset); + } + + try { + // Try to get timezone location from database + final location = getLocation(timeZone); + dt = TZDateTime.from(dt, location); + return (dt, dt.timeZoneOffset); + } on LocationNotFoundException { + // Handle UTC offset format (e.g., "UTC+08:00") + RegExp re = RegExp(r'^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$', caseSensitive: false); + final m = re.firstMatch(timeZone); + if (m != null) { + final duration = Duration(hours: int.parse(m.group(1) ?? '0'), minutes: int.parse(m.group(2) ?? '0')); + dt = dt.add(duration); + return (dt, duration); + } + } + + // If timezone is invalid, return UTC + return (dt, dt.timeZoneOffset); +} diff --git a/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart b/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart index c6a557964d..53fc32ddb3 100644 --- a/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart +++ b/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart @@ -193,7 +193,7 @@ class ImmichAppBarDialog extends HookConsumerWidget { InkWell( onTap: () { context.pop(); - launchUrl(Uri.parse('https://immich.app'), mode: LaunchMode.externalApplication); + launchUrl(Uri.parse('https://docs.immich.app'), mode: LaunchMode.externalApplication); }, child: Text("documentation", style: context.textTheme.bodySmall).tr(), ), diff --git a/mobile/lib/widgets/common/location_picker.dart b/mobile/lib/widgets/common/location_picker.dart index 1f63299dd7..4736b182ed 100644 --- a/mobile/lib/widgets/common/location_picker.dart +++ b/mobile/lib/widgets/common/location_picker.dart @@ -5,7 +5,6 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/string_extensions.dart'; -import 'package:immich_mobile/widgets/map/map_thumbnail.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; @@ -17,19 +16,36 @@ Future showLocationPicker({required BuildContext context, LatLng? initi ); } -enum _LocationPickerMode { map, manual } - class _LocationPicker extends HookWidget { final LatLng? initialLatLng; const _LocationPicker({this.initialLatLng}); + bool _validateLat(String value) { + final l = double.tryParse(value); + return l != null && l > -90 && l < 90; + } + + bool _validateLong(String value) { + final l = double.tryParse(value); + return l != null && l > -180 && l < 180; + } + @override Widget build(BuildContext context) { final latitude = useState(initialLatLng?.latitude ?? 0.0); final longitude = useState(initialLatLng?.longitude ?? 0.0); final latlng = LatLng(latitude.value, longitude.value); - final pickerMode = useState(_LocationPickerMode.map); + final latitiudeFocusNode = useFocusNode(); + final longitudeFocusNode = useFocusNode(); + final latitudeController = useTextEditingController(text: latitude.value.toStringAsFixed(4)); + final longitudeController = useTextEditingController(text: longitude.value.toStringAsFixed(4)); + + useEffect(() { + latitudeController.text = latitude.value.toStringAsFixed(4); + longitudeController.text = longitude.value.toStringAsFixed(4); + return null; + }, [latitude.value, longitude.value]); Future onMapTap() async { final newLatLng = await context.pushRoute(MapLocationPickerRoute(initialLatLng: latlng)); @@ -39,23 +55,55 @@ class _LocationPicker extends HookWidget { } } + void onLatitudeUpdated(double value) { + latitude.value = value; + longitudeFocusNode.requestFocus(); + } + + void onLongitudeEditingCompleted(double value) { + longitude.value = value; + longitudeFocusNode.unfocus(); + } + return AlertDialog( contentPadding: const EdgeInsets.all(30), alignment: Alignment.center, content: SingleChildScrollView( - child: pickerMode.value == _LocationPickerMode.map - ? _MapPicker( - key: ValueKey(latlng), - latlng: latlng, - onModeSwitch: () => pickerMode.value = _LocationPickerMode.manual, - onMapTap: onMapTap, - ) - : _ManualPicker( - latlng: latlng, - onModeSwitch: () => pickerMode.value = _LocationPickerMode.map, - onLatUpdated: (value) => latitude.value = value, - onLonUpdated: (value) => longitude.value = value, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("edit_location_dialog_title", style: context.textTheme.titleMedium).tr(), + Align( + alignment: Alignment.center, + child: TextButton.icon( + icon: const Text("location_picker_choose_on_map").tr(), + label: const Icon(Icons.map_outlined, size: 16), + onPressed: onMapTap, ), + ), + const SizedBox(height: 12), + _ManualPickerInput( + controller: latitudeController, + decorationText: "latitude", + hintText: "location_picker_latitude_hint", + errorText: "location_picker_latitude_error", + focusNode: latitiudeFocusNode, + validator: _validateLat, + onUpdated: onLatitudeUpdated, + ), + const SizedBox(height: 24), + _ManualPickerInput( + controller: longitudeController, + decorationText: "longitude", + hintText: "location_picker_longitude_hint", + errorText: "location_picker_longitude_error", + focusNode: longitudeFocusNode, + validator: _validateLong, + onUpdated: onLongitudeEditingCompleted, + ), + ], + ), ), actions: [ TextButton( @@ -81,7 +129,7 @@ class _LocationPicker extends HookWidget { } class _ManualPickerInput extends HookWidget { - final String initialValue; + final TextEditingController controller; final String decorationText; final String hintText; final String errorText; @@ -90,7 +138,7 @@ class _ManualPickerInput extends HookWidget { final Function(double value) onUpdated; const _ManualPickerInput({ - required this.initialValue, + required this.controller, required this.decorationText, required this.hintText, required this.errorText, @@ -101,7 +149,6 @@ class _ManualPickerInput extends HookWidget { @override Widget build(BuildContext context) { final isValid = useState(true); - final controller = useTextEditingController(text: initialValue); void onEditingComplete() { isValid.value = validator(controller.text); @@ -131,109 +178,3 @@ class _ManualPickerInput extends HookWidget { ); } } - -class _ManualPicker extends HookWidget { - final LatLng latlng; - final Function() onModeSwitch; - final Function(double) onLatUpdated; - final Function(double) onLonUpdated; - - const _ManualPicker({ - required this.latlng, - required this.onModeSwitch, - required this.onLatUpdated, - required this.onLonUpdated, - }); - - bool _validateLat(String value) { - final l = double.tryParse(value); - return l != null && l > -90 && l < 90; - } - - bool _validateLong(String value) { - final l = double.tryParse(value); - return l != null && l > -180 && l < 180; - } - - @override - Widget build(BuildContext context) { - final latitiudeFocusNode = useFocusNode(); - final longitudeFocusNode = useFocusNode(); - - void onLatitudeUpdated(double value) { - onLatUpdated(value); - longitudeFocusNode.requestFocus(); - } - - void onLongitudeEditingCompleted(double value) { - onLonUpdated(value); - longitudeFocusNode.unfocus(); - } - - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text("edit_location_dialog_title", textAlign: TextAlign.center).tr(), - const SizedBox(height: 12), - TextButton.icon( - icon: const Text("location_picker_choose_on_map").tr(), - label: const Icon(Icons.map_outlined, size: 16), - onPressed: onModeSwitch, - ), - const SizedBox(height: 12), - _ManualPickerInput( - initialValue: latlng.latitude.toStringAsFixed(4), - decorationText: "latitude", - hintText: "location_picker_latitude_hint", - errorText: "location_picker_latitude_error", - focusNode: latitiudeFocusNode, - validator: _validateLat, - onUpdated: onLatitudeUpdated, - ), - const SizedBox(height: 24), - _ManualPickerInput( - initialValue: latlng.longitude.toStringAsFixed(4), - decorationText: "longitude", - hintText: "location_picker_longitude_hint", - errorText: "location_picker_longitude_error", - focusNode: longitudeFocusNode, - validator: _validateLong, - onUpdated: onLongitudeEditingCompleted, - ), - ], - ); - } -} - -class _MapPicker extends StatelessWidget { - final LatLng latlng; - final Function() onModeSwitch; - final Function() onMapTap; - - const _MapPicker({required this.latlng, required this.onModeSwitch, required this.onMapTap, super.key}); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text("edit_location_dialog_title", textAlign: TextAlign.center).tr(), - const SizedBox(height: 12), - TextButton.icon( - icon: Text("${latlng.latitude.toStringAsFixed(4)}, ${latlng.longitude.toStringAsFixed(4)}"), - label: const Icon(Icons.edit_outlined, size: 16), - onPressed: onModeSwitch, - ), - const SizedBox(height: 12), - MapThumbnail( - centre: latlng, - height: 200, - width: 200, - zoom: 8, - showMarkerPin: true, - onTap: (_, __) => onMapTap(), - ), - ], - ); - } -} diff --git a/mobile/lib/widgets/common/mesmerizing_sliver_app_bar.dart b/mobile/lib/widgets/common/mesmerizing_sliver_app_bar.dart index 73dbbfc85b..44b547a5f1 100644 --- a/mobile/lib/widgets/common/mesmerizing_sliver_app_bar.dart +++ b/mobile/lib/widgets/common/mesmerizing_sliver_app_bar.dart @@ -4,7 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; diff --git a/mobile/lib/widgets/common/person_sliver_app_bar.dart b/mobile/lib/widgets/common/person_sliver_app_bar.dart index 0f9555a101..d5a7ea7cd9 100644 --- a/mobile/lib/widgets/common/person_sliver_app_bar.dart +++ b/mobile/lib/widgets/common/person_sliver_app_bar.dart @@ -6,8 +6,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/person.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; diff --git a/mobile/lib/widgets/common/remote_album_sliver_app_bar.dart b/mobile/lib/widgets/common/remote_album_sliver_app_bar.dart index c0661bad48..c486d473b0 100644 --- a/mobile/lib/widgets/common/remote_album_sliver_app_bar.dart +++ b/mobile/lib/widgets/common/remote_album_sliver_app_bar.dart @@ -7,7 +7,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; diff --git a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart index 0296a6bd99..64c3d9b832 100644 --- a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart +++ b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart @@ -108,82 +108,80 @@ class SyncStatusAndActions extends HookConsumerWidget { ); } - return Padding( - padding: const EdgeInsets.only(top: 16, bottom: 32), - child: ListView( - children: [ - const _SyncStatsCounts(), - const Divider(height: 1, indent: 16, endIndent: 16), - const SizedBox(height: 24), - _SectionHeaderText(text: "jobs".t(context: context)), - ListTile( - title: Text( - "sync_local".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - subtitle: Text("tap_to_run_job".t(context: context)), - leading: const Icon(Icons.sync), - trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).localSyncStatus), - onTap: () { - ref.read(backgroundSyncProvider).syncLocal(full: true); - }, + return ListView( + padding: const EdgeInsets.only(top: 16, bottom: 96), + children: [ + const _SyncStatsCounts(), + const Divider(height: 1, indent: 16, endIndent: 16), + const SizedBox(height: 24), + _SectionHeaderText(text: "jobs".t(context: context)), + ListTile( + title: Text( + "sync_local".t(context: context), + style: const TextStyle(fontWeight: FontWeight.w500), ), - ListTile( - title: Text( - "sync_remote".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - subtitle: Text("tap_to_run_job".t(context: context)), - leading: const Icon(Icons.cloud_sync), - trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).remoteSyncStatus), - onTap: () { - ref.read(backgroundSyncProvider).syncRemote(); - }, + subtitle: Text("tap_to_run_job".t(context: context)), + leading: const Icon(Icons.sync), + trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).localSyncStatus), + onTap: () { + ref.read(backgroundSyncProvider).syncLocal(full: true); + }, + ), + ListTile( + title: Text( + "sync_remote".t(context: context), + style: const TextStyle(fontWeight: FontWeight.w500), ), - ListTile( - title: Text( - "hash_asset".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - leading: const Icon(Icons.tag), - subtitle: Text("tap_to_run_job".t(context: context)), - trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).hashJobStatus), - onTap: () { - ref.read(backgroundSyncProvider).hashAssets(); - }, + subtitle: Text("tap_to_run_job".t(context: context)), + leading: const Icon(Icons.cloud_sync), + trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).remoteSyncStatus), + onTap: () { + ref.read(backgroundSyncProvider).syncRemote(); + }, + ), + ListTile( + title: Text( + "hash_asset".t(context: context), + style: const TextStyle(fontWeight: FontWeight.w500), ), - const Divider(height: 1, indent: 16, endIndent: 16), - const SizedBox(height: 24), - _SectionHeaderText(text: "actions".t(context: context)), - ListTile( - title: Text( - "clear_file_cache".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - leading: const Icon(Icons.playlist_remove_rounded), - onTap: clearFileCache, + leading: const Icon(Icons.tag), + subtitle: Text("tap_to_run_job".t(context: context)), + trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).hashJobStatus), + onTap: () { + ref.read(backgroundSyncProvider).hashAssets(); + }, + ), + const Divider(height: 1, indent: 16, endIndent: 16), + const SizedBox(height: 24), + _SectionHeaderText(text: "actions".t(context: context)), + ListTile( + title: Text( + "clear_file_cache".t(context: context), + style: const TextStyle(fontWeight: FontWeight.w500), ), - ListTile( - title: Text( - "export_database".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - subtitle: Text("export_database_description".t(context: context)), - leading: const Icon(Icons.download), - onTap: exportDatabase, + leading: const Icon(Icons.playlist_remove_rounded), + onTap: clearFileCache, + ), + ListTile( + title: Text( + "export_database".t(context: context), + style: const TextStyle(fontWeight: FontWeight.w500), ), - ListTile( - title: Text( - "reset_sqlite".t(context: context), - style: TextStyle(color: context.colorScheme.error, fontWeight: FontWeight.w500), - ), - leading: Icon(Icons.settings_backup_restore_rounded, color: context.colorScheme.error), - onTap: () async { - await resetSqliteDb(context); - }, + subtitle: Text("export_database_description".t(context: context)), + leading: const Icon(Icons.download), + onTap: exportDatabase, + ), + ListTile( + title: Text( + "reset_sqlite".t(context: context), + style: TextStyle(color: context.colorScheme.error, fontWeight: FontWeight.w500), ), - ], - ), + leading: Icon(Icons.settings_backup_restore_rounded, color: context.colorScheme.error), + onTap: () async { + await resetSqliteDb(context); + }, + ), + ], ); } } diff --git a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart index 426ea5ac0f..272b83c9aa 100644 --- a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart +++ b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart @@ -86,7 +86,6 @@ class NetworkingSettings extends HookConsumerWidget { return ListView( padding: const EdgeInsets.only(bottom: 96), - physics: const ClampingScrollPhysics(), children: [ Padding( padding: const EdgeInsets.only(top: 8, left: 16, bottom: 8), diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 4e34f66a81..268c4849c5 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -3,7 +3,7 @@ Immich API This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: -- API version: 2.2.3 +- API version: 2.3.1 - Generator version: 7.8.0 - Build package: org.openapitools.codegen.languages.DartClientCodegen @@ -137,8 +137,10 @@ Class | Method | HTTP request | Description *DeprecatedApi* | [**getAllUserAssetsByDeviceId**](doc//DeprecatedApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | Retrieve assets by device ID *DeprecatedApi* | [**getDeltaSync**](doc//DeprecatedApi.md#getdeltasync) | **POST** /sync/delta-sync | Get delta sync for user *DeprecatedApi* | [**getFullSyncForUser**](doc//DeprecatedApi.md#getfullsyncforuser) | **POST** /sync/full-sync | Get full sync for user +*DeprecatedApi* | [**getQueuesLegacy**](doc//DeprecatedApi.md#getqueueslegacy) | **GET** /jobs | Retrieve queue counts and status *DeprecatedApi* | [**getRandom**](doc//DeprecatedApi.md#getrandom) | **GET** /assets/random | Get random assets *DeprecatedApi* | [**replaceAsset**](doc//DeprecatedApi.md#replaceasset) | **PUT** /assets/{id}/original | Replace asset +*DeprecatedApi* | [**runQueueCommandLegacy**](doc//DeprecatedApi.md#runqueuecommandlegacy) | **PUT** /jobs/{name} | Run jobs *DownloadApi* | [**downloadArchive**](doc//DownloadApi.md#downloadarchive) | **POST** /download/archive | Download asset archive *DownloadApi* | [**getDownloadInfo**](doc//DownloadApi.md#getdownloadinfo) | **POST** /download/info | Retrieve download information *DuplicatesApi* | [**deleteDuplicate**](doc//DuplicatesApi.md#deleteduplicate) | **DELETE** /duplicates/{id} | Delete a duplicate @@ -159,6 +161,8 @@ Class | Method | HTTP request | Description *LibrariesApi* | [**scanLibrary**](doc//LibrariesApi.md#scanlibrary) | **POST** /libraries/{id}/scan | Scan a library *LibrariesApi* | [**updateLibrary**](doc//LibrariesApi.md#updatelibrary) | **PUT** /libraries/{id} | Update a library *LibrariesApi* | [**validate**](doc//LibrariesApi.md#validate) | **POST** /libraries/{id}/validate | Validate library settings +*MaintenanceAdminApi* | [**maintenanceLogin**](doc//MaintenanceAdminApi.md#maintenancelogin) | **POST** /admin/maintenance/login | Log into maintenance mode +*MaintenanceAdminApi* | [**setMaintenanceMode**](doc//MaintenanceAdminApi.md#setmaintenancemode) | **POST** /admin/maintenance | Set maintenance mode *MapApi* | [**getMapMarkers**](doc//MapApi.md#getmapmarkers) | **GET** /map/markers | Retrieve map markers *MapApi* | [**reverseGeocode**](doc//MapApi.md#reversegeocode) | **GET** /map/reverse-geocode | Reverse geocode coordinates *MemoriesApi* | [**addMemoryAssets**](doc//MemoriesApi.md#addmemoryassets) | **PUT** /memories/{id}/assets | Add assets to a memory @@ -196,6 +200,11 @@ Class | Method | HTTP request | Description *PeopleApi* | [**updatePerson**](doc//PeopleApi.md#updateperson) | **PUT** /people/{id} | Update person *PluginsApi* | [**getPlugin**](doc//PluginsApi.md#getplugin) | **GET** /plugins/{id} | Retrieve a plugin *PluginsApi* | [**getPlugins**](doc//PluginsApi.md#getplugins) | **GET** /plugins | List all plugins +*QueuesApi* | [**emptyQueue**](doc//QueuesApi.md#emptyqueue) | **DELETE** /queues/{name}/jobs | Empty a queue +*QueuesApi* | [**getQueue**](doc//QueuesApi.md#getqueue) | **GET** /queues/{name} | Retrieve a queue +*QueuesApi* | [**getQueueJobs**](doc//QueuesApi.md#getqueuejobs) | **GET** /queues/{name}/jobs | Retrieve queue jobs +*QueuesApi* | [**getQueues**](doc//QueuesApi.md#getqueues) | **GET** /queues | List all queues +*QueuesApi* | [**updateQueue**](doc//QueuesApi.md#updatequeue) | **PUT** /queues/{name} | Update a queue *SearchApi* | [**getAssetsByCity**](doc//SearchApi.md#getassetsbycity) | **GET** /search/cities | Retrieve assets by city *SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore | Retrieve explore data *SearchApi* | [**getSearchSuggestions**](doc//SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions | Retrieve search suggestions @@ -394,6 +403,7 @@ Class | Method | HTTP request | Description - [FoldersUpdate](doc//FoldersUpdate.md) - [ImageFormat](doc//ImageFormat.md) - [JobCreateDto](doc//JobCreateDto.md) + - [JobName](doc//JobName.md) - [JobSettingsDto](doc//JobSettingsDto.md) - [LibraryResponseDto](doc//LibraryResponseDto.md) - [LibraryStatsResponseDto](doc//LibraryStatsResponseDto.md) @@ -404,6 +414,9 @@ Class | Method | HTTP request | Description - [LoginResponseDto](doc//LoginResponseDto.md) - [LogoutResponseDto](doc//LogoutResponseDto.md) - [MachineLearningAvailabilityChecksDto](doc//MachineLearningAvailabilityChecksDto.md) + - [MaintenanceAction](doc//MaintenanceAction.md) + - [MaintenanceAuthDto](doc//MaintenanceAuthDto.md) + - [MaintenanceLoginDto](doc//MaintenanceLoginDto.md) - [ManualJobName](doc//ManualJobName.md) - [MapMarkerResponseDto](doc//MapMarkerResponseDto.md) - [MapReverseGeocodeResponseDto](doc//MapReverseGeocodeResponseDto.md) @@ -460,11 +473,16 @@ Class | Method | HTTP request | Description - [PurchaseUpdate](doc//PurchaseUpdate.md) - [QueueCommand](doc//QueueCommand.md) - [QueueCommandDto](doc//QueueCommandDto.md) + - [QueueDeleteDto](doc//QueueDeleteDto.md) + - [QueueJobResponseDto](doc//QueueJobResponseDto.md) + - [QueueJobStatus](doc//QueueJobStatus.md) - [QueueName](doc//QueueName.md) - [QueueResponseDto](doc//QueueResponseDto.md) + - [QueueResponseLegacyDto](doc//QueueResponseLegacyDto.md) - [QueueStatisticsDto](doc//QueueStatisticsDto.md) - - [QueueStatusDto](doc//QueueStatusDto.md) - - [QueuesResponseDto](doc//QueuesResponseDto.md) + - [QueueStatusLegacyDto](doc//QueueStatusLegacyDto.md) + - [QueueUpdateDto](doc//QueueUpdateDto.md) + - [QueuesResponseLegacyDto](doc//QueuesResponseLegacyDto.md) - [RandomSearchDto](doc//RandomSearchDto.md) - [RatingsResponse](doc//RatingsResponse.md) - [RatingsUpdate](doc//RatingsUpdate.md) @@ -496,6 +514,7 @@ Class | Method | HTTP request | Description - [SessionResponseDto](doc//SessionResponseDto.md) - [SessionUnlockDto](doc//SessionUnlockDto.md) - [SessionUpdateDto](doc//SessionUpdateDto.md) + - [SetMaintenanceModeDto](doc//SetMaintenanceModeDto.md) - [SharedLinkCreateDto](doc//SharedLinkCreateDto.md) - [SharedLinkEditDto](doc//SharedLinkEditDto.md) - [SharedLinkResponseDto](doc//SharedLinkResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index f3db370c92..21730074aa 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -42,6 +42,7 @@ part 'api/duplicates_api.dart'; part 'api/faces_api.dart'; part 'api/jobs_api.dart'; part 'api/libraries_api.dart'; +part 'api/maintenance_admin_api.dart'; part 'api/map_api.dart'; part 'api/memories_api.dart'; part 'api/notifications_api.dart'; @@ -49,6 +50,7 @@ part 'api/notifications_admin_api.dart'; part 'api/partners_api.dart'; part 'api/people_api.dart'; part 'api/plugins_api.dart'; +part 'api/queues_api.dart'; part 'api/search_api.dart'; part 'api/server_api.dart'; part 'api/sessions_api.dart'; @@ -153,6 +155,7 @@ part 'model/folders_response.dart'; part 'model/folders_update.dart'; part 'model/image_format.dart'; part 'model/job_create_dto.dart'; +part 'model/job_name.dart'; part 'model/job_settings_dto.dart'; part 'model/library_response_dto.dart'; part 'model/library_stats_response_dto.dart'; @@ -163,6 +166,9 @@ part 'model/login_credential_dto.dart'; part 'model/login_response_dto.dart'; part 'model/logout_response_dto.dart'; part 'model/machine_learning_availability_checks_dto.dart'; +part 'model/maintenance_action.dart'; +part 'model/maintenance_auth_dto.dart'; +part 'model/maintenance_login_dto.dart'; part 'model/manual_job_name.dart'; part 'model/map_marker_response_dto.dart'; part 'model/map_reverse_geocode_response_dto.dart'; @@ -219,11 +225,16 @@ part 'model/purchase_response.dart'; part 'model/purchase_update.dart'; part 'model/queue_command.dart'; part 'model/queue_command_dto.dart'; +part 'model/queue_delete_dto.dart'; +part 'model/queue_job_response_dto.dart'; +part 'model/queue_job_status.dart'; part 'model/queue_name.dart'; part 'model/queue_response_dto.dart'; +part 'model/queue_response_legacy_dto.dart'; part 'model/queue_statistics_dto.dart'; -part 'model/queue_status_dto.dart'; -part 'model/queues_response_dto.dart'; +part 'model/queue_status_legacy_dto.dart'; +part 'model/queue_update_dto.dart'; +part 'model/queues_response_legacy_dto.dart'; part 'model/random_search_dto.dart'; part 'model/ratings_response.dart'; part 'model/ratings_update.dart'; @@ -255,6 +266,7 @@ part 'model/session_create_response_dto.dart'; part 'model/session_response_dto.dart'; part 'model/session_unlock_dto.dart'; part 'model/session_update_dto.dart'; +part 'model/set_maintenance_mode_dto.dart'; part 'model/shared_link_create_dto.dart'; part 'model/shared_link_edit_dto.dart'; part 'model/shared_link_response_dto.dart'; diff --git a/mobile/openapi/lib/api/deprecated_api.dart b/mobile/openapi/lib/api/deprecated_api.dart index aaf7c074b9..d0d92d804d 100644 --- a/mobile/openapi/lib/api/deprecated_api.dart +++ b/mobile/openapi/lib/api/deprecated_api.dart @@ -248,6 +248,54 @@ class DeprecatedApi { return null; } + /// Retrieve queue counts and status + /// + /// Retrieve the counts of the current queue, as well as the current status. + /// + /// Note: This method returns the HTTP [Response]. + Future getQueuesLegacyWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/jobs'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Retrieve queue counts and status + /// + /// Retrieve the counts of the current queue, as well as the current status. + Future getQueuesLegacy() async { + final response = await getQueuesLegacyWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueuesResponseLegacyDto',) as QueuesResponseLegacyDto; + + } + return null; + } + /// Get random assets /// /// Retrieve a specified number of random assets for the authenticated user. @@ -444,4 +492,65 @@ class DeprecatedApi { } return null; } + + /// Run jobs + /// + /// Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueCommandDto] queueCommandDto (required): + Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/jobs/{name}' + .replaceAll('{name}', name.toString()); + + // ignore: prefer_final_locals + Object? postBody = queueCommandDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Run jobs + /// + /// Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueCommandDto] queueCommandDto (required): + Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { + final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueueResponseLegacyDto',) as QueueResponseLegacyDto; + + } + return null; + } } diff --git a/mobile/openapi/lib/api/jobs_api.dart b/mobile/openapi/lib/api/jobs_api.dart index 906dce6d37..9dda59a883 100644 --- a/mobile/openapi/lib/api/jobs_api.dart +++ b/mobile/openapi/lib/api/jobs_api.dart @@ -97,7 +97,7 @@ class JobsApi { /// Retrieve queue counts and status /// /// Retrieve the counts of the current queue, as well as the current status. - Future getQueuesLegacy() async { + Future getQueuesLegacy() async { final response = await getQueuesLegacyWithHttpInfo(); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); @@ -106,7 +106,7 @@ class JobsApi { // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" // FormatException when trying to decode an empty string. if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueuesResponseDto',) as QueuesResponseDto; + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueuesResponseLegacyDto',) as QueuesResponseLegacyDto; } return null; @@ -158,7 +158,7 @@ class JobsApi { /// * [QueueName] name (required): /// /// * [QueueCommandDto] queueCommandDto (required): - Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { + Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); @@ -167,7 +167,7 @@ class JobsApi { // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" // FormatException when trying to decode an empty string. if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueueResponseDto',) as QueueResponseDto; + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueueResponseLegacyDto',) as QueueResponseLegacyDto; } return null; diff --git a/mobile/openapi/lib/api/maintenance_admin_api.dart b/mobile/openapi/lib/api/maintenance_admin_api.dart new file mode 100644 index 0000000000..7e46f96c6e --- /dev/null +++ b/mobile/openapi/lib/api/maintenance_admin_api.dart @@ -0,0 +1,122 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class MaintenanceAdminApi { + MaintenanceAdminApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Log into maintenance mode + /// + /// Login with maintenance token or cookie to receive current information and perform further actions. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [MaintenanceLoginDto] maintenanceLoginDto (required): + Future maintenanceLoginWithHttpInfo(MaintenanceLoginDto maintenanceLoginDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/admin/maintenance/login'; + + // ignore: prefer_final_locals + Object? postBody = maintenanceLoginDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Log into maintenance mode + /// + /// Login with maintenance token or cookie to receive current information and perform further actions. + /// + /// Parameters: + /// + /// * [MaintenanceLoginDto] maintenanceLoginDto (required): + Future maintenanceLogin(MaintenanceLoginDto maintenanceLoginDto,) async { + final response = await maintenanceLoginWithHttpInfo(maintenanceLoginDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'MaintenanceAuthDto',) as MaintenanceAuthDto; + + } + return null; + } + + /// Set maintenance mode + /// + /// Put Immich into or take it out of maintenance mode + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [SetMaintenanceModeDto] setMaintenanceModeDto (required): + Future setMaintenanceModeWithHttpInfo(SetMaintenanceModeDto setMaintenanceModeDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/admin/maintenance'; + + // ignore: prefer_final_locals + Object? postBody = setMaintenanceModeDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Set maintenance mode + /// + /// Put Immich into or take it out of maintenance mode + /// + /// Parameters: + /// + /// * [SetMaintenanceModeDto] setMaintenanceModeDto (required): + Future setMaintenanceMode(SetMaintenanceModeDto setMaintenanceModeDto,) async { + final response = await setMaintenanceModeWithHttpInfo(setMaintenanceModeDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } +} diff --git a/mobile/openapi/lib/api/queues_api.dart b/mobile/openapi/lib/api/queues_api.dart new file mode 100644 index 0000000000..50575ed706 --- /dev/null +++ b/mobile/openapi/lib/api/queues_api.dart @@ -0,0 +1,308 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class QueuesApi { + QueuesApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Empty a queue + /// + /// Removes all jobs from the specified queue. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueDeleteDto] queueDeleteDto (required): + Future emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/queues/{name}/jobs' + .replaceAll('{name}', name.toString()); + + // ignore: prefer_final_locals + Object? postBody = queueDeleteDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Empty a queue + /// + /// Removes all jobs from the specified queue. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueDeleteDto] queueDeleteDto (required): + Future emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto,) async { + final response = await emptyQueueWithHttpInfo(name, queueDeleteDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Retrieve a queue + /// + /// Retrieves a specific queue by its name. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + Future getQueueWithHttpInfo(QueueName name,) async { + // ignore: prefer_const_declarations + final apiPath = r'/queues/{name}' + .replaceAll('{name}', name.toString()); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Retrieve a queue + /// + /// Retrieves a specific queue by its name. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + Future getQueue(QueueName name,) async { + final response = await getQueueWithHttpInfo(name,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueueResponseDto',) as QueueResponseDto; + + } + return null; + } + + /// Retrieve queue jobs + /// + /// Retrieves a list of queue jobs from the specified queue. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [List] status: + Future getQueueJobsWithHttpInfo(QueueName name, { List? status, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/queues/{name}/jobs' + .replaceAll('{name}', name.toString()); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (status != null) { + queryParams.addAll(_queryParams('multi', 'status', status)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Retrieve queue jobs + /// + /// Retrieves a list of queue jobs from the specified queue. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [List] status: + Future?> getQueueJobs(QueueName name, { List? status, }) async { + final response = await getQueueJobsWithHttpInfo(name, status: status, ); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(growable: false); + + } + return null; + } + + /// List all queues + /// + /// Retrieves a list of queues. + /// + /// Note: This method returns the HTTP [Response]. + Future getQueuesWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/queues'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// List all queues + /// + /// Retrieves a list of queues. + Future?> getQueues() async { + final response = await getQueuesWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(growable: false); + + } + return null; + } + + /// Update a queue + /// + /// Change the paused status of a specific queue. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueUpdateDto] queueUpdateDto (required): + Future updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/queues/{name}' + .replaceAll('{name}', name.toString()); + + // ignore: prefer_final_locals + Object? postBody = queueUpdateDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Update a queue + /// + /// Change the paused status of a specific queue. + /// + /// Parameters: + /// + /// * [QueueName] name (required): + /// + /// * [QueueUpdateDto] queueUpdateDto (required): + Future updateQueue(QueueName name, QueueUpdateDto queueUpdateDto,) async { + final response = await updateQueueWithHttpInfo(name, queueUpdateDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'QueueResponseDto',) as QueueResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 91dc670d12..041be67015 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -358,6 +358,8 @@ class ApiClient { return ImageFormatTypeTransformer().decode(value); case 'JobCreateDto': return JobCreateDto.fromJson(value); + case 'JobName': + return JobNameTypeTransformer().decode(value); case 'JobSettingsDto': return JobSettingsDto.fromJson(value); case 'LibraryResponseDto': @@ -378,6 +380,12 @@ class ApiClient { return LogoutResponseDto.fromJson(value); case 'MachineLearningAvailabilityChecksDto': return MachineLearningAvailabilityChecksDto.fromJson(value); + case 'MaintenanceAction': + return MaintenanceActionTypeTransformer().decode(value); + case 'MaintenanceAuthDto': + return MaintenanceAuthDto.fromJson(value); + case 'MaintenanceLoginDto': + return MaintenanceLoginDto.fromJson(value); case 'ManualJobName': return ManualJobNameTypeTransformer().decode(value); case 'MapMarkerResponseDto': @@ -490,16 +498,26 @@ class ApiClient { return QueueCommandTypeTransformer().decode(value); case 'QueueCommandDto': return QueueCommandDto.fromJson(value); + case 'QueueDeleteDto': + return QueueDeleteDto.fromJson(value); + case 'QueueJobResponseDto': + return QueueJobResponseDto.fromJson(value); + case 'QueueJobStatus': + return QueueJobStatusTypeTransformer().decode(value); case 'QueueName': return QueueNameTypeTransformer().decode(value); case 'QueueResponseDto': return QueueResponseDto.fromJson(value); + case 'QueueResponseLegacyDto': + return QueueResponseLegacyDto.fromJson(value); case 'QueueStatisticsDto': return QueueStatisticsDto.fromJson(value); - case 'QueueStatusDto': - return QueueStatusDto.fromJson(value); - case 'QueuesResponseDto': - return QueuesResponseDto.fromJson(value); + case 'QueueStatusLegacyDto': + return QueueStatusLegacyDto.fromJson(value); + case 'QueueUpdateDto': + return QueueUpdateDto.fromJson(value); + case 'QueuesResponseLegacyDto': + return QueuesResponseLegacyDto.fromJson(value); case 'RandomSearchDto': return RandomSearchDto.fromJson(value); case 'RatingsResponse': @@ -562,6 +580,8 @@ class ApiClient { return SessionUnlockDto.fromJson(value); case 'SessionUpdateDto': return SessionUpdateDto.fromJson(value); + case 'SetMaintenanceModeDto': + return SetMaintenanceModeDto.fromJson(value); case 'SharedLinkCreateDto': return SharedLinkCreateDto.fromJson(value); case 'SharedLinkEditDto': diff --git a/mobile/openapi/lib/api_helper.dart b/mobile/openapi/lib/api_helper.dart index 4b33a07214..2c97eeb314 100644 --- a/mobile/openapi/lib/api_helper.dart +++ b/mobile/openapi/lib/api_helper.dart @@ -94,9 +94,15 @@ String parameterToString(dynamic value) { if (value is ImageFormat) { return ImageFormatTypeTransformer().encode(value).toString(); } + if (value is JobName) { + return JobNameTypeTransformer().encode(value).toString(); + } if (value is LogLevel) { return LogLevelTypeTransformer().encode(value).toString(); } + if (value is MaintenanceAction) { + return MaintenanceActionTypeTransformer().encode(value).toString(); + } if (value is ManualJobName) { return ManualJobNameTypeTransformer().encode(value).toString(); } @@ -130,6 +136,9 @@ String parameterToString(dynamic value) { if (value is QueueCommand) { return QueueCommandTypeTransformer().encode(value).toString(); } + if (value is QueueJobStatus) { + return QueueJobStatusTypeTransformer().encode(value).toString(); + } if (value is QueueName) { return QueueNameTypeTransformer().encode(value).toString(); } diff --git a/mobile/openapi/lib/model/job_name.dart b/mobile/openapi/lib/model/job_name.dart new file mode 100644 index 0000000000..038a17a8e6 --- /dev/null +++ b/mobile/openapi/lib/model/job_name.dart @@ -0,0 +1,244 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class JobName { + /// Instantiate a new enum with the provided [value]. + const JobName._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const assetDelete = JobName._(r'AssetDelete'); + static const assetDeleteCheck = JobName._(r'AssetDeleteCheck'); + static const assetDetectFacesQueueAll = JobName._(r'AssetDetectFacesQueueAll'); + static const assetDetectFaces = JobName._(r'AssetDetectFaces'); + static const assetDetectDuplicatesQueueAll = JobName._(r'AssetDetectDuplicatesQueueAll'); + static const assetDetectDuplicates = JobName._(r'AssetDetectDuplicates'); + static const assetEncodeVideoQueueAll = JobName._(r'AssetEncodeVideoQueueAll'); + static const assetEncodeVideo = JobName._(r'AssetEncodeVideo'); + static const assetEmptyTrash = JobName._(r'AssetEmptyTrash'); + static const assetExtractMetadataQueueAll = JobName._(r'AssetExtractMetadataQueueAll'); + static const assetExtractMetadata = JobName._(r'AssetExtractMetadata'); + static const assetFileMigration = JobName._(r'AssetFileMigration'); + static const assetGenerateThumbnailsQueueAll = JobName._(r'AssetGenerateThumbnailsQueueAll'); + static const assetGenerateThumbnails = JobName._(r'AssetGenerateThumbnails'); + static const auditLogCleanup = JobName._(r'AuditLogCleanup'); + static const auditTableCleanup = JobName._(r'AuditTableCleanup'); + static const databaseBackup = JobName._(r'DatabaseBackup'); + static const facialRecognitionQueueAll = JobName._(r'FacialRecognitionQueueAll'); + static const facialRecognition = JobName._(r'FacialRecognition'); + static const fileDelete = JobName._(r'FileDelete'); + static const fileMigrationQueueAll = JobName._(r'FileMigrationQueueAll'); + static const libraryDeleteCheck = JobName._(r'LibraryDeleteCheck'); + static const libraryDelete = JobName._(r'LibraryDelete'); + static const libraryRemoveAsset = JobName._(r'LibraryRemoveAsset'); + static const libraryScanAssetsQueueAll = JobName._(r'LibraryScanAssetsQueueAll'); + static const librarySyncAssets = JobName._(r'LibrarySyncAssets'); + static const librarySyncFilesQueueAll = JobName._(r'LibrarySyncFilesQueueAll'); + static const librarySyncFiles = JobName._(r'LibrarySyncFiles'); + static const libraryScanQueueAll = JobName._(r'LibraryScanQueueAll'); + static const memoryCleanup = JobName._(r'MemoryCleanup'); + static const memoryGenerate = JobName._(r'MemoryGenerate'); + static const notificationsCleanup = JobName._(r'NotificationsCleanup'); + static const notifyUserSignup = JobName._(r'NotifyUserSignup'); + static const notifyAlbumInvite = JobName._(r'NotifyAlbumInvite'); + static const notifyAlbumUpdate = JobName._(r'NotifyAlbumUpdate'); + static const userDelete = JobName._(r'UserDelete'); + static const userDeleteCheck = JobName._(r'UserDeleteCheck'); + static const userSyncUsage = JobName._(r'UserSyncUsage'); + static const personCleanup = JobName._(r'PersonCleanup'); + static const personFileMigration = JobName._(r'PersonFileMigration'); + static const personGenerateThumbnail = JobName._(r'PersonGenerateThumbnail'); + static const sessionCleanup = JobName._(r'SessionCleanup'); + static const sendMail = JobName._(r'SendMail'); + static const sidecarQueueAll = JobName._(r'SidecarQueueAll'); + static const sidecarCheck = JobName._(r'SidecarCheck'); + static const sidecarWrite = JobName._(r'SidecarWrite'); + static const smartSearchQueueAll = JobName._(r'SmartSearchQueueAll'); + static const smartSearch = JobName._(r'SmartSearch'); + static const storageTemplateMigration = JobName._(r'StorageTemplateMigration'); + static const storageTemplateMigrationSingle = JobName._(r'StorageTemplateMigrationSingle'); + static const tagCleanup = JobName._(r'TagCleanup'); + static const versionCheck = JobName._(r'VersionCheck'); + static const ocrQueueAll = JobName._(r'OcrQueueAll'); + static const ocr = JobName._(r'Ocr'); + static const workflowRun = JobName._(r'WorkflowRun'); + + /// List of all possible values in this [enum][JobName]. + static const values = [ + assetDelete, + assetDeleteCheck, + assetDetectFacesQueueAll, + assetDetectFaces, + assetDetectDuplicatesQueueAll, + assetDetectDuplicates, + assetEncodeVideoQueueAll, + assetEncodeVideo, + assetEmptyTrash, + assetExtractMetadataQueueAll, + assetExtractMetadata, + assetFileMigration, + assetGenerateThumbnailsQueueAll, + assetGenerateThumbnails, + auditLogCleanup, + auditTableCleanup, + databaseBackup, + facialRecognitionQueueAll, + facialRecognition, + fileDelete, + fileMigrationQueueAll, + libraryDeleteCheck, + libraryDelete, + libraryRemoveAsset, + libraryScanAssetsQueueAll, + librarySyncAssets, + librarySyncFilesQueueAll, + librarySyncFiles, + libraryScanQueueAll, + memoryCleanup, + memoryGenerate, + notificationsCleanup, + notifyUserSignup, + notifyAlbumInvite, + notifyAlbumUpdate, + userDelete, + userDeleteCheck, + userSyncUsage, + personCleanup, + personFileMigration, + personGenerateThumbnail, + sessionCleanup, + sendMail, + sidecarQueueAll, + sidecarCheck, + sidecarWrite, + smartSearchQueueAll, + smartSearch, + storageTemplateMigration, + storageTemplateMigrationSingle, + tagCleanup, + versionCheck, + ocrQueueAll, + ocr, + workflowRun, + ]; + + static JobName? fromJson(dynamic value) => JobNameTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = JobName.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [JobName] to String, +/// and [decode] dynamic data back to [JobName]. +class JobNameTypeTransformer { + factory JobNameTypeTransformer() => _instance ??= const JobNameTypeTransformer._(); + + const JobNameTypeTransformer._(); + + String encode(JobName data) => data.value; + + /// Decodes a [dynamic value][data] to a JobName. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + JobName? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'AssetDelete': return JobName.assetDelete; + case r'AssetDeleteCheck': return JobName.assetDeleteCheck; + case r'AssetDetectFacesQueueAll': return JobName.assetDetectFacesQueueAll; + case r'AssetDetectFaces': return JobName.assetDetectFaces; + case r'AssetDetectDuplicatesQueueAll': return JobName.assetDetectDuplicatesQueueAll; + case r'AssetDetectDuplicates': return JobName.assetDetectDuplicates; + case r'AssetEncodeVideoQueueAll': return JobName.assetEncodeVideoQueueAll; + case r'AssetEncodeVideo': return JobName.assetEncodeVideo; + case r'AssetEmptyTrash': return JobName.assetEmptyTrash; + case r'AssetExtractMetadataQueueAll': return JobName.assetExtractMetadataQueueAll; + case r'AssetExtractMetadata': return JobName.assetExtractMetadata; + case r'AssetFileMigration': return JobName.assetFileMigration; + case r'AssetGenerateThumbnailsQueueAll': return JobName.assetGenerateThumbnailsQueueAll; + case r'AssetGenerateThumbnails': return JobName.assetGenerateThumbnails; + case r'AuditLogCleanup': return JobName.auditLogCleanup; + case r'AuditTableCleanup': return JobName.auditTableCleanup; + case r'DatabaseBackup': return JobName.databaseBackup; + case r'FacialRecognitionQueueAll': return JobName.facialRecognitionQueueAll; + case r'FacialRecognition': return JobName.facialRecognition; + case r'FileDelete': return JobName.fileDelete; + case r'FileMigrationQueueAll': return JobName.fileMigrationQueueAll; + case r'LibraryDeleteCheck': return JobName.libraryDeleteCheck; + case r'LibraryDelete': return JobName.libraryDelete; + case r'LibraryRemoveAsset': return JobName.libraryRemoveAsset; + case r'LibraryScanAssetsQueueAll': return JobName.libraryScanAssetsQueueAll; + case r'LibrarySyncAssets': return JobName.librarySyncAssets; + case r'LibrarySyncFilesQueueAll': return JobName.librarySyncFilesQueueAll; + case r'LibrarySyncFiles': return JobName.librarySyncFiles; + case r'LibraryScanQueueAll': return JobName.libraryScanQueueAll; + case r'MemoryCleanup': return JobName.memoryCleanup; + case r'MemoryGenerate': return JobName.memoryGenerate; + case r'NotificationsCleanup': return JobName.notificationsCleanup; + case r'NotifyUserSignup': return JobName.notifyUserSignup; + case r'NotifyAlbumInvite': return JobName.notifyAlbumInvite; + case r'NotifyAlbumUpdate': return JobName.notifyAlbumUpdate; + case r'UserDelete': return JobName.userDelete; + case r'UserDeleteCheck': return JobName.userDeleteCheck; + case r'UserSyncUsage': return JobName.userSyncUsage; + case r'PersonCleanup': return JobName.personCleanup; + case r'PersonFileMigration': return JobName.personFileMigration; + case r'PersonGenerateThumbnail': return JobName.personGenerateThumbnail; + case r'SessionCleanup': return JobName.sessionCleanup; + case r'SendMail': return JobName.sendMail; + case r'SidecarQueueAll': return JobName.sidecarQueueAll; + case r'SidecarCheck': return JobName.sidecarCheck; + case r'SidecarWrite': return JobName.sidecarWrite; + case r'SmartSearchQueueAll': return JobName.smartSearchQueueAll; + case r'SmartSearch': return JobName.smartSearch; + case r'StorageTemplateMigration': return JobName.storageTemplateMigration; + case r'StorageTemplateMigrationSingle': return JobName.storageTemplateMigrationSingle; + case r'TagCleanup': return JobName.tagCleanup; + case r'VersionCheck': return JobName.versionCheck; + case r'OcrQueueAll': return JobName.ocrQueueAll; + case r'Ocr': return JobName.ocr; + case r'WorkflowRun': return JobName.workflowRun; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [JobNameTypeTransformer] instance. + static JobNameTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/maintenance_action.dart b/mobile/openapi/lib/model/maintenance_action.dart new file mode 100644 index 0000000000..9be628961f --- /dev/null +++ b/mobile/openapi/lib/model/maintenance_action.dart @@ -0,0 +1,85 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class MaintenanceAction { + /// Instantiate a new enum with the provided [value]. + const MaintenanceAction._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const start = MaintenanceAction._(r'start'); + static const end = MaintenanceAction._(r'end'); + + /// List of all possible values in this [enum][MaintenanceAction]. + static const values = [ + start, + end, + ]; + + static MaintenanceAction? fromJson(dynamic value) => MaintenanceActionTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MaintenanceAction.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [MaintenanceAction] to String, +/// and [decode] dynamic data back to [MaintenanceAction]. +class MaintenanceActionTypeTransformer { + factory MaintenanceActionTypeTransformer() => _instance ??= const MaintenanceActionTypeTransformer._(); + + const MaintenanceActionTypeTransformer._(); + + String encode(MaintenanceAction data) => data.value; + + /// Decodes a [dynamic value][data] to a MaintenanceAction. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + MaintenanceAction? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'start': return MaintenanceAction.start; + case r'end': return MaintenanceAction.end; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [MaintenanceActionTypeTransformer] instance. + static MaintenanceActionTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/maintenance_auth_dto.dart b/mobile/openapi/lib/model/maintenance_auth_dto.dart new file mode 100644 index 0000000000..919da5502b --- /dev/null +++ b/mobile/openapi/lib/model/maintenance_auth_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class MaintenanceAuthDto { + /// Returns a new [MaintenanceAuthDto] instance. + MaintenanceAuthDto({ + required this.username, + }); + + String username; + + @override + bool operator ==(Object other) => identical(this, other) || other is MaintenanceAuthDto && + other.username == username; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (username.hashCode); + + @override + String toString() => 'MaintenanceAuthDto[username=$username]'; + + Map toJson() { + final json = {}; + json[r'username'] = this.username; + return json; + } + + /// Returns a new [MaintenanceAuthDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static MaintenanceAuthDto? fromJson(dynamic value) { + upgradeDto(value, "MaintenanceAuthDto"); + if (value is Map) { + final json = value.cast(); + + return MaintenanceAuthDto( + username: mapValueOfType(json, r'username')!, + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MaintenanceAuthDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = MaintenanceAuthDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of MaintenanceAuthDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = MaintenanceAuthDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'username', + }; +} + diff --git a/mobile/openapi/lib/model/maintenance_login_dto.dart b/mobile/openapi/lib/model/maintenance_login_dto.dart new file mode 100644 index 0000000000..45f56bd3ba --- /dev/null +++ b/mobile/openapi/lib/model/maintenance_login_dto.dart @@ -0,0 +1,108 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class MaintenanceLoginDto { + /// Returns a new [MaintenanceLoginDto] instance. + MaintenanceLoginDto({ + this.token, + }); + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? token; + + @override + bool operator ==(Object other) => identical(this, other) || other is MaintenanceLoginDto && + other.token == token; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (token == null ? 0 : token!.hashCode); + + @override + String toString() => 'MaintenanceLoginDto[token=$token]'; + + Map toJson() { + final json = {}; + if (this.token != null) { + json[r'token'] = this.token; + } else { + // json[r'token'] = null; + } + return json; + } + + /// Returns a new [MaintenanceLoginDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static MaintenanceLoginDto? fromJson(dynamic value) { + upgradeDto(value, "MaintenanceLoginDto"); + if (value is Map) { + final json = value.cast(); + + return MaintenanceLoginDto( + token: mapValueOfType(json, r'token'), + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MaintenanceLoginDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = MaintenanceLoginDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of MaintenanceLoginDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = MaintenanceLoginDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/permission.dart b/mobile/openapi/lib/model/permission.dart index 8b05de523b..3b9a3964b6 100644 --- a/mobile/openapi/lib/model/permission.dart +++ b/mobile/openapi/lib/model/permission.dart @@ -73,6 +73,7 @@ class Permission { static const libraryPeriodStatistics = Permission._(r'library.statistics'); static const timelinePeriodRead = Permission._(r'timeline.read'); static const timelinePeriodDownload = Permission._(r'timeline.download'); + static const maintenance = Permission._(r'maintenance'); static const memoryPeriodCreate = Permission._(r'memory.create'); static const memoryPeriodRead = Permission._(r'memory.read'); static const memoryPeriodUpdate = Permission._(r'memory.update'); @@ -151,6 +152,12 @@ class Permission { static const userProfileImagePeriodRead = Permission._(r'userProfileImage.read'); static const userProfileImagePeriodUpdate = Permission._(r'userProfileImage.update'); static const userProfileImagePeriodDelete = Permission._(r'userProfileImage.delete'); + static const queuePeriodRead = Permission._(r'queue.read'); + static const queuePeriodUpdate = Permission._(r'queue.update'); + static const queueJobPeriodCreate = Permission._(r'queueJob.create'); + static const queueJobPeriodRead = Permission._(r'queueJob.read'); + static const queueJobPeriodUpdate = Permission._(r'queueJob.update'); + static const queueJobPeriodDelete = Permission._(r'queueJob.delete'); static const workflowPeriodCreate = Permission._(r'workflow.create'); static const workflowPeriodRead = Permission._(r'workflow.read'); static const workflowPeriodUpdate = Permission._(r'workflow.update'); @@ -214,6 +221,7 @@ class Permission { libraryPeriodStatistics, timelinePeriodRead, timelinePeriodDownload, + maintenance, memoryPeriodCreate, memoryPeriodRead, memoryPeriodUpdate, @@ -292,6 +300,12 @@ class Permission { userProfileImagePeriodRead, userProfileImagePeriodUpdate, userProfileImagePeriodDelete, + queuePeriodRead, + queuePeriodUpdate, + queueJobPeriodCreate, + queueJobPeriodRead, + queueJobPeriodUpdate, + queueJobPeriodDelete, workflowPeriodCreate, workflowPeriodRead, workflowPeriodUpdate, @@ -390,6 +404,7 @@ class PermissionTypeTransformer { case r'library.statistics': return Permission.libraryPeriodStatistics; case r'timeline.read': return Permission.timelinePeriodRead; case r'timeline.download': return Permission.timelinePeriodDownload; + case r'maintenance': return Permission.maintenance; case r'memory.create': return Permission.memoryPeriodCreate; case r'memory.read': return Permission.memoryPeriodRead; case r'memory.update': return Permission.memoryPeriodUpdate; @@ -468,6 +483,12 @@ class PermissionTypeTransformer { case r'userProfileImage.read': return Permission.userProfileImagePeriodRead; case r'userProfileImage.update': return Permission.userProfileImagePeriodUpdate; case r'userProfileImage.delete': return Permission.userProfileImagePeriodDelete; + case r'queue.read': return Permission.queuePeriodRead; + case r'queue.update': return Permission.queuePeriodUpdate; + case r'queueJob.create': return Permission.queueJobPeriodCreate; + case r'queueJob.read': return Permission.queueJobPeriodRead; + case r'queueJob.update': return Permission.queueJobPeriodUpdate; + case r'queueJob.delete': return Permission.queueJobPeriodDelete; case r'workflow.create': return Permission.workflowPeriodCreate; case r'workflow.read': return Permission.workflowPeriodRead; case r'workflow.update': return Permission.workflowPeriodUpdate; diff --git a/mobile/openapi/lib/model/queue_delete_dto.dart b/mobile/openapi/lib/model/queue_delete_dto.dart new file mode 100644 index 0000000000..d319238f92 --- /dev/null +++ b/mobile/openapi/lib/model/queue_delete_dto.dart @@ -0,0 +1,109 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class QueueDeleteDto { + /// Returns a new [QueueDeleteDto] instance. + QueueDeleteDto({ + this.failed, + }); + + /// If true, will also remove failed jobs from the queue. + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? failed; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueDeleteDto && + other.failed == failed; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (failed == null ? 0 : failed!.hashCode); + + @override + String toString() => 'QueueDeleteDto[failed=$failed]'; + + Map toJson() { + final json = {}; + if (this.failed != null) { + json[r'failed'] = this.failed; + } else { + // json[r'failed'] = null; + } + return json; + } + + /// Returns a new [QueueDeleteDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueDeleteDto? fromJson(dynamic value) { + upgradeDto(value, "QueueDeleteDto"); + if (value is Map) { + final json = value.cast(); + + return QueueDeleteDto( + failed: mapValueOfType(json, r'failed'), + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = QueueDeleteDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = QueueDeleteDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueDeleteDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = QueueDeleteDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/queue_job_response_dto.dart b/mobile/openapi/lib/model/queue_job_response_dto.dart new file mode 100644 index 0000000000..1bfaa56195 --- /dev/null +++ b/mobile/openapi/lib/model/queue_job_response_dto.dart @@ -0,0 +1,132 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class QueueJobResponseDto { + /// Returns a new [QueueJobResponseDto] instance. + QueueJobResponseDto({ + required this.data, + this.id, + required this.name, + required this.timestamp, + }); + + Object data; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? id; + + JobName name; + + int timestamp; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueJobResponseDto && + other.data == data && + other.id == id && + other.name == name && + other.timestamp == timestamp; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (id == null ? 0 : id!.hashCode) + + (name.hashCode) + + (timestamp.hashCode); + + @override + String toString() => 'QueueJobResponseDto[data=$data, id=$id, name=$name, timestamp=$timestamp]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + if (this.id != null) { + json[r'id'] = this.id; + } else { + // json[r'id'] = null; + } + json[r'name'] = this.name; + json[r'timestamp'] = this.timestamp; + return json; + } + + /// Returns a new [QueueJobResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueJobResponseDto? fromJson(dynamic value) { + upgradeDto(value, "QueueJobResponseDto"); + if (value is Map) { + final json = value.cast(); + + return QueueJobResponseDto( + data: mapValueOfType(json, r'data')!, + id: mapValueOfType(json, r'id'), + name: JobName.fromJson(json[r'name'])!, + timestamp: mapValueOfType(json, r'timestamp')!, + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = QueueJobResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = QueueJobResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueJobResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = QueueJobResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + 'timestamp', + }; +} + diff --git a/mobile/openapi/lib/model/queue_job_status.dart b/mobile/openapi/lib/model/queue_job_status.dart new file mode 100644 index 0000000000..03a1371cc5 --- /dev/null +++ b/mobile/openapi/lib/model/queue_job_status.dart @@ -0,0 +1,97 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class QueueJobStatus { + /// Instantiate a new enum with the provided [value]. + const QueueJobStatus._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const active = QueueJobStatus._(r'active'); + static const failed = QueueJobStatus._(r'failed'); + static const completed = QueueJobStatus._(r'completed'); + static const delayed = QueueJobStatus._(r'delayed'); + static const waiting = QueueJobStatus._(r'waiting'); + static const paused = QueueJobStatus._(r'paused'); + + /// List of all possible values in this [enum][QueueJobStatus]. + static const values = [ + active, + failed, + completed, + delayed, + waiting, + paused, + ]; + + static QueueJobStatus? fromJson(dynamic value) => QueueJobStatusTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = QueueJobStatus.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [QueueJobStatus] to String, +/// and [decode] dynamic data back to [QueueJobStatus]. +class QueueJobStatusTypeTransformer { + factory QueueJobStatusTypeTransformer() => _instance ??= const QueueJobStatusTypeTransformer._(); + + const QueueJobStatusTypeTransformer._(); + + String encode(QueueJobStatus data) => data.value; + + /// Decodes a [dynamic value][data] to a QueueJobStatus. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + QueueJobStatus? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'active': return QueueJobStatus.active; + case r'failed': return QueueJobStatus.failed; + case r'completed': return QueueJobStatus.completed; + case r'delayed': return QueueJobStatus.delayed; + case r'waiting': return QueueJobStatus.waiting; + case r'paused': return QueueJobStatus.paused; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [QueueJobStatusTypeTransformer] instance. + static QueueJobStatusTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/queue_response_dto.dart b/mobile/openapi/lib/model/queue_response_dto.dart index b20449f721..c5d4ed8e3d 100644 --- a/mobile/openapi/lib/model/queue_response_dto.dart +++ b/mobile/openapi/lib/model/queue_response_dto.dart @@ -13,32 +13,38 @@ part of openapi.api; class QueueResponseDto { /// Returns a new [QueueResponseDto] instance. QueueResponseDto({ - required this.jobCounts, - required this.queueStatus, + required this.isPaused, + required this.name, + required this.statistics, }); - QueueStatisticsDto jobCounts; + bool isPaused; - QueueStatusDto queueStatus; + QueueName name; + + QueueStatisticsDto statistics; @override bool operator ==(Object other) => identical(this, other) || other is QueueResponseDto && - other.jobCounts == jobCounts && - other.queueStatus == queueStatus; + other.isPaused == isPaused && + other.name == name && + other.statistics == statistics; @override int get hashCode => // ignore: unnecessary_parenthesis - (jobCounts.hashCode) + - (queueStatus.hashCode); + (isPaused.hashCode) + + (name.hashCode) + + (statistics.hashCode); @override - String toString() => 'QueueResponseDto[jobCounts=$jobCounts, queueStatus=$queueStatus]'; + String toString() => 'QueueResponseDto[isPaused=$isPaused, name=$name, statistics=$statistics]'; Map toJson() { final json = {}; - json[r'jobCounts'] = this.jobCounts; - json[r'queueStatus'] = this.queueStatus; + json[r'isPaused'] = this.isPaused; + json[r'name'] = this.name; + json[r'statistics'] = this.statistics; return json; } @@ -51,8 +57,9 @@ class QueueResponseDto { final json = value.cast(); return QueueResponseDto( - jobCounts: QueueStatisticsDto.fromJson(json[r'jobCounts'])!, - queueStatus: QueueStatusDto.fromJson(json[r'queueStatus'])!, + isPaused: mapValueOfType(json, r'isPaused')!, + name: QueueName.fromJson(json[r'name'])!, + statistics: QueueStatisticsDto.fromJson(json[r'statistics'])!, ); } return null; @@ -100,8 +107,9 @@ class QueueResponseDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { - 'jobCounts', - 'queueStatus', + 'isPaused', + 'name', + 'statistics', }; } diff --git a/mobile/openapi/lib/model/queue_response_legacy_dto.dart b/mobile/openapi/lib/model/queue_response_legacy_dto.dart new file mode 100644 index 0000000000..214b0b31f6 --- /dev/null +++ b/mobile/openapi/lib/model/queue_response_legacy_dto.dart @@ -0,0 +1,107 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class QueueResponseLegacyDto { + /// Returns a new [QueueResponseLegacyDto] instance. + QueueResponseLegacyDto({ + required this.jobCounts, + required this.queueStatus, + }); + + QueueStatisticsDto jobCounts; + + QueueStatusLegacyDto queueStatus; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueResponseLegacyDto && + other.jobCounts == jobCounts && + other.queueStatus == queueStatus; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (jobCounts.hashCode) + + (queueStatus.hashCode); + + @override + String toString() => 'QueueResponseLegacyDto[jobCounts=$jobCounts, queueStatus=$queueStatus]'; + + Map toJson() { + final json = {}; + json[r'jobCounts'] = this.jobCounts; + json[r'queueStatus'] = this.queueStatus; + return json; + } + + /// Returns a new [QueueResponseLegacyDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueResponseLegacyDto? fromJson(dynamic value) { + upgradeDto(value, "QueueResponseLegacyDto"); + if (value is Map) { + final json = value.cast(); + + return QueueResponseLegacyDto( + jobCounts: QueueStatisticsDto.fromJson(json[r'jobCounts'])!, + queueStatus: QueueStatusLegacyDto.fromJson(json[r'queueStatus'])!, + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = QueueResponseLegacyDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = QueueResponseLegacyDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueResponseLegacyDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = QueueResponseLegacyDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'jobCounts', + 'queueStatus', + }; +} + diff --git a/mobile/openapi/lib/model/queue_status_dto.dart b/mobile/openapi/lib/model/queue_status_legacy_dto.dart similarity index 63% rename from mobile/openapi/lib/model/queue_status_dto.dart rename to mobile/openapi/lib/model/queue_status_legacy_dto.dart index 77591affe2..88c4eac340 100644 --- a/mobile/openapi/lib/model/queue_status_dto.dart +++ b/mobile/openapi/lib/model/queue_status_legacy_dto.dart @@ -10,9 +10,9 @@ part of openapi.api; -class QueueStatusDto { - /// Returns a new [QueueStatusDto] instance. - QueueStatusDto({ +class QueueStatusLegacyDto { + /// Returns a new [QueueStatusLegacyDto] instance. + QueueStatusLegacyDto({ required this.isActive, required this.isPaused, }); @@ -22,7 +22,7 @@ class QueueStatusDto { bool isPaused; @override - bool operator ==(Object other) => identical(this, other) || other is QueueStatusDto && + bool operator ==(Object other) => identical(this, other) || other is QueueStatusLegacyDto && other.isActive == isActive && other.isPaused == isPaused; @@ -33,7 +33,7 @@ class QueueStatusDto { (isPaused.hashCode); @override - String toString() => 'QueueStatusDto[isActive=$isActive, isPaused=$isPaused]'; + String toString() => 'QueueStatusLegacyDto[isActive=$isActive, isPaused=$isPaused]'; Map toJson() { final json = {}; @@ -42,15 +42,15 @@ class QueueStatusDto { return json; } - /// Returns a new [QueueStatusDto] instance and imports its values from + /// Returns a new [QueueStatusLegacyDto] instance and imports its values from /// [value] if it's a [Map], null otherwise. // ignore: prefer_constructors_over_static_methods - static QueueStatusDto? fromJson(dynamic value) { - upgradeDto(value, "QueueStatusDto"); + static QueueStatusLegacyDto? fromJson(dynamic value) { + upgradeDto(value, "QueueStatusLegacyDto"); if (value is Map) { final json = value.cast(); - return QueueStatusDto( + return QueueStatusLegacyDto( isActive: mapValueOfType(json, r'isActive')!, isPaused: mapValueOfType(json, r'isPaused')!, ); @@ -58,11 +58,11 @@ class QueueStatusDto { return null; } - static List listFromJson(dynamic json, {bool growable = false,}) { - final result = []; + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; if (json is List && json.isNotEmpty) { for (final row in json) { - final value = QueueStatusDto.fromJson(row); + final value = QueueStatusLegacyDto.fromJson(row); if (value != null) { result.add(value); } @@ -71,12 +71,12 @@ class QueueStatusDto { return result.toList(growable: growable); } - static Map mapFromJson(dynamic json) { - final map = {}; + static Map mapFromJson(dynamic json) { + final map = {}; if (json is Map && json.isNotEmpty) { json = json.cast(); // ignore: parameter_assignments for (final entry in json.entries) { - final value = QueueStatusDto.fromJson(entry.value); + final value = QueueStatusLegacyDto.fromJson(entry.value); if (value != null) { map[entry.key] = value; } @@ -85,14 +85,14 @@ class QueueStatusDto { return map; } - // maps a json object with a list of QueueStatusDto-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; + // maps a json object with a list of QueueStatusLegacyDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; if (json is Map && json.isNotEmpty) { // ignore: parameter_assignments json = json.cast(); for (final entry in json.entries) { - map[entry.key] = QueueStatusDto.listFromJson(entry.value, growable: growable,); + map[entry.key] = QueueStatusLegacyDto.listFromJson(entry.value, growable: growable,); } } return map; diff --git a/mobile/openapi/lib/model/queue_update_dto.dart b/mobile/openapi/lib/model/queue_update_dto.dart new file mode 100644 index 0000000000..ce89e51878 --- /dev/null +++ b/mobile/openapi/lib/model/queue_update_dto.dart @@ -0,0 +1,108 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class QueueUpdateDto { + /// Returns a new [QueueUpdateDto] instance. + QueueUpdateDto({ + this.isPaused, + }); + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isPaused; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueUpdateDto && + other.isPaused == isPaused; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (isPaused == null ? 0 : isPaused!.hashCode); + + @override + String toString() => 'QueueUpdateDto[isPaused=$isPaused]'; + + Map toJson() { + final json = {}; + if (this.isPaused != null) { + json[r'isPaused'] = this.isPaused; + } else { + // json[r'isPaused'] = null; + } + return json; + } + + /// Returns a new [QueueUpdateDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueUpdateDto? fromJson(dynamic value) { + upgradeDto(value, "QueueUpdateDto"); + if (value is Map) { + final json = value.cast(); + + return QueueUpdateDto( + isPaused: mapValueOfType(json, r'isPaused'), + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = QueueUpdateDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = QueueUpdateDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueUpdateDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = QueueUpdateDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/queues_response_dto.dart b/mobile/openapi/lib/model/queues_response_legacy_dto.dart similarity index 55% rename from mobile/openapi/lib/model/queues_response_dto.dart rename to mobile/openapi/lib/model/queues_response_legacy_dto.dart index be40a56fb1..4aab6d863b 100644 --- a/mobile/openapi/lib/model/queues_response_dto.dart +++ b/mobile/openapi/lib/model/queues_response_legacy_dto.dart @@ -10,9 +10,9 @@ part of openapi.api; -class QueuesResponseDto { - /// Returns a new [QueuesResponseDto] instance. - QueuesResponseDto({ +class QueuesResponseLegacyDto { + /// Returns a new [QueuesResponseLegacyDto] instance. + QueuesResponseLegacyDto({ required this.backgroundTask, required this.backupDatabase, required this.duplicateDetection, @@ -32,42 +32,42 @@ class QueuesResponseDto { required this.workflow, }); - QueueResponseDto backgroundTask; + QueueResponseLegacyDto backgroundTask; - QueueResponseDto backupDatabase; + QueueResponseLegacyDto backupDatabase; - QueueResponseDto duplicateDetection; + QueueResponseLegacyDto duplicateDetection; - QueueResponseDto faceDetection; + QueueResponseLegacyDto faceDetection; - QueueResponseDto facialRecognition; + QueueResponseLegacyDto facialRecognition; - QueueResponseDto library_; + QueueResponseLegacyDto library_; - QueueResponseDto metadataExtraction; + QueueResponseLegacyDto metadataExtraction; - QueueResponseDto migration; + QueueResponseLegacyDto migration; - QueueResponseDto notifications; + QueueResponseLegacyDto notifications; - QueueResponseDto ocr; + QueueResponseLegacyDto ocr; - QueueResponseDto search; + QueueResponseLegacyDto search; - QueueResponseDto sidecar; + QueueResponseLegacyDto sidecar; - QueueResponseDto smartSearch; + QueueResponseLegacyDto smartSearch; - QueueResponseDto storageTemplateMigration; + QueueResponseLegacyDto storageTemplateMigration; - QueueResponseDto thumbnailGeneration; + QueueResponseLegacyDto thumbnailGeneration; - QueueResponseDto videoConversion; + QueueResponseLegacyDto videoConversion; - QueueResponseDto workflow; + QueueResponseLegacyDto workflow; @override - bool operator ==(Object other) => identical(this, other) || other is QueuesResponseDto && + bool operator ==(Object other) => identical(this, other) || other is QueuesResponseLegacyDto && other.backgroundTask == backgroundTask && other.backupDatabase == backupDatabase && other.duplicateDetection == duplicateDetection && @@ -108,7 +108,7 @@ class QueuesResponseDto { (workflow.hashCode); @override - String toString() => 'QueuesResponseDto[backgroundTask=$backgroundTask, backupDatabase=$backupDatabase, duplicateDetection=$duplicateDetection, faceDetection=$faceDetection, facialRecognition=$facialRecognition, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, notifications=$notifications, ocr=$ocr, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion, workflow=$workflow]'; + String toString() => 'QueuesResponseLegacyDto[backgroundTask=$backgroundTask, backupDatabase=$backupDatabase, duplicateDetection=$duplicateDetection, faceDetection=$faceDetection, facialRecognition=$facialRecognition, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, notifications=$notifications, ocr=$ocr, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion, workflow=$workflow]'; Map toJson() { final json = {}; @@ -132,42 +132,42 @@ class QueuesResponseDto { return json; } - /// Returns a new [QueuesResponseDto] instance and imports its values from + /// Returns a new [QueuesResponseLegacyDto] instance and imports its values from /// [value] if it's a [Map], null otherwise. // ignore: prefer_constructors_over_static_methods - static QueuesResponseDto? fromJson(dynamic value) { - upgradeDto(value, "QueuesResponseDto"); + static QueuesResponseLegacyDto? fromJson(dynamic value) { + upgradeDto(value, "QueuesResponseLegacyDto"); if (value is Map) { final json = value.cast(); - return QueuesResponseDto( - backgroundTask: QueueResponseDto.fromJson(json[r'backgroundTask'])!, - backupDatabase: QueueResponseDto.fromJson(json[r'backupDatabase'])!, - duplicateDetection: QueueResponseDto.fromJson(json[r'duplicateDetection'])!, - faceDetection: QueueResponseDto.fromJson(json[r'faceDetection'])!, - facialRecognition: QueueResponseDto.fromJson(json[r'facialRecognition'])!, - library_: QueueResponseDto.fromJson(json[r'library'])!, - metadataExtraction: QueueResponseDto.fromJson(json[r'metadataExtraction'])!, - migration: QueueResponseDto.fromJson(json[r'migration'])!, - notifications: QueueResponseDto.fromJson(json[r'notifications'])!, - ocr: QueueResponseDto.fromJson(json[r'ocr'])!, - search: QueueResponseDto.fromJson(json[r'search'])!, - sidecar: QueueResponseDto.fromJson(json[r'sidecar'])!, - smartSearch: QueueResponseDto.fromJson(json[r'smartSearch'])!, - storageTemplateMigration: QueueResponseDto.fromJson(json[r'storageTemplateMigration'])!, - thumbnailGeneration: QueueResponseDto.fromJson(json[r'thumbnailGeneration'])!, - videoConversion: QueueResponseDto.fromJson(json[r'videoConversion'])!, - workflow: QueueResponseDto.fromJson(json[r'workflow'])!, + return QueuesResponseLegacyDto( + backgroundTask: QueueResponseLegacyDto.fromJson(json[r'backgroundTask'])!, + backupDatabase: QueueResponseLegacyDto.fromJson(json[r'backupDatabase'])!, + duplicateDetection: QueueResponseLegacyDto.fromJson(json[r'duplicateDetection'])!, + faceDetection: QueueResponseLegacyDto.fromJson(json[r'faceDetection'])!, + facialRecognition: QueueResponseLegacyDto.fromJson(json[r'facialRecognition'])!, + library_: QueueResponseLegacyDto.fromJson(json[r'library'])!, + metadataExtraction: QueueResponseLegacyDto.fromJson(json[r'metadataExtraction'])!, + migration: QueueResponseLegacyDto.fromJson(json[r'migration'])!, + notifications: QueueResponseLegacyDto.fromJson(json[r'notifications'])!, + ocr: QueueResponseLegacyDto.fromJson(json[r'ocr'])!, + search: QueueResponseLegacyDto.fromJson(json[r'search'])!, + sidecar: QueueResponseLegacyDto.fromJson(json[r'sidecar'])!, + smartSearch: QueueResponseLegacyDto.fromJson(json[r'smartSearch'])!, + storageTemplateMigration: QueueResponseLegacyDto.fromJson(json[r'storageTemplateMigration'])!, + thumbnailGeneration: QueueResponseLegacyDto.fromJson(json[r'thumbnailGeneration'])!, + videoConversion: QueueResponseLegacyDto.fromJson(json[r'videoConversion'])!, + workflow: QueueResponseLegacyDto.fromJson(json[r'workflow'])!, ); } return null; } - static List listFromJson(dynamic json, {bool growable = false,}) { - final result = []; + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; if (json is List && json.isNotEmpty) { for (final row in json) { - final value = QueuesResponseDto.fromJson(row); + final value = QueuesResponseLegacyDto.fromJson(row); if (value != null) { result.add(value); } @@ -176,12 +176,12 @@ class QueuesResponseDto { return result.toList(growable: growable); } - static Map mapFromJson(dynamic json) { - final map = {}; + static Map mapFromJson(dynamic json) { + final map = {}; if (json is Map && json.isNotEmpty) { json = json.cast(); // ignore: parameter_assignments for (final entry in json.entries) { - final value = QueuesResponseDto.fromJson(entry.value); + final value = QueuesResponseLegacyDto.fromJson(entry.value); if (value != null) { map[entry.key] = value; } @@ -190,14 +190,14 @@ class QueuesResponseDto { return map; } - // maps a json object with a list of QueuesResponseDto-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; + // maps a json object with a list of QueuesResponseLegacyDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; if (json is Map && json.isNotEmpty) { // ignore: parameter_assignments json = json.cast(); for (final entry in json.entries) { - map[entry.key] = QueuesResponseDto.listFromJson(entry.value, growable: growable,); + map[entry.key] = QueuesResponseLegacyDto.listFromJson(entry.value, growable: growable,); } } return map; diff --git a/mobile/openapi/lib/model/server_config_dto.dart b/mobile/openapi/lib/model/server_config_dto.dart index 01c82af4d9..8e701472b1 100644 --- a/mobile/openapi/lib/model/server_config_dto.dart +++ b/mobile/openapi/lib/model/server_config_dto.dart @@ -17,6 +17,7 @@ class ServerConfigDto { required this.isInitialized, required this.isOnboarded, required this.loginPageMessage, + required this.maintenanceMode, required this.mapDarkStyleUrl, required this.mapLightStyleUrl, required this.oauthButtonText, @@ -33,6 +34,8 @@ class ServerConfigDto { String loginPageMessage; + bool maintenanceMode; + String mapDarkStyleUrl; String mapLightStyleUrl; @@ -51,6 +54,7 @@ class ServerConfigDto { other.isInitialized == isInitialized && other.isOnboarded == isOnboarded && other.loginPageMessage == loginPageMessage && + other.maintenanceMode == maintenanceMode && other.mapDarkStyleUrl == mapDarkStyleUrl && other.mapLightStyleUrl == mapLightStyleUrl && other.oauthButtonText == oauthButtonText && @@ -65,6 +69,7 @@ class ServerConfigDto { (isInitialized.hashCode) + (isOnboarded.hashCode) + (loginPageMessage.hashCode) + + (maintenanceMode.hashCode) + (mapDarkStyleUrl.hashCode) + (mapLightStyleUrl.hashCode) + (oauthButtonText.hashCode) + @@ -73,7 +78,7 @@ class ServerConfigDto { (userDeleteDelay.hashCode); @override - String toString() => 'ServerConfigDto[externalDomain=$externalDomain, isInitialized=$isInitialized, isOnboarded=$isOnboarded, loginPageMessage=$loginPageMessage, mapDarkStyleUrl=$mapDarkStyleUrl, mapLightStyleUrl=$mapLightStyleUrl, oauthButtonText=$oauthButtonText, publicUsers=$publicUsers, trashDays=$trashDays, userDeleteDelay=$userDeleteDelay]'; + String toString() => 'ServerConfigDto[externalDomain=$externalDomain, isInitialized=$isInitialized, isOnboarded=$isOnboarded, loginPageMessage=$loginPageMessage, maintenanceMode=$maintenanceMode, mapDarkStyleUrl=$mapDarkStyleUrl, mapLightStyleUrl=$mapLightStyleUrl, oauthButtonText=$oauthButtonText, publicUsers=$publicUsers, trashDays=$trashDays, userDeleteDelay=$userDeleteDelay]'; Map toJson() { final json = {}; @@ -81,6 +86,7 @@ class ServerConfigDto { json[r'isInitialized'] = this.isInitialized; json[r'isOnboarded'] = this.isOnboarded; json[r'loginPageMessage'] = this.loginPageMessage; + json[r'maintenanceMode'] = this.maintenanceMode; json[r'mapDarkStyleUrl'] = this.mapDarkStyleUrl; json[r'mapLightStyleUrl'] = this.mapLightStyleUrl; json[r'oauthButtonText'] = this.oauthButtonText; @@ -103,6 +109,7 @@ class ServerConfigDto { isInitialized: mapValueOfType(json, r'isInitialized')!, isOnboarded: mapValueOfType(json, r'isOnboarded')!, loginPageMessage: mapValueOfType(json, r'loginPageMessage')!, + maintenanceMode: mapValueOfType(json, r'maintenanceMode')!, mapDarkStyleUrl: mapValueOfType(json, r'mapDarkStyleUrl')!, mapLightStyleUrl: mapValueOfType(json, r'mapLightStyleUrl')!, oauthButtonText: mapValueOfType(json, r'oauthButtonText')!, @@ -160,6 +167,7 @@ class ServerConfigDto { 'isInitialized', 'isOnboarded', 'loginPageMessage', + 'maintenanceMode', 'mapDarkStyleUrl', 'mapLightStyleUrl', 'oauthButtonText', diff --git a/mobile/openapi/lib/model/set_maintenance_mode_dto.dart b/mobile/openapi/lib/model/set_maintenance_mode_dto.dart new file mode 100644 index 0000000000..c724337529 --- /dev/null +++ b/mobile/openapi/lib/model/set_maintenance_mode_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class SetMaintenanceModeDto { + /// Returns a new [SetMaintenanceModeDto] instance. + SetMaintenanceModeDto({ + required this.action, + }); + + MaintenanceAction action; + + @override + bool operator ==(Object other) => identical(this, other) || other is SetMaintenanceModeDto && + other.action == action; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (action.hashCode); + + @override + String toString() => 'SetMaintenanceModeDto[action=$action]'; + + Map toJson() { + final json = {}; + json[r'action'] = this.action; + return json; + } + + /// Returns a new [SetMaintenanceModeDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SetMaintenanceModeDto? fromJson(dynamic value) { + upgradeDto(value, "SetMaintenanceModeDto"); + if (value is Map) { + final json = value.cast(); + + return SetMaintenanceModeDto( + action: MaintenanceAction.fromJson(json[r'action'])!, + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = SetMaintenanceModeDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SetMaintenanceModeDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SetMaintenanceModeDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = SetMaintenanceModeDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'action', + }; +} + diff --git a/mobile/openapi/lib/model/workflow_action_item_dto.dart b/mobile/openapi/lib/model/workflow_action_item_dto.dart index ee0b30216d..cb0c39eae9 100644 --- a/mobile/openapi/lib/model/workflow_action_item_dto.dart +++ b/mobile/openapi/lib/model/workflow_action_item_dto.dart @@ -14,7 +14,7 @@ class WorkflowActionItemDto { /// Returns a new [WorkflowActionItemDto] instance. WorkflowActionItemDto({ this.actionConfig, - required this.actionId, + required this.pluginActionId, }); /// @@ -25,21 +25,21 @@ class WorkflowActionItemDto { /// Object? actionConfig; - String actionId; + String pluginActionId; @override bool operator ==(Object other) => identical(this, other) || other is WorkflowActionItemDto && other.actionConfig == actionConfig && - other.actionId == actionId; + other.pluginActionId == pluginActionId; @override int get hashCode => // ignore: unnecessary_parenthesis (actionConfig == null ? 0 : actionConfig!.hashCode) + - (actionId.hashCode); + (pluginActionId.hashCode); @override - String toString() => 'WorkflowActionItemDto[actionConfig=$actionConfig, actionId=$actionId]'; + String toString() => 'WorkflowActionItemDto[actionConfig=$actionConfig, pluginActionId=$pluginActionId]'; Map toJson() { final json = {}; @@ -48,7 +48,7 @@ class WorkflowActionItemDto { } else { // json[r'actionConfig'] = null; } - json[r'actionId'] = this.actionId; + json[r'pluginActionId'] = this.pluginActionId; return json; } @@ -62,7 +62,7 @@ class WorkflowActionItemDto { return WorkflowActionItemDto( actionConfig: mapValueOfType(json, r'actionConfig'), - actionId: mapValueOfType(json, r'actionId')!, + pluginActionId: mapValueOfType(json, r'pluginActionId')!, ); } return null; @@ -110,7 +110,7 @@ class WorkflowActionItemDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { - 'actionId', + 'pluginActionId', }; } diff --git a/mobile/openapi/lib/model/workflow_action_response_dto.dart b/mobile/openapi/lib/model/workflow_action_response_dto.dart index 6528f018c9..5132623e89 100644 --- a/mobile/openapi/lib/model/workflow_action_response_dto.dart +++ b/mobile/openapi/lib/model/workflow_action_response_dto.dart @@ -14,41 +14,41 @@ class WorkflowActionResponseDto { /// Returns a new [WorkflowActionResponseDto] instance. WorkflowActionResponseDto({ required this.actionConfig, - required this.actionId, required this.id, required this.order, + required this.pluginActionId, required this.workflowId, }); Object? actionConfig; - String actionId; - String id; num order; + String pluginActionId; + String workflowId; @override bool operator ==(Object other) => identical(this, other) || other is WorkflowActionResponseDto && other.actionConfig == actionConfig && - other.actionId == actionId && other.id == id && other.order == order && + other.pluginActionId == pluginActionId && other.workflowId == workflowId; @override int get hashCode => // ignore: unnecessary_parenthesis (actionConfig == null ? 0 : actionConfig!.hashCode) + - (actionId.hashCode) + (id.hashCode) + (order.hashCode) + + (pluginActionId.hashCode) + (workflowId.hashCode); @override - String toString() => 'WorkflowActionResponseDto[actionConfig=$actionConfig, actionId=$actionId, id=$id, order=$order, workflowId=$workflowId]'; + String toString() => 'WorkflowActionResponseDto[actionConfig=$actionConfig, id=$id, order=$order, pluginActionId=$pluginActionId, workflowId=$workflowId]'; Map toJson() { final json = {}; @@ -57,9 +57,9 @@ class WorkflowActionResponseDto { } else { // json[r'actionConfig'] = null; } - json[r'actionId'] = this.actionId; json[r'id'] = this.id; json[r'order'] = this.order; + json[r'pluginActionId'] = this.pluginActionId; json[r'workflowId'] = this.workflowId; return json; } @@ -74,9 +74,9 @@ class WorkflowActionResponseDto { return WorkflowActionResponseDto( actionConfig: mapValueOfType(json, r'actionConfig'), - actionId: mapValueOfType(json, r'actionId')!, id: mapValueOfType(json, r'id')!, order: num.parse('${json[r'order']}'), + pluginActionId: mapValueOfType(json, r'pluginActionId')!, workflowId: mapValueOfType(json, r'workflowId')!, ); } @@ -126,9 +126,9 @@ class WorkflowActionResponseDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { 'actionConfig', - 'actionId', 'id', 'order', + 'pluginActionId', 'workflowId', }; } diff --git a/mobile/openapi/lib/model/workflow_filter_item_dto.dart b/mobile/openapi/lib/model/workflow_filter_item_dto.dart index 5b78585c3d..bd8090b05e 100644 --- a/mobile/openapi/lib/model/workflow_filter_item_dto.dart +++ b/mobile/openapi/lib/model/workflow_filter_item_dto.dart @@ -14,7 +14,7 @@ class WorkflowFilterItemDto { /// Returns a new [WorkflowFilterItemDto] instance. WorkflowFilterItemDto({ this.filterConfig, - required this.filterId, + required this.pluginFilterId, }); /// @@ -25,21 +25,21 @@ class WorkflowFilterItemDto { /// Object? filterConfig; - String filterId; + String pluginFilterId; @override bool operator ==(Object other) => identical(this, other) || other is WorkflowFilterItemDto && other.filterConfig == filterConfig && - other.filterId == filterId; + other.pluginFilterId == pluginFilterId; @override int get hashCode => // ignore: unnecessary_parenthesis (filterConfig == null ? 0 : filterConfig!.hashCode) + - (filterId.hashCode); + (pluginFilterId.hashCode); @override - String toString() => 'WorkflowFilterItemDto[filterConfig=$filterConfig, filterId=$filterId]'; + String toString() => 'WorkflowFilterItemDto[filterConfig=$filterConfig, pluginFilterId=$pluginFilterId]'; Map toJson() { final json = {}; @@ -48,7 +48,7 @@ class WorkflowFilterItemDto { } else { // json[r'filterConfig'] = null; } - json[r'filterId'] = this.filterId; + json[r'pluginFilterId'] = this.pluginFilterId; return json; } @@ -62,7 +62,7 @@ class WorkflowFilterItemDto { return WorkflowFilterItemDto( filterConfig: mapValueOfType(json, r'filterConfig'), - filterId: mapValueOfType(json, r'filterId')!, + pluginFilterId: mapValueOfType(json, r'pluginFilterId')!, ); } return null; @@ -110,7 +110,7 @@ class WorkflowFilterItemDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { - 'filterId', + 'pluginFilterId', }; } diff --git a/mobile/openapi/lib/model/workflow_filter_response_dto.dart b/mobile/openapi/lib/model/workflow_filter_response_dto.dart index 5257c92b80..94dce27a3f 100644 --- a/mobile/openapi/lib/model/workflow_filter_response_dto.dart +++ b/mobile/openapi/lib/model/workflow_filter_response_dto.dart @@ -14,41 +14,41 @@ class WorkflowFilterResponseDto { /// Returns a new [WorkflowFilterResponseDto] instance. WorkflowFilterResponseDto({ required this.filterConfig, - required this.filterId, required this.id, required this.order, + required this.pluginFilterId, required this.workflowId, }); Object? filterConfig; - String filterId; - String id; num order; + String pluginFilterId; + String workflowId; @override bool operator ==(Object other) => identical(this, other) || other is WorkflowFilterResponseDto && other.filterConfig == filterConfig && - other.filterId == filterId && other.id == id && other.order == order && + other.pluginFilterId == pluginFilterId && other.workflowId == workflowId; @override int get hashCode => // ignore: unnecessary_parenthesis (filterConfig == null ? 0 : filterConfig!.hashCode) + - (filterId.hashCode) + (id.hashCode) + (order.hashCode) + + (pluginFilterId.hashCode) + (workflowId.hashCode); @override - String toString() => 'WorkflowFilterResponseDto[filterConfig=$filterConfig, filterId=$filterId, id=$id, order=$order, workflowId=$workflowId]'; + String toString() => 'WorkflowFilterResponseDto[filterConfig=$filterConfig, id=$id, order=$order, pluginFilterId=$pluginFilterId, workflowId=$workflowId]'; Map toJson() { final json = {}; @@ -57,9 +57,9 @@ class WorkflowFilterResponseDto { } else { // json[r'filterConfig'] = null; } - json[r'filterId'] = this.filterId; json[r'id'] = this.id; json[r'order'] = this.order; + json[r'pluginFilterId'] = this.pluginFilterId; json[r'workflowId'] = this.workflowId; return json; } @@ -74,9 +74,9 @@ class WorkflowFilterResponseDto { return WorkflowFilterResponseDto( filterConfig: mapValueOfType(json, r'filterConfig'), - filterId: mapValueOfType(json, r'filterId')!, id: mapValueOfType(json, r'id')!, order: num.parse('${json[r'order']}'), + pluginFilterId: mapValueOfType(json, r'pluginFilterId')!, workflowId: mapValueOfType(json, r'workflowId')!, ); } @@ -126,9 +126,9 @@ class WorkflowFilterResponseDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { 'filterConfig', - 'filterId', 'id', 'order', + 'pluginFilterId', 'workflowId', }; } diff --git a/mobile/pigeon/native_sync_api.dart b/mobile/pigeon/native_sync_api.dart index 822e2eddb3..ec28afb008 100644 --- a/mobile/pigeon/native_sync_api.dart +++ b/mobile/pigeon/native_sync_api.dart @@ -27,6 +27,10 @@ class PlatformAsset { final int orientation; final bool isFavorite; + final int? adjustmentTime; + final double? latitude; + final double? longitude; + const PlatformAsset({ required this.id, required this.name, @@ -38,6 +42,9 @@ class PlatformAsset { this.durationInSeconds = 0, this.orientation = 0, this.isFavorite = false, + this.adjustmentTime, + this.latitude, + this.longitude, }); } diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index d0e6031bdf..735031846f 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -452,10 +452,11 @@ packages: drift: dependency: "direct main" description: - name: drift - sha256: "14a61af39d4584faf1d73b5b35e4b758a43008cf4c0fdb0576ec8e7032c0d9a5" - url: "https://pub.dev" - source: hosted + path: drift + ref: "53ef7e9f19fe8f68416251760b4b99fe43f1c575" + resolved-ref: "53ef7e9f19fe8f68416251760b4b99fe43f1c575" + url: "https://github.com/immich-app/drift" + source: git version: "2.26.0" drift_dev: dependency: "direct dev" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 6b06d26e4d..2c2816e548 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -2,7 +2,7 @@ name: immich_mobile description: Immich - selfhosted backup media file on mobile phone publish_to: 'none' -version: 2.2.3+3026 +version: 2.3.1+3028 environment: sdk: '>=3.8.0 <4.0.0' @@ -114,6 +114,13 @@ dev_dependencies: riverpod_generator: ^2.6.1 riverpod_lint: ^2.6.1 +dependency_overrides: + drift: + git: + url: https://github.com/immich-app/drift + ref: '53ef7e9f19fe8f68416251760b4b99fe43f1c575' + path: drift/ + flutter: uses-material-design: true assets: diff --git a/mobile/test/domain/services/album.service_test.dart b/mobile/test/domain/services/album.service_test.dart index ebd94a9450..b86819536d 100644 --- a/mobile/test/domain/services/album.service_test.dart +++ b/mobile/test/domain/services/album.service_test.dart @@ -2,6 +2,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; import 'package:immich_mobile/repositories/drift_album_api_repository.dart'; import 'package:mocktail/mocktail.dart'; @@ -76,42 +77,42 @@ void main() { test('should sort correctly based on name', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.title); + final result = await sut.sortAlbums(albums, AlbumSortMode.title); expect(result, [albumA, albumB]); }); test('should sort correctly based on createdAt', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.created); + final result = await sut.sortAlbums(albums, AlbumSortMode.created); expect(result, [albumA, albumB]); }); test('should sort correctly based on updatedAt', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.lastModified); + final result = await sut.sortAlbums(albums, AlbumSortMode.lastModified); expect(result, [albumA, albumB]); }); test('should sort correctly based on assetCount', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.assetCount); + final result = await sut.sortAlbums(albums, AlbumSortMode.assetCount); expect(result, [albumA, albumB]); }); test('should sort correctly based on newestAssetTimestamp', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.mostRecent); + final result = await sut.sortAlbums(albums, AlbumSortMode.mostRecent); expect(result, [albumA, albumB]); }); test('should sort correctly based on oldestAssetTimestamp', () async { final albums = [albumB, albumA]; - final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.mostOldest); + final result = await sut.sortAlbums(albums, AlbumSortMode.mostOldest); expect(result, [albumB, albumA]); }); }); diff --git a/mobile/test/domain/services/asset.service_test.dart b/mobile/test/domain/services/asset.service_test.dart new file mode 100644 index 0000000000..5e7179ffa6 --- /dev/null +++ b/mobile/test/domain/services/asset.service_test.dart @@ -0,0 +1,165 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/domain/models/exif.model.dart'; +import 'package:immich_mobile/domain/services/asset.service.dart'; +import 'package:mocktail/mocktail.dart'; + +import '../../infrastructure/repository.mock.dart'; +import '../../test_utils.dart'; + +void main() { + late AssetService sut; + late MockRemoteAssetRepository mockRemoteAssetRepository; + late MockDriftLocalAssetRepository mockLocalAssetRepository; + + setUp(() { + mockRemoteAssetRepository = MockRemoteAssetRepository(); + mockLocalAssetRepository = MockDriftLocalAssetRepository(); + sut = AssetService( + remoteAssetRepository: mockRemoteAssetRepository, + localAssetRepository: mockLocalAssetRepository, + ); + }); + + group('getAspectRatio', () { + test('flips dimensions on Android for 90° and 270° orientations', () async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + addTearDown(() => debugDefaultTargetPlatformOverride = null); + + for (final orientation in [90, 270]) { + final localAsset = TestUtils.createLocalAsset( + id: 'local-$orientation', + width: 1920, + height: 1080, + orientation: orientation, + ); + + final result = await sut.getAspectRatio(localAsset); + + expect(result, 1080 / 1920, reason: 'Orientation $orientation should flip on Android'); + } + }); + + test('does not flip dimensions on iOS regardless of orientation', () async { + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + addTearDown(() => debugDefaultTargetPlatformOverride = null); + + for (final orientation in [0, 90, 270]) { + final localAsset = TestUtils.createLocalAsset( + id: 'local-$orientation', + width: 1920, + height: 1080, + orientation: orientation, + ); + + final result = await sut.getAspectRatio(localAsset); + + expect(result, 1920 / 1080, reason: 'iOS should never flip dimensions'); + } + }); + + test('fetches dimensions from remote repository when missing from asset', () async { + final remoteAsset = TestUtils.createRemoteAsset(id: 'remote-1', width: null, height: null); + + final exif = const ExifInfo(orientation: '1'); + + final fetchedAsset = TestUtils.createRemoteAsset(id: 'remote-1', width: 1920, height: 1080); + + when(() => mockRemoteAssetRepository.getExif('remote-1')).thenAnswer((_) async => exif); + when(() => mockRemoteAssetRepository.get('remote-1')).thenAnswer((_) async => fetchedAsset); + + final result = await sut.getAspectRatio(remoteAsset); + + expect(result, 1920 / 1080); + verify(() => mockRemoteAssetRepository.get('remote-1')).called(1); + }); + + test('fetches dimensions from local repository when missing from local asset', () async { + final localAsset = TestUtils.createLocalAsset(id: 'local-1', width: null, height: null, orientation: 0); + + final fetchedAsset = TestUtils.createLocalAsset(id: 'local-1', width: 1920, height: 1080, orientation: 0); + + when(() => mockLocalAssetRepository.get('local-1')).thenAnswer((_) async => fetchedAsset); + + final result = await sut.getAspectRatio(localAsset); + + expect(result, 1920 / 1080); + verify(() => mockLocalAssetRepository.get('local-1')).called(1); + }); + + test('returns 1.0 when dimensions are still unavailable after fetching', () async { + final remoteAsset = TestUtils.createRemoteAsset(id: 'remote-1', width: null, height: null); + + final exif = const ExifInfo(orientation: '1'); + + when(() => mockRemoteAssetRepository.getExif('remote-1')).thenAnswer((_) async => exif); + when(() => mockRemoteAssetRepository.get('remote-1')).thenAnswer((_) async => null); + + final result = await sut.getAspectRatio(remoteAsset); + + expect(result, 1.0); + }); + + test('returns 1.0 when height is zero', () async { + final remoteAsset = TestUtils.createRemoteAsset(id: 'remote-1', width: 1920, height: 0); + + final exif = const ExifInfo(orientation: '1'); + + when(() => mockRemoteAssetRepository.getExif('remote-1')).thenAnswer((_) async => exif); + + final result = await sut.getAspectRatio(remoteAsset); + + expect(result, 1.0); + }); + + test('handles local asset with remoteId and uses exif from remote', () async { + final localAsset = TestUtils.createLocalAsset( + id: 'local-1', + remoteId: 'remote-1', + width: 1920, + height: 1080, + orientation: 0, + ); + + final exif = const ExifInfo(orientation: '6'); + + when(() => mockRemoteAssetRepository.getExif('remote-1')).thenAnswer((_) async => exif); + + final result = await sut.getAspectRatio(localAsset); + + expect(result, 1080 / 1920); + }); + + test('handles various flipped EXIF orientations correctly', () async { + final flippedOrientations = ['5', '6', '7', '8', '90', '-90']; + + for (final orientation in flippedOrientations) { + final remoteAsset = TestUtils.createRemoteAsset(id: 'remote-$orientation', width: 1920, height: 1080); + + final exif = ExifInfo(orientation: orientation); + + when(() => mockRemoteAssetRepository.getExif('remote-$orientation')).thenAnswer((_) async => exif); + + final result = await sut.getAspectRatio(remoteAsset); + + expect(result, 1080 / 1920, reason: 'Orientation $orientation should flip dimensions'); + } + }); + + test('handles various non-flipped EXIF orientations correctly', () async { + final nonFlippedOrientations = ['1', '2', '3', '4']; + + for (final orientation in nonFlippedOrientations) { + final remoteAsset = TestUtils.createRemoteAsset(id: 'remote-$orientation', width: 1920, height: 1080); + + final exif = ExifInfo(orientation: orientation); + + when(() => mockRemoteAssetRepository.getExif('remote-$orientation')).thenAnswer((_) async => exif); + + final result = await sut.getAspectRatio(remoteAsset); + + expect(result, 1920 / 1080, reason: 'Orientation $orientation should NOT flip dimensions'); + } + }); + }); +} diff --git a/mobile/test/domain/services/local_sync_service_test.dart b/mobile/test/domain/services/local_sync_service_test.dart index 2f236971e0..92ab01c7e0 100644 --- a/mobile/test/domain/services/local_sync_service_test.dart +++ b/mobile/test/domain/services/local_sync_service_test.dart @@ -54,12 +54,7 @@ void main() { when(() => mockNativeSyncApi.shouldFullSync()).thenAnswer((_) async => false); when(() => mockNativeSyncApi.getMediaChanges()).thenAnswer( - (_) async => SyncDelta( - hasChanges: false, - updates: const [], - deletes: const [], - assetAlbums: const {}, - ), + (_) async => SyncDelta(hasChanges: false, updates: const [], deletes: const [], assetAlbums: const {}), ); when(() => mockNativeSyncApi.getTrashedAssets()).thenAnswer((_) async => {}); when(() => mockTrashedLocalAssetRepository.processTrashSnapshot(any())).thenAnswer((_) async {}); @@ -144,13 +139,19 @@ void main() { }); final localAssetToTrash = LocalAssetStub.image2.copyWith(id: 'local-trash', checksum: 'checksum-trash'); - when(() => mockTrashedLocalAssetRepository.getToTrash()).thenAnswer((_) async => {'album-a': [localAssetToTrash]}); + when(() => mockTrashedLocalAssetRepository.getToTrash()).thenAnswer( + (_) async => { + 'album-a': [localAssetToTrash], + }, + ); final assetEntity = MockAssetEntity(); when(() => assetEntity.getMediaUrl()).thenAnswer((_) async => 'content://local-trash'); when(() => mockStorageRepository.getAssetEntityForAsset(localAssetToTrash)).thenAnswer((_) async => assetEntity); - await sut.processTrashedAssets({'album-a': [platformAsset]}); + await sut.processTrashedAssets({ + 'album-a': [platformAsset], + }); verify(() => mockTrashedLocalAssetRepository.processTrashSnapshot(any())).called(1); verify(() => mockTrashedLocalAssetRepository.getToTrash()).called(1); @@ -159,8 +160,7 @@ void main() { verify(() => mockTrashedLocalAssetRepository.applyRestoredAssets(restoredIds)).called(1); verify(() => mockStorageRepository.getAssetEntityForAsset(localAssetToTrash)).called(1); - final moveArgs = - verify(() => mockLocalFilesManager.moveToTrash(captureAny())).captured.single as List; + final moveArgs = verify(() => mockLocalFilesManager.moveToTrash(captureAny())).captured.single as List; expect(moveArgs, ['content://local-trash']); final trashArgs = verify(() => mockTrashedLocalAssetRepository.trashLocalAsset(captureAny())).captured.single @@ -187,4 +187,25 @@ void main() { verifyNever(() => mockTrashedLocalAssetRepository.trashLocalAsset(any())); }); }); + + group('LocalSyncService - PlatformAsset conversion', () { + test('toLocalAsset uses correct updatedAt timestamp', () { + final platformAsset = PlatformAsset( + id: 'test-id', + name: 'test.jpg', + type: AssetType.image.index, + durationInSeconds: 0, + orientation: 0, + isFavorite: false, + createdAt: 1700000000, + updatedAt: 1732000000, + ); + + final localAsset = platformAsset.toLocalAsset(); + + expect(localAsset.createdAt.millisecondsSinceEpoch ~/ 1000, 1700000000); + expect(localAsset.updatedAt.millisecondsSinceEpoch ~/ 1000, 1732000000); + expect(localAsset.updatedAt, isNot(localAsset.createdAt)); + }); + }); } diff --git a/mobile/test/drift/main/generated/schema.dart b/mobile/test/drift/main/generated/schema.dart index 69dff89fb1..5e19610574 100644 --- a/mobile/test/drift/main/generated/schema.dart +++ b/mobile/test/drift/main/generated/schema.dart @@ -16,6 +16,7 @@ import 'schema_v10.dart' as v10; import 'schema_v11.dart' as v11; import 'schema_v12.dart' as v12; import 'schema_v13.dart' as v13; +import 'schema_v14.dart' as v14; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -47,10 +48,12 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v12.DatabaseAtV12(db); case 13: return v13.DatabaseAtV13(db); + case 14: + return v14.DatabaseAtV14(db); default: throw MissingSchemaException(version, versions); } } - static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; } diff --git a/mobile/test/drift/main/generated/schema_v14.dart b/mobile/test/drift/main/generated/schema_v14.dart new file mode 100644 index 0000000000..242aa581f3 --- /dev/null +++ b/mobile/test/drift/main/generated/schema_v14.dart @@ -0,0 +1,7878 @@ +// dart format width=80 +// GENERATED CODE, DO NOT EDIT BY HAND. +// ignore_for_file: type=lint +import 'package:drift/drift.dart'; + +class UserEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("has_profile_image" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = + GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + id, + name, + email, + hasProfileImage, + profileChangedAt, + avatarColor, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_entity'; + @override + Set get $primaryKey => {id}; + @override + UserEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + email: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}email'], + )!, + hasProfileImage: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}profile_changed_at'], + )!, + avatarColor: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}avatar_color'], + )!, + ); + } + + @override + UserEntity createAlias(String alias) { + return UserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class UserEntityData extends DataClass implements Insertable { + final String id; + final String name; + final String email; + final bool hasProfileImage; + final DateTime profileChangedAt; + final int avatarColor; + const UserEntityData({ + required this.id, + required this.name, + required this.email, + required this.hasProfileImage, + required this.profileChangedAt, + required this.avatarColor, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['email'] = Variable(email); + map['has_profile_image'] = Variable(hasProfileImage); + map['profile_changed_at'] = Variable(profileChangedAt); + map['avatar_color'] = Variable(avatarColor); + return map; + } + + factory UserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + email: serializer.fromJson(json['email']), + hasProfileImage: serializer.fromJson(json['hasProfileImage']), + profileChangedAt: serializer.fromJson(json['profileChangedAt']), + avatarColor: serializer.fromJson(json['avatarColor']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'email': serializer.toJson(email), + 'hasProfileImage': serializer.toJson(hasProfileImage), + 'profileChangedAt': serializer.toJson(profileChangedAt), + 'avatarColor': serializer.toJson(avatarColor), + }; + } + + UserEntityData copyWith({ + String? id, + String? name, + String? email, + bool? hasProfileImage, + DateTime? profileChangedAt, + int? avatarColor, + }) => UserEntityData( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + ); + UserEntityData copyWithCompanion(UserEntityCompanion data) { + return UserEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + email: data.email.present ? data.email.value : this.email, + hasProfileImage: data.hasProfileImage.present + ? data.hasProfileImage.value + : this.hasProfileImage, + profileChangedAt: data.profileChangedAt.present + ? data.profileChangedAt.value + : this.profileChangedAt, + avatarColor: data.avatarColor.present + ? data.avatarColor.value + : this.avatarColor, + ); + } + + @override + String toString() { + return (StringBuffer('UserEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + email, + hasProfileImage, + profileChangedAt, + avatarColor, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserEntityData && + other.id == this.id && + other.name == this.name && + other.email == this.email && + other.hasProfileImage == this.hasProfileImage && + other.profileChangedAt == this.profileChangedAt && + other.avatarColor == this.avatarColor); +} + +class UserEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value email; + final Value hasProfileImage; + final Value profileChangedAt; + final Value avatarColor; + const UserEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.email = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + }); + UserEntityCompanion.insert({ + required String id, + required String name, + required String email, + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + }) : id = Value(id), + name = Value(name), + email = Value(email); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? email, + Expression? hasProfileImage, + Expression? profileChangedAt, + Expression? avatarColor, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (email != null) 'email': email, + if (hasProfileImage != null) 'has_profile_image': hasProfileImage, + if (profileChangedAt != null) 'profile_changed_at': profileChangedAt, + if (avatarColor != null) 'avatar_color': avatarColor, + }); + } + + UserEntityCompanion copyWith({ + Value? id, + Value? name, + Value? email, + Value? hasProfileImage, + Value? profileChangedAt, + Value? avatarColor, + }) { + return UserEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (email.present) { + map['email'] = Variable(email.value); + } + if (hasProfileImage.present) { + map['has_profile_image'] = Variable(hasProfileImage.value); + } + if (profileChangedAt.present) { + map['profile_changed_at'] = Variable(profileChangedAt.value); + } + if (avatarColor.present) { + map['avatar_color'] = Variable(avatarColor.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor') + ..write(')')) + .toString(); + } +} + +class RemoteAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn durationInSeconds = GeneratedColumn( + 'duration_in_seconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn localDateTime = + GeneratedColumn( + 'local_date_time', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn thumbHash = GeneratedColumn( + 'thumb_hash', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn livePhotoVideoId = GeneratedColumn( + 'live_photo_video_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn visibility = GeneratedColumn( + 'visibility', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn stackId = GeneratedColumn( + 'stack_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn libraryId = GeneratedColumn( + 'library_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_asset_entity'; + @override + Set get $primaryKey => {id}; + @override + RemoteAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationInSeconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_in_seconds'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + )!, + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + localDateTime: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}local_date_time'], + ), + thumbHash: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumb_hash'], + ), + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}deleted_at'], + ), + livePhotoVideoId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}live_photo_video_id'], + ), + visibility: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}visibility'], + )!, + stackId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}stack_id'], + ), + libraryId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}library_id'], + ), + ); + } + + @override + RemoteAssetEntity createAlias(String alias) { + return RemoteAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final DateTime createdAt; + final DateTime updatedAt; + final int? width; + final int? height; + final int? durationInSeconds; + final String id; + final String checksum; + final bool isFavorite; + final String ownerId; + final DateTime? localDateTime; + final String? thumbHash; + final DateTime? deletedAt; + final String? livePhotoVideoId; + final int visibility; + final String? stackId; + final String? libraryId; + const RemoteAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationInSeconds, + required this.id, + required this.checksum, + required this.isFavorite, + required this.ownerId, + this.localDateTime, + this.thumbHash, + this.deletedAt, + this.livePhotoVideoId, + required this.visibility, + this.stackId, + this.libraryId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['name'] = Variable(name); + map['type'] = Variable(type); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || durationInSeconds != null) { + map['duration_in_seconds'] = Variable(durationInSeconds); + } + map['id'] = Variable(id); + map['checksum'] = Variable(checksum); + map['is_favorite'] = Variable(isFavorite); + map['owner_id'] = Variable(ownerId); + if (!nullToAbsent || localDateTime != null) { + map['local_date_time'] = Variable(localDateTime); + } + if (!nullToAbsent || thumbHash != null) { + map['thumb_hash'] = Variable(thumbHash); + } + if (!nullToAbsent || deletedAt != null) { + map['deleted_at'] = Variable(deletedAt); + } + if (!nullToAbsent || livePhotoVideoId != null) { + map['live_photo_video_id'] = Variable(livePhotoVideoId); + } + map['visibility'] = Variable(visibility); + if (!nullToAbsent || stackId != null) { + map['stack_id'] = Variable(stackId); + } + if (!nullToAbsent || libraryId != null) { + map['library_id'] = Variable(libraryId); + } + return map; + } + + factory RemoteAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAssetEntityData( + name: serializer.fromJson(json['name']), + type: serializer.fromJson(json['type']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + width: serializer.fromJson(json['width']), + height: serializer.fromJson(json['height']), + durationInSeconds: serializer.fromJson(json['durationInSeconds']), + id: serializer.fromJson(json['id']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + ownerId: serializer.fromJson(json['ownerId']), + localDateTime: serializer.fromJson(json['localDateTime']), + thumbHash: serializer.fromJson(json['thumbHash']), + deletedAt: serializer.fromJson(json['deletedAt']), + livePhotoVideoId: serializer.fromJson(json['livePhotoVideoId']), + visibility: serializer.fromJson(json['visibility']), + stackId: serializer.fromJson(json['stackId']), + libraryId: serializer.fromJson(json['libraryId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'name': serializer.toJson(name), + 'type': serializer.toJson(type), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'width': serializer.toJson(width), + 'height': serializer.toJson(height), + 'durationInSeconds': serializer.toJson(durationInSeconds), + 'id': serializer.toJson(id), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'ownerId': serializer.toJson(ownerId), + 'localDateTime': serializer.toJson(localDateTime), + 'thumbHash': serializer.toJson(thumbHash), + 'deletedAt': serializer.toJson(deletedAt), + 'livePhotoVideoId': serializer.toJson(livePhotoVideoId), + 'visibility': serializer.toJson(visibility), + 'stackId': serializer.toJson(stackId), + 'libraryId': serializer.toJson(libraryId), + }; + } + + RemoteAssetEntityData copyWith({ + String? name, + int? type, + DateTime? createdAt, + DateTime? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationInSeconds = const Value.absent(), + String? id, + String? checksum, + bool? isFavorite, + String? ownerId, + Value localDateTime = const Value.absent(), + Value thumbHash = const Value.absent(), + Value deletedAt = const Value.absent(), + Value livePhotoVideoId = const Value.absent(), + int? visibility, + Value stackId = const Value.absent(), + Value libraryId = const Value.absent(), + }) => RemoteAssetEntityData( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width.present ? width.value : this.width, + height: height.present ? height.value : this.height, + durationInSeconds: durationInSeconds.present + ? durationInSeconds.value + : this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + ownerId: ownerId ?? this.ownerId, + localDateTime: localDateTime.present + ? localDateTime.value + : this.localDateTime, + thumbHash: thumbHash.present ? thumbHash.value : this.thumbHash, + deletedAt: deletedAt.present ? deletedAt.value : this.deletedAt, + livePhotoVideoId: livePhotoVideoId.present + ? livePhotoVideoId.value + : this.livePhotoVideoId, + visibility: visibility ?? this.visibility, + stackId: stackId.present ? stackId.value : this.stackId, + libraryId: libraryId.present ? libraryId.value : this.libraryId, + ); + RemoteAssetEntityData copyWithCompanion(RemoteAssetEntityCompanion data) { + return RemoteAssetEntityData( + name: data.name.present ? data.name.value : this.name, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + width: data.width.present ? data.width.value : this.width, + height: data.height.present ? data.height.value : this.height, + durationInSeconds: data.durationInSeconds.present + ? data.durationInSeconds.value + : this.durationInSeconds, + id: data.id.present ? data.id.value : this.id, + checksum: data.checksum.present ? data.checksum.value : this.checksum, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + localDateTime: data.localDateTime.present + ? data.localDateTime.value + : this.localDateTime, + thumbHash: data.thumbHash.present ? data.thumbHash.value : this.thumbHash, + deletedAt: data.deletedAt.present ? data.deletedAt.value : this.deletedAt, + livePhotoVideoId: data.livePhotoVideoId.present + ? data.livePhotoVideoId.value + : this.livePhotoVideoId, + visibility: data.visibility.present + ? data.visibility.value + : this.visibility, + stackId: data.stackId.present ? data.stackId.value : this.stackId, + libraryId: data.libraryId.present ? data.libraryId.value : this.libraryId, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAssetEntityData && + other.name == this.name && + other.type == this.type && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.width == this.width && + other.height == this.height && + other.durationInSeconds == this.durationInSeconds && + other.id == this.id && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.ownerId == this.ownerId && + other.localDateTime == this.localDateTime && + other.thumbHash == this.thumbHash && + other.deletedAt == this.deletedAt && + other.livePhotoVideoId == this.livePhotoVideoId && + other.visibility == this.visibility && + other.stackId == this.stackId && + other.libraryId == this.libraryId); +} + +class RemoteAssetEntityCompanion + extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationInSeconds; + final Value id; + final Value checksum; + final Value isFavorite; + final Value ownerId; + final Value localDateTime; + final Value thumbHash; + final Value deletedAt; + final Value livePhotoVideoId; + final Value visibility; + final Value stackId; + final Value libraryId; + const RemoteAssetEntityCompanion({ + this.name = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + this.id = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.ownerId = const Value.absent(), + this.localDateTime = const Value.absent(), + this.thumbHash = const Value.absent(), + this.deletedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + this.visibility = const Value.absent(), + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + }); + RemoteAssetEntityCompanion.insert({ + required String name, + required int type, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + required String id, + required String checksum, + this.isFavorite = const Value.absent(), + required String ownerId, + this.localDateTime = const Value.absent(), + this.thumbHash = const Value.absent(), + this.deletedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + required int visibility, + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id), + checksum = Value(checksum), + ownerId = Value(ownerId), + visibility = Value(visibility); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationInSeconds, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? ownerId, + Expression? localDateTime, + Expression? thumbHash, + Expression? deletedAt, + Expression? livePhotoVideoId, + Expression? visibility, + Expression? stackId, + Expression? libraryId, + }) { + return RawValuesInsertable({ + if (name != null) 'name': name, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (width != null) 'width': width, + if (height != null) 'height': height, + if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds, + if (id != null) 'id': id, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (ownerId != null) 'owner_id': ownerId, + if (localDateTime != null) 'local_date_time': localDateTime, + if (thumbHash != null) 'thumb_hash': thumbHash, + if (deletedAt != null) 'deleted_at': deletedAt, + if (livePhotoVideoId != null) 'live_photo_video_id': livePhotoVideoId, + if (visibility != null) 'visibility': visibility, + if (stackId != null) 'stack_id': stackId, + if (libraryId != null) 'library_id': libraryId, + }); + } + + RemoteAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationInSeconds, + Value? id, + Value? checksum, + Value? isFavorite, + Value? ownerId, + Value? localDateTime, + Value? thumbHash, + Value? deletedAt, + Value? livePhotoVideoId, + Value? visibility, + Value? stackId, + Value? libraryId, + }) { + return RemoteAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationInSeconds: durationInSeconds ?? this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + ownerId: ownerId ?? this.ownerId, + localDateTime: localDateTime ?? this.localDateTime, + thumbHash: thumbHash ?? this.thumbHash, + deletedAt: deletedAt ?? this.deletedAt, + livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId, + visibility: visibility ?? this.visibility, + stackId: stackId ?? this.stackId, + libraryId: libraryId ?? this.libraryId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (name.present) { + map['name'] = Variable(name.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (durationInSeconds.present) { + map['duration_in_seconds'] = Variable(durationInSeconds.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (checksum.present) { + map['checksum'] = Variable(checksum.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (localDateTime.present) { + map['local_date_time'] = Variable(localDateTime.value); + } + if (thumbHash.present) { + map['thumb_hash'] = Variable(thumbHash.value); + } + if (deletedAt.present) { + map['deleted_at'] = Variable(deletedAt.value); + } + if (livePhotoVideoId.present) { + map['live_photo_video_id'] = Variable(livePhotoVideoId.value); + } + if (visibility.present) { + map['visibility'] = Variable(visibility.value); + } + if (stackId.present) { + map['stack_id'] = Variable(stackId.value); + } + if (libraryId.present) { + map['library_id'] = Variable(libraryId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId') + ..write(')')) + .toString(); + } +} + +class StackEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + StackEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn primaryAssetId = GeneratedColumn( + 'primary_asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + ownerId, + primaryAssetId, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'stack_entity'; + @override + Set get $primaryKey => {id}; + @override + StackEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return StackEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + primaryAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}primary_asset_id'], + )!, + ); + } + + @override + StackEntity createAlias(String alias) { + return StackEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class StackEntityData extends DataClass implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String primaryAssetId; + const StackEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.primaryAssetId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + map['primary_asset_id'] = Variable(primaryAssetId); + return map; + } + + factory StackEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return StackEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + primaryAssetId: serializer.fromJson(json['primaryAssetId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'primaryAssetId': serializer.toJson(primaryAssetId), + }; + } + + StackEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? primaryAssetId, + }) => StackEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + StackEntityData copyWithCompanion(StackEntityCompanion data) { + return StackEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + primaryAssetId: data.primaryAssetId.present + ? data.primaryAssetId.value + : this.primaryAssetId, + ); + } + + @override + String toString() { + return (StringBuffer('StackEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(id, createdAt, updatedAt, ownerId, primaryAssetId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is StackEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.primaryAssetId == this.primaryAssetId); +} + +class StackEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value primaryAssetId; + const StackEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.primaryAssetId = const Value.absent(), + }); + StackEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + required String primaryAssetId, + }) : id = Value(id), + ownerId = Value(ownerId), + primaryAssetId = Value(primaryAssetId); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? primaryAssetId, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (primaryAssetId != null) 'primary_asset_id': primaryAssetId, + }); + } + + StackEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? primaryAssetId, + }) { + return StackEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (primaryAssetId.present) { + map['primary_asset_id'] = Variable(primaryAssetId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('StackEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } +} + +class LocalAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn durationInSeconds = GeneratedColumn( + 'duration_in_seconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn adjustmentTime = + GeneratedColumn( + 'adjustment_time', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + orientation, + adjustmentTime, + latitude, + longitude, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_asset_entity'; + @override + Set get $primaryKey => {id}; + @override + LocalAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationInSeconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_in_seconds'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}orientation'], + )!, + adjustmentTime: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}adjustment_time'], + ), + latitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), + ); + } + + @override + LocalAssetEntity createAlias(String alias) { + return LocalAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final DateTime createdAt; + final DateTime updatedAt; + final int? width; + final int? height; + final int? durationInSeconds; + final String id; + final String? checksum; + final bool isFavorite; + final int orientation; + final DateTime? adjustmentTime; + final double? latitude; + final double? longitude; + const LocalAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationInSeconds, + required this.id, + this.checksum, + required this.isFavorite, + required this.orientation, + this.adjustmentTime, + this.latitude, + this.longitude, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['name'] = Variable(name); + map['type'] = Variable(type); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || durationInSeconds != null) { + map['duration_in_seconds'] = Variable(durationInSeconds); + } + map['id'] = Variable(id); + if (!nullToAbsent || checksum != null) { + map['checksum'] = Variable(checksum); + } + map['is_favorite'] = Variable(isFavorite); + map['orientation'] = Variable(orientation); + if (!nullToAbsent || adjustmentTime != null) { + map['adjustment_time'] = Variable(adjustmentTime); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = Variable(longitude); + } + return map; + } + + factory LocalAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAssetEntityData( + name: serializer.fromJson(json['name']), + type: serializer.fromJson(json['type']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + width: serializer.fromJson(json['width']), + height: serializer.fromJson(json['height']), + durationInSeconds: serializer.fromJson(json['durationInSeconds']), + id: serializer.fromJson(json['id']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + orientation: serializer.fromJson(json['orientation']), + adjustmentTime: serializer.fromJson(json['adjustmentTime']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'name': serializer.toJson(name), + 'type': serializer.toJson(type), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'width': serializer.toJson(width), + 'height': serializer.toJson(height), + 'durationInSeconds': serializer.toJson(durationInSeconds), + 'id': serializer.toJson(id), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'orientation': serializer.toJson(orientation), + 'adjustmentTime': serializer.toJson(adjustmentTime), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + }; + } + + LocalAssetEntityData copyWith({ + String? name, + int? type, + DateTime? createdAt, + DateTime? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationInSeconds = const Value.absent(), + String? id, + Value checksum = const Value.absent(), + bool? isFavorite, + int? orientation, + Value adjustmentTime = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + }) => LocalAssetEntityData( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width.present ? width.value : this.width, + height: height.present ? height.value : this.height, + durationInSeconds: durationInSeconds.present + ? durationInSeconds.value + : this.durationInSeconds, + id: id ?? this.id, + checksum: checksum.present ? checksum.value : this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + adjustmentTime: adjustmentTime.present + ? adjustmentTime.value + : this.adjustmentTime, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, + ); + LocalAssetEntityData copyWithCompanion(LocalAssetEntityCompanion data) { + return LocalAssetEntityData( + name: data.name.present ? data.name.value : this.name, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + width: data.width.present ? data.width.value : this.width, + height: data.height.present ? data.height.value : this.height, + durationInSeconds: data.durationInSeconds.present + ? data.durationInSeconds.value + : this.durationInSeconds, + id: data.id.present ? data.id.value : this.id, + checksum: data.checksum.present ? data.checksum.value : this.checksum, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + orientation: data.orientation.present + ? data.orientation.value + : this.orientation, + adjustmentTime: data.adjustmentTime.present + ? data.adjustmentTime.value + : this.adjustmentTime, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + orientation, + adjustmentTime, + latitude, + longitude, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAssetEntityData && + other.name == this.name && + other.type == this.type && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.width == this.width && + other.height == this.height && + other.durationInSeconds == this.durationInSeconds && + other.id == this.id && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.orientation == this.orientation && + other.adjustmentTime == this.adjustmentTime && + other.latitude == this.latitude && + other.longitude == this.longitude); +} + +class LocalAssetEntityCompanion extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationInSeconds; + final Value id; + final Value checksum; + final Value isFavorite; + final Value orientation; + final Value adjustmentTime; + final Value latitude; + final Value longitude; + const LocalAssetEntityCompanion({ + this.name = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + this.id = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + }); + LocalAssetEntityCompanion.insert({ + required String name, + required int type, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + required String id, + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationInSeconds, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? orientation, + Expression? adjustmentTime, + Expression? latitude, + Expression? longitude, + }) { + return RawValuesInsertable({ + if (name != null) 'name': name, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (width != null) 'width': width, + if (height != null) 'height': height, + if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds, + if (id != null) 'id': id, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (orientation != null) 'orientation': orientation, + if (adjustmentTime != null) 'adjustment_time': adjustmentTime, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + }); + } + + LocalAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationInSeconds, + Value? id, + Value? checksum, + Value? isFavorite, + Value? orientation, + Value? adjustmentTime, + Value? latitude, + Value? longitude, + }) { + return LocalAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationInSeconds: durationInSeconds ?? this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + adjustmentTime: adjustmentTime ?? this.adjustmentTime, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (name.present) { + map['name'] = Variable(name.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (durationInSeconds.present) { + map['duration_in_seconds'] = Variable(durationInSeconds.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (checksum.present) { + map['checksum'] = Variable(checksum.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (orientation.present) { + map['orientation'] = Variable(orientation.value); + } + if (adjustmentTime.present) { + map['adjustment_time'] = Variable(adjustmentTime.value); + } + if (latitude.present) { + map['latitude'] = Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = Variable(longitude.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const CustomExpression('\'\''), + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn thumbnailAssetId = GeneratedColumn( + 'thumbnail_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn isActivityEnabled = GeneratedColumn( + 'is_activity_enabled', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_activity_enabled" IN (0, 1))', + ), + defaultValue: const CustomExpression('1'), + ); + late final GeneratedColumn order = GeneratedColumn( + 'order', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + name, + description, + createdAt, + updatedAt, + ownerId, + thumbnailAssetId, + isActivityEnabled, + order, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_entity'; + @override + Set get $primaryKey => {id}; + @override + RemoteAlbumEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + description: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}description'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + thumbnailAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumbnail_asset_id'], + ), + isActivityEnabled: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_activity_enabled'], + )!, + order: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}order'], + )!, + ); + } + + @override + RemoteAlbumEntity createAlias(String alias) { + return RemoteAlbumEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String description; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String? thumbnailAssetId; + final bool isActivityEnabled; + final int order; + const RemoteAlbumEntityData({ + required this.id, + required this.name, + required this.description, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + this.thumbnailAssetId, + required this.isActivityEnabled, + required this.order, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['description'] = Variable(description); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + if (!nullToAbsent || thumbnailAssetId != null) { + map['thumbnail_asset_id'] = Variable(thumbnailAssetId); + } + map['is_activity_enabled'] = Variable(isActivityEnabled); + map['order'] = Variable(order); + return map; + } + + factory RemoteAlbumEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + description: serializer.fromJson(json['description']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + thumbnailAssetId: serializer.fromJson(json['thumbnailAssetId']), + isActivityEnabled: serializer.fromJson(json['isActivityEnabled']), + order: serializer.fromJson(json['order']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'description': serializer.toJson(description), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'thumbnailAssetId': serializer.toJson(thumbnailAssetId), + 'isActivityEnabled': serializer.toJson(isActivityEnabled), + 'order': serializer.toJson(order), + }; + } + + RemoteAlbumEntityData copyWith({ + String? id, + String? name, + String? description, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + Value thumbnailAssetId = const Value.absent(), + bool? isActivityEnabled, + int? order, + }) => RemoteAlbumEntityData( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + thumbnailAssetId: thumbnailAssetId.present + ? thumbnailAssetId.value + : this.thumbnailAssetId, + isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled, + order: order ?? this.order, + ); + RemoteAlbumEntityData copyWithCompanion(RemoteAlbumEntityCompanion data) { + return RemoteAlbumEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + description: data.description.present + ? data.description.value + : this.description, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + thumbnailAssetId: data.thumbnailAssetId.present + ? data.thumbnailAssetId.value + : this.thumbnailAssetId, + isActivityEnabled: data.isActivityEnabled.present + ? data.isActivityEnabled.value + : this.isActivityEnabled, + order: data.order.present ? data.order.value : this.order, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('thumbnailAssetId: $thumbnailAssetId, ') + ..write('isActivityEnabled: $isActivityEnabled, ') + ..write('order: $order') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + description, + createdAt, + updatedAt, + ownerId, + thumbnailAssetId, + isActivityEnabled, + order, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumEntityData && + other.id == this.id && + other.name == this.name && + other.description == this.description && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.thumbnailAssetId == this.thumbnailAssetId && + other.isActivityEnabled == this.isActivityEnabled && + other.order == this.order); +} + +class RemoteAlbumEntityCompanion + extends UpdateCompanion { + final Value id; + final Value name; + final Value description; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value thumbnailAssetId; + final Value isActivityEnabled; + final Value order; + const RemoteAlbumEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.description = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.thumbnailAssetId = const Value.absent(), + this.isActivityEnabled = const Value.absent(), + this.order = const Value.absent(), + }); + RemoteAlbumEntityCompanion.insert({ + required String id, + required String name, + this.description = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + this.thumbnailAssetId = const Value.absent(), + this.isActivityEnabled = const Value.absent(), + required int order, + }) : id = Value(id), + name = Value(name), + ownerId = Value(ownerId), + order = Value(order); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? description, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? thumbnailAssetId, + Expression? isActivityEnabled, + Expression? order, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (description != null) 'description': description, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (thumbnailAssetId != null) 'thumbnail_asset_id': thumbnailAssetId, + if (isActivityEnabled != null) 'is_activity_enabled': isActivityEnabled, + if (order != null) 'order': order, + }); + } + + RemoteAlbumEntityCompanion copyWith({ + Value? id, + Value? name, + Value? description, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? thumbnailAssetId, + Value? isActivityEnabled, + Value? order, + }) { + return RemoteAlbumEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + thumbnailAssetId: thumbnailAssetId ?? this.thumbnailAssetId, + isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled, + order: order ?? this.order, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (description.present) { + map['description'] = Variable(description.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (thumbnailAssetId.present) { + map['thumbnail_asset_id'] = Variable(thumbnailAssetId.value); + } + if (isActivityEnabled.present) { + map['is_activity_enabled'] = Variable(isActivityEnabled.value); + } + if (order.present) { + map['order'] = Variable(order.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('thumbnailAssetId: $thumbnailAssetId, ') + ..write('isActivityEnabled: $isActivityEnabled, ') + ..write('order: $order') + ..write(')')) + .toString(); + } +} + +class LocalAlbumEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAlbumEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn backupSelection = GeneratedColumn( + 'backup_selection', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn isIosSharedAlbum = GeneratedColumn( + 'is_ios_shared_album', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_ios_shared_album" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn linkedRemoteAlbumId = + GeneratedColumn( + 'linked_remote_album_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn marker_ = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("marker" IN (0, 1))', + ), + ); + @override + List get $columns => [ + id, + name, + updatedAt, + backupSelection, + isIosSharedAlbum, + linkedRemoteAlbumId, + marker_, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_album_entity'; + @override + Set get $primaryKey => {id}; + @override + LocalAlbumEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAlbumEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + backupSelection: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}backup_selection'], + )!, + isIosSharedAlbum: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_ios_shared_album'], + )!, + linkedRemoteAlbumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}linked_remote_album_id'], + ), + marker_: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumEntity createAlias(String alias) { + return LocalAlbumEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final DateTime updatedAt; + final int backupSelection; + final bool isIosSharedAlbum; + final String? linkedRemoteAlbumId; + final bool? marker_; + const LocalAlbumEntityData({ + required this.id, + required this.name, + required this.updatedAt, + required this.backupSelection, + required this.isIosSharedAlbum, + this.linkedRemoteAlbumId, + this.marker_, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['updated_at'] = Variable(updatedAt); + map['backup_selection'] = Variable(backupSelection); + map['is_ios_shared_album'] = Variable(isIosSharedAlbum); + if (!nullToAbsent || linkedRemoteAlbumId != null) { + map['linked_remote_album_id'] = Variable(linkedRemoteAlbumId); + } + if (!nullToAbsent || marker_ != null) { + map['marker'] = Variable(marker_); + } + return map; + } + + factory LocalAlbumEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAlbumEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + updatedAt: serializer.fromJson(json['updatedAt']), + backupSelection: serializer.fromJson(json['backupSelection']), + isIosSharedAlbum: serializer.fromJson(json['isIosSharedAlbum']), + linkedRemoteAlbumId: serializer.fromJson( + json['linkedRemoteAlbumId'], + ), + marker_: serializer.fromJson(json['marker_']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'updatedAt': serializer.toJson(updatedAt), + 'backupSelection': serializer.toJson(backupSelection), + 'isIosSharedAlbum': serializer.toJson(isIosSharedAlbum), + 'linkedRemoteAlbumId': serializer.toJson(linkedRemoteAlbumId), + 'marker_': serializer.toJson(marker_), + }; + } + + LocalAlbumEntityData copyWith({ + String? id, + String? name, + DateTime? updatedAt, + int? backupSelection, + bool? isIosSharedAlbum, + Value linkedRemoteAlbumId = const Value.absent(), + Value marker_ = const Value.absent(), + }) => LocalAlbumEntityData( + id: id ?? this.id, + name: name ?? this.name, + updatedAt: updatedAt ?? this.updatedAt, + backupSelection: backupSelection ?? this.backupSelection, + isIosSharedAlbum: isIosSharedAlbum ?? this.isIosSharedAlbum, + linkedRemoteAlbumId: linkedRemoteAlbumId.present + ? linkedRemoteAlbumId.value + : this.linkedRemoteAlbumId, + marker_: marker_.present ? marker_.value : this.marker_, + ); + LocalAlbumEntityData copyWithCompanion(LocalAlbumEntityCompanion data) { + return LocalAlbumEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + backupSelection: data.backupSelection.present + ? data.backupSelection.value + : this.backupSelection, + isIosSharedAlbum: data.isIosSharedAlbum.present + ? data.isIosSharedAlbum.value + : this.isIosSharedAlbum, + linkedRemoteAlbumId: data.linkedRemoteAlbumId.present + ? data.linkedRemoteAlbumId.value + : this.linkedRemoteAlbumId, + marker_: data.marker_.present ? data.marker_.value : this.marker_, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAlbumEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('updatedAt: $updatedAt, ') + ..write('backupSelection: $backupSelection, ') + ..write('isIosSharedAlbum: $isIosSharedAlbum, ') + ..write('linkedRemoteAlbumId: $linkedRemoteAlbumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + updatedAt, + backupSelection, + isIosSharedAlbum, + linkedRemoteAlbumId, + marker_, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAlbumEntityData && + other.id == this.id && + other.name == this.name && + other.updatedAt == this.updatedAt && + other.backupSelection == this.backupSelection && + other.isIosSharedAlbum == this.isIosSharedAlbum && + other.linkedRemoteAlbumId == this.linkedRemoteAlbumId && + other.marker_ == this.marker_); +} + +class LocalAlbumEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value updatedAt; + final Value backupSelection; + final Value isIosSharedAlbum; + final Value linkedRemoteAlbumId; + final Value marker_; + const LocalAlbumEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.updatedAt = const Value.absent(), + this.backupSelection = const Value.absent(), + this.isIosSharedAlbum = const Value.absent(), + this.linkedRemoteAlbumId = const Value.absent(), + this.marker_ = const Value.absent(), + }); + LocalAlbumEntityCompanion.insert({ + required String id, + required String name, + this.updatedAt = const Value.absent(), + required int backupSelection, + this.isIosSharedAlbum = const Value.absent(), + this.linkedRemoteAlbumId = const Value.absent(), + this.marker_ = const Value.absent(), + }) : id = Value(id), + name = Value(name), + backupSelection = Value(backupSelection); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? updatedAt, + Expression? backupSelection, + Expression? isIosSharedAlbum, + Expression? linkedRemoteAlbumId, + Expression? marker_, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (updatedAt != null) 'updated_at': updatedAt, + if (backupSelection != null) 'backup_selection': backupSelection, + if (isIosSharedAlbum != null) 'is_ios_shared_album': isIosSharedAlbum, + if (linkedRemoteAlbumId != null) + 'linked_remote_album_id': linkedRemoteAlbumId, + if (marker_ != null) 'marker': marker_, + }); + } + + LocalAlbumEntityCompanion copyWith({ + Value? id, + Value? name, + Value? updatedAt, + Value? backupSelection, + Value? isIosSharedAlbum, + Value? linkedRemoteAlbumId, + Value? marker_, + }) { + return LocalAlbumEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + updatedAt: updatedAt ?? this.updatedAt, + backupSelection: backupSelection ?? this.backupSelection, + isIosSharedAlbum: isIosSharedAlbum ?? this.isIosSharedAlbum, + linkedRemoteAlbumId: linkedRemoteAlbumId ?? this.linkedRemoteAlbumId, + marker_: marker_ ?? this.marker_, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (backupSelection.present) { + map['backup_selection'] = Variable(backupSelection.value); + } + if (isIosSharedAlbum.present) { + map['is_ios_shared_album'] = Variable(isIosSharedAlbum.value); + } + if (linkedRemoteAlbumId.present) { + map['linked_remote_album_id'] = Variable( + linkedRemoteAlbumId.value, + ); + } + if (marker_.present) { + map['marker'] = Variable(marker_.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAlbumEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('updatedAt: $updatedAt, ') + ..write('backupSelection: $backupSelection, ') + ..write('isIosSharedAlbum: $isIosSharedAlbum, ') + ..write('linkedRemoteAlbumId: $linkedRemoteAlbumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } +} + +class LocalAlbumAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAlbumAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES local_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES local_album_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn marker_ = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("marker" IN (0, 1))', + ), + ); + @override + List get $columns => [assetId, albumId, marker_]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_album_asset_entity'; + @override + Set get $primaryKey => {assetId, albumId}; + @override + LocalAlbumAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAlbumAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + marker_: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumAssetEntity createAlias(String alias) { + return LocalAlbumAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAlbumAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String albumId; + final bool? marker_; + const LocalAlbumAssetEntityData({ + required this.assetId, + required this.albumId, + this.marker_, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['album_id'] = Variable(albumId); + if (!nullToAbsent || marker_ != null) { + map['marker'] = Variable(marker_); + } + return map; + } + + factory LocalAlbumAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAlbumAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + albumId: serializer.fromJson(json['albumId']), + marker_: serializer.fromJson(json['marker_']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'albumId': serializer.toJson(albumId), + 'marker_': serializer.toJson(marker_), + }; + } + + LocalAlbumAssetEntityData copyWith({ + String? assetId, + String? albumId, + Value marker_ = const Value.absent(), + }) => LocalAlbumAssetEntityData( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + marker_: marker_.present ? marker_.value : this.marker_, + ); + LocalAlbumAssetEntityData copyWithCompanion( + LocalAlbumAssetEntityCompanion data, + ) { + return LocalAlbumAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + marker_: data.marker_.present ? data.marker_.value : this.marker_, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAlbumAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, albumId, marker_); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAlbumAssetEntityData && + other.assetId == this.assetId && + other.albumId == this.albumId && + other.marker_ == this.marker_); +} + +class LocalAlbumAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value albumId; + final Value marker_; + const LocalAlbumAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.albumId = const Value.absent(), + this.marker_ = const Value.absent(), + }); + LocalAlbumAssetEntityCompanion.insert({ + required String assetId, + required String albumId, + this.marker_ = const Value.absent(), + }) : assetId = Value(assetId), + albumId = Value(albumId); + static Insertable custom({ + Expression? assetId, + Expression? albumId, + Expression? marker_, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (albumId != null) 'album_id': albumId, + if (marker_ != null) 'marker': marker_, + }); + } + + LocalAlbumAssetEntityCompanion copyWith({ + Value? assetId, + Value? albumId, + Value? marker_, + }) { + return LocalAlbumAssetEntityCompanion( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + marker_: marker_ ?? this.marker_, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + if (marker_.present) { + map['marker'] = Variable(marker_.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAlbumAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } +} + +class AuthUserEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + AuthUserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isAdmin = GeneratedColumn( + 'is_admin', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_admin" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("has_profile_image" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = + GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn quotaSizeInBytes = GeneratedColumn( + 'quota_size_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn quotaUsageInBytes = GeneratedColumn( + 'quota_usage_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn pinCode = GeneratedColumn( + 'pin_code', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + name, + email, + isAdmin, + hasProfileImage, + profileChangedAt, + avatarColor, + quotaSizeInBytes, + quotaUsageInBytes, + pinCode, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'auth_user_entity'; + @override + Set get $primaryKey => {id}; + @override + AuthUserEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return AuthUserEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + email: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}email'], + )!, + isAdmin: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_admin'], + )!, + hasProfileImage: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}profile_changed_at'], + )!, + avatarColor: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}avatar_color'], + )!, + quotaSizeInBytes: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}quota_size_in_bytes'], + )!, + quotaUsageInBytes: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}quota_usage_in_bytes'], + )!, + pinCode: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}pin_code'], + ), + ); + } + + @override + AuthUserEntity createAlias(String alias) { + return AuthUserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class AuthUserEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String email; + final bool isAdmin; + final bool hasProfileImage; + final DateTime profileChangedAt; + final int avatarColor; + final int quotaSizeInBytes; + final int quotaUsageInBytes; + final String? pinCode; + const AuthUserEntityData({ + required this.id, + required this.name, + required this.email, + required this.isAdmin, + required this.hasProfileImage, + required this.profileChangedAt, + required this.avatarColor, + required this.quotaSizeInBytes, + required this.quotaUsageInBytes, + this.pinCode, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['email'] = Variable(email); + map['is_admin'] = Variable(isAdmin); + map['has_profile_image'] = Variable(hasProfileImage); + map['profile_changed_at'] = Variable(profileChangedAt); + map['avatar_color'] = Variable(avatarColor); + map['quota_size_in_bytes'] = Variable(quotaSizeInBytes); + map['quota_usage_in_bytes'] = Variable(quotaUsageInBytes); + if (!nullToAbsent || pinCode != null) { + map['pin_code'] = Variable(pinCode); + } + return map; + } + + factory AuthUserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return AuthUserEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + email: serializer.fromJson(json['email']), + isAdmin: serializer.fromJson(json['isAdmin']), + hasProfileImage: serializer.fromJson(json['hasProfileImage']), + profileChangedAt: serializer.fromJson(json['profileChangedAt']), + avatarColor: serializer.fromJson(json['avatarColor']), + quotaSizeInBytes: serializer.fromJson(json['quotaSizeInBytes']), + quotaUsageInBytes: serializer.fromJson(json['quotaUsageInBytes']), + pinCode: serializer.fromJson(json['pinCode']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'email': serializer.toJson(email), + 'isAdmin': serializer.toJson(isAdmin), + 'hasProfileImage': serializer.toJson(hasProfileImage), + 'profileChangedAt': serializer.toJson(profileChangedAt), + 'avatarColor': serializer.toJson(avatarColor), + 'quotaSizeInBytes': serializer.toJson(quotaSizeInBytes), + 'quotaUsageInBytes': serializer.toJson(quotaUsageInBytes), + 'pinCode': serializer.toJson(pinCode), + }; + } + + AuthUserEntityData copyWith({ + String? id, + String? name, + String? email, + bool? isAdmin, + bool? hasProfileImage, + DateTime? profileChangedAt, + int? avatarColor, + int? quotaSizeInBytes, + int? quotaUsageInBytes, + Value pinCode = const Value.absent(), + }) => AuthUserEntityData( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + isAdmin: isAdmin ?? this.isAdmin, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + quotaSizeInBytes: quotaSizeInBytes ?? this.quotaSizeInBytes, + quotaUsageInBytes: quotaUsageInBytes ?? this.quotaUsageInBytes, + pinCode: pinCode.present ? pinCode.value : this.pinCode, + ); + AuthUserEntityData copyWithCompanion(AuthUserEntityCompanion data) { + return AuthUserEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + email: data.email.present ? data.email.value : this.email, + isAdmin: data.isAdmin.present ? data.isAdmin.value : this.isAdmin, + hasProfileImage: data.hasProfileImage.present + ? data.hasProfileImage.value + : this.hasProfileImage, + profileChangedAt: data.profileChangedAt.present + ? data.profileChangedAt.value + : this.profileChangedAt, + avatarColor: data.avatarColor.present + ? data.avatarColor.value + : this.avatarColor, + quotaSizeInBytes: data.quotaSizeInBytes.present + ? data.quotaSizeInBytes.value + : this.quotaSizeInBytes, + quotaUsageInBytes: data.quotaUsageInBytes.present + ? data.quotaUsageInBytes.value + : this.quotaUsageInBytes, + pinCode: data.pinCode.present ? data.pinCode.value : this.pinCode, + ); + } + + @override + String toString() { + return (StringBuffer('AuthUserEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('isAdmin: $isAdmin, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor, ') + ..write('quotaSizeInBytes: $quotaSizeInBytes, ') + ..write('quotaUsageInBytes: $quotaUsageInBytes, ') + ..write('pinCode: $pinCode') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + email, + isAdmin, + hasProfileImage, + profileChangedAt, + avatarColor, + quotaSizeInBytes, + quotaUsageInBytes, + pinCode, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is AuthUserEntityData && + other.id == this.id && + other.name == this.name && + other.email == this.email && + other.isAdmin == this.isAdmin && + other.hasProfileImage == this.hasProfileImage && + other.profileChangedAt == this.profileChangedAt && + other.avatarColor == this.avatarColor && + other.quotaSizeInBytes == this.quotaSizeInBytes && + other.quotaUsageInBytes == this.quotaUsageInBytes && + other.pinCode == this.pinCode); +} + +class AuthUserEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value email; + final Value isAdmin; + final Value hasProfileImage; + final Value profileChangedAt; + final Value avatarColor; + final Value quotaSizeInBytes; + final Value quotaUsageInBytes; + final Value pinCode; + const AuthUserEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.email = const Value.absent(), + this.isAdmin = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + this.quotaSizeInBytes = const Value.absent(), + this.quotaUsageInBytes = const Value.absent(), + this.pinCode = const Value.absent(), + }); + AuthUserEntityCompanion.insert({ + required String id, + required String name, + required String email, + this.isAdmin = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + required int avatarColor, + this.quotaSizeInBytes = const Value.absent(), + this.quotaUsageInBytes = const Value.absent(), + this.pinCode = const Value.absent(), + }) : id = Value(id), + name = Value(name), + email = Value(email), + avatarColor = Value(avatarColor); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? email, + Expression? isAdmin, + Expression? hasProfileImage, + Expression? profileChangedAt, + Expression? avatarColor, + Expression? quotaSizeInBytes, + Expression? quotaUsageInBytes, + Expression? pinCode, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (email != null) 'email': email, + if (isAdmin != null) 'is_admin': isAdmin, + if (hasProfileImage != null) 'has_profile_image': hasProfileImage, + if (profileChangedAt != null) 'profile_changed_at': profileChangedAt, + if (avatarColor != null) 'avatar_color': avatarColor, + if (quotaSizeInBytes != null) 'quota_size_in_bytes': quotaSizeInBytes, + if (quotaUsageInBytes != null) 'quota_usage_in_bytes': quotaUsageInBytes, + if (pinCode != null) 'pin_code': pinCode, + }); + } + + AuthUserEntityCompanion copyWith({ + Value? id, + Value? name, + Value? email, + Value? isAdmin, + Value? hasProfileImage, + Value? profileChangedAt, + Value? avatarColor, + Value? quotaSizeInBytes, + Value? quotaUsageInBytes, + Value? pinCode, + }) { + return AuthUserEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + isAdmin: isAdmin ?? this.isAdmin, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + quotaSizeInBytes: quotaSizeInBytes ?? this.quotaSizeInBytes, + quotaUsageInBytes: quotaUsageInBytes ?? this.quotaUsageInBytes, + pinCode: pinCode ?? this.pinCode, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (email.present) { + map['email'] = Variable(email.value); + } + if (isAdmin.present) { + map['is_admin'] = Variable(isAdmin.value); + } + if (hasProfileImage.present) { + map['has_profile_image'] = Variable(hasProfileImage.value); + } + if (profileChangedAt.present) { + map['profile_changed_at'] = Variable(profileChangedAt.value); + } + if (avatarColor.present) { + map['avatar_color'] = Variable(avatarColor.value); + } + if (quotaSizeInBytes.present) { + map['quota_size_in_bytes'] = Variable(quotaSizeInBytes.value); + } + if (quotaUsageInBytes.present) { + map['quota_usage_in_bytes'] = Variable(quotaUsageInBytes.value); + } + if (pinCode.present) { + map['pin_code'] = Variable(pinCode.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AuthUserEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('isAdmin: $isAdmin, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor, ') + ..write('quotaSizeInBytes: $quotaSizeInBytes, ') + ..write('quotaUsageInBytes: $quotaUsageInBytes, ') + ..write('pinCode: $pinCode') + ..write(')')) + .toString(); + } +} + +class UserMetadataEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserMetadataEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn key = GeneratedColumn( + 'key', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn value = GeneratedColumn( + 'value', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + ); + @override + List get $columns => [userId, key, value]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_metadata_entity'; + @override + Set get $primaryKey => {userId, key}; + @override + UserMetadataEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserMetadataEntityData( + userId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}user_id'], + )!, + key: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}key'], + )!, + value: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}value'], + )!, + ); + } + + @override + UserMetadataEntity createAlias(String alias) { + return UserMetadataEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class UserMetadataEntityData extends DataClass + implements Insertable { + final String userId; + final int key; + final Uint8List value; + const UserMetadataEntityData({ + required this.userId, + required this.key, + required this.value, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['user_id'] = Variable(userId); + map['key'] = Variable(key); + map['value'] = Variable(value); + return map; + } + + factory UserMetadataEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserMetadataEntityData( + userId: serializer.fromJson(json['userId']), + key: serializer.fromJson(json['key']), + value: serializer.fromJson(json['value']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'userId': serializer.toJson(userId), + 'key': serializer.toJson(key), + 'value': serializer.toJson(value), + }; + } + + UserMetadataEntityData copyWith({ + String? userId, + int? key, + Uint8List? value, + }) => UserMetadataEntityData( + userId: userId ?? this.userId, + key: key ?? this.key, + value: value ?? this.value, + ); + UserMetadataEntityData copyWithCompanion(UserMetadataEntityCompanion data) { + return UserMetadataEntityData( + userId: data.userId.present ? data.userId.value : this.userId, + key: data.key.present ? data.key.value : this.key, + value: data.value.present ? data.value.value : this.value, + ); + } + + @override + String toString() { + return (StringBuffer('UserMetadataEntityData(') + ..write('userId: $userId, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(userId, key, $driftBlobEquality.hash(value)); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserMetadataEntityData && + other.userId == this.userId && + other.key == this.key && + $driftBlobEquality.equals(other.value, this.value)); +} + +class UserMetadataEntityCompanion + extends UpdateCompanion { + final Value userId; + final Value key; + final Value value; + const UserMetadataEntityCompanion({ + this.userId = const Value.absent(), + this.key = const Value.absent(), + this.value = const Value.absent(), + }); + UserMetadataEntityCompanion.insert({ + required String userId, + required int key, + required Uint8List value, + }) : userId = Value(userId), + key = Value(key), + value = Value(value); + static Insertable custom({ + Expression? userId, + Expression? key, + Expression? value, + }) { + return RawValuesInsertable({ + if (userId != null) 'user_id': userId, + if (key != null) 'key': key, + if (value != null) 'value': value, + }); + } + + UserMetadataEntityCompanion copyWith({ + Value? userId, + Value? key, + Value? value, + }) { + return UserMetadataEntityCompanion( + userId: userId ?? this.userId, + key: key ?? this.key, + value: value ?? this.value, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (key.present) { + map['key'] = Variable(key.value); + } + if (value.present) { + map['value'] = Variable(value.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserMetadataEntityCompanion(') + ..write('userId: $userId, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } +} + +class PartnerEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + PartnerEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn sharedById = GeneratedColumn( + 'shared_by_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn sharedWithId = GeneratedColumn( + 'shared_with_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn inTimeline = GeneratedColumn( + 'in_timeline', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("in_timeline" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [sharedById, sharedWithId, inTimeline]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'partner_entity'; + @override + Set get $primaryKey => {sharedById, sharedWithId}; + @override + PartnerEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PartnerEntityData( + sharedById: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}shared_by_id'], + )!, + sharedWithId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}shared_with_id'], + )!, + inTimeline: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}in_timeline'], + )!, + ); + } + + @override + PartnerEntity createAlias(String alias) { + return PartnerEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class PartnerEntityData extends DataClass + implements Insertable { + final String sharedById; + final String sharedWithId; + final bool inTimeline; + const PartnerEntityData({ + required this.sharedById, + required this.sharedWithId, + required this.inTimeline, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['shared_by_id'] = Variable(sharedById); + map['shared_with_id'] = Variable(sharedWithId); + map['in_timeline'] = Variable(inTimeline); + return map; + } + + factory PartnerEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PartnerEntityData( + sharedById: serializer.fromJson(json['sharedById']), + sharedWithId: serializer.fromJson(json['sharedWithId']), + inTimeline: serializer.fromJson(json['inTimeline']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'sharedById': serializer.toJson(sharedById), + 'sharedWithId': serializer.toJson(sharedWithId), + 'inTimeline': serializer.toJson(inTimeline), + }; + } + + PartnerEntityData copyWith({ + String? sharedById, + String? sharedWithId, + bool? inTimeline, + }) => PartnerEntityData( + sharedById: sharedById ?? this.sharedById, + sharedWithId: sharedWithId ?? this.sharedWithId, + inTimeline: inTimeline ?? this.inTimeline, + ); + PartnerEntityData copyWithCompanion(PartnerEntityCompanion data) { + return PartnerEntityData( + sharedById: data.sharedById.present + ? data.sharedById.value + : this.sharedById, + sharedWithId: data.sharedWithId.present + ? data.sharedWithId.value + : this.sharedWithId, + inTimeline: data.inTimeline.present + ? data.inTimeline.value + : this.inTimeline, + ); + } + + @override + String toString() { + return (StringBuffer('PartnerEntityData(') + ..write('sharedById: $sharedById, ') + ..write('sharedWithId: $sharedWithId, ') + ..write('inTimeline: $inTimeline') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(sharedById, sharedWithId, inTimeline); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PartnerEntityData && + other.sharedById == this.sharedById && + other.sharedWithId == this.sharedWithId && + other.inTimeline == this.inTimeline); +} + +class PartnerEntityCompanion extends UpdateCompanion { + final Value sharedById; + final Value sharedWithId; + final Value inTimeline; + const PartnerEntityCompanion({ + this.sharedById = const Value.absent(), + this.sharedWithId = const Value.absent(), + this.inTimeline = const Value.absent(), + }); + PartnerEntityCompanion.insert({ + required String sharedById, + required String sharedWithId, + this.inTimeline = const Value.absent(), + }) : sharedById = Value(sharedById), + sharedWithId = Value(sharedWithId); + static Insertable custom({ + Expression? sharedById, + Expression? sharedWithId, + Expression? inTimeline, + }) { + return RawValuesInsertable({ + if (sharedById != null) 'shared_by_id': sharedById, + if (sharedWithId != null) 'shared_with_id': sharedWithId, + if (inTimeline != null) 'in_timeline': inTimeline, + }); + } + + PartnerEntityCompanion copyWith({ + Value? sharedById, + Value? sharedWithId, + Value? inTimeline, + }) { + return PartnerEntityCompanion( + sharedById: sharedById ?? this.sharedById, + sharedWithId: sharedWithId ?? this.sharedWithId, + inTimeline: inTimeline ?? this.inTimeline, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (sharedById.present) { + map['shared_by_id'] = Variable(sharedById.value); + } + if (sharedWithId.present) { + map['shared_with_id'] = Variable(sharedWithId.value); + } + if (inTimeline.present) { + map['in_timeline'] = Variable(inTimeline.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PartnerEntityCompanion(') + ..write('sharedById: $sharedById, ') + ..write('sharedWithId: $sharedWithId, ') + ..write('inTimeline: $inTimeline') + ..write(')')) + .toString(); + } +} + +class RemoteExifEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteExifEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn city = GeneratedColumn( + 'city', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn state = GeneratedColumn( + 'state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn country = GeneratedColumn( + 'country', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn dateTimeOriginal = + GeneratedColumn( + 'date_time_original', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn exposureTime = GeneratedColumn( + 'exposure_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn fNumber = GeneratedColumn( + 'f_number', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn fileSize = GeneratedColumn( + 'file_size', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn focalLength = GeneratedColumn( + 'focal_length', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn iso = GeneratedColumn( + 'iso', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn make = GeneratedColumn( + 'make', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn model = GeneratedColumn( + 'model', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn lens = GeneratedColumn( + 'lens', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn timeZone = GeneratedColumn( + 'time_zone', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn rating = GeneratedColumn( + 'rating', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn projectionType = GeneratedColumn( + 'projection_type', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + assetId, + city, + state, + country, + dateTimeOriginal, + description, + height, + width, + exposureTime, + fNumber, + fileSize, + focalLength, + latitude, + longitude, + iso, + make, + model, + lens, + orientation, + timeZone, + rating, + projectionType, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_exif_entity'; + @override + Set get $primaryKey => {assetId}; + @override + RemoteExifEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteExifEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + city: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}city'], + ), + state: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}state'], + ), + country: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}country'], + ), + dateTimeOriginal: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}date_time_original'], + ), + description: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}description'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + exposureTime: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}exposure_time'], + ), + fNumber: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}f_number'], + ), + fileSize: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}file_size'], + ), + focalLength: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}focal_length'], + ), + latitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), + iso: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}iso'], + ), + make: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}make'], + ), + model: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}model'], + ), + lens: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}lens'], + ), + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}orientation'], + ), + timeZone: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}time_zone'], + ), + rating: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}rating'], + ), + projectionType: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}projection_type'], + ), + ); + } + + @override + RemoteExifEntity createAlias(String alias) { + return RemoteExifEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteExifEntityData extends DataClass + implements Insertable { + final String assetId; + final String? city; + final String? state; + final String? country; + final DateTime? dateTimeOriginal; + final String? description; + final int? height; + final int? width; + final String? exposureTime; + final double? fNumber; + final int? fileSize; + final double? focalLength; + final double? latitude; + final double? longitude; + final int? iso; + final String? make; + final String? model; + final String? lens; + final String? orientation; + final String? timeZone; + final int? rating; + final String? projectionType; + const RemoteExifEntityData({ + required this.assetId, + this.city, + this.state, + this.country, + this.dateTimeOriginal, + this.description, + this.height, + this.width, + this.exposureTime, + this.fNumber, + this.fileSize, + this.focalLength, + this.latitude, + this.longitude, + this.iso, + this.make, + this.model, + this.lens, + this.orientation, + this.timeZone, + this.rating, + this.projectionType, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + if (!nullToAbsent || city != null) { + map['city'] = Variable(city); + } + if (!nullToAbsent || state != null) { + map['state'] = Variable(state); + } + if (!nullToAbsent || country != null) { + map['country'] = Variable(country); + } + if (!nullToAbsent || dateTimeOriginal != null) { + map['date_time_original'] = Variable(dateTimeOriginal); + } + if (!nullToAbsent || description != null) { + map['description'] = Variable(description); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || exposureTime != null) { + map['exposure_time'] = Variable(exposureTime); + } + if (!nullToAbsent || fNumber != null) { + map['f_number'] = Variable(fNumber); + } + if (!nullToAbsent || fileSize != null) { + map['file_size'] = Variable(fileSize); + } + if (!nullToAbsent || focalLength != null) { + map['focal_length'] = Variable(focalLength); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = Variable(longitude); + } + if (!nullToAbsent || iso != null) { + map['iso'] = Variable(iso); + } + if (!nullToAbsent || make != null) { + map['make'] = Variable(make); + } + if (!nullToAbsent || model != null) { + map['model'] = Variable(model); + } + if (!nullToAbsent || lens != null) { + map['lens'] = Variable(lens); + } + if (!nullToAbsent || orientation != null) { + map['orientation'] = Variable(orientation); + } + if (!nullToAbsent || timeZone != null) { + map['time_zone'] = Variable(timeZone); + } + if (!nullToAbsent || rating != null) { + map['rating'] = Variable(rating); + } + if (!nullToAbsent || projectionType != null) { + map['projection_type'] = Variable(projectionType); + } + return map; + } + + factory RemoteExifEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteExifEntityData( + assetId: serializer.fromJson(json['assetId']), + city: serializer.fromJson(json['city']), + state: serializer.fromJson(json['state']), + country: serializer.fromJson(json['country']), + dateTimeOriginal: serializer.fromJson( + json['dateTimeOriginal'], + ), + description: serializer.fromJson(json['description']), + height: serializer.fromJson(json['height']), + width: serializer.fromJson(json['width']), + exposureTime: serializer.fromJson(json['exposureTime']), + fNumber: serializer.fromJson(json['fNumber']), + fileSize: serializer.fromJson(json['fileSize']), + focalLength: serializer.fromJson(json['focalLength']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + iso: serializer.fromJson(json['iso']), + make: serializer.fromJson(json['make']), + model: serializer.fromJson(json['model']), + lens: serializer.fromJson(json['lens']), + orientation: serializer.fromJson(json['orientation']), + timeZone: serializer.fromJson(json['timeZone']), + rating: serializer.fromJson(json['rating']), + projectionType: serializer.fromJson(json['projectionType']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'city': serializer.toJson(city), + 'state': serializer.toJson(state), + 'country': serializer.toJson(country), + 'dateTimeOriginal': serializer.toJson(dateTimeOriginal), + 'description': serializer.toJson(description), + 'height': serializer.toJson(height), + 'width': serializer.toJson(width), + 'exposureTime': serializer.toJson(exposureTime), + 'fNumber': serializer.toJson(fNumber), + 'fileSize': serializer.toJson(fileSize), + 'focalLength': serializer.toJson(focalLength), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + 'iso': serializer.toJson(iso), + 'make': serializer.toJson(make), + 'model': serializer.toJson(model), + 'lens': serializer.toJson(lens), + 'orientation': serializer.toJson(orientation), + 'timeZone': serializer.toJson(timeZone), + 'rating': serializer.toJson(rating), + 'projectionType': serializer.toJson(projectionType), + }; + } + + RemoteExifEntityData copyWith({ + String? assetId, + Value city = const Value.absent(), + Value state = const Value.absent(), + Value country = const Value.absent(), + Value dateTimeOriginal = const Value.absent(), + Value description = const Value.absent(), + Value height = const Value.absent(), + Value width = const Value.absent(), + Value exposureTime = const Value.absent(), + Value fNumber = const Value.absent(), + Value fileSize = const Value.absent(), + Value focalLength = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + Value iso = const Value.absent(), + Value make = const Value.absent(), + Value model = const Value.absent(), + Value lens = const Value.absent(), + Value orientation = const Value.absent(), + Value timeZone = const Value.absent(), + Value rating = const Value.absent(), + Value projectionType = const Value.absent(), + }) => RemoteExifEntityData( + assetId: assetId ?? this.assetId, + city: city.present ? city.value : this.city, + state: state.present ? state.value : this.state, + country: country.present ? country.value : this.country, + dateTimeOriginal: dateTimeOriginal.present + ? dateTimeOriginal.value + : this.dateTimeOriginal, + description: description.present ? description.value : this.description, + height: height.present ? height.value : this.height, + width: width.present ? width.value : this.width, + exposureTime: exposureTime.present ? exposureTime.value : this.exposureTime, + fNumber: fNumber.present ? fNumber.value : this.fNumber, + fileSize: fileSize.present ? fileSize.value : this.fileSize, + focalLength: focalLength.present ? focalLength.value : this.focalLength, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, + iso: iso.present ? iso.value : this.iso, + make: make.present ? make.value : this.make, + model: model.present ? model.value : this.model, + lens: lens.present ? lens.value : this.lens, + orientation: orientation.present ? orientation.value : this.orientation, + timeZone: timeZone.present ? timeZone.value : this.timeZone, + rating: rating.present ? rating.value : this.rating, + projectionType: projectionType.present + ? projectionType.value + : this.projectionType, + ); + RemoteExifEntityData copyWithCompanion(RemoteExifEntityCompanion data) { + return RemoteExifEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + city: data.city.present ? data.city.value : this.city, + state: data.state.present ? data.state.value : this.state, + country: data.country.present ? data.country.value : this.country, + dateTimeOriginal: data.dateTimeOriginal.present + ? data.dateTimeOriginal.value + : this.dateTimeOriginal, + description: data.description.present + ? data.description.value + : this.description, + height: data.height.present ? data.height.value : this.height, + width: data.width.present ? data.width.value : this.width, + exposureTime: data.exposureTime.present + ? data.exposureTime.value + : this.exposureTime, + fNumber: data.fNumber.present ? data.fNumber.value : this.fNumber, + fileSize: data.fileSize.present ? data.fileSize.value : this.fileSize, + focalLength: data.focalLength.present + ? data.focalLength.value + : this.focalLength, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + iso: data.iso.present ? data.iso.value : this.iso, + make: data.make.present ? data.make.value : this.make, + model: data.model.present ? data.model.value : this.model, + lens: data.lens.present ? data.lens.value : this.lens, + orientation: data.orientation.present + ? data.orientation.value + : this.orientation, + timeZone: data.timeZone.present ? data.timeZone.value : this.timeZone, + rating: data.rating.present ? data.rating.value : this.rating, + projectionType: data.projectionType.present + ? data.projectionType.value + : this.projectionType, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteExifEntityData(') + ..write('assetId: $assetId, ') + ..write('city: $city, ') + ..write('state: $state, ') + ..write('country: $country, ') + ..write('dateTimeOriginal: $dateTimeOriginal, ') + ..write('description: $description, ') + ..write('height: $height, ') + ..write('width: $width, ') + ..write('exposureTime: $exposureTime, ') + ..write('fNumber: $fNumber, ') + ..write('fileSize: $fileSize, ') + ..write('focalLength: $focalLength, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('iso: $iso, ') + ..write('make: $make, ') + ..write('model: $model, ') + ..write('lens: $lens, ') + ..write('orientation: $orientation, ') + ..write('timeZone: $timeZone, ') + ..write('rating: $rating, ') + ..write('projectionType: $projectionType') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + assetId, + city, + state, + country, + dateTimeOriginal, + description, + height, + width, + exposureTime, + fNumber, + fileSize, + focalLength, + latitude, + longitude, + iso, + make, + model, + lens, + orientation, + timeZone, + rating, + projectionType, + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteExifEntityData && + other.assetId == this.assetId && + other.city == this.city && + other.state == this.state && + other.country == this.country && + other.dateTimeOriginal == this.dateTimeOriginal && + other.description == this.description && + other.height == this.height && + other.width == this.width && + other.exposureTime == this.exposureTime && + other.fNumber == this.fNumber && + other.fileSize == this.fileSize && + other.focalLength == this.focalLength && + other.latitude == this.latitude && + other.longitude == this.longitude && + other.iso == this.iso && + other.make == this.make && + other.model == this.model && + other.lens == this.lens && + other.orientation == this.orientation && + other.timeZone == this.timeZone && + other.rating == this.rating && + other.projectionType == this.projectionType); +} + +class RemoteExifEntityCompanion extends UpdateCompanion { + final Value assetId; + final Value city; + final Value state; + final Value country; + final Value dateTimeOriginal; + final Value description; + final Value height; + final Value width; + final Value exposureTime; + final Value fNumber; + final Value fileSize; + final Value focalLength; + final Value latitude; + final Value longitude; + final Value iso; + final Value make; + final Value model; + final Value lens; + final Value orientation; + final Value timeZone; + final Value rating; + final Value projectionType; + const RemoteExifEntityCompanion({ + this.assetId = const Value.absent(), + this.city = const Value.absent(), + this.state = const Value.absent(), + this.country = const Value.absent(), + this.dateTimeOriginal = const Value.absent(), + this.description = const Value.absent(), + this.height = const Value.absent(), + this.width = const Value.absent(), + this.exposureTime = const Value.absent(), + this.fNumber = const Value.absent(), + this.fileSize = const Value.absent(), + this.focalLength = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.iso = const Value.absent(), + this.make = const Value.absent(), + this.model = const Value.absent(), + this.lens = const Value.absent(), + this.orientation = const Value.absent(), + this.timeZone = const Value.absent(), + this.rating = const Value.absent(), + this.projectionType = const Value.absent(), + }); + RemoteExifEntityCompanion.insert({ + required String assetId, + this.city = const Value.absent(), + this.state = const Value.absent(), + this.country = const Value.absent(), + this.dateTimeOriginal = const Value.absent(), + this.description = const Value.absent(), + this.height = const Value.absent(), + this.width = const Value.absent(), + this.exposureTime = const Value.absent(), + this.fNumber = const Value.absent(), + this.fileSize = const Value.absent(), + this.focalLength = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.iso = const Value.absent(), + this.make = const Value.absent(), + this.model = const Value.absent(), + this.lens = const Value.absent(), + this.orientation = const Value.absent(), + this.timeZone = const Value.absent(), + this.rating = const Value.absent(), + this.projectionType = const Value.absent(), + }) : assetId = Value(assetId); + static Insertable custom({ + Expression? assetId, + Expression? city, + Expression? state, + Expression? country, + Expression? dateTimeOriginal, + Expression? description, + Expression? height, + Expression? width, + Expression? exposureTime, + Expression? fNumber, + Expression? fileSize, + Expression? focalLength, + Expression? latitude, + Expression? longitude, + Expression? iso, + Expression? make, + Expression? model, + Expression? lens, + Expression? orientation, + Expression? timeZone, + Expression? rating, + Expression? projectionType, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (city != null) 'city': city, + if (state != null) 'state': state, + if (country != null) 'country': country, + if (dateTimeOriginal != null) 'date_time_original': dateTimeOriginal, + if (description != null) 'description': description, + if (height != null) 'height': height, + if (width != null) 'width': width, + if (exposureTime != null) 'exposure_time': exposureTime, + if (fNumber != null) 'f_number': fNumber, + if (fileSize != null) 'file_size': fileSize, + if (focalLength != null) 'focal_length': focalLength, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + if (iso != null) 'iso': iso, + if (make != null) 'make': make, + if (model != null) 'model': model, + if (lens != null) 'lens': lens, + if (orientation != null) 'orientation': orientation, + if (timeZone != null) 'time_zone': timeZone, + if (rating != null) 'rating': rating, + if (projectionType != null) 'projection_type': projectionType, + }); + } + + RemoteExifEntityCompanion copyWith({ + Value? assetId, + Value? city, + Value? state, + Value? country, + Value? dateTimeOriginal, + Value? description, + Value? height, + Value? width, + Value? exposureTime, + Value? fNumber, + Value? fileSize, + Value? focalLength, + Value? latitude, + Value? longitude, + Value? iso, + Value? make, + Value? model, + Value? lens, + Value? orientation, + Value? timeZone, + Value? rating, + Value? projectionType, + }) { + return RemoteExifEntityCompanion( + assetId: assetId ?? this.assetId, + city: city ?? this.city, + state: state ?? this.state, + country: country ?? this.country, + dateTimeOriginal: dateTimeOriginal ?? this.dateTimeOriginal, + description: description ?? this.description, + height: height ?? this.height, + width: width ?? this.width, + exposureTime: exposureTime ?? this.exposureTime, + fNumber: fNumber ?? this.fNumber, + fileSize: fileSize ?? this.fileSize, + focalLength: focalLength ?? this.focalLength, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + iso: iso ?? this.iso, + make: make ?? this.make, + model: model ?? this.model, + lens: lens ?? this.lens, + orientation: orientation ?? this.orientation, + timeZone: timeZone ?? this.timeZone, + rating: rating ?? this.rating, + projectionType: projectionType ?? this.projectionType, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (city.present) { + map['city'] = Variable(city.value); + } + if (state.present) { + map['state'] = Variable(state.value); + } + if (country.present) { + map['country'] = Variable(country.value); + } + if (dateTimeOriginal.present) { + map['date_time_original'] = Variable(dateTimeOriginal.value); + } + if (description.present) { + map['description'] = Variable(description.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (exposureTime.present) { + map['exposure_time'] = Variable(exposureTime.value); + } + if (fNumber.present) { + map['f_number'] = Variable(fNumber.value); + } + if (fileSize.present) { + map['file_size'] = Variable(fileSize.value); + } + if (focalLength.present) { + map['focal_length'] = Variable(focalLength.value); + } + if (latitude.present) { + map['latitude'] = Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = Variable(longitude.value); + } + if (iso.present) { + map['iso'] = Variable(iso.value); + } + if (make.present) { + map['make'] = Variable(make.value); + } + if (model.present) { + map['model'] = Variable(model.value); + } + if (lens.present) { + map['lens'] = Variable(lens.value); + } + if (orientation.present) { + map['orientation'] = Variable(orientation.value); + } + if (timeZone.present) { + map['time_zone'] = Variable(timeZone.value); + } + if (rating.present) { + map['rating'] = Variable(rating.value); + } + if (projectionType.present) { + map['projection_type'] = Variable(projectionType.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteExifEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('city: $city, ') + ..write('state: $state, ') + ..write('country: $country, ') + ..write('dateTimeOriginal: $dateTimeOriginal, ') + ..write('description: $description, ') + ..write('height: $height, ') + ..write('width: $width, ') + ..write('exposureTime: $exposureTime, ') + ..write('fNumber: $fNumber, ') + ..write('fileSize: $fileSize, ') + ..write('focalLength: $focalLength, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('iso: $iso, ') + ..write('make: $make, ') + ..write('model: $model, ') + ..write('lens: $lens, ') + ..write('orientation: $orientation, ') + ..write('timeZone: $timeZone, ') + ..write('rating: $rating, ') + ..write('projectionType: $projectionType') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE CASCADE', + ), + ); + @override + List get $columns => [assetId, albumId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_asset_entity'; + @override + Set get $primaryKey => {assetId, albumId}; + @override + RemoteAlbumAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + ); + } + + @override + RemoteAlbumAssetEntity createAlias(String alias) { + return RemoteAlbumAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String albumId; + const RemoteAlbumAssetEntityData({ + required this.assetId, + required this.albumId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['album_id'] = Variable(albumId); + return map; + } + + factory RemoteAlbumAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + albumId: serializer.fromJson(json['albumId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'albumId': serializer.toJson(albumId), + }; + } + + RemoteAlbumAssetEntityData copyWith({String? assetId, String? albumId}) => + RemoteAlbumAssetEntityData( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + ); + RemoteAlbumAssetEntityData copyWithCompanion( + RemoteAlbumAssetEntityCompanion data, + ) { + return RemoteAlbumAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, albumId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumAssetEntityData && + other.assetId == this.assetId && + other.albumId == this.albumId); +} + +class RemoteAlbumAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value albumId; + const RemoteAlbumAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.albumId = const Value.absent(), + }); + RemoteAlbumAssetEntityCompanion.insert({ + required String assetId, + required String albumId, + }) : assetId = Value(assetId), + albumId = Value(albumId); + static Insertable custom({ + Expression? assetId, + Expression? albumId, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (albumId != null) 'album_id': albumId, + }); + } + + RemoteAlbumAssetEntityCompanion copyWith({ + Value? assetId, + Value? albumId, + }) { + return RemoteAlbumAssetEntityCompanion( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumUserEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumUserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn role = GeneratedColumn( + 'role', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + @override + List get $columns => [albumId, userId, role]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_user_entity'; + @override + Set get $primaryKey => {albumId, userId}; + @override + RemoteAlbumUserEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumUserEntityData( + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + userId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}user_id'], + )!, + role: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}role'], + )!, + ); + } + + @override + RemoteAlbumUserEntity createAlias(String alias) { + return RemoteAlbumUserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumUserEntityData extends DataClass + implements Insertable { + final String albumId; + final String userId; + final int role; + const RemoteAlbumUserEntityData({ + required this.albumId, + required this.userId, + required this.role, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['album_id'] = Variable(albumId); + map['user_id'] = Variable(userId); + map['role'] = Variable(role); + return map; + } + + factory RemoteAlbumUserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumUserEntityData( + albumId: serializer.fromJson(json['albumId']), + userId: serializer.fromJson(json['userId']), + role: serializer.fromJson(json['role']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'albumId': serializer.toJson(albumId), + 'userId': serializer.toJson(userId), + 'role': serializer.toJson(role), + }; + } + + RemoteAlbumUserEntityData copyWith({ + String? albumId, + String? userId, + int? role, + }) => RemoteAlbumUserEntityData( + albumId: albumId ?? this.albumId, + userId: userId ?? this.userId, + role: role ?? this.role, + ); + RemoteAlbumUserEntityData copyWithCompanion( + RemoteAlbumUserEntityCompanion data, + ) { + return RemoteAlbumUserEntityData( + albumId: data.albumId.present ? data.albumId.value : this.albumId, + userId: data.userId.present ? data.userId.value : this.userId, + role: data.role.present ? data.role.value : this.role, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumUserEntityData(') + ..write('albumId: $albumId, ') + ..write('userId: $userId, ') + ..write('role: $role') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(albumId, userId, role); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumUserEntityData && + other.albumId == this.albumId && + other.userId == this.userId && + other.role == this.role); +} + +class RemoteAlbumUserEntityCompanion + extends UpdateCompanion { + final Value albumId; + final Value userId; + final Value role; + const RemoteAlbumUserEntityCompanion({ + this.albumId = const Value.absent(), + this.userId = const Value.absent(), + this.role = const Value.absent(), + }); + RemoteAlbumUserEntityCompanion.insert({ + required String albumId, + required String userId, + required int role, + }) : albumId = Value(albumId), + userId = Value(userId), + role = Value(role); + static Insertable custom({ + Expression? albumId, + Expression? userId, + Expression? role, + }) { + return RawValuesInsertable({ + if (albumId != null) 'album_id': albumId, + if (userId != null) 'user_id': userId, + if (role != null) 'role': role, + }); + } + + RemoteAlbumUserEntityCompanion copyWith({ + Value? albumId, + Value? userId, + Value? role, + }) { + return RemoteAlbumUserEntityCompanion( + albumId: albumId ?? this.albumId, + userId: userId ?? this.userId, + role: role ?? this.role, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (role.present) { + map['role'] = Variable(role.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumUserEntityCompanion(') + ..write('albumId: $albumId, ') + ..write('userId: $userId, ') + ..write('role: $role') + ..write(')')) + .toString(); + } +} + +class MemoryEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MemoryEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn data = GeneratedColumn( + 'data', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isSaved = GeneratedColumn( + 'is_saved', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_saved" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn memoryAt = GeneratedColumn( + 'memory_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: true, + ); + late final GeneratedColumn seenAt = GeneratedColumn( + 'seen_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn showAt = GeneratedColumn( + 'show_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn hideAt = GeneratedColumn( + 'hide_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + deletedAt, + ownerId, + type, + data, + isSaved, + memoryAt, + seenAt, + showAt, + hideAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'memory_entity'; + @override + Set get $primaryKey => {id}; + @override + MemoryEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MemoryEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}deleted_at'], + ), + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + data: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}data'], + )!, + isSaved: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_saved'], + )!, + memoryAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}memory_at'], + )!, + seenAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}seen_at'], + ), + showAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}show_at'], + ), + hideAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}hide_at'], + ), + ); + } + + @override + MemoryEntity createAlias(String alias) { + return MemoryEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class MemoryEntityData extends DataClass + implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final DateTime? deletedAt; + final String ownerId; + final int type; + final String data; + final bool isSaved; + final DateTime memoryAt; + final DateTime? seenAt; + final DateTime? showAt; + final DateTime? hideAt; + const MemoryEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + this.deletedAt, + required this.ownerId, + required this.type, + required this.data, + required this.isSaved, + required this.memoryAt, + this.seenAt, + this.showAt, + this.hideAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || deletedAt != null) { + map['deleted_at'] = Variable(deletedAt); + } + map['owner_id'] = Variable(ownerId); + map['type'] = Variable(type); + map['data'] = Variable(data); + map['is_saved'] = Variable(isSaved); + map['memory_at'] = Variable(memoryAt); + if (!nullToAbsent || seenAt != null) { + map['seen_at'] = Variable(seenAt); + } + if (!nullToAbsent || showAt != null) { + map['show_at'] = Variable(showAt); + } + if (!nullToAbsent || hideAt != null) { + map['hide_at'] = Variable(hideAt); + } + return map; + } + + factory MemoryEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MemoryEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + deletedAt: serializer.fromJson(json['deletedAt']), + ownerId: serializer.fromJson(json['ownerId']), + type: serializer.fromJson(json['type']), + data: serializer.fromJson(json['data']), + isSaved: serializer.fromJson(json['isSaved']), + memoryAt: serializer.fromJson(json['memoryAt']), + seenAt: serializer.fromJson(json['seenAt']), + showAt: serializer.fromJson(json['showAt']), + hideAt: serializer.fromJson(json['hideAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'deletedAt': serializer.toJson(deletedAt), + 'ownerId': serializer.toJson(ownerId), + 'type': serializer.toJson(type), + 'data': serializer.toJson(data), + 'isSaved': serializer.toJson(isSaved), + 'memoryAt': serializer.toJson(memoryAt), + 'seenAt': serializer.toJson(seenAt), + 'showAt': serializer.toJson(showAt), + 'hideAt': serializer.toJson(hideAt), + }; + } + + MemoryEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + Value deletedAt = const Value.absent(), + String? ownerId, + int? type, + String? data, + bool? isSaved, + DateTime? memoryAt, + Value seenAt = const Value.absent(), + Value showAt = const Value.absent(), + Value hideAt = const Value.absent(), + }) => MemoryEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + deletedAt: deletedAt.present ? deletedAt.value : this.deletedAt, + ownerId: ownerId ?? this.ownerId, + type: type ?? this.type, + data: data ?? this.data, + isSaved: isSaved ?? this.isSaved, + memoryAt: memoryAt ?? this.memoryAt, + seenAt: seenAt.present ? seenAt.value : this.seenAt, + showAt: showAt.present ? showAt.value : this.showAt, + hideAt: hideAt.present ? hideAt.value : this.hideAt, + ); + MemoryEntityData copyWithCompanion(MemoryEntityCompanion data) { + return MemoryEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + deletedAt: data.deletedAt.present ? data.deletedAt.value : this.deletedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + type: data.type.present ? data.type.value : this.type, + data: data.data.present ? data.data.value : this.data, + isSaved: data.isSaved.present ? data.isSaved.value : this.isSaved, + memoryAt: data.memoryAt.present ? data.memoryAt.value : this.memoryAt, + seenAt: data.seenAt.present ? data.seenAt.value : this.seenAt, + showAt: data.showAt.present ? data.showAt.value : this.showAt, + hideAt: data.hideAt.present ? data.hideAt.value : this.hideAt, + ); + } + + @override + String toString() { + return (StringBuffer('MemoryEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('deletedAt: $deletedAt, ') + ..write('ownerId: $ownerId, ') + ..write('type: $type, ') + ..write('data: $data, ') + ..write('isSaved: $isSaved, ') + ..write('memoryAt: $memoryAt, ') + ..write('seenAt: $seenAt, ') + ..write('showAt: $showAt, ') + ..write('hideAt: $hideAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + createdAt, + updatedAt, + deletedAt, + ownerId, + type, + data, + isSaved, + memoryAt, + seenAt, + showAt, + hideAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MemoryEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.deletedAt == this.deletedAt && + other.ownerId == this.ownerId && + other.type == this.type && + other.data == this.data && + other.isSaved == this.isSaved && + other.memoryAt == this.memoryAt && + other.seenAt == this.seenAt && + other.showAt == this.showAt && + other.hideAt == this.hideAt); +} + +class MemoryEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value deletedAt; + final Value ownerId; + final Value type; + final Value data; + final Value isSaved; + final Value memoryAt; + final Value seenAt; + final Value showAt; + final Value hideAt; + const MemoryEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.deletedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.type = const Value.absent(), + this.data = const Value.absent(), + this.isSaved = const Value.absent(), + this.memoryAt = const Value.absent(), + this.seenAt = const Value.absent(), + this.showAt = const Value.absent(), + this.hideAt = const Value.absent(), + }); + MemoryEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.deletedAt = const Value.absent(), + required String ownerId, + required int type, + required String data, + this.isSaved = const Value.absent(), + required DateTime memoryAt, + this.seenAt = const Value.absent(), + this.showAt = const Value.absent(), + this.hideAt = const Value.absent(), + }) : id = Value(id), + ownerId = Value(ownerId), + type = Value(type), + data = Value(data), + memoryAt = Value(memoryAt); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? deletedAt, + Expression? ownerId, + Expression? type, + Expression? data, + Expression? isSaved, + Expression? memoryAt, + Expression? seenAt, + Expression? showAt, + Expression? hideAt, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (deletedAt != null) 'deleted_at': deletedAt, + if (ownerId != null) 'owner_id': ownerId, + if (type != null) 'type': type, + if (data != null) 'data': data, + if (isSaved != null) 'is_saved': isSaved, + if (memoryAt != null) 'memory_at': memoryAt, + if (seenAt != null) 'seen_at': seenAt, + if (showAt != null) 'show_at': showAt, + if (hideAt != null) 'hide_at': hideAt, + }); + } + + MemoryEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? deletedAt, + Value? ownerId, + Value? type, + Value? data, + Value? isSaved, + Value? memoryAt, + Value? seenAt, + Value? showAt, + Value? hideAt, + }) { + return MemoryEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + deletedAt: deletedAt ?? this.deletedAt, + ownerId: ownerId ?? this.ownerId, + type: type ?? this.type, + data: data ?? this.data, + isSaved: isSaved ?? this.isSaved, + memoryAt: memoryAt ?? this.memoryAt, + seenAt: seenAt ?? this.seenAt, + showAt: showAt ?? this.showAt, + hideAt: hideAt ?? this.hideAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (deletedAt.present) { + map['deleted_at'] = Variable(deletedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (data.present) { + map['data'] = Variable(data.value); + } + if (isSaved.present) { + map['is_saved'] = Variable(isSaved.value); + } + if (memoryAt.present) { + map['memory_at'] = Variable(memoryAt.value); + } + if (seenAt.present) { + map['seen_at'] = Variable(seenAt.value); + } + if (showAt.present) { + map['show_at'] = Variable(showAt.value); + } + if (hideAt.present) { + map['hide_at'] = Variable(hideAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MemoryEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('deletedAt: $deletedAt, ') + ..write('ownerId: $ownerId, ') + ..write('type: $type, ') + ..write('data: $data, ') + ..write('isSaved: $isSaved, ') + ..write('memoryAt: $memoryAt, ') + ..write('seenAt: $seenAt, ') + ..write('showAt: $showAt, ') + ..write('hideAt: $hideAt') + ..write(')')) + .toString(); + } +} + +class MemoryAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MemoryAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn memoryId = GeneratedColumn( + 'memory_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES memory_entity (id) ON DELETE CASCADE', + ), + ); + @override + List get $columns => [assetId, memoryId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'memory_asset_entity'; + @override + Set get $primaryKey => {assetId, memoryId}; + @override + MemoryAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MemoryAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + memoryId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}memory_id'], + )!, + ); + } + + @override + MemoryAssetEntity createAlias(String alias) { + return MemoryAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class MemoryAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String memoryId; + const MemoryAssetEntityData({required this.assetId, required this.memoryId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['memory_id'] = Variable(memoryId); + return map; + } + + factory MemoryAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MemoryAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + memoryId: serializer.fromJson(json['memoryId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'memoryId': serializer.toJson(memoryId), + }; + } + + MemoryAssetEntityData copyWith({String? assetId, String? memoryId}) => + MemoryAssetEntityData( + assetId: assetId ?? this.assetId, + memoryId: memoryId ?? this.memoryId, + ); + MemoryAssetEntityData copyWithCompanion(MemoryAssetEntityCompanion data) { + return MemoryAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + memoryId: data.memoryId.present ? data.memoryId.value : this.memoryId, + ); + } + + @override + String toString() { + return (StringBuffer('MemoryAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('memoryId: $memoryId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, memoryId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MemoryAssetEntityData && + other.assetId == this.assetId && + other.memoryId == this.memoryId); +} + +class MemoryAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value memoryId; + const MemoryAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.memoryId = const Value.absent(), + }); + MemoryAssetEntityCompanion.insert({ + required String assetId, + required String memoryId, + }) : assetId = Value(assetId), + memoryId = Value(memoryId); + static Insertable custom({ + Expression? assetId, + Expression? memoryId, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (memoryId != null) 'memory_id': memoryId, + }); + } + + MemoryAssetEntityCompanion copyWith({ + Value? assetId, + Value? memoryId, + }) { + return MemoryAssetEntityCompanion( + assetId: assetId ?? this.assetId, + memoryId: memoryId ?? this.memoryId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (memoryId.present) { + map['memory_id'] = Variable(memoryId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MemoryAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('memoryId: $memoryId') + ..write(')')) + .toString(); + } +} + +class PersonEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + PersonEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn faceAssetId = GeneratedColumn( + 'face_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + ); + late final GeneratedColumn isHidden = GeneratedColumn( + 'is_hidden', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_hidden" IN (0, 1))', + ), + ); + late final GeneratedColumn color = GeneratedColumn( + 'color', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn birthDate = GeneratedColumn( + 'birth_date', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + ownerId, + name, + faceAssetId, + isFavorite, + isHidden, + color, + birthDate, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'person_entity'; + @override + Set get $primaryKey => {id}; + @override + PersonEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PersonEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + faceAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}face_asset_id'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + isHidden: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_hidden'], + )!, + color: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}color'], + ), + birthDate: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}birth_date'], + ), + ); + } + + @override + PersonEntity createAlias(String alias) { + return PersonEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class PersonEntityData extends DataClass + implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String name; + final String? faceAssetId; + final bool isFavorite; + final bool isHidden; + final String? color; + final DateTime? birthDate; + const PersonEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.name, + this.faceAssetId, + required this.isFavorite, + required this.isHidden, + this.color, + this.birthDate, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + map['name'] = Variable(name); + if (!nullToAbsent || faceAssetId != null) { + map['face_asset_id'] = Variable(faceAssetId); + } + map['is_favorite'] = Variable(isFavorite); + map['is_hidden'] = Variable(isHidden); + if (!nullToAbsent || color != null) { + map['color'] = Variable(color); + } + if (!nullToAbsent || birthDate != null) { + map['birth_date'] = Variable(birthDate); + } + return map; + } + + factory PersonEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PersonEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + name: serializer.fromJson(json['name']), + faceAssetId: serializer.fromJson(json['faceAssetId']), + isFavorite: serializer.fromJson(json['isFavorite']), + isHidden: serializer.fromJson(json['isHidden']), + color: serializer.fromJson(json['color']), + birthDate: serializer.fromJson(json['birthDate']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'name': serializer.toJson(name), + 'faceAssetId': serializer.toJson(faceAssetId), + 'isFavorite': serializer.toJson(isFavorite), + 'isHidden': serializer.toJson(isHidden), + 'color': serializer.toJson(color), + 'birthDate': serializer.toJson(birthDate), + }; + } + + PersonEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? name, + Value faceAssetId = const Value.absent(), + bool? isFavorite, + bool? isHidden, + Value color = const Value.absent(), + Value birthDate = const Value.absent(), + }) => PersonEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + name: name ?? this.name, + faceAssetId: faceAssetId.present ? faceAssetId.value : this.faceAssetId, + isFavorite: isFavorite ?? this.isFavorite, + isHidden: isHidden ?? this.isHidden, + color: color.present ? color.value : this.color, + birthDate: birthDate.present ? birthDate.value : this.birthDate, + ); + PersonEntityData copyWithCompanion(PersonEntityCompanion data) { + return PersonEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + name: data.name.present ? data.name.value : this.name, + faceAssetId: data.faceAssetId.present + ? data.faceAssetId.value + : this.faceAssetId, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + isHidden: data.isHidden.present ? data.isHidden.value : this.isHidden, + color: data.color.present ? data.color.value : this.color, + birthDate: data.birthDate.present ? data.birthDate.value : this.birthDate, + ); + } + + @override + String toString() { + return (StringBuffer('PersonEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('name: $name, ') + ..write('faceAssetId: $faceAssetId, ') + ..write('isFavorite: $isFavorite, ') + ..write('isHidden: $isHidden, ') + ..write('color: $color, ') + ..write('birthDate: $birthDate') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + createdAt, + updatedAt, + ownerId, + name, + faceAssetId, + isFavorite, + isHidden, + color, + birthDate, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PersonEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.name == this.name && + other.faceAssetId == this.faceAssetId && + other.isFavorite == this.isFavorite && + other.isHidden == this.isHidden && + other.color == this.color && + other.birthDate == this.birthDate); +} + +class PersonEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value name; + final Value faceAssetId; + final Value isFavorite; + final Value isHidden; + final Value color; + final Value birthDate; + const PersonEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.name = const Value.absent(), + this.faceAssetId = const Value.absent(), + this.isFavorite = const Value.absent(), + this.isHidden = const Value.absent(), + this.color = const Value.absent(), + this.birthDate = const Value.absent(), + }); + PersonEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + required String name, + this.faceAssetId = const Value.absent(), + required bool isFavorite, + required bool isHidden, + this.color = const Value.absent(), + this.birthDate = const Value.absent(), + }) : id = Value(id), + ownerId = Value(ownerId), + name = Value(name), + isFavorite = Value(isFavorite), + isHidden = Value(isHidden); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? name, + Expression? faceAssetId, + Expression? isFavorite, + Expression? isHidden, + Expression? color, + Expression? birthDate, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (name != null) 'name': name, + if (faceAssetId != null) 'face_asset_id': faceAssetId, + if (isFavorite != null) 'is_favorite': isFavorite, + if (isHidden != null) 'is_hidden': isHidden, + if (color != null) 'color': color, + if (birthDate != null) 'birth_date': birthDate, + }); + } + + PersonEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? name, + Value? faceAssetId, + Value? isFavorite, + Value? isHidden, + Value? color, + Value? birthDate, + }) { + return PersonEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + name: name ?? this.name, + faceAssetId: faceAssetId ?? this.faceAssetId, + isFavorite: isFavorite ?? this.isFavorite, + isHidden: isHidden ?? this.isHidden, + color: color ?? this.color, + birthDate: birthDate ?? this.birthDate, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (faceAssetId.present) { + map['face_asset_id'] = Variable(faceAssetId.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (isHidden.present) { + map['is_hidden'] = Variable(isHidden.value); + } + if (color.present) { + map['color'] = Variable(color.value); + } + if (birthDate.present) { + map['birth_date'] = Variable(birthDate.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PersonEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('name: $name, ') + ..write('faceAssetId: $faceAssetId, ') + ..write('isFavorite: $isFavorite, ') + ..write('isHidden: $isHidden, ') + ..write('color: $color, ') + ..write('birthDate: $birthDate') + ..write(')')) + .toString(); + } +} + +class AssetFaceEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + AssetFaceEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn personId = GeneratedColumn( + 'person_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES person_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn imageWidth = GeneratedColumn( + 'image_width', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn imageHeight = GeneratedColumn( + 'image_height', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxX1 = GeneratedColumn( + 'bounding_box_x1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxY1 = GeneratedColumn( + 'bounding_box_y1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxX2 = GeneratedColumn( + 'bounding_box_x2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxY2 = GeneratedColumn( + 'bounding_box_y2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn sourceType = GeneratedColumn( + 'source_type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'asset_face_entity'; + @override + Set get $primaryKey => {id}; + @override + AssetFaceEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return AssetFaceEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + personId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}person_id'], + ), + imageWidth: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}image_width'], + )!, + imageHeight: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}image_height'], + )!, + boundingBoxX1: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_x1'], + )!, + boundingBoxY1: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_y1'], + )!, + boundingBoxX2: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_x2'], + )!, + boundingBoxY2: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_y2'], + )!, + sourceType: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}source_type'], + )!, + ); + } + + @override + AssetFaceEntity createAlias(String alias) { + return AssetFaceEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class AssetFaceEntityData extends DataClass + implements Insertable { + final String id; + final String assetId; + final String? personId; + final int imageWidth; + final int imageHeight; + final int boundingBoxX1; + final int boundingBoxY1; + final int boundingBoxX2; + final int boundingBoxY2; + final String sourceType; + const AssetFaceEntityData({ + required this.id, + required this.assetId, + this.personId, + required this.imageWidth, + required this.imageHeight, + required this.boundingBoxX1, + required this.boundingBoxY1, + required this.boundingBoxX2, + required this.boundingBoxY2, + required this.sourceType, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['asset_id'] = Variable(assetId); + if (!nullToAbsent || personId != null) { + map['person_id'] = Variable(personId); + } + map['image_width'] = Variable(imageWidth); + map['image_height'] = Variable(imageHeight); + map['bounding_box_x1'] = Variable(boundingBoxX1); + map['bounding_box_y1'] = Variable(boundingBoxY1); + map['bounding_box_x2'] = Variable(boundingBoxX2); + map['bounding_box_y2'] = Variable(boundingBoxY2); + map['source_type'] = Variable(sourceType); + return map; + } + + factory AssetFaceEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return AssetFaceEntityData( + id: serializer.fromJson(json['id']), + assetId: serializer.fromJson(json['assetId']), + personId: serializer.fromJson(json['personId']), + imageWidth: serializer.fromJson(json['imageWidth']), + imageHeight: serializer.fromJson(json['imageHeight']), + boundingBoxX1: serializer.fromJson(json['boundingBoxX1']), + boundingBoxY1: serializer.fromJson(json['boundingBoxY1']), + boundingBoxX2: serializer.fromJson(json['boundingBoxX2']), + boundingBoxY2: serializer.fromJson(json['boundingBoxY2']), + sourceType: serializer.fromJson(json['sourceType']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'assetId': serializer.toJson(assetId), + 'personId': serializer.toJson(personId), + 'imageWidth': serializer.toJson(imageWidth), + 'imageHeight': serializer.toJson(imageHeight), + 'boundingBoxX1': serializer.toJson(boundingBoxX1), + 'boundingBoxY1': serializer.toJson(boundingBoxY1), + 'boundingBoxX2': serializer.toJson(boundingBoxX2), + 'boundingBoxY2': serializer.toJson(boundingBoxY2), + 'sourceType': serializer.toJson(sourceType), + }; + } + + AssetFaceEntityData copyWith({ + String? id, + String? assetId, + Value personId = const Value.absent(), + int? imageWidth, + int? imageHeight, + int? boundingBoxX1, + int? boundingBoxY1, + int? boundingBoxX2, + int? boundingBoxY2, + String? sourceType, + }) => AssetFaceEntityData( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + personId: personId.present ? personId.value : this.personId, + imageWidth: imageWidth ?? this.imageWidth, + imageHeight: imageHeight ?? this.imageHeight, + boundingBoxX1: boundingBoxX1 ?? this.boundingBoxX1, + boundingBoxY1: boundingBoxY1 ?? this.boundingBoxY1, + boundingBoxX2: boundingBoxX2 ?? this.boundingBoxX2, + boundingBoxY2: boundingBoxY2 ?? this.boundingBoxY2, + sourceType: sourceType ?? this.sourceType, + ); + AssetFaceEntityData copyWithCompanion(AssetFaceEntityCompanion data) { + return AssetFaceEntityData( + id: data.id.present ? data.id.value : this.id, + assetId: data.assetId.present ? data.assetId.value : this.assetId, + personId: data.personId.present ? data.personId.value : this.personId, + imageWidth: data.imageWidth.present + ? data.imageWidth.value + : this.imageWidth, + imageHeight: data.imageHeight.present + ? data.imageHeight.value + : this.imageHeight, + boundingBoxX1: data.boundingBoxX1.present + ? data.boundingBoxX1.value + : this.boundingBoxX1, + boundingBoxY1: data.boundingBoxY1.present + ? data.boundingBoxY1.value + : this.boundingBoxY1, + boundingBoxX2: data.boundingBoxX2.present + ? data.boundingBoxX2.value + : this.boundingBoxX2, + boundingBoxY2: data.boundingBoxY2.present + ? data.boundingBoxY2.value + : this.boundingBoxY2, + sourceType: data.sourceType.present + ? data.sourceType.value + : this.sourceType, + ); + } + + @override + String toString() { + return (StringBuffer('AssetFaceEntityData(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('personId: $personId, ') + ..write('imageWidth: $imageWidth, ') + ..write('imageHeight: $imageHeight, ') + ..write('boundingBoxX1: $boundingBoxX1, ') + ..write('boundingBoxY1: $boundingBoxY1, ') + ..write('boundingBoxX2: $boundingBoxX2, ') + ..write('boundingBoxY2: $boundingBoxY2, ') + ..write('sourceType: $sourceType') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is AssetFaceEntityData && + other.id == this.id && + other.assetId == this.assetId && + other.personId == this.personId && + other.imageWidth == this.imageWidth && + other.imageHeight == this.imageHeight && + other.boundingBoxX1 == this.boundingBoxX1 && + other.boundingBoxY1 == this.boundingBoxY1 && + other.boundingBoxX2 == this.boundingBoxX2 && + other.boundingBoxY2 == this.boundingBoxY2 && + other.sourceType == this.sourceType); +} + +class AssetFaceEntityCompanion extends UpdateCompanion { + final Value id; + final Value assetId; + final Value personId; + final Value imageWidth; + final Value imageHeight; + final Value boundingBoxX1; + final Value boundingBoxY1; + final Value boundingBoxX2; + final Value boundingBoxY2; + final Value sourceType; + const AssetFaceEntityCompanion({ + this.id = const Value.absent(), + this.assetId = const Value.absent(), + this.personId = const Value.absent(), + this.imageWidth = const Value.absent(), + this.imageHeight = const Value.absent(), + this.boundingBoxX1 = const Value.absent(), + this.boundingBoxY1 = const Value.absent(), + this.boundingBoxX2 = const Value.absent(), + this.boundingBoxY2 = const Value.absent(), + this.sourceType = const Value.absent(), + }); + AssetFaceEntityCompanion.insert({ + required String id, + required String assetId, + this.personId = const Value.absent(), + required int imageWidth, + required int imageHeight, + required int boundingBoxX1, + required int boundingBoxY1, + required int boundingBoxX2, + required int boundingBoxY2, + required String sourceType, + }) : id = Value(id), + assetId = Value(assetId), + imageWidth = Value(imageWidth), + imageHeight = Value(imageHeight), + boundingBoxX1 = Value(boundingBoxX1), + boundingBoxY1 = Value(boundingBoxY1), + boundingBoxX2 = Value(boundingBoxX2), + boundingBoxY2 = Value(boundingBoxY2), + sourceType = Value(sourceType); + static Insertable custom({ + Expression? id, + Expression? assetId, + Expression? personId, + Expression? imageWidth, + Expression? imageHeight, + Expression? boundingBoxX1, + Expression? boundingBoxY1, + Expression? boundingBoxX2, + Expression? boundingBoxY2, + Expression? sourceType, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (assetId != null) 'asset_id': assetId, + if (personId != null) 'person_id': personId, + if (imageWidth != null) 'image_width': imageWidth, + if (imageHeight != null) 'image_height': imageHeight, + if (boundingBoxX1 != null) 'bounding_box_x1': boundingBoxX1, + if (boundingBoxY1 != null) 'bounding_box_y1': boundingBoxY1, + if (boundingBoxX2 != null) 'bounding_box_x2': boundingBoxX2, + if (boundingBoxY2 != null) 'bounding_box_y2': boundingBoxY2, + if (sourceType != null) 'source_type': sourceType, + }); + } + + AssetFaceEntityCompanion copyWith({ + Value? id, + Value? assetId, + Value? personId, + Value? imageWidth, + Value? imageHeight, + Value? boundingBoxX1, + Value? boundingBoxY1, + Value? boundingBoxX2, + Value? boundingBoxY2, + Value? sourceType, + }) { + return AssetFaceEntityCompanion( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + personId: personId ?? this.personId, + imageWidth: imageWidth ?? this.imageWidth, + imageHeight: imageHeight ?? this.imageHeight, + boundingBoxX1: boundingBoxX1 ?? this.boundingBoxX1, + boundingBoxY1: boundingBoxY1 ?? this.boundingBoxY1, + boundingBoxX2: boundingBoxX2 ?? this.boundingBoxX2, + boundingBoxY2: boundingBoxY2 ?? this.boundingBoxY2, + sourceType: sourceType ?? this.sourceType, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (personId.present) { + map['person_id'] = Variable(personId.value); + } + if (imageWidth.present) { + map['image_width'] = Variable(imageWidth.value); + } + if (imageHeight.present) { + map['image_height'] = Variable(imageHeight.value); + } + if (boundingBoxX1.present) { + map['bounding_box_x1'] = Variable(boundingBoxX1.value); + } + if (boundingBoxY1.present) { + map['bounding_box_y1'] = Variable(boundingBoxY1.value); + } + if (boundingBoxX2.present) { + map['bounding_box_x2'] = Variable(boundingBoxX2.value); + } + if (boundingBoxY2.present) { + map['bounding_box_y2'] = Variable(boundingBoxY2.value); + } + if (sourceType.present) { + map['source_type'] = Variable(sourceType.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AssetFaceEntityCompanion(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('personId: $personId, ') + ..write('imageWidth: $imageWidth, ') + ..write('imageHeight: $imageHeight, ') + ..write('boundingBoxX1: $boundingBoxX1, ') + ..write('boundingBoxY1: $boundingBoxY1, ') + ..write('boundingBoxX2: $boundingBoxX2, ') + ..write('boundingBoxY2: $boundingBoxY2, ') + ..write('sourceType: $sourceType') + ..write(')')) + .toString(); + } +} + +class StoreEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + StoreEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn stringValue = GeneratedColumn( + 'string_value', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn intValue = GeneratedColumn( + 'int_value', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + @override + List get $columns => [id, stringValue, intValue]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'store_entity'; + @override + Set get $primaryKey => {id}; + @override + StoreEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return StoreEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}id'], + )!, + stringValue: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}string_value'], + ), + intValue: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}int_value'], + ), + ); + } + + @override + StoreEntity createAlias(String alias) { + return StoreEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class StoreEntityData extends DataClass implements Insertable { + final int id; + final String? stringValue; + final int? intValue; + const StoreEntityData({required this.id, this.stringValue, this.intValue}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + if (!nullToAbsent || stringValue != null) { + map['string_value'] = Variable(stringValue); + } + if (!nullToAbsent || intValue != null) { + map['int_value'] = Variable(intValue); + } + return map; + } + + factory StoreEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return StoreEntityData( + id: serializer.fromJson(json['id']), + stringValue: serializer.fromJson(json['stringValue']), + intValue: serializer.fromJson(json['intValue']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'stringValue': serializer.toJson(stringValue), + 'intValue': serializer.toJson(intValue), + }; + } + + StoreEntityData copyWith({ + int? id, + Value stringValue = const Value.absent(), + Value intValue = const Value.absent(), + }) => StoreEntityData( + id: id ?? this.id, + stringValue: stringValue.present ? stringValue.value : this.stringValue, + intValue: intValue.present ? intValue.value : this.intValue, + ); + StoreEntityData copyWithCompanion(StoreEntityCompanion data) { + return StoreEntityData( + id: data.id.present ? data.id.value : this.id, + stringValue: data.stringValue.present + ? data.stringValue.value + : this.stringValue, + intValue: data.intValue.present ? data.intValue.value : this.intValue, + ); + } + + @override + String toString() { + return (StringBuffer('StoreEntityData(') + ..write('id: $id, ') + ..write('stringValue: $stringValue, ') + ..write('intValue: $intValue') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, stringValue, intValue); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is StoreEntityData && + other.id == this.id && + other.stringValue == this.stringValue && + other.intValue == this.intValue); +} + +class StoreEntityCompanion extends UpdateCompanion { + final Value id; + final Value stringValue; + final Value intValue; + const StoreEntityCompanion({ + this.id = const Value.absent(), + this.stringValue = const Value.absent(), + this.intValue = const Value.absent(), + }); + StoreEntityCompanion.insert({ + required int id, + this.stringValue = const Value.absent(), + this.intValue = const Value.absent(), + }) : id = Value(id); + static Insertable custom({ + Expression? id, + Expression? stringValue, + Expression? intValue, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (stringValue != null) 'string_value': stringValue, + if (intValue != null) 'int_value': intValue, + }); + } + + StoreEntityCompanion copyWith({ + Value? id, + Value? stringValue, + Value? intValue, + }) { + return StoreEntityCompanion( + id: id ?? this.id, + stringValue: stringValue ?? this.stringValue, + intValue: intValue ?? this.intValue, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (stringValue.present) { + map['string_value'] = Variable(stringValue.value); + } + if (intValue.present) { + map['int_value'] = Variable(intValue.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('StoreEntityCompanion(') + ..write('id: $id, ') + ..write('stringValue: $stringValue, ') + ..write('intValue: $intValue') + ..write(')')) + .toString(); + } +} + +class TrashedLocalAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + TrashedLocalAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn durationInSeconds = GeneratedColumn( + 'duration_in_seconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + albumId, + checksum, + isFavorite, + orientation, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'trashed_local_asset_entity'; + @override + Set get $primaryKey => {id, albumId}; + @override + TrashedLocalAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return TrashedLocalAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationInSeconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_in_seconds'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}orientation'], + )!, + ); + } + + @override + TrashedLocalAssetEntity createAlias(String alias) { + return TrashedLocalAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class TrashedLocalAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final DateTime createdAt; + final DateTime updatedAt; + final int? width; + final int? height; + final int? durationInSeconds; + final String id; + final String albumId; + final String? checksum; + final bool isFavorite; + final int orientation; + const TrashedLocalAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationInSeconds, + required this.id, + required this.albumId, + this.checksum, + required this.isFavorite, + required this.orientation, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['name'] = Variable(name); + map['type'] = Variable(type); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || durationInSeconds != null) { + map['duration_in_seconds'] = Variable(durationInSeconds); + } + map['id'] = Variable(id); + map['album_id'] = Variable(albumId); + if (!nullToAbsent || checksum != null) { + map['checksum'] = Variable(checksum); + } + map['is_favorite'] = Variable(isFavorite); + map['orientation'] = Variable(orientation); + return map; + } + + factory TrashedLocalAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return TrashedLocalAssetEntityData( + name: serializer.fromJson(json['name']), + type: serializer.fromJson(json['type']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + width: serializer.fromJson(json['width']), + height: serializer.fromJson(json['height']), + durationInSeconds: serializer.fromJson(json['durationInSeconds']), + id: serializer.fromJson(json['id']), + albumId: serializer.fromJson(json['albumId']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + orientation: serializer.fromJson(json['orientation']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'name': serializer.toJson(name), + 'type': serializer.toJson(type), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'width': serializer.toJson(width), + 'height': serializer.toJson(height), + 'durationInSeconds': serializer.toJson(durationInSeconds), + 'id': serializer.toJson(id), + 'albumId': serializer.toJson(albumId), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'orientation': serializer.toJson(orientation), + }; + } + + TrashedLocalAssetEntityData copyWith({ + String? name, + int? type, + DateTime? createdAt, + DateTime? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationInSeconds = const Value.absent(), + String? id, + String? albumId, + Value checksum = const Value.absent(), + bool? isFavorite, + int? orientation, + }) => TrashedLocalAssetEntityData( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width.present ? width.value : this.width, + height: height.present ? height.value : this.height, + durationInSeconds: durationInSeconds.present + ? durationInSeconds.value + : this.durationInSeconds, + id: id ?? this.id, + albumId: albumId ?? this.albumId, + checksum: checksum.present ? checksum.value : this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + ); + TrashedLocalAssetEntityData copyWithCompanion( + TrashedLocalAssetEntityCompanion data, + ) { + return TrashedLocalAssetEntityData( + name: data.name.present ? data.name.value : this.name, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + width: data.width.present ? data.width.value : this.width, + height: data.height.present ? data.height.value : this.height, + durationInSeconds: data.durationInSeconds.present + ? data.durationInSeconds.value + : this.durationInSeconds, + id: data.id.present ? data.id.value : this.id, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + checksum: data.checksum.present ? data.checksum.value : this.checksum, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + orientation: data.orientation.present + ? data.orientation.value + : this.orientation, + ); + } + + @override + String toString() { + return (StringBuffer('TrashedLocalAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('albumId: $albumId, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + albumId, + checksum, + isFavorite, + orientation, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is TrashedLocalAssetEntityData && + other.name == this.name && + other.type == this.type && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.width == this.width && + other.height == this.height && + other.durationInSeconds == this.durationInSeconds && + other.id == this.id && + other.albumId == this.albumId && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.orientation == this.orientation); +} + +class TrashedLocalAssetEntityCompanion + extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationInSeconds; + final Value id; + final Value albumId; + final Value checksum; + final Value isFavorite; + final Value orientation; + const TrashedLocalAssetEntityCompanion({ + this.name = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + this.id = const Value.absent(), + this.albumId = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + }); + TrashedLocalAssetEntityCompanion.insert({ + required String name, + required int type, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + required String id, + required String albumId, + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id), + albumId = Value(albumId); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationInSeconds, + Expression? id, + Expression? albumId, + Expression? checksum, + Expression? isFavorite, + Expression? orientation, + }) { + return RawValuesInsertable({ + if (name != null) 'name': name, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (width != null) 'width': width, + if (height != null) 'height': height, + if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds, + if (id != null) 'id': id, + if (albumId != null) 'album_id': albumId, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (orientation != null) 'orientation': orientation, + }); + } + + TrashedLocalAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationInSeconds, + Value? id, + Value? albumId, + Value? checksum, + Value? isFavorite, + Value? orientation, + }) { + return TrashedLocalAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationInSeconds: durationInSeconds ?? this.durationInSeconds, + id: id ?? this.id, + albumId: albumId ?? this.albumId, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (name.present) { + map['name'] = Variable(name.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (durationInSeconds.present) { + map['duration_in_seconds'] = Variable(durationInSeconds.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + if (checksum.present) { + map['checksum'] = Variable(checksum.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (orientation.present) { + map['orientation'] = Variable(orientation.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('TrashedLocalAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('albumId: $albumId, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation') + ..write(')')) + .toString(); + } +} + +class DatabaseAtV14 extends GeneratedDatabase { + DatabaseAtV14(QueryExecutor e) : super(e); + late final UserEntity userEntity = UserEntity(this); + late final RemoteAssetEntity remoteAssetEntity = RemoteAssetEntity(this); + late final StackEntity stackEntity = StackEntity(this); + late final LocalAssetEntity localAssetEntity = LocalAssetEntity(this); + late final RemoteAlbumEntity remoteAlbumEntity = RemoteAlbumEntity(this); + late final LocalAlbumEntity localAlbumEntity = LocalAlbumEntity(this); + late final LocalAlbumAssetEntity localAlbumAssetEntity = + LocalAlbumAssetEntity(this); + late final Index idxLocalAssetChecksum = Index( + 'idx_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)', + ); + late final Index idxRemoteAssetOwnerChecksum = Index( + 'idx_remote_asset_owner_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)', + ); + late final Index uQRemoteAssetsOwnerChecksum = Index( + 'UQ_remote_assets_owner_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)', + ); + late final Index uQRemoteAssetsOwnerLibraryChecksum = Index( + 'UQ_remote_assets_owner_library_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)', + ); + late final Index idxRemoteAssetChecksum = Index( + 'idx_remote_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)', + ); + late final AuthUserEntity authUserEntity = AuthUserEntity(this); + late final UserMetadataEntity userMetadataEntity = UserMetadataEntity(this); + late final PartnerEntity partnerEntity = PartnerEntity(this); + late final RemoteExifEntity remoteExifEntity = RemoteExifEntity(this); + late final RemoteAlbumAssetEntity remoteAlbumAssetEntity = + RemoteAlbumAssetEntity(this); + late final RemoteAlbumUserEntity remoteAlbumUserEntity = + RemoteAlbumUserEntity(this); + late final MemoryEntity memoryEntity = MemoryEntity(this); + late final MemoryAssetEntity memoryAssetEntity = MemoryAssetEntity(this); + late final PersonEntity personEntity = PersonEntity(this); + late final AssetFaceEntity assetFaceEntity = AssetFaceEntity(this); + late final StoreEntity storeEntity = StoreEntity(this); + late final TrashedLocalAssetEntity trashedLocalAssetEntity = + TrashedLocalAssetEntity(this); + late final Index idxLatLng = Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); + late final Index idxTrashedLocalAssetChecksum = Index( + 'idx_trashed_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)', + ); + late final Index idxTrashedLocalAssetAlbum = Index( + 'idx_trashed_local_asset_album', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)', + ); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAssetChecksum, + idxRemoteAssetOwnerChecksum, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + trashedLocalAssetEntity, + idxLatLng, + idxTrashedLocalAssetChecksum, + idxTrashedLocalAssetAlbum, + ]; + @override + int get schemaVersion => 14; + @override + DriftDatabaseOptions get options => + const DriftDatabaseOptions(storeDateTimeAsText: true); +} diff --git a/mobile/test/infrastructure/repository.mock.dart b/mobile/test/infrastructure/repository.mock.dart index becfafe33d..aac384c29e 100644 --- a/mobile/test/infrastructure/repository.mock.dart +++ b/mobile/test/infrastructure/repository.mock.dart @@ -4,6 +4,7 @@ import 'package:immich_mobile/infrastructure/repositories/local_album.repository import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/log.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart'; @@ -35,6 +36,8 @@ class MockLocalAssetRepository extends Mock implements DriftLocalAssetRepository class MockDriftLocalAssetRepository extends Mock implements DriftLocalAssetRepository {} +class MockRemoteAssetRepository extends Mock implements RemoteAssetRepository {} + class MockTrashedLocalAssetRepository extends Mock implements DriftTrashedLocalAssetRepository {} class MockStorageRepository extends Mock implements StorageRepository {} diff --git a/mobile/test/test_utils.dart b/mobile/test/test_utils.dart index 9b59773d3b..498607e3d2 100644 --- a/mobile/test/test_utils.dart +++ b/mobile/test/test_utils.dart @@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:fake_async/fake_async.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/domain/models/asset/base_asset.model.dart' as domain; import 'package:immich_mobile/entities/album.entity.dart'; import 'package:immich_mobile/entities/android_device_asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; @@ -116,4 +117,43 @@ abstract final class TestUtils { } return result; } + + static domain.RemoteAsset createRemoteAsset({required String id, int? width, int? height, String? ownerId}) { + return domain.RemoteAsset( + id: id, + checksum: 'checksum1', + ownerId: ownerId ?? 'owner1', + name: 'test.jpg', + type: domain.AssetType.image, + createdAt: DateTime(2024, 1, 1), + updatedAt: DateTime(2024, 1, 1), + durationInSeconds: 0, + isFavorite: false, + width: width, + height: height, + ); + } + + static domain.LocalAsset createLocalAsset({ + required String id, + String? remoteId, + int? width, + int? height, + int orientation = 0, + }) { + return domain.LocalAsset( + id: id, + remoteId: remoteId, + checksum: 'checksum1', + name: 'test.jpg', + type: domain.AssetType.image, + createdAt: DateTime(2024, 1, 1), + updatedAt: DateTime(2024, 1, 1), + durationInSeconds: 0, + isFavorite: false, + width: width, + height: height, + orientation: orientation, + ); + } } diff --git a/mobile/test/utils/timezone_test.dart b/mobile/test/utils/timezone_test.dart new file mode 100644 index 0000000000..d1e89dc473 --- /dev/null +++ b/mobile/test/utils/timezone_test.dart @@ -0,0 +1,278 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/utils/timezone.dart'; +import 'package:timezone/data/latest.dart' as tz; + +void main() { + setUpAll(() { + tz.initializeTimeZones(); + }); + + group('applyTimezoneOffset', () { + group('with named timezone locations', () { + test('should convert UTC to Asia/Hong_Kong (+08:00)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'Asia/Hong_Kong', + ); + + expect(adjustedTime.hour, 20); // 12:00 UTC + 8 hours = 20:00 + expect(offset, const Duration(hours: 8)); + }); + + test('should convert UTC to America/New_York (handles DST)', () { + // Summer time (EDT = UTC-4) + final summerUtc = DateTime.utc(2024, 6, 15, 12, 0, 0); + final (summerTime, summerOffset) = applyTimezoneOffset( + dateTime: summerUtc, + timeZone: 'America/New_York', + ); + + expect(summerTime.hour, 8); // 12:00 UTC - 4 hours = 08:00 + expect(summerOffset, const Duration(hours: -4)); + + // Winter time (EST = UTC-5) + final winterUtc = DateTime.utc(2024, 1, 15, 12, 0, 0); + final (winterTime, winterOffset) = applyTimezoneOffset( + dateTime: winterUtc, + timeZone: 'America/New_York', + ); + + expect(winterTime.hour, 7); // 12:00 UTC - 5 hours = 07:00 + expect(winterOffset, const Duration(hours: -5)); + }); + + test('should convert UTC to Europe/London', () { + // Winter (GMT = UTC+0) + final winterUtc = DateTime.utc(2024, 1, 15, 12, 0, 0); + final (winterTime, winterOffset) = applyTimezoneOffset( + dateTime: winterUtc, + timeZone: 'Europe/London', + ); + + expect(winterTime.hour, 12); + expect(winterOffset, Duration.zero); + + // Summer (BST = UTC+1) + final summerUtc = DateTime.utc(2024, 6, 15, 12, 0, 0); + final (summerTime, summerOffset) = applyTimezoneOffset( + dateTime: summerUtc, + timeZone: 'Europe/London', + ); + + expect(summerTime.hour, 13); + expect(summerOffset, const Duration(hours: 1)); + }); + + test('should handle timezone with 30-minute offset (Asia/Kolkata)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'Asia/Kolkata', + ); + + expect(adjustedTime.hour, 17); + expect(adjustedTime.minute, 30); // 12:00 UTC + 5:30 = 17:30 + expect(offset, const Duration(hours: 5, minutes: 30)); + }); + + test('should handle timezone with 45-minute offset (Asia/Kathmandu)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'Asia/Kathmandu', + ); + + expect(adjustedTime.hour, 17); + expect(adjustedTime.minute, 45); // 12:00 UTC + 5:45 = 17:45 + expect(offset, const Duration(hours: 5, minutes: 45)); + }); + }); + + group('with UTC offset format', () { + test('should handle UTC+08:00 format', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC+08:00', + ); + + expect(adjustedTime.hour, 20); + expect(offset, const Duration(hours: 8)); + }); + + test('should handle UTC-05:00 format', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC-05:00', + ); + + expect(adjustedTime.hour, 7); + expect(offset, const Duration(hours: -5)); + }); + + test('should handle UTC+8 format (without minutes)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC+8', + ); + + expect(adjustedTime.hour, 20); + expect(offset, const Duration(hours: 8)); + }); + + test('should handle UTC-5 format (without minutes)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC-5', + ); + + expect(adjustedTime.hour, 7); + expect(offset, const Duration(hours: -5)); + }); + + test('should handle plain UTC format', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC', + ); + + expect(adjustedTime.hour, 12); + expect(offset, Duration.zero); + }); + + test('should handle lowercase utc format', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'utc+08:00', + ); + + expect(adjustedTime.hour, 20); + expect(offset, const Duration(hours: 8)); + }); + + test('should handle UTC+05:30 format (with minutes)', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC+05:30', + ); + + expect(adjustedTime.hour, 17); + expect(adjustedTime.minute, 30); + expect(offset, const Duration(hours: 5, minutes: 30)); + }); + }); + + group('with null or invalid timezone', () { + test('should return UTC time when timezone is null', () { + final localTime = DateTime(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: localTime, + timeZone: null, + ); + + expect(adjustedTime.isUtc, true); + expect(offset, adjustedTime.timeZoneOffset); + }); + + test('should return UTC time when timezone is invalid', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'Invalid/Timezone', + ); + + expect(adjustedTime.isUtc, true); + expect(adjustedTime.hour, 12); + expect(offset, adjustedTime.timeZoneOffset); + }); + + test('should return UTC time when UTC offset format is malformed', () { + final utcTime = DateTime.utc(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'UTC++08', + ); + + expect(adjustedTime.isUtc, true); + expect(adjustedTime.hour, 12); + }); + }); + + group('edge cases', () { + test('should handle date crossing midnight forward', () { + final utcTime = DateTime.utc(2024, 6, 15, 20, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'Asia/Tokyo', // UTC+9 + ); + + expect(adjustedTime.day, 16); // Crosses to next day + expect(adjustedTime.hour, 5); // 20:00 UTC + 9 = 05:00 next day + expect(offset, const Duration(hours: 9)); + }); + + test('should handle date crossing midnight backward', () { + final utcTime = DateTime.utc(2024, 6, 15, 3, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'America/Los_Angeles', // UTC-7 in summer + ); + + expect(adjustedTime.day, 14); // Crosses to previous day + expect(adjustedTime.hour, 20); // 03:00 UTC - 7 = 20:00 previous day + expect(offset, const Duration(hours: -7)); + }); + + test('should handle year boundary crossing', () { + final utcTime = DateTime.utc(2024, 1, 1, 2, 0, 0); + + final (adjustedTime, offset) = applyTimezoneOffset( + dateTime: utcTime, + timeZone: 'America/New_York', // UTC-5 in winter + ); + + expect(adjustedTime.year, 2023); + expect(adjustedTime.month, 12); + expect(adjustedTime.day, 31); + expect(adjustedTime.hour, 21); // 02:00 UTC - 5 = 21:00 Dec 31 + }); + + test('should convert local time to UTC before applying timezone', () { + // Create a local time (not UTC) + final localTime = DateTime(2024, 6, 15, 12, 0, 0); + + final (adjustedTime, _) = applyTimezoneOffset( + dateTime: localTime, + timeZone: 'Asia/Hong_Kong', + ); + + // The function converts to UTC first, then applies timezone + // So local 12:00 -> UTC (depends on local timezone) -> HK time + // We can verify it's working by checking it's a TZDateTime + expect(adjustedTime, isNotNull); + }); + }); + }); +} diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index d42aa0baa1..e21cf27beb 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -322,6 +322,100 @@ "x-immich-state": "Stable" } }, + "/admin/maintenance": { + "post": { + "description": "Put Immich into or take it out of maintenance mode", + "operationId": "setMaintenanceMode", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetMaintenanceModeDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Set maintenance mode", + "tags": [ + "Maintenance (admin)" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.3.0", + "state": "Added" + }, + { + "version": "v2.3.0", + "state": "Alpha" + } + ], + "x-immich-permission": "maintenance", + "x-immich-state": "Alpha" + } + }, + "/admin/maintenance/login": { + "post": { + "description": "Login with maintenance token or cookie to receive current information and perform further actions.", + "operationId": "maintenanceLogin", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MaintenanceLoginDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MaintenanceAuthDto" + } + } + }, + "description": "" + } + }, + "summary": "Log into maintenance mode", + "tags": [ + "Maintenance (admin)" + ], + "x-immich-history": [ + { + "version": "v2.3.0", + "state": "Added" + }, + { + "version": "v2.3.0", + "state": "Alpha" + } + ], + "x-immich-state": "Alpha" + } + }, "/admin/notifications": { "post": { "description": "Create a new notification for a specific user.", @@ -4835,6 +4929,7 @@ }, "/jobs": { "get": { + "deprecated": true, "description": "Retrieve the counts of the current queue, as well as the current status.", "operationId": "getQueuesLegacy", "parameters": [], @@ -4843,7 +4938,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/QueuesResponseDto" + "$ref": "#/components/schemas/QueuesResponseLegacyDto" } } }, @@ -4863,7 +4958,8 @@ ], "summary": "Retrieve queue counts and status", "tags": [ - "Jobs" + "Jobs", + "Deprecated" ], "x-immich-admin-only": true, "x-immich-history": [ @@ -4878,10 +4974,14 @@ { "version": "v2", "state": "Stable" + }, + { + "version": "v2.4.0", + "state": "Deprecated" } ], "x-immich-permission": "job.read", - "x-immich-state": "Stable" + "x-immich-state": "Deprecated" }, "post": { "description": "Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup.", @@ -4938,6 +5038,7 @@ }, "/jobs/{name}": { "put": { + "deprecated": true, "description": "Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets.", "operationId": "runQueueCommandLegacy", "parameters": [ @@ -4965,7 +5066,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" } } }, @@ -4985,7 +5086,8 @@ ], "summary": "Run jobs", "tags": [ - "Jobs" + "Jobs", + "Deprecated" ], "x-immich-admin-only": true, "x-immich-history": [ @@ -5000,10 +5102,14 @@ { "version": "v2", "state": "Stable" + }, + { + "version": "v2.4.0", + "state": "Deprecated" } ], "x-immich-permission": "job.create", - "x-immich-state": "Stable" + "x-immich-state": "Deprecated" } }, "/libraries": { @@ -7970,6 +8076,303 @@ "x-immich-state": "Alpha" } }, + "/queues": { + "get": { + "description": "Retrieves a list of queues.", + "operationId": "getQueues", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/QueueResponseDto" + }, + "type": "array" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "List all queues", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-permission": "queue.read", + "x-immich-state": "Alpha" + } + }, + "/queues/{name}": { + "get": { + "description": "Retrieves a specific queue by its name.", + "operationId": "getQueue", + "parameters": [ + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "$ref": "#/components/schemas/QueueName" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueueResponseDto" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Retrieve a queue", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-permission": "queue.read", + "x-immich-state": "Alpha" + }, + "put": { + "description": "Change the paused status of a specific queue.", + "operationId": "updateQueue", + "parameters": [ + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "$ref": "#/components/schemas/QueueName" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueueUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueueResponseDto" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Update a queue", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-permission": "queue.update", + "x-immich-state": "Alpha" + } + }, + "/queues/{name}/jobs": { + "delete": { + "description": "Removes all jobs from the specified queue.", + "operationId": "emptyQueue", + "parameters": [ + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "$ref": "#/components/schemas/QueueName" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueueDeleteDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Empty a queue", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-permission": "queueJob.delete", + "x-immich-state": "Alpha" + }, + "get": { + "description": "Retrieves a list of queue jobs from the specified queue.", + "operationId": "getQueueJobs", + "parameters": [ + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "$ref": "#/components/schemas/QueueName" + } + }, + { + "name": "status", + "required": false, + "in": "query", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/QueueJobStatus" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/QueueJobResponseDto" + }, + "type": "array" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Retrieve queue jobs", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-permission": "queueJob.read", + "x-immich-state": "Alpha" + } + }, "/search/cities": { "get": { "description": "Retrieve a list of assets with each asset belonging to a different city. This endpoint is used on the places pages to show a single thumbnail for each city the user has assets in.", @@ -13865,7 +14268,7 @@ "info": { "title": "Immich", "description": "Immich API", - "version": "2.2.3", + "version": "2.3.1", "contact": {} }, "tags": [ @@ -13917,6 +14320,10 @@ "name": "Libraries", "description": "An external library is made up of input file paths or expressions that are scanned for asset files. Discovered files are automatically imported. Assets much be unique within a library, but can be duplicated across libraries. Each user has a default upload library, and can have one or more external libraries." }, + { + "name": "Maintenance (admin)", + "description": "Maintenance mode allows you to put Immich in a read-only state to perform various operations." + }, { "name": "Map", "description": "Map endpoints include supplemental functionality related to geolocation, such as reverse geocoding and retrieving map markers for assets with geolocation data." @@ -13945,6 +14352,10 @@ "name": "Plugins", "description": "A plugin is an installed module that makes filters and actions available for the workflow feature." }, + { + "name": "Queues", + "description": "Queues and background jobs are used for processing tasks asynchronously. Queues can be paused and resumed as needed." + }, { "name": "Search", "description": "Endpoints related to searching assets via text, smart search, optical character recognition (OCR), and other filters like person, album, and other metadata. Search endpoints usually support pagination and sorting." @@ -16193,6 +16604,66 @@ ], "type": "object" }, + "JobName": { + "enum": [ + "AssetDelete", + "AssetDeleteCheck", + "AssetDetectFacesQueueAll", + "AssetDetectFaces", + "AssetDetectDuplicatesQueueAll", + "AssetDetectDuplicates", + "AssetEncodeVideoQueueAll", + "AssetEncodeVideo", + "AssetEmptyTrash", + "AssetExtractMetadataQueueAll", + "AssetExtractMetadata", + "AssetFileMigration", + "AssetGenerateThumbnailsQueueAll", + "AssetGenerateThumbnails", + "AuditLogCleanup", + "AuditTableCleanup", + "DatabaseBackup", + "FacialRecognitionQueueAll", + "FacialRecognition", + "FileDelete", + "FileMigrationQueueAll", + "LibraryDeleteCheck", + "LibraryDelete", + "LibraryRemoveAsset", + "LibraryScanAssetsQueueAll", + "LibrarySyncAssets", + "LibrarySyncFilesQueueAll", + "LibrarySyncFiles", + "LibraryScanQueueAll", + "MemoryCleanup", + "MemoryGenerate", + "NotificationsCleanup", + "NotifyUserSignup", + "NotifyAlbumInvite", + "NotifyAlbumUpdate", + "UserDelete", + "UserDeleteCheck", + "UserSyncUsage", + "PersonCleanup", + "PersonFileMigration", + "PersonGenerateThumbnail", + "SessionCleanup", + "SendMail", + "SidecarQueueAll", + "SidecarCheck", + "SidecarWrite", + "SmartSearchQueueAll", + "SmartSearch", + "StorageTemplateMigration", + "StorageTemplateMigrationSingle", + "TagCleanup", + "VersionCheck", + "OcrQueueAll", + "Ocr", + "WorkflowRun" + ], + "type": "string" + }, "JobSettingsDto": { "properties": { "concurrency": { @@ -16425,6 +16896,32 @@ ], "type": "object" }, + "MaintenanceAction": { + "enum": [ + "start", + "end" + ], + "type": "string" + }, + "MaintenanceAuthDto": { + "properties": { + "username": { + "type": "string" + } + }, + "required": [ + "username" + ], + "type": "object" + }, + "MaintenanceLoginDto": { + "properties": { + "token": { + "type": "string" + } + }, + "type": "object" + }, "ManualJobName": { "enum": [ "person-cleanup", @@ -17380,6 +17877,7 @@ "library.statistics", "timeline.read", "timeline.download", + "maintenance", "memory.create", "memory.read", "memory.update", @@ -17458,6 +17956,12 @@ "userProfileImage.read", "userProfileImage.update", "userProfileImage.delete", + "queue.read", + "queue.update", + "queueJob.create", + "queueJob.read", + "queueJob.update", + "queueJob.delete", "workflow.create", "workflow.read", "workflow.update", @@ -17958,6 +18462,63 @@ ], "type": "object" }, + "QueueDeleteDto": { + "properties": { + "failed": { + "description": "If true, will also remove failed jobs from the queue.", + "type": "boolean", + "x-immich-history": [ + { + "version": "v2.4.0", + "state": "Added" + }, + { + "version": "v2.4.0", + "state": "Alpha" + } + ], + "x-immich-state": "Alpha" + } + }, + "type": "object" + }, + "QueueJobResponseDto": { + "properties": { + "data": { + "type": "object" + }, + "id": { + "type": "string" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/JobName" + } + ] + }, + "timestamp": { + "type": "integer" + } + }, + "required": [ + "data", + "name", + "timestamp" + ], + "type": "object" + }, + "QueueJobStatus": { + "enum": [ + "active", + "failed", + "completed", + "delayed", + "waiting", + "paused" + ], + "type": "string" + }, "QueueName": { "enum": [ "thumbnailGeneration", @@ -17981,12 +18542,35 @@ "type": "string" }, "QueueResponseDto": { + "properties": { + "isPaused": { + "type": "boolean" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/QueueName" + } + ] + }, + "statistics": { + "$ref": "#/components/schemas/QueueStatisticsDto" + } + }, + "required": [ + "isPaused", + "name", + "statistics" + ], + "type": "object" + }, + "QueueResponseLegacyDto": { "properties": { "jobCounts": { "$ref": "#/components/schemas/QueueStatisticsDto" }, "queueStatus": { - "$ref": "#/components/schemas/QueueStatusDto" + "$ref": "#/components/schemas/QueueStatusLegacyDto" } }, "required": [ @@ -18026,7 +18610,7 @@ ], "type": "object" }, - "QueueStatusDto": { + "QueueStatusLegacyDto": { "properties": { "isActive": { "type": "boolean" @@ -18041,58 +18625,66 @@ ], "type": "object" }, - "QueuesResponseDto": { + "QueueUpdateDto": { + "properties": { + "isPaused": { + "type": "boolean" + } + }, + "type": "object" + }, + "QueuesResponseLegacyDto": { "properties": { "backgroundTask": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "backupDatabase": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "duplicateDetection": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "faceDetection": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "facialRecognition": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "library": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "metadataExtraction": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "migration": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "notifications": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "ocr": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "search": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "sidecar": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "smartSearch": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "storageTemplateMigration": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "thumbnailGeneration": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "videoConversion": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" }, "workflow": { - "$ref": "#/components/schemas/QueueResponseDto" + "$ref": "#/components/schemas/QueueResponseLegacyDto" } }, "required": [ @@ -18587,6 +19179,9 @@ "loginPageMessage": { "type": "string" }, + "maintenanceMode": { + "type": "boolean" + }, "mapDarkStyleUrl": { "type": "string" }, @@ -18611,6 +19206,7 @@ "isInitialized", "isOnboarded", "loginPageMessage", + "maintenanceMode", "mapDarkStyleUrl", "mapLightStyleUrl", "oauthButtonText", @@ -18996,6 +19592,21 @@ }, "type": "object" }, + "SetMaintenanceModeDto": { + "properties": { + "action": { + "allOf": [ + { + "$ref": "#/components/schemas/MaintenanceAction" + } + ] + } + }, + "required": [ + "action" + ], + "type": "object" + }, "SharedLinkCreateDto": { "properties": { "albumId": { @@ -22551,13 +23162,13 @@ "actionConfig": { "type": "object" }, - "actionId": { + "pluginActionId": { "format": "uuid", "type": "string" } }, "required": [ - "actionId" + "pluginActionId" ], "type": "object" }, @@ -22567,24 +23178,24 @@ "nullable": true, "type": "object" }, - "actionId": { - "type": "string" - }, "id": { "type": "string" }, "order": { "type": "number" }, + "pluginActionId": { + "type": "string" + }, "workflowId": { "type": "string" } }, "required": [ "actionConfig", - "actionId", "id", "order", + "pluginActionId", "workflowId" ], "type": "object" @@ -22633,13 +23244,13 @@ "filterConfig": { "type": "object" }, - "filterId": { + "pluginFilterId": { "format": "uuid", "type": "string" } }, "required": [ - "filterId" + "pluginFilterId" ], "type": "object" }, @@ -22649,24 +23260,24 @@ "nullable": true, "type": "object" }, - "filterId": { - "type": "string" - }, "id": { "type": "string" }, "order": { "type": "number" }, + "pluginFilterId": { + "type": "string" + }, "workflowId": { "type": "string" } }, "required": [ "filterConfig", - "filterId", "id", "order", + "pluginFilterId", "workflowId" ], "type": "object" diff --git a/open-api/typescript-sdk/.nvmrc b/open-api/typescript-sdk/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/open-api/typescript-sdk/.nvmrc +++ b/open-api/typescript-sdk/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/open-api/typescript-sdk/package.json b/open-api/typescript-sdk/package.json index 1756675ddd..56520b0efe 100644 --- a/open-api/typescript-sdk/package.json +++ b/open-api/typescript-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@immich/sdk", - "version": "2.2.3", + "version": "2.3.1", "description": "Auto-generated TypeScript SDK for the Immich API", "type": "module", "main": "./build/index.js", @@ -19,7 +19,7 @@ "@oazapfts/runtime": "^1.0.2" }, "devDependencies": { - "@types/node": "^22.19.0", + "@types/node": "^24.10.1", "typescript": "^5.3.3" }, "repository": { @@ -28,6 +28,6 @@ "directory": "open-api/typescript-sdk" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" } } diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index 0664d26995..7afee42e2c 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -1,6 +1,6 @@ /** * Immich - * 2.2.3 + * 2.3.1 * DO NOT MODIFY - This file has been generated using oazapfts. * See https://www.npmjs.com/package/oazapfts */ @@ -40,6 +40,15 @@ export type ActivityStatisticsResponseDto = { comments: number; likes: number; }; +export type SetMaintenanceModeDto = { + action: MaintenanceAction; +}; +export type MaintenanceLoginDto = { + token?: string; +}; +export type MaintenanceAuthDto = { + username: string; +}; export type NotificationCreateDto = { data?: object; description?: string | null; @@ -707,32 +716,32 @@ export type QueueStatisticsDto = { paused: number; waiting: number; }; -export type QueueStatusDto = { +export type QueueStatusLegacyDto = { isActive: boolean; isPaused: boolean; }; -export type QueueResponseDto = { +export type QueueResponseLegacyDto = { jobCounts: QueueStatisticsDto; - queueStatus: QueueStatusDto; + queueStatus: QueueStatusLegacyDto; }; -export type QueuesResponseDto = { - backgroundTask: QueueResponseDto; - backupDatabase: QueueResponseDto; - duplicateDetection: QueueResponseDto; - faceDetection: QueueResponseDto; - facialRecognition: QueueResponseDto; - library: QueueResponseDto; - metadataExtraction: QueueResponseDto; - migration: QueueResponseDto; - notifications: QueueResponseDto; - ocr: QueueResponseDto; - search: QueueResponseDto; - sidecar: QueueResponseDto; - smartSearch: QueueResponseDto; - storageTemplateMigration: QueueResponseDto; - thumbnailGeneration: QueueResponseDto; - videoConversion: QueueResponseDto; - workflow: QueueResponseDto; +export type QueuesResponseLegacyDto = { + backgroundTask: QueueResponseLegacyDto; + backupDatabase: QueueResponseLegacyDto; + duplicateDetection: QueueResponseLegacyDto; + faceDetection: QueueResponseLegacyDto; + facialRecognition: QueueResponseLegacyDto; + library: QueueResponseLegacyDto; + metadataExtraction: QueueResponseLegacyDto; + migration: QueueResponseLegacyDto; + notifications: QueueResponseLegacyDto; + ocr: QueueResponseLegacyDto; + search: QueueResponseLegacyDto; + sidecar: QueueResponseLegacyDto; + smartSearch: QueueResponseLegacyDto; + storageTemplateMigration: QueueResponseLegacyDto; + thumbnailGeneration: QueueResponseLegacyDto; + videoConversion: QueueResponseLegacyDto; + workflow: QueueResponseLegacyDto; }; export type JobCreateDto = { name: ManualJobName; @@ -957,6 +966,24 @@ export type PluginResponseDto = { updatedAt: string; version: string; }; +export type QueueResponseDto = { + isPaused: boolean; + name: QueueName; + statistics: QueueStatisticsDto; +}; +export type QueueUpdateDto = { + isPaused?: boolean; +}; +export type QueueDeleteDto = { + /** If true, will also remove failed jobs from the queue. */ + failed?: boolean; +}; +export type QueueJobResponseDto = { + data: object; + id?: string; + name: JobName; + timestamp: number; +}; export type SearchExploreItem = { data: AssetResponseDto; value: string; @@ -1183,6 +1210,7 @@ export type ServerConfigDto = { isInitialized: boolean; isOnboarded: boolean; loginPageMessage: string; + maintenanceMode: boolean; mapDarkStyleUrl: string; mapLightStyleUrl: string; oauthButtonText: string; @@ -1701,16 +1729,16 @@ export type CreateProfileImageResponseDto = { }; export type WorkflowActionResponseDto = { actionConfig: object | null; - actionId: string; id: string; order: number; + pluginActionId: string; workflowId: string; }; export type WorkflowFilterResponseDto = { filterConfig: object | null; - filterId: string; id: string; order: number; + pluginFilterId: string; workflowId: string; }; export type WorkflowResponseDto = { @@ -1726,11 +1754,11 @@ export type WorkflowResponseDto = { }; export type WorkflowActionItemDto = { actionConfig?: object; - actionId: string; + pluginActionId: string; }; export type WorkflowFilterItemDto = { filterConfig?: object; - filterId: string; + pluginFilterId: string; }; export type WorkflowCreateDto = { actions: WorkflowActionItemDto[]; @@ -1822,6 +1850,33 @@ export function unlinkAllOAuthAccountsAdmin(opts?: Oazapfts.RequestOpts) { method: "POST" })); } +/** + * Set maintenance mode + */ +export function setMaintenanceMode({ setMaintenanceModeDto }: { + setMaintenanceModeDto: SetMaintenanceModeDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/admin/maintenance", oazapfts.json({ + ...opts, + method: "POST", + body: setMaintenanceModeDto + }))); +} +/** + * Log into maintenance mode + */ +export function maintenanceLogin({ maintenanceLoginDto }: { + maintenanceLoginDto: MaintenanceLoginDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 201; + data: MaintenanceAuthDto; + }>("/admin/maintenance/login", oazapfts.json({ + ...opts, + method: "POST", + body: maintenanceLoginDto + }))); +} /** * Create a notification */ @@ -2888,7 +2943,7 @@ export function reassignFacesById({ id, faceDto }: { export function getQueuesLegacy(opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; - data: QueuesResponseDto; + data: QueuesResponseLegacyDto; }>("/jobs", { ...opts })); @@ -2914,7 +2969,7 @@ export function runQueueCommandLegacy({ name, queueCommandDto }: { }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; - data: QueueResponseDto; + data: QueueResponseLegacyDto; }>(`/jobs/${encodeURIComponent(name)}`, oazapfts.json({ ...opts, method: "PUT", @@ -3614,6 +3669,75 @@ export function getPlugin({ id }: { ...opts })); } +/** + * List all queues + */ +export function getQueues(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: QueueResponseDto[]; + }>("/queues", { + ...opts + })); +} +/** + * Retrieve a queue + */ +export function getQueue({ name }: { + name: QueueName; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: QueueResponseDto; + }>(`/queues/${encodeURIComponent(name)}`, { + ...opts + })); +} +/** + * Update a queue + */ +export function updateQueue({ name, queueUpdateDto }: { + name: QueueName; + queueUpdateDto: QueueUpdateDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: QueueResponseDto; + }>(`/queues/${encodeURIComponent(name)}`, oazapfts.json({ + ...opts, + method: "PUT", + body: queueUpdateDto + }))); +} +/** + * Empty a queue + */ +export function emptyQueue({ name, queueDeleteDto }: { + name: QueueName; + queueDeleteDto: QueueDeleteDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/queues/${encodeURIComponent(name)}/jobs`, oazapfts.json({ + ...opts, + method: "DELETE", + body: queueDeleteDto + }))); +} +/** + * Retrieve queue jobs + */ +export function getQueueJobs({ name, status }: { + name: QueueName; + status?: QueueJobStatus[]; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: QueueJobResponseDto[]; + }>(`/queues/${encodeURIComponent(name)}/jobs${QS.query(QS.explode({ + status + }))}`, { + ...opts + })); +} /** * Retrieve assets by city */ @@ -5014,6 +5138,10 @@ export enum UserAvatarColor { Gray = "gray", Amber = "amber" } +export enum MaintenanceAction { + Start = "start", + End = "end" +} export enum NotificationLevel { Success = "success", Error = "error", @@ -5121,6 +5249,7 @@ export enum Permission { LibraryStatistics = "library.statistics", TimelineRead = "timeline.read", TimelineDownload = "timeline.download", + Maintenance = "maintenance", MemoryCreate = "memory.create", MemoryRead = "memory.read", MemoryUpdate = "memory.update", @@ -5199,6 +5328,12 @@ export enum Permission { UserProfileImageRead = "userProfileImage.read", UserProfileImageUpdate = "userProfileImage.update", UserProfileImageDelete = "userProfileImage.delete", + QueueRead = "queue.read", + QueueUpdate = "queue.update", + QueueJobCreate = "queueJob.create", + QueueJobRead = "queueJob.read", + QueueJobUpdate = "queueJob.update", + QueueJobDelete = "queueJob.delete", WorkflowCreate = "workflow.create", WorkflowRead = "workflow.read", WorkflowUpdate = "workflow.update", @@ -5288,6 +5423,71 @@ export enum PluginContext { Album = "album", Person = "person" } +export enum QueueJobStatus { + Active = "active", + Failed = "failed", + Completed = "completed", + Delayed = "delayed", + Waiting = "waiting", + Paused = "paused" +} +export enum JobName { + AssetDelete = "AssetDelete", + AssetDeleteCheck = "AssetDeleteCheck", + AssetDetectFacesQueueAll = "AssetDetectFacesQueueAll", + AssetDetectFaces = "AssetDetectFaces", + AssetDetectDuplicatesQueueAll = "AssetDetectDuplicatesQueueAll", + AssetDetectDuplicates = "AssetDetectDuplicates", + AssetEncodeVideoQueueAll = "AssetEncodeVideoQueueAll", + AssetEncodeVideo = "AssetEncodeVideo", + AssetEmptyTrash = "AssetEmptyTrash", + AssetExtractMetadataQueueAll = "AssetExtractMetadataQueueAll", + AssetExtractMetadata = "AssetExtractMetadata", + AssetFileMigration = "AssetFileMigration", + AssetGenerateThumbnailsQueueAll = "AssetGenerateThumbnailsQueueAll", + AssetGenerateThumbnails = "AssetGenerateThumbnails", + AuditLogCleanup = "AuditLogCleanup", + AuditTableCleanup = "AuditTableCleanup", + DatabaseBackup = "DatabaseBackup", + FacialRecognitionQueueAll = "FacialRecognitionQueueAll", + FacialRecognition = "FacialRecognition", + FileDelete = "FileDelete", + FileMigrationQueueAll = "FileMigrationQueueAll", + LibraryDeleteCheck = "LibraryDeleteCheck", + LibraryDelete = "LibraryDelete", + LibraryRemoveAsset = "LibraryRemoveAsset", + LibraryScanAssetsQueueAll = "LibraryScanAssetsQueueAll", + LibrarySyncAssets = "LibrarySyncAssets", + LibrarySyncFilesQueueAll = "LibrarySyncFilesQueueAll", + LibrarySyncFiles = "LibrarySyncFiles", + LibraryScanQueueAll = "LibraryScanQueueAll", + MemoryCleanup = "MemoryCleanup", + MemoryGenerate = "MemoryGenerate", + NotificationsCleanup = "NotificationsCleanup", + NotifyUserSignup = "NotifyUserSignup", + NotifyAlbumInvite = "NotifyAlbumInvite", + NotifyAlbumUpdate = "NotifyAlbumUpdate", + UserDelete = "UserDelete", + UserDeleteCheck = "UserDeleteCheck", + UserSyncUsage = "UserSyncUsage", + PersonCleanup = "PersonCleanup", + PersonFileMigration = "PersonFileMigration", + PersonGenerateThumbnail = "PersonGenerateThumbnail", + SessionCleanup = "SessionCleanup", + SendMail = "SendMail", + SidecarQueueAll = "SidecarQueueAll", + SidecarCheck = "SidecarCheck", + SidecarWrite = "SidecarWrite", + SmartSearchQueueAll = "SmartSearchQueueAll", + SmartSearch = "SmartSearch", + StorageTemplateMigration = "StorageTemplateMigration", + StorageTemplateMigrationSingle = "StorageTemplateMigrationSingle", + TagCleanup = "TagCleanup", + VersionCheck = "VersionCheck", + OcrQueueAll = "OcrQueueAll", + Ocr = "Ocr", + WorkflowRun = "WorkflowRun" +} export enum SearchSuggestionType { Country = "country", State = "state", diff --git a/package.json b/package.json index d08ea46edf..a5421c0e36 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Monorepo for Immich", "private": true, - "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd", + "packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a", "engines": { "pnpm": ">=10.0.0" } diff --git a/plugins/package-lock.json b/plugins/package-lock.json index 3b0f0b34cb..2cdf7b7e53 100644 --- a/plugins/package-lock.json +++ b/plugins/package-lock.json @@ -1,436 +1,519 @@ { - "name": "js-pdk-template", + "name": "plugins", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "js-pdk-template", + "name": "plugins", "version": "1.0.0", - "license": "BSD-3-Clause", + "license": "AGPL-3.0", "devDependencies": { "@extism/js-pdk": "^1.0.1", - "esbuild": "^0.19.6", + "esbuild": "^0.27.0", "typescript": "^5.3.2" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@extism/js-pdk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@extism/js-pdk/-/js-pdk-1.0.1.tgz", - "integrity": "sha512-YJWfHGeOuJnQw4V8NPNHvbSr6S8iDd2Ga6VEukwlRP7tu62ozTxIgokYw8i+rajD/16zz/gK0KYARBpm2qPAmQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@extism/js-pdk/-/js-pdk-1.1.1.tgz", + "integrity": "sha512-VZLn/dX0ttA1uKk2PZeR/FL3N+nA1S5Vc7E5gdjkR60LuUIwCZT9cYON245V4HowHlBA7YOegh0TLjkx+wNbrA==", + "dev": true, + "license": "BSD-Clause-3", + "dependencies": { + "urlpattern-polyfill": "^8.0.2" + } }, "node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -438,6 +521,13 @@ "engines": { "node": ">=14.17" } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "dev": true, + "license": "MIT" } } } diff --git a/plugins/package.json b/plugins/package.json index ab6b2f8435..abeabe7161 100644 --- a/plugins/package.json +++ b/plugins/package.json @@ -13,7 +13,7 @@ "license": "AGPL-3.0", "devDependencies": { "@extism/js-pdk": "^1.0.1", - "esbuild": "^0.19.6", + "esbuild": "^0.27.0", "typescript": "^5.3.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0e4b5ea78..43d2848e16 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ settings: overrides: canvas: 2.11.2 - sharp: ^0.34.4 + sharp: ^0.34.5 packageExtensionsChecksum: sha256-3l4AQg4iuprBDup+q+2JaPvbPg/7XodWCE0ZteH+s54= @@ -21,7 +21,7 @@ importers: devDependencies: prettier: specifier: ^3.5.3 - version: 3.6.2 + version: 3.7.1 cli: dependencies: @@ -43,7 +43,7 @@ importers: devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.38.0 + version: 9.39.1 '@immich/sdk': specifier: file:../open-api/typescript-sdk version: link:../open-api/typescript-sdk @@ -63,11 +63,11 @@ importers: specifier: ^4.13.1 version: 4.13.4 '@types/node': - specifier: ^22.19.0 - version: 22.19.0 + specifier: ^24.10.1 + version: 24.10.1 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) byte-size: specifier: ^9.0.0 version: 9.0.1 @@ -79,61 +79,61 @@ importers: version: 12.1.0 eslint: specifier: ^9.14.0 - version: 9.38.0(jiti@2.6.1) + version: 9.39.1(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.38.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.38.0(jiti@2.6.1)))(eslint@9.38.0(jiti@2.6.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.1) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.38.0(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) globals: specifier: ^16.0.0 - version: 16.4.0 + version: 16.5.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 prettier: specifier: ^3.2.5 - version: 3.6.2 + version: 3.7.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.6.2)(typescript@5.9.3) + version: 4.3.0(prettier@3.7.1)(typescript@5.9.3) typescript: specifier: ^5.3.3 version: 5.9.3 typescript-eslint: specifier: ^8.28.0 - version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.0.0 - version: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.0.0 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) vitest-fetch-mock: specifier: ^0.4.0 - version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) yaml: specifier: ^2.3.1 - version: 2.8.1 + version: 2.8.2 docs: dependencies: '@docusaurus/core': specifier: ~3.9.0 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/preset-classic': specifier: ~3.9.0 - version: 3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) + version: 3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) '@docusaurus/theme-common': specifier: ~3.9.0 - version: 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdi/js': specifier: ^7.3.67 version: 7.4.47 @@ -142,13 +142,13 @@ importers: version: 1.6.1 '@mdx-js/react': specifier: ^3.0.0 - version: 3.1.1(@types/react@19.2.2)(react@18.3.1) + version: 3.1.1(@types/react@19.2.7)(react@18.3.1) autoprefixer: specifier: ^10.4.17 - version: 10.4.21(postcss@8.5.6) + version: 10.4.22(postcss@8.5.6) docusaurus-lunr-search: specifier: ^3.3.2 - version: 3.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lunr: specifier: ^2.3.9 version: 2.3.9 @@ -160,7 +160,7 @@ importers: version: 2.4.1(react@18.3.1) raw-loader: specifier: ^4.0.2 - version: 4.0.2(webpack@5.102.1) + version: 4.0.2(webpack@5.103.0) react: specifier: ^18.0.0 version: 18.3.1 @@ -169,7 +169,7 @@ importers: version: 18.3.1(react@18.3.1) tailwindcss: specifier: ^3.2.4 - version: 3.4.18(yaml@2.8.1) + version: 3.4.18(yaml@2.8.2) url: specifier: ^0.11.0 version: 0.11.4 @@ -185,7 +185,7 @@ importers: version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) prettier: specifier: ^3.2.4 - version: 3.6.2 + version: 3.7.1 typescript: specifier: ^5.1.6 version: 5.9.3 @@ -194,7 +194,10 @@ importers: devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.38.0 + version: 9.39.1 + '@faker-js/faker': + specifier: ^10.1.0 + version: 10.1.0 '@immich/cli': specifier: file:../cli version: link:../cli @@ -203,7 +206,7 @@ importers: version: link:../open-api/typescript-sdk '@playwright/test': specifier: ^1.44.1 - version: 1.56.1 + version: 1.57.0 '@socket.io/component-emitter': specifier: ^3.1.2 version: 3.1.2 @@ -211,8 +214,8 @@ importers: specifier: ^3.4.2 version: 3.7.1 '@types/node': - specifier: ^22.19.0 - version: 22.19.0 + specifier: ^24.10.1 + version: 24.10.1 '@types/oidc-provider': specifier: ^9.0.0 version: 9.5.0 @@ -225,24 +228,27 @@ importers: '@types/supertest': specifier: ^6.0.2 version: 6.0.3 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 eslint: specifier: ^9.14.0 - version: 9.38.0(jiti@2.6.1) + version: 9.39.1(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.38.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.38.0(jiti@2.6.1)))(eslint@9.38.0(jiti@2.6.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.1) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.38.0(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) exiftool-vendored: - specifier: ^31.1.0 - version: 31.3.0 + specifier: ^33.0.0 + version: 33.5.0 globals: specifier: ^16.0.0 - version: 16.4.0 + version: 16.5.0 jose: specifier: ^5.6.3 version: 5.10.0 @@ -260,13 +266,13 @@ importers: version: 7.0.0 prettier: specifier: ^3.2.5 - version: 3.6.2 + version: 3.7.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.6.2)(typescript@5.9.3) + version: 4.3.0(prettier@3.7.1)(typescript@5.9.3) sharp: - specifier: ^0.34.4 - version: 0.34.4 + specifier: ^0.34.5 + version: 0.34.5 socket.io-client: specifier: ^4.7.4 version: 4.8.1 @@ -278,13 +284,13 @@ importers: version: 5.9.3 typescript-eslint: specifier: ^8.28.0 - version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) utimes: specifier: ^5.2.1 version: 5.2.1(encoding@0.1.13) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) open-api/typescript-sdk: dependencies: @@ -293,8 +299,8 @@ importers: version: 1.0.4 devDependencies: '@types/node': - specifier: ^22.19.0 - version: 22.19.0 + specifier: ^24.10.1 + version: 24.10.1 typescript: specifier: ^5.3.3 version: 5.9.3 @@ -305,8 +311,8 @@ importers: specifier: ^1.0.1 version: 1.1.1 esbuild: - specifier: ^0.19.6 - version: 0.19.12 + specifier: ^0.27.0 + version: 0.27.0 typescript: specifier: ^5.3.2 version: 5.9.3 @@ -318,28 +324,28 @@ importers: version: 2.0.0-rc13 '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.4(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(bullmq@5.62.1) + version: 11.0.4(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(bullmq@5.65.0) '@nestjs/common': specifier: ^11.0.4 - version: 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': specifier: ^11.0.4 - version: 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.4 - version: 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) + version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) '@nestjs/platform-socket.io': specifier: ^11.0.4 - version: 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.8)(rxjs@7.8.2) + version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.9)(rxjs@7.8.2) '@nestjs/schedule': specifier: ^6.0.0 - version: 6.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) + version: 6.0.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) '@nestjs/swagger': specifier: ^11.0.2 - version: 11.2.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2) + version: 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) '@nestjs/websockets': specifier: ^11.0.4 - version: 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-socket.io@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-socket.io@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -347,20 +353,20 @@ importers: specifier: ^2.0.0 version: 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-prometheus': - specifier: ^0.207.0 - version: 0.207.0(@opentelemetry/api@1.9.0) + specifier: ^0.208.0 + version: 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-http': - specifier: ^0.207.0 - version: 0.207.0(@opentelemetry/api@1.9.0) + specifier: ^0.208.0 + version: 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-ioredis': + specifier: ^0.56.0 + version: 0.56.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': specifier: ^0.55.0 version: 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': - specifier: ^0.54.0 - version: 0.54.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-pg': - specifier: ^0.60.0 - version: 0.60.0(@opentelemetry/api@1.9.0) + specifier: ^0.61.0 + version: 0.61.1(@opentelemetry/api@1.9.0) '@opentelemetry/resources': specifier: ^2.0.1 version: 2.2.0(@opentelemetry/api@1.9.0) @@ -368,11 +374,11 @@ importers: specifier: ^2.0.1 version: 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-node': - specifier: ^0.207.0 - version: 0.207.0(@opentelemetry/api@1.9.0) + specifier: ^0.208.0 + version: 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': specifier: ^1.34.0 - version: 1.37.0 + version: 1.38.0 '@react-email/components': specifier: ^0.5.0 version: 0.5.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -396,10 +402,10 @@ importers: version: 6.0.0 body-parser: specifier: ^2.2.0 - version: 2.2.0 + version: 2.2.1 bullmq: specifier: ^5.51.0 - version: 5.62.1 + version: 5.65.0 chokidar: specifier: ^4.0.3 version: 4.0.3 @@ -408,13 +414,13 @@ importers: version: 0.5.1 class-validator: specifier: ^0.14.0 - version: 0.14.2 + version: 0.14.3 compression: specifier: ^1.8.0 version: 1.8.1 cookie: specifier: ^1.0.2 - version: 1.0.2 + version: 1.1.1 cookie-parser: specifier: ^1.4.7 version: 1.4.7 @@ -422,11 +428,11 @@ importers: specifier: 4.3.3 version: 4.3.3 exiftool-vendored: - specifier: ^31.1.0 - version: 31.3.0 + specifier: ^33.0.0 + version: 33.5.0 express: specifier: ^5.1.0 - version: 5.1.0 + version: 5.2.0 fast-glob: specifier: ^3.3.2 version: 3.3.3 @@ -445,9 +451,12 @@ importers: ioredis: specifier: ^5.8.2 version: 5.8.2 + jose: + specifier: ^5.10.0 + version: 5.10.0 js-yaml: specifier: ^4.1.0 - version: 4.1.0 + version: 4.1.1 jsonwebtoken: specifier: ^9.0.2 version: 9.0.2 @@ -471,19 +480,19 @@ importers: version: 2.0.2 nest-commander: specifier: ^3.16.0 - version: 3.20.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@types/inquirer@8.2.11)(@types/node@22.19.0)(typescript@5.9.3) + version: 3.20.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@types/inquirer@8.2.11)(@types/node@24.10.1)(typescript@5.9.3) nestjs-cls: specifier: ^5.0.0 - version: 5.4.3(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 5.4.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: 3.1.2 - version: 3.1.2(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(kysely@0.28.2)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(kysely@0.28.2)(reflect-metadata@0.2.2) nestjs-otel: specifier: ^7.0.0 - version: 7.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) + version: 7.0.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) nodemailer: specifier: ^7.0.0 - version: 7.0.10 + version: 7.0.11 openid-client: specifier: ^6.3.3 version: 6.8.1 @@ -524,8 +533,8 @@ importers: specifier: ^7.6.2 version: 7.7.3 sharp: - specifier: ^0.34.4 - version: 0.34.4 + specifier: ^0.34.5 + version: 0.34.5 sirv: specifier: ^3.0.0 version: 3.0.2 @@ -534,7 +543,7 @@ importers: version: 4.8.1 tailwindcss-preset-email: specifier: ^1.4.0 - version: 1.4.1(tailwindcss@3.4.18(yaml@2.8.1)) + version: 1.4.1(tailwindcss@3.4.18(yaml@2.8.2)) thumbhash: specifier: ^0.1.1 version: 0.1.1 @@ -546,26 +555,26 @@ importers: version: 11.1.0 validator: specifier: ^13.12.0 - version: 13.15.20 + version: 13.15.23 devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.38.0 + version: 9.39.1 '@nestjs/cli': specifier: ^11.0.2 - version: 11.0.10(@swc/core@1.14.0(@swc/helpers@0.5.17))(@types/node@22.19.0) + version: 11.0.13(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@24.10.1) '@nestjs/schematics': specifier: ^11.0.0 version: 11.0.9(chokidar@4.0.3)(typescript@5.9.3) '@nestjs/testing': specifier: ^11.0.4 - version: 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-express@11.1.8) + version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9) '@swc/core': specifier: ^1.4.14 - version: 1.14.0(@swc/helpers@0.5.17) + version: 1.15.3(@swc/helpers@0.5.17) '@types/archiver': - specifier: ^6.0.0 - version: 6.0.4 + specifier: ^7.0.0 + version: 7.0.0 '@types/async-lock': specifier: ^1.4.2 version: 1.4.2 @@ -595,7 +604,7 @@ importers: version: 9.0.10 '@types/lodash': specifier: ^4.14.197 - version: 4.17.20 + version: 4.17.21 '@types/luxon': specifier: ^3.6.2 version: 3.7.1 @@ -606,11 +615,11 @@ importers: specifier: ^2.0.0 version: 2.0.0 '@types/node': - specifier: ^22.19.0 - version: 22.19.0 + specifier: ^24.10.1 + version: 24.10.1 '@types/nodemailer': specifier: ^7.0.0 - version: 7.0.3 + version: 7.0.4 '@types/picomatch': specifier: ^4.0.0 version: 4.0.2 @@ -619,7 +628,7 @@ importers: version: 6.0.5 '@types/react': specifier: ^19.0.0 - version: 19.2.2 + version: 19.2.7 '@types/sanitize-html': specifier: ^2.13.0 version: 2.16.0 @@ -634,40 +643,40 @@ importers: version: 0.7.39 '@types/validator': specifier: ^13.15.2 - version: 13.15.4 + version: 13.15.10 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) eslint: specifier: ^9.14.0 - version: 9.38.0(jiti@2.6.1) + version: 9.39.1(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.38.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.38.0(jiti@2.6.1)))(eslint@9.38.0(jiti@2.6.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.1) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.38.0(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) globals: specifier: ^16.0.0 - version: 16.4.0 + version: 16.5.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 node-gyp: - specifier: ^11.2.0 - version: 11.5.0 + specifier: ^12.0.0 + version: 12.1.0 pngjs: specifier: ^7.0.0 version: 7.0.0 prettier: specifier: ^3.0.2 - version: 3.6.2 + version: 3.7.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.6.2)(typescript@5.9.3) + version: 4.3.0(prettier@3.7.1)(typescript@5.9.3) sql-formatter: specifier: ^15.0.0 version: 15.6.10 @@ -676,25 +685,25 @@ importers: version: 7.1.4 tailwindcss: specifier: ^3.4.0 - version: 3.4.18(yaml@2.8.1) + version: 3.4.18(yaml@2.8.2) testcontainers: specifier: ^11.0.0 - version: 11.7.2 + version: 11.9.0 typescript: specifier: ^5.9.2 version: 5.9.3 typescript-eslint: specifier: ^8.28.0 - version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) unplugin-swc: specifier: ^1.4.5 - version: 1.5.8(@swc/core@1.14.0(@swc/helpers@0.5.17))(rollup@4.52.5) + version: 1.5.9(@swc/core@1.15.3(@swc/helpers@0.5.17))(rollup@4.53.3) vite-tsconfig-paths: specifier: ^5.0.0 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) web: dependencies: @@ -708,8 +717,8 @@ importers: specifier: file:../open-api/typescript-sdk version: link:../open-api/typescript-sdk '@immich/ui': - specifier: ^0.43.0 - version: 0.43.0(@internationalized/date@3.8.2)(svelte@5.43.0) + specifier: ^0.49.2 + version: 0.49.3(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2) '@mapbox/mapbox-gl-rtl-text': specifier: 0.2.3 version: 0.2.3(mapbox-gl@1.13.3) @@ -717,29 +726,32 @@ importers: specifier: ^7.4.47 version: 7.4.47 '@photo-sphere-viewer/core': - specifier: ^5.11.5 + specifier: ^5.14.0 version: 5.14.0 '@photo-sphere-viewer/equirectangular-video-adapter': - specifier: ^5.11.5 + specifier: ^5.14.0 version: 5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/video-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)) + '@photo-sphere-viewer/markers-plugin': + specifier: ^5.14.0 + version: 5.14.0(@photo-sphere-viewer/core@5.14.0) '@photo-sphere-viewer/resolution-plugin': - specifier: ^5.11.5 + specifier: ^5.14.0 version: 5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/settings-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)) '@photo-sphere-viewer/settings-plugin': - specifier: ^5.11.5 + specifier: ^5.14.0 version: 5.14.0(@photo-sphere-viewer/core@5.14.0) '@photo-sphere-viewer/video-plugin': - specifier: ^5.11.5 + specifier: ^5.14.0 version: 5.14.0(@photo-sphere-viewer/core@5.14.0) '@types/geojson': specifier: ^7946.0.16 version: 7946.0.16 '@zoom-image/core': specifier: ^0.41.0 - version: 0.41.3 + version: 0.41.4 '@zoom-image/svelte': specifier: ^0.3.0 - version: 0.3.7(svelte@5.43.0) + version: 0.3.8(svelte@5.45.2) async-mutex: specifier: ^0.5.0 version: 0.5.0 @@ -748,7 +760,7 @@ importers: version: 2.6.0 fabric: specifier: ^6.5.4 - version: 6.7.1 + version: 6.9.0 geo-coordinates-parser: specifier: ^1.7.4 version: 1.7.4 @@ -775,7 +787,7 @@ importers: version: 3.7.2 maplibre-gl: specifier: ^5.6.2 - version: 5.10.0 + version: 5.13.0 pmtiles: specifier: ^4.3.0 version: 4.3.0 @@ -784,7 +796,7 @@ importers: version: 1.5.4 simple-icons: specifier: ^15.15.0 - version: 15.18.0 + version: 15.22.0 socket.io-client: specifier: ~4.8.0 version: 4.8.1 @@ -793,56 +805,59 @@ importers: version: 5.2.2 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.43.0) + version: 4.0.1(svelte@5.45.2) svelte-maplibre: specifier: ^1.2.5 - version: 1.2.5(svelte@5.43.0) + version: 1.2.5(svelte@5.45.2) svelte-persisted-store: specifier: ^0.12.0 - version: 0.12.0(svelte@5.43.0) + version: 0.12.0(svelte@5.45.2) tabbable: specifier: ^6.2.0 version: 6.3.0 thumbhash: specifier: ^0.1.1 version: 0.1.1 + uplot: + specifier: ^1.6.32 + version: 1.6.32 devDependencies: '@eslint/js': specifier: ^9.36.0 - version: 9.38.0 + version: 9.39.1 '@faker-js/faker': specifier: ^10.0.0 version: 10.1.0 '@koddsson/eslint-plugin-tscompat': specifier: ^0.2.0 - version: 0.2.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + version: 0.2.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@socket.io/component-emitter': specifier: ^3.1.0 version: 3.1.2 '@sveltejs/adapter-static': specifier: ^3.0.8 - version: 3.0.10(@sveltejs/kit@2.48.3(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))) + version: 3.0.10(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))) '@sveltejs/enhanced-img': - specifier: ^0.8.0 - version: 0.8.4(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(rollup@4.52.5)(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + specifier: ^0.9.0 + version: 0.9.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(rollup@4.53.3)(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@sveltejs/kit': specifier: ^2.27.1 - version: 2.48.3(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@sveltejs/vite-plugin-svelte': specifier: 6.2.1 - version: 6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@tailwindcss/vite': specifier: ^4.1.7 - version: 4.1.16(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 4.1.17(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@testing-library/jest-dom': specifier: ^6.4.2 version: 6.9.1 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.2.8(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 5.2.9(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@testing-library/user-event': specifier: ^14.5.2 - version: 14.6.1(@testing-library/dom@10.4.0) + version: 14.6.1(@testing-library/dom@10.4.1) '@types/chromecast-caf-sender': specifier: ^1.0.11 version: 1.0.11 @@ -863,70 +878,70 @@ importers: version: 1.5.6 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) dotenv: specifier: ^17.0.0 version: 17.2.3 eslint: specifier: ^9.36.0 - version: 9.38.0(jiti@2.6.1) + version: 9.39.1(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.38.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-compat: specifier: ^6.0.2 - version: 6.0.2(eslint@9.38.0(jiti@2.6.1)) + version: 6.0.2(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-svelte: specifier: ^3.12.4 - version: 3.12.5(eslint@9.38.0(jiti@2.6.1))(svelte@5.43.0) + version: 3.13.0(eslint@9.39.1(jiti@2.6.1))(svelte@5.45.2) eslint-plugin-unicorn: - specifier: ^61.0.2 - version: 61.0.2(eslint@9.38.0(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) factory.ts: specifier: ^1.4.1 version: 1.4.2 globals: specifier: ^16.0.0 - version: 16.4.0 + version: 16.5.0 prettier: specifier: ^3.4.2 - version: 3.6.2 + version: 3.7.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.6.2)(typescript@5.9.3) + version: 4.3.0(prettier@3.7.1)(typescript@5.9.3) prettier-plugin-sort-json: specifier: ^4.1.1 - version: 4.1.1(prettier@3.6.2) + version: 4.1.1(prettier@3.7.1) prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.4.0(prettier@3.6.2)(svelte@5.43.0) + version: 3.4.0(prettier@3.7.1)(svelte@5.45.2) rollup-plugin-visualizer: specifier: ^6.0.0 - version: 6.0.5(rollup@4.52.5) + version: 6.0.5(rollup@4.53.3) svelte: - specifier: 5.43.0 - version: 5.43.0 + specifier: 5.45.2 + version: 5.45.2 svelte-check: specifier: ^4.1.5 - version: 4.3.3(picomatch@4.0.3)(svelte@5.43.0)(typescript@5.9.3) + version: 4.3.4(picomatch@4.0.3)(svelte@5.45.2)(typescript@5.9.3) svelte-eslint-parser: specifier: ^1.3.3 - version: 1.4.0(svelte@5.43.0) + version: 1.4.0(svelte@5.45.2) tailwindcss: specifier: ^4.1.7 - version: 4.1.16 + version: 4.1.17 typescript: specifier: ^5.8.3 version: 5.9.3 typescript-eslint: specifier: ^8.45.0 - version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + version: 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.1.2 - version: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) packages: @@ -1040,15 +1055,6 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular-devkit/core@19.2.15': - resolution: {integrity: sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^4.0.0 - peerDependenciesMeta: - chokidar: - optional: true - '@angular-devkit/core@19.2.17': resolution: {integrity: sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} @@ -1058,19 +1064,28 @@ packages: chokidar: optional: true - '@angular-devkit/schematics-cli@19.2.15': - resolution: {integrity: sha512-1ESFmFGMpGQmalDB3t2EtmWDGv6gOFYBMxmHO2f1KI/UDl8UmZnCGL4mD3EWo8Hv0YIsZ9wOH9Q7ZHNYjeSpzg==} + '@angular-devkit/core@19.2.19': + resolution: {integrity: sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics-cli@19.2.19': + resolution: {integrity: sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/schematics@19.2.15': - resolution: {integrity: sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular-devkit/schematics@19.2.17': resolution: {integrity: sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@angular-devkit/schematics@19.2.19': + resolution: {integrity: sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} @@ -1087,103 +1102,107 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-sesv2@3.919.0': - resolution: {integrity: sha512-3OomeIFXid1iUZybdI2wAkxMgKyKNHzP9lVBtQVNFD0iZLon71XShAwpNyzrp+UTf/vgTqIJShazlcLVpvSXCA==} + '@aws-sdk/client-sesv2@3.939.0': + resolution: {integrity: sha512-vua5ZoOMMc/0yxAv6UsiN6pcaiqM+L7R1gLAki9fB3hHC+TvJAY0TX0eRrgTxV+ATyuD0lL3njrVA+xV8gHiEQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.919.0': - resolution: {integrity: sha512-9DVw/1DCzZ9G7Jofnhpg/XDC3wdJ3NAJdNWY1TrgE5ZcpTM+UTIQMGyaljCv9rgxggutHBgmBI5lP3YMcPk9ZQ==} + '@aws-sdk/client-sso@3.936.0': + resolution: {integrity: sha512-0G73S2cDqYwJVvqL08eakj79MZG2QRaB56Ul8/Ps9oQxllr7DMI1IQ/N3j3xjxgpq/U36pkoFZ8aK1n7Sbr3IQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.916.0': - resolution: {integrity: sha512-1JHE5s6MD5PKGovmx/F1e01hUbds/1y3X8rD+Gvi/gWVfdg5noO7ZCerpRsWgfzgvCMZC9VicopBqNHCKLykZA==} + '@aws-sdk/core@3.936.0': + resolution: {integrity: sha512-eGJ2ySUMvgtOziHhDRDLCrj473RJoL4J1vPjVM3NrKC/fF3/LoHjkut8AAnKmrW6a2uTzNKubigw8dEnpmpERw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.916.0': - resolution: {integrity: sha512-3gDeqOXcBRXGHScc6xb7358Lyf64NRG2P08g6Bu5mv1Vbg9PKDyCAZvhKLkG7hkdfAM8Yc6UJNhbFxr1ud/tCQ==} + '@aws-sdk/credential-provider-env@3.936.0': + resolution: {integrity: sha512-dKajFuaugEA5i9gCKzOaVy9uTeZcApE+7Z5wdcZ6j40523fY1a56khDAUYkCfwqa7sHci4ccmxBkAo+fW1RChA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.916.0': - resolution: {integrity: sha512-NmooA5Z4/kPFJdsyoJgDxuqXC1C6oPMmreJjbOPqcwo6E/h2jxaG8utlQFgXe5F9FeJsMx668dtxVxSYnAAqHQ==} + '@aws-sdk/credential-provider-http@3.936.0': + resolution: {integrity: sha512-5FguODLXG1tWx/x8fBxH+GVrk7Hey2LbXV5h9SFzYCx/2h50URBm0+9hndg0Rd23+xzYe14F6SI9HA9c1sPnjg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.919.0': - resolution: {integrity: sha512-fAWVfh0P54UFbyAK4tmIPh/X3COFAyXYSp8b2Pc1R6GRwDDMvrAigwGJuyZS4BmpPlXij1gB0nXbhM5Yo4MMMA==} + '@aws-sdk/credential-provider-ini@3.939.0': + resolution: {integrity: sha512-RHQ3xKz5pn5PMuoBYNYLMIdN4iU8gklxcsfJzOflSrwkhb8ukVRS9LjHXUtyE4qQ2J+dfj1QSr4PFOSxvzRZkA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.919.0': - resolution: {integrity: sha512-GL5filyxYS+eZq8ZMQnY5hh79Wxor7Rljo0SUJxZVwEj8cf3zY0MMuwoXU1HQrVabvYtkPDOWSreX8GkIBtBCw==} + '@aws-sdk/credential-provider-login@3.939.0': + resolution: {integrity: sha512-SbbzlsH2ZSsu2szyl494QOUS69LZgU8bYlFoDnUxy2L89YzLyR4D9wWlJzKCm4cS1eyNxPsOMkbVVL42JRvdZw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.916.0': - resolution: {integrity: sha512-SXDyDvpJ1+WbotZDLJW1lqP6gYGaXfZJrgFSXIuZjHb75fKeNRgPkQX/wZDdUvCwdrscvxmtyJorp2sVYkMcvA==} + '@aws-sdk/credential-provider-node@3.939.0': + resolution: {integrity: sha512-OAwCqDNlKC3JmWb+N0zFfsPJJ8J5b8ZD63vWHdSf9c7ZlRKpFRD/uePqVMQKOq4h3DO0P0smAPk/m5p66oYLrw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.919.0': - resolution: {integrity: sha512-oN1XG/frOc2K2KdVwRQjLTBLM1oSFJLtOhuV/6g9N0ASD+44uVJai1CF9JJv5GjHGV+wsqAt+/Dzde0tZEXirA==} + '@aws-sdk/credential-provider-process@3.936.0': + resolution: {integrity: sha512-GpA4AcHb96KQK2PSPUyvChvrsEKiLhQ5NWjeef2IZ3Jc8JoosiedYqp6yhZR+S8cTysuvx56WyJIJc8y8OTrLA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.919.0': - resolution: {integrity: sha512-Wi7RmyWA8kUJ++/8YceC7U5r4LyvOHGCnJLDHliP8rOC8HLdSgxw/Upeq3WmC+RPw1zyGOtEDRS/caop2xLXEA==} + '@aws-sdk/credential-provider-sso@3.939.0': + resolution: {integrity: sha512-gXWI+5xf+2n7kJSqYgDw1VkNLGRe2IYNCjOW/F04/7l8scxOP84SZ634OI9IR/8JWvFwMUjxH4JigPU0j6ZWzQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.914.0': - resolution: {integrity: sha512-7r9ToySQ15+iIgXMF/h616PcQStByylVkCshmQqcdeynD/lCn2l667ynckxW4+ql0Q+Bo/URljuhJRxVJzydNA==} + '@aws-sdk/credential-provider-web-identity@3.939.0': + resolution: {integrity: sha512-b/ySLC6DfWwZIAP2Glq9mkJJ/9LIDiKfYN2f9ZenQF+k2lO1i6/QtBuslvLmBJ+mNz0lPRSHW29alyqOpBgeCQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.914.0': - resolution: {integrity: sha512-/gaW2VENS5vKvJbcE1umV4Ag3NuiVzpsANxtrqISxT3ovyro29o1RezW/Avz/6oJqjnmgz8soe9J1t65jJdiNg==} + '@aws-sdk/middleware-host-header@3.936.0': + resolution: {integrity: sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.919.0': - resolution: {integrity: sha512-q3MAUxLQve4rTfAannUCx2q1kAHkBBsxt6hVUpzi63KC4lBLScc1ltr7TI+hDxlfGRWGo54jRegb2SsY9Jm+Mw==} + '@aws-sdk/middleware-logger@3.936.0': + resolution: {integrity: sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.916.0': - resolution: {integrity: sha512-pjmzzjkEkpJObzmTthqJPq/P13KoNFuEi/x5PISlzJtHofCNcyXeVAQ90yvY2dQ6UXHf511Rh1/ytiKy2A8M0g==} + '@aws-sdk/middleware-recursion-detection@3.936.0': + resolution: {integrity: sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.916.0': - resolution: {integrity: sha512-mzF5AdrpQXc2SOmAoaQeHpDFsK2GE6EGcEACeNuoESluPI2uYMpuuNMYrUufdnIAIyqgKlis0NVxiahA5jG42w==} + '@aws-sdk/middleware-sdk-s3@3.939.0': + resolution: {integrity: sha512-9WMPAAyuSPvEawZJ5ndZKD+UZuISGS885kFyNyfHCNNWMws8Rohji6nysda2gL8SSpGdbvTBZRjSIzim13bYRg==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.919.0': - resolution: {integrity: sha512-5D9OQsMPkbkp4KHM7JZv/RcGCpr3E1L7XX7U9sCxY+sFGeysltoviTmaIBXsJ2IjAJbBULtf0G/J+2cfH5OP+w==} + '@aws-sdk/middleware-user-agent@3.936.0': + resolution: {integrity: sha512-YB40IPa7K3iaYX0lSnV9easDOLPLh+fJyUDF3BH8doX4i1AOSsYn86L4lVldmOaSX+DwiaqKHpvk4wPBdcIPWw==} engines: {node: '>=18.0.0'} - '@aws-sdk/region-config-resolver@3.914.0': - resolution: {integrity: sha512-KlmHhRbn1qdwXUdsdrJ7S/MAkkC1jLpQ11n+XvxUUUCGAJd1gjC7AjxPZUM7ieQ2zcb8bfEzIU7al+Q3ZT0u7Q==} + '@aws-sdk/nested-clients@3.939.0': + resolution: {integrity: sha512-QeNsjHBCbsVRbgEt9FZNnrrbMTUuIYML3FX5xFgEJz4aI5uXwMBjYOi5TvAY+Y4CBHY4cp3dd/zSpHu0gX68GQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.916.0': - resolution: {integrity: sha512-fuzUMo6xU7e0NBzBA6TQ4FUf1gqNbg4woBSvYfxRRsIfKmSMn9/elXXn4sAE5UKvlwVQmYnb6p7dpVRPyFvnQA==} + '@aws-sdk/region-config-resolver@3.936.0': + resolution: {integrity: sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.919.0': - resolution: {integrity: sha512-6aFv4lzXbfbkl0Pv37Us8S/ZkqplOQZIEgQg7bfMru7P96Wv2jVnDGsEc5YyxMnnRyIB90naQ5JgslZ4rkpknw==} + '@aws-sdk/signature-v4-multi-region@3.939.0': + resolution: {integrity: sha512-pERVG90nneZWIenPvPoOnEcfqpUHiL9KMHf+TtHIWSBcaRL1kWuNm4CfEs7mo4EM0LHbaMgoZma6woIsJ6MOwA==} engines: {node: '>=18.0.0'} - '@aws-sdk/types@3.914.0': - resolution: {integrity: sha512-kQWPsRDmom4yvAfyG6L1lMmlwnTzm1XwMHOU+G5IFlsP4YEaMtXidDzW/wiivY0QFrhfCz/4TVmu0a2aPU57ug==} + '@aws-sdk/token-providers@3.939.0': + resolution: {integrity: sha512-paNeLZdr2/sk7XYMZz2OIqFFF3AkA5vUpKYahVDYmMeiMecQTqa/EptA3aVvWa4yWobEF0Kk+WSUPrOIGI3eQg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/types@3.936.0': + resolution: {integrity: sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==} engines: {node: '>=18.0.0'} '@aws-sdk/util-arn-parser@3.893.0': resolution: {integrity: sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.916.0': - resolution: {integrity: sha512-bAgUQwvixdsiGNcuZSDAOWbyHlnPtg8G8TyHD6DTfTmKTHUW6tAn+af/ZYJPXEzXhhpwgJqi58vWnsiDhmr7NQ==} + '@aws-sdk/util-endpoints@3.936.0': + resolution: {integrity: sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==} engines: {node: '>=18.0.0'} '@aws-sdk/util-locate-window@3.893.0': resolution: {integrity: sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.914.0': - resolution: {integrity: sha512-rMQUrM1ECH4kmIwlGl9UB0BtbHy6ZuKdWFrIknu8yGTRI/saAucqNTh5EI1vWBxZ0ElhK5+g7zOnUuhSmVQYUA==} + '@aws-sdk/util-user-agent-browser@3.936.0': + resolution: {integrity: sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==} - '@aws-sdk/util-user-agent-node@3.916.0': - resolution: {integrity: sha512-CwfWV2ch6UdjuSV75ZU99N03seEUb31FIUrXBnwa6oONqj/xqXwrxtlUMLx6WH3OJEE4zI3zt5PjlTdGcVwf4g==} + '@aws-sdk/util-user-agent-node@3.936.0': + resolution: {integrity: sha512-XOEc7PF9Op00pWV2AYCGDSu5iHgYjIO53Py2VUQTIvP7SRCaCsXmA33mjBvC2Ms6FhSyWNa4aK4naUGIz0hQcw==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1191,12 +1210,12 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.914.0': - resolution: {integrity: sha512-k75evsBD5TcIjedycYS7QXQ98AmOtbnxRJOPtCo0IwYRmy7UvqgS/gBL5SmrIqeV6FDSYRQMgdBxSMp6MLmdew==} + '@aws-sdk/xml-builder@3.930.0': + resolution: {integrity: sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==} engines: {node: '>=18.0.0'} - '@aws/lambda-invoke-store@0.1.1': - resolution: {integrity: sha512-RcLam17LdlbSOSp9VxmUu1eI6Mwxp+OwhD2QhiSNmNCzoDb0EeUXTD2n/WbcnrAYMGlmf05th6QYq23VqvJqpA==} + '@aws/lambda-invoke-store@0.2.1': + resolution: {integrity: sha512-sIyFcoPZkTtNu9xFeEoynMef3bPJIAbOfUh+ueYcfhVl6xm2VRtMcMclSxmZCMnHHd4hlYKJeq/aggmBEWynww==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.27.1': @@ -2253,8 +2272,8 @@ packages: resolution: {integrity: sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==} engines: {node: '>=20.0'} - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} @@ -2268,6 +2287,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.0': + resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.19.12': resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} engines: {node: '>=12'} @@ -2280,6 +2305,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.0': + resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.19.12': resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} engines: {node: '>=12'} @@ -2292,6 +2323,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.0': + resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.19.12': resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} engines: {node: '>=12'} @@ -2304,6 +2341,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.0': + resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.19.12': resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} engines: {node: '>=12'} @@ -2316,6 +2359,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.0': + resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.19.12': resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} engines: {node: '>=12'} @@ -2328,6 +2377,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.0': + resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.19.12': resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} engines: {node: '>=12'} @@ -2340,6 +2395,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.0': + resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.19.12': resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} engines: {node: '>=12'} @@ -2352,6 +2413,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.0': + resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.19.12': resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} engines: {node: '>=12'} @@ -2364,6 +2431,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.0': + resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.19.12': resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} engines: {node: '>=12'} @@ -2376,6 +2449,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.0': + resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.19.12': resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} engines: {node: '>=12'} @@ -2388,6 +2467,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.0': + resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.19.12': resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} engines: {node: '>=12'} @@ -2400,6 +2485,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.0': + resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.19.12': resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} engines: {node: '>=12'} @@ -2412,6 +2503,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.0': + resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.19.12': resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} engines: {node: '>=12'} @@ -2424,6 +2521,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.0': + resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.19.12': resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} engines: {node: '>=12'} @@ -2436,6 +2539,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.0': + resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.19.12': resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} engines: {node: '>=12'} @@ -2448,6 +2557,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.0': + resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.19.12': resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} engines: {node: '>=12'} @@ -2460,12 +2575,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.0': + resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.12': resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.0': + resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.19.12': resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} engines: {node: '>=12'} @@ -2478,12 +2605,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.0': + resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.12': resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.0': + resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.19.12': resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} engines: {node: '>=12'} @@ -2496,12 +2635,24 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.0': + resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.12': resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.0': + resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.19.12': resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} engines: {node: '>=12'} @@ -2514,6 +2665,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.0': + resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.19.12': resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} engines: {node: '>=12'} @@ -2526,6 +2683,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.0': + resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.19.12': resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} engines: {node: '>=12'} @@ -2538,6 +2701,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.0': + resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.19.12': resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} engines: {node: '>=12'} @@ -2550,6 +2719,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.0': + resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2564,36 +2739,28 @@ packages: resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.4.1': - resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.16.0': - resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.38.0': - resolution: {integrity: sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==} + '@eslint/js@9.39.1': + resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.7': resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.4.0': - resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@extism/extism@2.0.0-rc13': @@ -2641,8 +2808,8 @@ packages: '@nestjs/common': ^11.0.20 '@nestjs/core': ^11.0.20 - '@grpc/grpc-js@1.14.0': - resolution: {integrity: sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==} + '@grpc/grpc-js@1.14.2': + resolution: {integrity: sha512-QzVUtEFyu05UNx2xr0fCQmStUO17uVQhGNowtxs00IgTZT6/W2PBLfUkj30s0FKJ29VtTa3ArVNIhNP6akQhqA==} engines: {node: '>=12.10.0'} '@grpc/proto-loader@0.7.15': @@ -2681,124 +2848,135 @@ packages: resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} engines: {node: '>=18'} - '@img/sharp-darwin-arm64@0.34.4': - resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.4': - resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.3': - resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.3': - resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.3': - resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.3': - resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.3': - resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.3': - resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.3': - resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.4': - resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.4': - resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-ppc64@0.34.4': - resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] - '@img/sharp-linux-s390x@0.34.4': - resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.4': - resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.4': - resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.4': - resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.4': - resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.4': - resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.4': - resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.4': - resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -2811,13 +2989,17 @@ packages: peerDependencies: svelte: ^5.0.0 - '@immich/ui@0.43.0': - resolution: {integrity: sha512-dwWIURsGghsbeFnqxCqUyWslyRU2vQjih7uewNr0nsW68bJ5/esl+V/Kiw2opiNiwI4Q3HEcuTRY57k4Hq+X3Q==} + '@immich/ui@0.49.3': + resolution: {integrity: sha512-joqT72Y6gmGK6z25Suzr2VhYANrLo43g20T4UHmbQenz/z/Ax6sl1Ao9SjIOwEkKMm9N3Txoh7WOOzmHVl04OA==} peerDependencies: svelte: ^5.0.0 - '@inquirer/checkbox@4.2.1': - resolution: {integrity: sha512-bevKGO6kX1eM/N+pdh9leS5L7TBF4ICrzi9a+cbWkrxeAeIcwlo/7OfWGCDERdRCI2/Q6tjltX4bt07ALHDwFw==} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2825,8 +3007,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.15': - resolution: {integrity: sha512-SwHMGa8Z47LawQN0rog0sT+6JpiL0B7eW9p1Bb7iCeKDGTI5Ez25TSc2l8kw52VV7hA4sX/C78CGkMrKXfuspA==} + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2834,8 +3016,8 @@ packages: '@types/node': optional: true - '@inquirer/core@10.1.15': - resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2843,8 +3025,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@4.2.17': - resolution: {integrity: sha512-r6bQLsyPSzbWrZZ9ufoWL+CztkSatnJ6uSxqd6N+o41EZC51sQeWOzI6s5jLb+xxTWxl7PlUppqm8/sow241gg==} + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2852,8 +3034,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@4.0.17': - resolution: {integrity: sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==} + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2861,8 +3043,8 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@1.0.2': - resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2870,12 +3052,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@1.0.13': - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/input@4.2.1': - resolution: {integrity: sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==} + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2883,8 +3065,8 @@ packages: '@types/node': optional: true - '@inquirer/number@3.0.17': - resolution: {integrity: sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==} + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2892,8 +3074,17 @@ packages: '@types/node': optional: true - '@inquirer/password@4.0.17': - resolution: {integrity: sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==} + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.10.1': + resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2910,8 +3101,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@7.8.0': - resolution: {integrity: sha512-JHwGbQ6wjf1dxxnalDYpZwZxUEosT+6CPGD9Zh4sm9WXdtUp9XODCQD3NjSTmu+0OAyxWXNOqf0spjIymJa2Tw==} + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2919,8 +3110,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@4.1.5': - resolution: {integrity: sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==} + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2928,8 +3119,8 @@ packages: '@types/node': optional: true - '@inquirer/search@3.1.0': - resolution: {integrity: sha512-PMk1+O/WBcYJDq2H7foV0aAZSmDdkzZB9Mw2v/DmONRJopwA/128cS9M/TXWLKKdEQKZnKwBzqu2G4x/2Nqx8Q==} + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2937,8 +3128,8 @@ packages: '@types/node': optional: true - '@inquirer/select@4.3.1': - resolution: {integrity: sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==} + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2946,17 +3137,8 @@ packages: '@types/node': optional: true - '@inquirer/type@3.0.8': - resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@internationalized/date@3.8.2': - resolution: {integrity: sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA==} + '@internationalized/date@3.10.0': + resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} '@ioredis/commands@1.4.0': resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==} @@ -3122,6 +3304,9 @@ packages: resolution: {integrity: sha512-TUM5JD40H2mgtVXl5IwWz03BuQabw8oZQLJTmPpJA0YTYF+B+oZppy5lNMO6bMvHzB+/5mxqW9VLG3wFdeqtOw==} hasBin: true + '@maplibre/mlt@1.1.0': + resolution: {integrity: sha512-anR8WxKIgZUJQLlZtID0v06wd9Q//9K/6lLLU3dOzmeO/xLEzAwmEqP24jEnEUBcnZGkM4vidz9H6Q4guNAAlw==} + '@maplibre/vt-pbf@4.0.3': resolution: {integrity: sha512-YsW99BwnT+ukJRkseBcLuZHfITB4puJoxnqPVjo72rhW/TaawVYsgQHcqWLzTxqknttYoDpgyERzWSa/XrETdA==} @@ -3146,8 +3331,8 @@ packages: '@types/react': '>=16' react: '>=16' - '@microsoft/tsdoc@0.15.1': - resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} + '@microsoft/tsdoc@0.16.0': + resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} @@ -3195,8 +3380,8 @@ packages: '@nestjs/core': ^10.0.0 || ^11.0.0 bullmq: ^3.0.0 || ^4.0.0 || ^5.0.0 - '@nestjs/cli@11.0.10': - resolution: {integrity: sha512-4waDT0yGWANg0pKz4E47+nUrqIJv/UqrZ5wLPkCqc7oMGRMWKAaw1NDZ9rKsaqhqvxb2LfI5+uXOWr4yi94DOQ==} + '@nestjs/cli@11.0.13': + resolution: {integrity: sha512-cPDDahP/IPDcqraIHjUZQXPupYQDoZlBRFOjgM76vVfcVnWQ45TUaat0tgR2ptfeQG0gY2kwtm4/JYwe5xu/8A==} engines: {node: '>= 20.11'} hasBin: true peerDependencies: @@ -3208,8 +3393,8 @@ packages: '@swc/core': optional: true - '@nestjs/common@11.1.8': - resolution: {integrity: sha512-bbsOqwld/GdBfiRNc4nnjyWWENDEicq4SH+R5AuYatvf++vf1x5JIsHB1i1KtfZMD3eRte0D4K9WXuAYil6XAg==} + '@nestjs/common@11.1.9': + resolution: {integrity: sha512-zDntUTReRbAThIfSp3dQZ9kKqI+LjgLp5YZN5c1bgNRDuoeLySAoZg46Bg1a+uV8TMgIRziHocglKGNzr6l+bQ==} peerDependencies: class-transformer: '>=0.4.1' class-validator: '>=0.13.2' @@ -3221,8 +3406,8 @@ packages: class-validator: optional: true - '@nestjs/core@11.1.8': - resolution: {integrity: sha512-7riWfmTmMhCJHZ5ZiaG+crj4t85IPCq/wLRuOUSigBYyFT2JZj0lVHtAdf4Davp9ouNI8GINBDt9h9b5Gz9nTw==} + '@nestjs/core@11.1.9': + resolution: {integrity: sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -3252,14 +3437,14 @@ packages: class-validator: optional: true - '@nestjs/platform-express@11.1.8': - resolution: {integrity: sha512-rL6pZH9BW7BnL5X2eWbJMtt86uloAKjFgyY5+L2UkizgfEp7rgAs0+Z1z0BcW2Pgu5+q8O7RKPNyHJ/9ZNz/ZQ==} + '@nestjs/platform-express@11.1.9': + resolution: {integrity: sha512-GVd3+0lO0mJq2m1kl9hDDnVrX3Nd4oH3oDfklz0pZEVEVS0KVSp63ufHq2Lu9cyPdSBuelJr9iPm2QQ1yX+Kmw==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 - '@nestjs/platform-socket.io@11.1.8': - resolution: {integrity: sha512-nMUvwcdztso8BjN9czRl4sm0Ewc5xrCcgLvy+QPt6VAnTdu06KcZqtA6Cl3MKxViSQsQ8NBN5foKvZehNt/tug==} + '@nestjs/platform-socket.io@11.1.9': + resolution: {integrity: sha512-OaAW+voXo5BXbFKd9Ot3SL05tEucRMhZRdw5wdWZf/RpIl9hB6G6OHr8DDxNbUGvuQWzNnZHCDHx3EQJzjcIyA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/websockets': ^11.0.0 @@ -3276,8 +3461,8 @@ packages: peerDependencies: typescript: '>=4.8.2' - '@nestjs/swagger@11.2.1': - resolution: {integrity: sha512-1MS7xf0pzc1mofG53xrrtrurnziafPUHkqzRm4YUVPA/egeiMaSerQBD/feiAeQ2BnX0WiLsTX4HQFO0icvOjQ==} + '@nestjs/swagger@11.2.3': + resolution: {integrity: sha512-a0xFfjeqk69uHIUpP8u0ryn4cKuHdra2Ug96L858i0N200Hxho+n3j+TlQXyOF4EstLSGjTfxI1Xb2E1lUxeNg==} peerDependencies: '@fastify/static': ^8.0.0 '@nestjs/common': ^11.0.1 @@ -3293,8 +3478,8 @@ packages: class-validator: optional: true - '@nestjs/testing@11.1.8': - resolution: {integrity: sha512-E6K+0UTKztcPxJzLnQa7S34lFjZbrj3Z1r7c5y5WDrL1m5HD1H4AeyBhicHgdaFmxjLAva2bq0sYKy/S7cdeYA==} + '@nestjs/testing@11.1.9': + resolution: {integrity: sha512-UFxerBDdb0RUNxQNj25pvkvNE7/vxKhXYWBt3QuwBFnYISzRIzhVlyIqLfoV5YI3zV0m0Nn4QAn1KM0zzwfEng==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3306,8 +3491,8 @@ packages: '@nestjs/platform-express': optional: true - '@nestjs/websockets@11.1.8': - resolution: {integrity: sha512-RXo2336p/vyAwJ0qPInglzNSQ//qz+JTLr2LE1vlbmN5WcyB7zV6+gY06YgNdsr3oy/cXRh7fnC3Ph/VAu1EVg==} + '@nestjs/websockets@11.1.9': + resolution: {integrity: sha512-kkkdeTVcc3X7ZzvVqUVpOAJoh49kTRUjWNUXo5jmG+27OvZoHfs/vuSiqxidrrbIgydSqN15HUsf1wZwQUrxCQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3334,13 +3519,13 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@3.0.0': - resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} - engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/agent@4.0.0': + resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} + engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/fs@4.0.0': - resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} - engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/fs@5.0.0': + resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} + engines: {node: ^20.17.0 || >=22.9.0} '@nuxt/opencollective@0.4.1': resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} @@ -3350,8 +3535,8 @@ packages: '@oazapfts/runtime@1.0.4': resolution: {integrity: sha512-7t6C2shug/6tZhQgkCa532oTYBLEnbASV/i1SG1rH2GB4h3aQQujYciYSPT92hvN4IwTe8S2hPkN/6iiOyTlCg==} - '@opentelemetry/api-logs@0.207.0': - resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} + '@opentelemetry/api-logs@0.208.0': + resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} engines: {node: '>=8.0.0'} '@opentelemetry/api@1.9.0': @@ -3370,62 +3555,62 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-logs-otlp-grpc@0.207.0': - resolution: {integrity: sha512-K92RN+kQGTMzFDsCzsYNGqOsXRUnko/Ckk+t/yPJao72MewOLgBUTWVHhebgkNfRCYqDz1v3K0aPT9OJkemvgg==} + '@opentelemetry/exporter-logs-otlp-grpc@0.208.0': + resolution: {integrity: sha512-AmZDKFzbq/idME/yq68M155CJW1y056MNBekH9OZewiZKaqgwYN4VYfn3mXVPftYsfrCM2r4V6tS8H2LmfiDCg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-http@0.207.0': - resolution: {integrity: sha512-JpOh7MguEUls8eRfkVVW3yRhClo5b9LqwWTOg8+i4gjr/+8eiCtquJnC7whvpTIGyff06cLZ2NsEj+CVP3Mjeg==} + '@opentelemetry/exporter-logs-otlp-http@0.208.0': + resolution: {integrity: sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-proto@0.207.0': - resolution: {integrity: sha512-RQJEV/K6KPbQrIUbsrRkEe0ufks1o5OGLHy6jbDD8tRjeCsbFHWfg99lYBRqBV33PYZJXsigqMaAbjWGTFYzLw==} + '@opentelemetry/exporter-logs-otlp-proto@0.208.0': + resolution: {integrity: sha512-Wy8dZm16AOfM7yddEzSFzutHZDZ6HspKUODSUJVjyhnZFMBojWDjSNgduyCMlw6qaxJYz0dlb0OEcb4Eme+BfQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-grpc@0.207.0': - resolution: {integrity: sha512-6flX89W54gkwmqYShdcTBR1AEF5C1Ob0O8pDgmLPikTKyEv27lByr9yBmO5WrP0+5qJuNPHrLfgFQFYi6npDGA==} + '@opentelemetry/exporter-metrics-otlp-grpc@0.208.0': + resolution: {integrity: sha512-YbEnk7jjYmvhIwp2xJGkEvdgnayrA2QSr28R1LR1klDPvCxsoQPxE6TokDbQpoCEhD3+KmJVEXfb4EeEQxjymg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-http@0.207.0': - resolution: {integrity: sha512-fG8FAJmvXOrKXGIRN8+y41U41IfVXxPRVwyB05LoMqYSjugx/FSBkMZUZXUT/wclTdmBKtS5MKoi0bEKkmRhSw==} + '@opentelemetry/exporter-metrics-otlp-http@0.208.0': + resolution: {integrity: sha512-QZ3TrI90Y0i1ezWQdvreryjY0a5TK4J9gyDLIyhLBwV+EQUvyp5wR7TFPKCAexD4TDSWM0t3ulQDbYYjVtzTyA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-proto@0.207.0': - resolution: {integrity: sha512-kDBxiTeQjaRlUQzS1COT9ic+et174toZH6jxaVuVAvGqmxOkgjpLOjrI5ff8SMMQE69r03L3Ll3nPKekLopLwg==} + '@opentelemetry/exporter-metrics-otlp-proto@0.208.0': + resolution: {integrity: sha512-CvvVD5kRDmRB/uSMalvEF6kiamY02pB46YAqclHtfjJccNZFxbkkXkMMmcJ7NgBFa5THmQBNVQ2AHyX29nRxOw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-prometheus@0.207.0': - resolution: {integrity: sha512-Y5p1s39FvIRmU+F1++j7ly8/KSqhMmn6cMfpQqiDCqDjdDHwUtSq0XI0WwL3HYGnZeaR/VV4BNmsYQJ7GAPrhw==} + '@opentelemetry/exporter-prometheus@0.208.0': + resolution: {integrity: sha512-Rgws8GfIfq2iNWCD3G1dTD9xwYsCof1+tc5S5X0Ahdb5CrAPE+k5P70XCWHqrFFurVCcKaHLJ/6DjIBHWVfLiw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-grpc@0.207.0': - resolution: {integrity: sha512-7u2ZmcIx6D4KG/+5np4X2qA0o+O0K8cnUDhR4WI/vr5ZZ0la9J9RG+tkSjC7Yz+2XgL6760gSIM7/nyd3yaBLA==} + '@opentelemetry/exporter-trace-otlp-grpc@0.208.0': + resolution: {integrity: sha512-E/eNdcqVUTAT7BC+e8VOw/krqb+5rjzYkztMZ/o+eyJl+iEY6PfczPXpwWuICwvsm0SIhBoh9hmYED5Vh5RwIw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-http@0.207.0': - resolution: {integrity: sha512-HSRBzXHIC7C8UfPQdu15zEEoBGv0yWkhEwxqgPCHVUKUQ9NLHVGXkVrf65Uaj7UwmAkC1gQfkuVYvLlD//AnUQ==} + '@opentelemetry/exporter-trace-otlp-http@0.208.0': + resolution: {integrity: sha512-jbzDw1q+BkwKFq9yxhjAJ9rjKldbt5AgIy1gmEIJjEV/WRxQ3B6HcLVkwbjJ3RcMif86BDNKR846KJ0tY0aOJA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-proto@0.207.0': - resolution: {integrity: sha512-ruUQB4FkWtxHjNmSXjrhmJZFvyMm+tBzHyMm7YPQshApy4wvZUTcrpPyP/A/rCl/8M4BwoVIZdiwijMdbZaq4w==} + '@opentelemetry/exporter-trace-otlp-proto@0.208.0': + resolution: {integrity: sha512-q844Jc3ApkZVdWYd5OAl+an3n1XXf3RWHa3Zgmnhw3HpsM3VluEKHckUUEqHPzbwDUx2lhPRVkqK7LsJ/CbDzA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3442,50 +3627,50 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.207.0': - resolution: {integrity: sha512-FC4i5hVixTzuhg4SV2ycTEAYx+0E2hm+GwbdoVPSA6kna0pPVI4etzaA9UkpJ9ussumQheFXP6rkGIaFJjMxsw==} + '@opentelemetry/instrumentation-http@0.208.0': + resolution: {integrity: sha512-rhmK46DRWEbQQB77RxmVXGyjs6783crXCnFjYQj+4tDH/Kpv9Rbg3h2kaNyp5Vz2emF1f9HOQQvZoHzwMWOFZQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.55.0': - resolution: {integrity: sha512-ASuBMzh0ImmfOnWj9vCPtBMqSjr54/r/HluUIylwZB7xzTU6gL2SfybxySJMzEL9+386gJJVApwQktVznAtrWA==} + '@opentelemetry/instrumentation-ioredis@0.56.0': + resolution: {integrity: sha512-XSWeqsd3rKSsT3WBz/JKJDcZD4QYElZEa0xVdX8f9dh4h4QgXhKRLorVsVkK3uXFbC2sZKAS2Ds+YolGwD83Dg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.54.0': - resolution: {integrity: sha512-kqJcOVcniazueWTXt9czK6gd9xlHw5IM5JQM4wfH0ZkjZjNkKtQNzlhjdJpvqVhU9bGHet1yfrHOKXxlP4YeOA==} + '@opentelemetry/instrumentation-nestjs-core@0.55.0': + resolution: {integrity: sha512-JFLNhbbEGnnQrMKOYoXx0nNk5N9cPeghu4xP/oup40a7VaSeYruyOiFbg9nkbS4ZQiI8aMuRqUT3Mo4lQjKEKg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.60.0': - resolution: {integrity: sha512-qZKeQojYJMoo7kWbHw/+SHopSdhfTxNISsBS+ZBbkr44sepmk/PmyU2AbOsSK7VOKvFt3oZde2n2nly7rk0SsA==} + '@opentelemetry/instrumentation-pg@0.61.1': + resolution: {integrity: sha512-VKKts/XcOCa7IPBxVjL2B4UyG+YTNa4Dh1Xx2vqL0jOEQBJlNsv++I12BUw/8NRLEr2K/gOM5tpVU7QqhWA65A==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.207.0': - resolution: {integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==} + '@opentelemetry/instrumentation@0.208.0': + resolution: {integrity: sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.207.0': - resolution: {integrity: sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw==} + '@opentelemetry/otlp-exporter-base@0.208.0': + resolution: {integrity: sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-grpc-exporter-base@0.207.0': - resolution: {integrity: sha512-eKFjKNdsPed4q9yYqeI5gBTLjXxDM/8jwhiC0icw3zKxHVGBySoDsed5J5q/PGY/3quzenTr3FiTxA3NiNT+nw==} + '@opentelemetry/otlp-grpc-exporter-base@0.208.0': + resolution: {integrity: sha512-fGvAg3zb8fC0oJAzfz7PQppADI2HYB7TSt/XoCaBJFi1mSquNUjtHXEoviMgObLAa1NRIgOC1lsV1OUKi+9+lQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-transformer@0.207.0': - resolution: {integrity: sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA==} + '@opentelemetry/otlp-transformer@0.208.0': + resolution: {integrity: sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3512,8 +3697,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-logs@0.207.0': - resolution: {integrity: sha512-4MEQmn04y+WFe6cyzdrXf58hZxilvY59lzZj2AccuHW/+BxLn/rGVN/Irsi/F0qfBOpMOrrCLKTExoSL2zoQmg==} + '@opentelemetry/sdk-logs@0.208.0': + resolution: {integrity: sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' @@ -3524,8 +3709,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' - '@opentelemetry/sdk-node@0.207.0': - resolution: {integrity: sha512-hnRsX/M8uj0WaXOBvFenQ8XsE8FLVh2uSnn1rkWu4mx+qu7EKGUZvZng6y/95cyzsqOfiaDDr08Ek4jppkIDNg==} + '@opentelemetry/sdk-node@0.208.0': + resolution: {integrity: sha512-pbAqpZ7zTMFuTf3YecYsecsto/mheuvnK2a/jgstsE5ynWotBjgF5bnz5500W9Xl2LeUfg04WMt63TWtAgzRMw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' @@ -3542,8 +3727,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.37.0': - resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} + '@opentelemetry/semantic-conventions@1.38.0': + resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.41.2': @@ -3564,6 +3749,11 @@ packages: '@photo-sphere-viewer/core': 5.14.0 '@photo-sphere-viewer/video-plugin': 5.14.0 + '@photo-sphere-viewer/markers-plugin@5.14.0': + resolution: {integrity: sha512-w7txVHtLxXMS61m0EbNjgvdNXQYRh6Aa0oatft5oruKgoXLg/UlCu1mG6Btg+zrNsG05W2zl4gRM3fcWoVdneA==} + peerDependencies: + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/resolution-plugin@5.14.0': resolution: {integrity: sha512-PvDMX1h+8FzWdySxiorQ2bSmyBGTPsZjNNFRBqIfmb5C+01aWCIE7kuXodXGHwpXQNcOojsVX9IiX0Vz4CiW4A==} peerDependencies: @@ -3591,8 +3781,8 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.56.1': - resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} + '@playwright/test@1.57.0': + resolution: {integrity: sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==} engines: {node: '>=18'} hasBin: true @@ -3775,113 +3965,113 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.52.5': - resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.5': - resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.5': - resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.5': - resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.5': - resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.5': - resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.5': - resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.5': - resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.5': - resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.5': - resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.5': - resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.5': - resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.5': - resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.5': - resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.5': - resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.5': - resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.5': - resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.5': - resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.5': - resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.5': - resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.5': - resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.5': - resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} cpu: [x64] os: [win32] @@ -3920,32 +4110,32 @@ packages: '@slorber/remark-comment@1.0.0': resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} - '@smithy/abort-controller@4.2.3': - resolution: {integrity: sha512-xWL9Mf8b7tIFuAlpjKtRPnHrR8XVrwTj5NPYO/QwZPtc0SDLsPxb56V5tzi5yspSMytISHybifez+4jlrx0vkQ==} + '@smithy/abort-controller@4.2.5': + resolution: {integrity: sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.0': - resolution: {integrity: sha512-Kkmz3Mup2PGp/HNJxhCWkLNdlajJORLSjwkcfrj0E7nu6STAEdcMR1ir5P9/xOmncx8xXfru0fbUYLlZog/cFg==} + '@smithy/config-resolver@4.4.3': + resolution: {integrity: sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==} engines: {node: '>=18.0.0'} - '@smithy/core@3.17.1': - resolution: {integrity: sha512-V4Qc2CIb5McABYfaGiIYLTmo/vwNIK7WXI5aGveBd9UcdhbOMwcvIMxIw/DJj1S9QgOMa/7FBkarMdIC0EOTEQ==} + '@smithy/core@3.18.5': + resolution: {integrity: sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.3': - resolution: {integrity: sha512-hA1MQ/WAHly4SYltJKitEsIDVsNmXcQfYBRv2e+q04fnqtAX5qXaybxy/fhUeAMCnQIdAjaGDb04fMHQefWRhw==} + '@smithy/credential-provider-imds@4.2.5': + resolution: {integrity: sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.4': - resolution: {integrity: sha512-bwigPylvivpRLCm+YK9I5wRIYjFESSVwl8JQ1vVx/XhCw0PtCi558NwTnT2DaVCl5pYlImGuQTSwMsZ+pIavRw==} + '@smithy/fetch-http-handler@5.3.6': + resolution: {integrity: sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.3': - resolution: {integrity: sha512-6+NOdZDbfuU6s1ISp3UOk5Rg953RJ2aBLNLLBEcamLjHAg1Po9Ha7QIB5ZWhdRUVuOUrT8BVFR+O2KIPmw027g==} + '@smithy/hash-node@4.2.5': + resolution: {integrity: sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.3': - resolution: {integrity: sha512-Cc9W5DwDuebXEDMpOpl4iERo8I0KFjTnomK2RMdhhR87GwrSmUmwMxS4P5JdRf+LsjOdIqumcerwRgYMr/tZ9Q==} + '@smithy/invalid-dependency@4.2.5': + resolution: {integrity: sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': @@ -3956,72 +4146,72 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.3': - resolution: {integrity: sha512-/atXLsT88GwKtfp5Jr0Ks1CSa4+lB+IgRnkNrrYP0h1wL4swHNb0YONEvTceNKNdZGJsye+W2HH8W7olbcPUeA==} + '@smithy/middleware-content-length@4.2.5': + resolution: {integrity: sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.3.5': - resolution: {integrity: sha512-SIzKVTvEudFWJbxAaq7f2GvP3jh2FHDpIFI6/VAf4FOWGFZy0vnYMPSRj8PGYI8Hjt29mvmwSRgKuO3bK4ixDw==} + '@smithy/middleware-endpoint@4.3.12': + resolution: {integrity: sha512-9pAX/H+VQPzNbouhDhkW723igBMLgrI8OtX+++M7iKJgg/zY/Ig3i1e6seCcx22FWhE6Q/S61BRdi2wXBORT+A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.5': - resolution: {integrity: sha512-DCaXbQqcZ4tONMvvdz+zccDE21sLcbwWoNqzPLFlZaxt1lDtOE2tlVpRSwcTOJrjJSUThdgEYn7HrX5oLGlK9A==} + '@smithy/middleware-retry@4.4.12': + resolution: {integrity: sha512-S4kWNKFowYd0lID7/DBqWHOQxmxlsf0jBaos9chQZUWTVOjSW1Ogyh8/ib5tM+agFDJ/TCxuCTvrnlc+9cIBcQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.3': - resolution: {integrity: sha512-8g4NuUINpYccxiCXM5s1/V+uLtts8NcX4+sPEbvYQDZk4XoJfDpq5y2FQxfmUL89syoldpzNzA0R9nhzdtdKnQ==} + '@smithy/middleware-serde@4.2.6': + resolution: {integrity: sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.3': - resolution: {integrity: sha512-iGuOJkH71faPNgOj/gWuEGS6xvQashpLwWB1HjHq1lNNiVfbiJLpZVbhddPuDbx9l4Cgl0vPLq5ltRfSaHfspA==} + '@smithy/middleware-stack@4.2.5': + resolution: {integrity: sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.3': - resolution: {integrity: sha512-NzI1eBpBSViOav8NVy1fqOlSfkLgkUjUTlohUSgAEhHaFWA3XJiLditvavIP7OpvTjDp5u2LhtlBhkBlEisMwA==} + '@smithy/node-config-provider@4.3.5': + resolution: {integrity: sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.4.3': - resolution: {integrity: sha512-MAwltrDB0lZB/H6/2M5PIsISSwdI5yIh6DaBB9r0Flo9nx3y0dzl/qTMJPd7tJvPdsx6Ks/cwVzheGNYzXyNbQ==} + '@smithy/node-http-handler@4.4.5': + resolution: {integrity: sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.3': - resolution: {integrity: sha512-+1EZ+Y+njiefCohjlhyOcy1UNYjT+1PwGFHCxA/gYctjg3DQWAU19WigOXAco/Ql8hZokNehpzLd0/+3uCreqQ==} + '@smithy/property-provider@4.2.5': + resolution: {integrity: sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.3': - resolution: {integrity: sha512-Mn7f/1aN2/jecywDcRDvWWWJF4uwg/A0XjFMJtj72DsgHTByfjRltSqcT9NyE9RTdBSN6X1RSXrhn/YWQl8xlw==} + '@smithy/protocol-http@5.3.5': + resolution: {integrity: sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.3': - resolution: {integrity: sha512-LOVCGCmwMahYUM/P0YnU/AlDQFjcu+gWbFJooC417QRB/lDJlWSn8qmPSDp+s4YVAHOgtgbNG4sR+SxF/VOcJQ==} + '@smithy/querystring-builder@4.2.5': + resolution: {integrity: sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.3': - resolution: {integrity: sha512-cYlSNHcTAX/wc1rpblli3aUlLMGgKZ/Oqn8hhjFASXMCXjIqeuQBei0cnq2JR8t4RtU9FpG6uyl6PxyArTiwKA==} + '@smithy/querystring-parser@4.2.5': + resolution: {integrity: sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.3': - resolution: {integrity: sha512-NkxsAxFWwsPsQiwFG2MzJ/T7uIR6AQNh1SzcxSUnmmIqIQMlLRQDKhc17M7IYjiuBXhrQRjQTo3CxX+DobS93g==} + '@smithy/service-error-classification@4.2.5': + resolution: {integrity: sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.3.3': - resolution: {integrity: sha512-9f9Ixej0hFhroOK2TxZfUUDR13WVa8tQzhSzPDgXe5jGL3KmaM9s8XN7RQwqtEypI82q9KHnKS71CJ+q/1xLtQ==} + '@smithy/shared-ini-file-loader@4.4.0': + resolution: {integrity: sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.3': - resolution: {integrity: sha512-CmSlUy+eEYbIEYN5N3vvQTRfqt0lJlQkaQUIf+oizu7BbDut0pozfDjBGecfcfWf7c62Yis4JIEgqQ/TCfodaA==} + '@smithy/signature-v4@5.3.5': + resolution: {integrity: sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.9.1': - resolution: {integrity: sha512-Ngb95ryR5A9xqvQFT5mAmYkCwbXvoLavLFwmi7zVg/IowFPCfiqRfkOKnbc/ZRL8ZKJ4f+Tp6kSu6wjDQb8L/g==} + '@smithy/smithy-client@4.9.8': + resolution: {integrity: sha512-8xgq3LgKDEFoIrLWBho/oYKyWByw9/corz7vuh1upv7ZBm0ZMjGYBhbn6v643WoIqA9UTcx5A5htEp/YatUwMA==} engines: {node: '>=18.0.0'} - '@smithy/types@4.8.0': - resolution: {integrity: sha512-QpELEHLO8SsQVtqP+MkEgCYTFW0pleGozfs3cZ183ZBj9z3VC1CX1/wtFMK64p+5bhtZo41SeLK1rBRtd25nHQ==} + '@smithy/types@4.9.0': + resolution: {integrity: sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.3': - resolution: {integrity: sha512-I066AigYvY3d9VlU3zG9XzZg1yT10aNqvCaBTw9EPgu5GrsEl1aUkcMvhkIXascYH1A8W0LQo3B1Kr1cJNcQEw==} + '@smithy/url-parser@4.2.5': + resolution: {integrity: sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==} engines: {node: '>=18.0.0'} '@smithy/util-base64@4.3.0': @@ -4048,32 +4238,32 @@ packages: resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.4': - resolution: {integrity: sha512-qI5PJSW52rnutos8Bln8nwQZRpyoSRN6k2ajyoUHNMUzmWqHnOJCnDELJuV6m5PML0VkHI+XcXzdB+6awiqYUw==} + '@smithy/util-defaults-mode-browser@4.3.11': + resolution: {integrity: sha512-yHv+r6wSQXEXTPVCIQTNmXVWs7ekBTpMVErjqZoWkYN75HIFN5y9+/+sYOejfAuvxWGvgzgxbTHa/oz61YTbKw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.6': - resolution: {integrity: sha512-c6M/ceBTm31YdcFpgfgQAJaw3KbaLuRKnAz91iMWFLSrgxRpYm03c3bu5cpYojNMfkV9arCUelelKA7XQT36SQ==} + '@smithy/util-defaults-mode-node@4.2.14': + resolution: {integrity: sha512-ljZN3iRvaJUgulfvobIuG97q1iUuCMrvXAlkZ4msY+ZuVHQHDIqn7FKZCEj+bx8omz6kF5yQXms/xhzjIO5XiA==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.2.3': - resolution: {integrity: sha512-aCfxUOVv0CzBIkU10TubdgKSx5uRvzH064kaiPEWfNIvKOtNpu642P4FP1hgOFkjQIkDObrfIDnKMKkeyrejvQ==} + '@smithy/util-endpoints@3.2.5': + resolution: {integrity: sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==} engines: {node: '>=18.0.0'} '@smithy/util-hex-encoding@4.2.0': resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.3': - resolution: {integrity: sha512-v5ObKlSe8PWUHCqEiX2fy1gNv6goiw6E5I/PN2aXg3Fb/hse0xeaAnSpXDiWl7x6LamVKq7senB+m5LOYHUAHw==} + '@smithy/util-middleware@4.2.5': + resolution: {integrity: sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.3': - resolution: {integrity: sha512-lLPWnakjC0q9z+OtiXk+9RPQiYPNAovt2IXD3CP4LkOnd9NpUsxOjMx1SnoUVB7Orb7fZp67cQMtTBKMFDvOGg==} + '@smithy/util-retry@4.2.5': + resolution: {integrity: sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.4': - resolution: {integrity: sha512-+qDxSkiErejw1BAIXUFBSfM5xh3arbz1MmxlbMCKanDDZtVEQ7PSKW9FQS0Vud1eI/kYn0oCTVKyNzRlq+9MUw==} + '@smithy/util-stream@4.5.6': + resolution: {integrity: sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.2.0': @@ -4104,8 +4294,8 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@sveltejs/acorn-typescript@1.0.6': - resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} + '@sveltejs/acorn-typescript@1.0.8': + resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} peerDependencies: acorn: ^8.9.0 @@ -4114,15 +4304,15 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/enhanced-img@0.8.4': - resolution: {integrity: sha512-/L12VUQj+ANIhskHT620jtxAs9wUPUIutgo37rwx5NgLnxOpVsP27fMiSpdIMgERldbgr6uRJ1WZGGOkzm7Vcg==} + '@sveltejs/enhanced-img@0.9.2': + resolution: {integrity: sha512-hAYZ8YFgYtqrQ0dXyq6rdmHBFyG+eIQnNjdIoVhqeZQEBIREXoBThkx+7FtDa6ZV35lTRaT9dgFKF4W+4LbuaQ==} peerDependencies: '@sveltejs/vite-plugin-svelte': ^6.0.0 svelte: ^5.0.0 vite: ^6.3.0 || >=7.0.0 - '@sveltejs/kit@2.48.3': - resolution: {integrity: sha512-jf8mx3yctRXE9hvixgcqqK94YI2hDnbxI/12Upkz99XFMvxnJKCMzvz0j7lmbXSyBSNEycWO5xHvi7b73y9qkQ==} + '@sveltejs/kit@2.49.0': + resolution: {integrity: sha512-oH8tXw7EZnie8FdOWYrF7Yn4IKrqTFHhXvl8YxXxbKwTMcD/5NNCryUSEXRk2ZR4ojnub0P8rNrsVGHXWqIDtA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -4227,68 +4417,68 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} - '@swc/core-darwin-arm64@1.14.0': - resolution: {integrity: sha512-uHPC8rlCt04nvYNczWzKVdgnRhxCa3ndKTBBbBpResOZsRmiwRAvByIGh599j+Oo6Z5eyTPrgY+XfJzVmXnN7Q==} + '@swc/core-darwin-arm64@1.15.3': + resolution: {integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.14.0': - resolution: {integrity: sha512-2SHrlpl68vtePRknv9shvM9YKKg7B9T13tcTg9aFCwR318QTYo+FzsKGmQSv9ox/Ua0Q2/5y2BNjieffJoo4nA==} + '@swc/core-darwin-x64@1.15.3': + resolution: {integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.14.0': - resolution: {integrity: sha512-SMH8zn01dxt809svetnxpeg/jWdpi6dqHKO3Eb11u4OzU2PK7I5uKS6gf2hx5LlTbcJMFKULZiVwjlQLe8eqtg==} + '@swc/core-linux-arm-gnueabihf@1.15.3': + resolution: {integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.14.0': - resolution: {integrity: sha512-q2JRu2D8LVqGeHkmpVCljVNltG0tB4o4eYg+dElFwCS8l2Mnt9qurMCxIeo9mgoqz0ax+k7jWtIRHktnVCbjvQ==} + '@swc/core-linux-arm64-gnu@1.15.3': + resolution: {integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.14.0': - resolution: {integrity: sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==} + '@swc/core-linux-arm64-musl@1.15.3': + resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.14.0': - resolution: {integrity: sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==} + '@swc/core-linux-x64-gnu@1.15.3': + resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.14.0': - resolution: {integrity: sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==} + '@swc/core-linux-x64-musl@1.15.3': + resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.14.0': - resolution: {integrity: sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==} + '@swc/core-win32-arm64-msvc@1.15.3': + resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.14.0': - resolution: {integrity: sha512-dPai3KUIcihV5hfoO4QNQF5HAaw8+2bT7dvi8E5zLtecW2SfL3mUZipzampXq5FHll0RSCLzlrXnSx+dBRZIIQ==} + '@swc/core-win32-ia32-msvc@1.15.3': + resolution: {integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.14.0': - resolution: {integrity: sha512-nm+JajGrTqUA6sEHdghDlHMNfH1WKSiuvljhdmBACW4ta4LC3gKurX2qZuiBARvPkephW9V/i5S8QPY1PzFEqg==} + '@swc/core-win32-x64-msvc@1.15.3': + resolution: {integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.14.0': - resolution: {integrity: sha512-oExhY90bes5pDTVrei0xlMVosTxwd/NMafIpqsC4dMbRYZ5KB981l/CX8tMnGsagTplj/RcG9BeRYmV6/J5m3w==} + '@swc/core@1.15.3': + resolution: {integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -4309,65 +4499,65 @@ packages: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - '@tailwindcss/node@4.1.16': - resolution: {integrity: sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==} + '@tailwindcss/node@4.1.17': + resolution: {integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==} - '@tailwindcss/oxide-android-arm64@4.1.16': - resolution: {integrity: sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==} + '@tailwindcss/oxide-android-arm64@4.1.17': + resolution: {integrity: sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.16': - resolution: {integrity: sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==} + '@tailwindcss/oxide-darwin-arm64@4.1.17': + resolution: {integrity: sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.16': - resolution: {integrity: sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==} + '@tailwindcss/oxide-darwin-x64@4.1.17': + resolution: {integrity: sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.16': - resolution: {integrity: sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==} + '@tailwindcss/oxide-freebsd-x64@4.1.17': + resolution: {integrity: sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16': - resolution: {integrity: sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': + resolution: {integrity: sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.16': - resolution: {integrity: sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': + resolution: {integrity: sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.16': - resolution: {integrity: sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': + resolution: {integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.16': - resolution: {integrity: sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': + resolution: {integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.16': - resolution: {integrity: sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==} + '@tailwindcss/oxide-linux-x64-musl@4.1.17': + resolution: {integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.16': - resolution: {integrity: sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==} + '@tailwindcss/oxide-wasm32-wasi@4.1.17': + resolution: {integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -4378,37 +4568,37 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.16': - resolution: {integrity: sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': + resolution: {integrity: sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.16': - resolution: {integrity: sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': + resolution: {integrity: sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.16': - resolution: {integrity: sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==} + '@tailwindcss/oxide@4.1.17': + resolution: {integrity: sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==} engines: {node: '>= 10'} - '@tailwindcss/vite@4.1.16': - resolution: {integrity: sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==} + '@tailwindcss/vite@4.1.17': + resolution: {integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 - '@testing-library/dom@10.4.0': - resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} '@testing-library/jest-dom@6.9.1': resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - '@testing-library/svelte@5.2.8': - resolution: {integrity: sha512-ucQOtGsJhtawOEtUmbR4rRh53e6RbM1KUluJIXRmh6D4UzxR847iIqqjRtg9mHNFmGQ8Vkam9yVcR5d1mhIHKA==} + '@testing-library/svelte@5.2.9': + resolution: {integrity: sha512-p0Lg/vL1iEsEasXKSipvW9nBCtItQGhYvxL8OZ4w7/IDdC+LGoSJw4mMS5bndVFON/gWryitEhMr29AlO4FvBg==} engines: {node: '>= 10'} peerDependencies: svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 @@ -4426,8 +4616,8 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tokenizer/inflate@0.2.7': - resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} + '@tokenizer/inflate@0.3.1': + resolution: {integrity: sha512-4oeoZEBQdLdt5WmP/hx1KZ6D3/Oid/0cUb2nk4F0pTDAWy+KCH3/EnAkZF/bvckWo8I33EqBm01lIPgmgc8rCA==} engines: {node: '>=18'} '@tokenizer/token@0.3.0': @@ -4453,8 +4643,8 @@ packages: '@types/accepts@1.3.7': resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} - '@types/archiver@6.0.4': - resolution: {integrity: sha512-ULdQpARQ3sz9WH4nb98mJDYA0ft2A8C4f4fovvUcFwINa1cgGjY36JCAYuP5YypRq4mco1lJp1/7jEMS2oR0Hg==} + '@types/archiver@7.0.0': + resolution: {integrity: sha512-/3vwGwx9n+mCQdYZ2IKGGHEFL30I96UgBlk8EtRDDFQ9uxM1l4O5Ci6r00EMAkiDaTqD9DQ6nVrWRICnBPtzzg==} '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -4527,8 +4717,8 @@ packages: '@types/docker-modem@3.0.6': resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} - '@types/dockerode@3.3.45': - resolution: {integrity: sha512-iYpZF+xr5QLpIICejLdUF2r5gh8IXY1Gw3WLmt41dUbS3Vn/3hVgL+6lJBVbmrhYBWfbWPPstdr6+A0s95DTWA==} + '@types/dockerode@3.3.47': + resolution: {integrity: sha512-ShM1mz7rCjdssXt7Xz0u1/R2BJC7piWa3SJpUBiVjCf2A3XNn4cP6pUVaD8bLanpPVVn4IKzJuw3dOvkJ8IbYw==} '@types/dom-to-image@2.6.7': resolution: {integrity: sha512-me5VbCv+fcXozblWwG13krNBvuEOm6kA5xoa4RrjDJCNFOZSWR3/QLtOXimBHk1Fisq69Gx3JtOoXtg1N1tijg==} @@ -4641,8 +4831,8 @@ packages: '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} '@types/luxon@3.7.1': resolution: {integrity: sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==} @@ -4683,14 +4873,11 @@ packages: '@types/node@20.19.24': resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} - '@types/node@22.19.0': - resolution: {integrity: sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==} + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - '@types/node@24.10.0': - resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} - - '@types/nodemailer@7.0.3': - resolution: {integrity: sha512-fC8w49YQ868IuPWRXqPfLf+MuTRex5Z1qxMoG8rr70riqqbOp2F5xgOKE9fODEBPzpnvjkJXFgK6IL2xgMSTnA==} + '@types/nodemailer@7.0.4': + resolution: {integrity: sha512-ee8fxWqOchH+Hv6MDDNNy028kwvVnLplrStm4Zf/3uHWw5zzo8FoYYeffpJtGs2wWysEumMH0ZIdMGMY1eMAow==} '@types/oidc-provider@9.5.0': resolution: {integrity: sha512-eEzCRVTSqIHD9Bo/qRJ4XQWQ5Z/zBcG+Z2cGJluRsSuWx1RJihqRyPxhIEpMXTwPzHYRTQkVp7hwisQOwzzSAg==} @@ -4701,9 +4888,6 @@ packages: '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} - '@types/pg@8.15.5': - resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} - '@types/pg@8.15.6': resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} @@ -4734,8 +4918,8 @@ packages: '@types/react-router@5.1.20': resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} - '@types/react@19.2.2': - resolution: {integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==} + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} '@types/readdir-glob@1.1.5': resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} @@ -4797,8 +4981,8 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/validator@13.15.4': - resolution: {integrity: sha512-LSFfpSnJJY9wbC0LQxgvfb+ynbHftFo0tMsFOl/J4wexLnYMmDSPaj2ZyDv3TkfL1UePxPrxOWJfbiRS8mQv7A==} + '@types/validator@13.15.10': + resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} @@ -4812,63 +4996,63 @@ packages: '@types/yargs@17.0.34': resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} - '@typescript-eslint/eslint-plugin@8.46.2': - resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==} + '@typescript-eslint/eslint-plugin@8.48.0': + resolution: {integrity: sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.46.2 + '@typescript-eslint/parser': ^8.48.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.46.2': - resolution: {integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==} + '@typescript-eslint/parser@8.48.0': + resolution: {integrity: sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.46.2': - resolution: {integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==} + '@typescript-eslint/project-service@8.48.0': + resolution: {integrity: sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.46.2': - resolution: {integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==} + '@typescript-eslint/scope-manager@8.48.0': + resolution: {integrity: sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.46.2': - resolution: {integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==} + '@typescript-eslint/tsconfig-utils@8.48.0': + resolution: {integrity: sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.46.2': - resolution: {integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==} + '@typescript-eslint/type-utils@8.48.0': + resolution: {integrity: sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.46.2': - resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} + '@typescript-eslint/types@8.48.0': + resolution: {integrity: sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.46.2': - resolution: {integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==} + '@typescript-eslint/typescript-estree@8.48.0': + resolution: {integrity: sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.46.2': - resolution: {integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==} + '@typescript-eslint/utils@8.48.0': + resolution: {integrity: sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.46.2': - resolution: {integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==} + '@typescript-eslint/visitor-keys@8.48.0': + resolution: {integrity: sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -4967,11 +5151,11 @@ packages: '@xtuc/long@4.2.2': resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - '@zoom-image/core@0.41.3': - resolution: {integrity: sha512-yW2sZRP6FnZZ7vREpYucDpSCsVFgMSWq22Sp1kabsMPz5+6LSs+sBPPDCVs/ahVYSHa9YOX8rlGHM5iiTFPZLA==} + '@zoom-image/core@0.41.4': + resolution: {integrity: sha512-zUJNHWQzx8rmfNOlp2Rr0+n8I7QK9hLNThnusdtvz20/HN+J//RcDJmCuRDj6jUW/qJGh9FWR5sROMFBuPLPfQ==} - '@zoom-image/svelte@0.3.7': - resolution: {integrity: sha512-vCgA2ClH8J2JBTzpJEgzy03yTi5uJE0963cUjBwc5fi7q8g1wxbbj4/W7YHwQfDmdh9uqHxlX0VcmUQqV44d+w==} + '@zoom-image/svelte@0.3.8': + resolution: {integrity: sha512-rkXS+JS4qkBccmRK9+I5j+Pe4rp78GWK/7y0EduBJNtt38q+AwmKhhQs8oTMKTU6lOzLgxjXy1TI802mtvcAmw==} peerDependencies: svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -4982,9 +5166,9 @@ packages: abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -5125,8 +5309,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - ansis@4.1.0: - resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} any-promise@1.3.0: @@ -5222,8 +5406,8 @@ packages: autocomplete.js@0.37.1: resolution: {integrity: sha512-PgSe9fHYhZEsm/9jggbjtVsGXJkPLvd+9mC7gZJ662vVL5CRWEtm/mIrrzCx0MrNxHVwxD5d00UOn6NsmL2LUQ==} - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + autoprefixer@10.4.22: + resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -5270,16 +5454,16 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.8.1: - resolution: {integrity: sha512-oxSAxTS1hRfnyit2CL5QpAOS5ixfBjj6ex3yTNvXyY/kE719jQ/IjuESJBK2w5v4wwQRAHGseVJXx9QBYOtFGQ==} + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.5.0: - resolution: {integrity: sha512-GljgCjeupKZJNetTqxKaQArLK10vpmK28or0+RwWjEl5Rk+/xG3wkpmkv+WrcBm3q1BwHKlnhXzR8O37kcvkXQ==} + bare-fs@4.5.2: + resolution: {integrity: sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -5305,8 +5489,8 @@ packages: bare-events: optional: true - bare-url@2.3.1: - resolution: {integrity: sha512-v2yl0TnaZTdEnelkKtXZGnotiV6qATBlnNuUMrHl6v9Lmmrh9mw9RYyImPU7/4RahumSwQS1k2oKXcRfXcbjJw==} + bare-url@2.3.2: + resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5315,8 +5499,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.8.20: - resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==} + baseline-browser-mapping@2.8.31: + resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} hasBin: true batch-cluster@15.0.1: @@ -5343,8 +5527,8 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bits-ui@2.9.8: - resolution: {integrity: sha512-oVAqdhLSuGIgEiT0yu3ShSI7AxncCxX26Gv6Lul94BuKHV2uzHoKfIodtnMQSq+udJ54svuCIRqA58whsv7vaA==} + bits-ui@2.14.4: + resolution: {integrity: sha512-W6kenhnbd/YVvur+DKkaVJ6GldE53eLewur5AhUCqslYQ0vjZr8eWlOfwZnMiPB+PF5HMVqf61vXBvmyrAmPWg==} engines: {node: '>=20'} peerDependencies: '@internationalized/date': ^3.8.1 @@ -5353,12 +5537,12 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} bonjour-service@1.3.0: @@ -5367,8 +5551,8 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - bowser@2.12.1: - resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} + bowser@2.13.0: + resolution: {integrity: sha512-yHAbSRuT6LTeKi6k2aS40csueHqgAsFEgmrOsfRyFpJnFv5O2hl9FYmWEUZ97gZ/dG17U4IQQcTx4YAFYPuWRQ==} boxen@6.2.1: resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} @@ -5388,8 +5572,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.27.0: - resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -5409,16 +5593,16 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - buildcheck@0.0.6: - resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} + buildcheck@0.0.7: + resolution: {integrity: sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==} engines: {node: '>=10.0.0'} builtin-modules@5.0.0: resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} engines: {node: '>=18.20'} - bullmq@5.62.1: - resolution: {integrity: sha512-FiRxqSquGTf8W8l8OMczKfEFG0BEqJ5NzChwKZ4vbSpZSPFLSmmxXAQlW4imB1rZHnlc7sYq8o+Oy4JavoIEpQ==} + bullmq@5.65.0: + resolution: {integrity: sha512-fyOcyf2ad4zrNmE18vdF/ie7DrW0TwhLt5e0DkqDxbRpDNiUdYqgp2QZJW2ntnUN08T2mDMC4deUUhF2UOAmeQ==} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -5453,9 +5637,9 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - cacache@19.0.1: - resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} - engines: {node: ^18.17.0 || >=20.5.0} + cacache@20.0.3: + resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} + engines: {node: ^20.17.0 || >=22.9.0} cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} @@ -5503,8 +5687,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001751: - resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} canvas@2.11.2: resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} @@ -5544,8 +5728,8 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chardet@2.1.0: - resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} @@ -5585,8 +5769,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-info@4.3.0: - resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} engines: {node: '>=8'} citty@0.1.6: @@ -5598,8 +5782,8 @@ packages: class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - class-validator@0.14.2: - resolution: {integrity: sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==} + class-validator@0.14.3: + resolution: {integrity: sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==} clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} @@ -5799,9 +5983,9 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} @@ -5817,6 +6001,9 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -5825,16 +6012,12 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} cookiejar@2.1.4: @@ -6042,8 +6225,8 @@ packages: resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} engines: {node: '>=18'} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} @@ -6207,8 +6390,8 @@ packages: engines: {node: '>= 4.0.0'} hasBin: true - devalue@5.4.2: - resolution: {integrity: sha512-MwPZTKEPK2k8Qgfmqrd48ZKVvzSQjgW0lXLxiIBA8dQjtf/6mw6pggHNLcyDKyf+fI6eXxlQwPsfaCMTU5U+Bw==} + devalue@5.5.0: + resolution: {integrity: sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -6336,8 +6519,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.243: - resolution: {integrity: sha512-ZCphxFW3Q1TVhcgS9blfut1PX8lusVi2SvXQgmEEnK4TCmE1JhH2JkjJN+DNt0pJJwfBri5AROBnz2b/C+YU9g==} + electron-to-chromium@1.5.260: + resolution: {integrity: sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -6457,6 +6640,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.0: + resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6511,8 +6699,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-svelte@3.12.5: - resolution: {integrity: sha512-4KRG84eAHQfYd9OjZ1K7sCHy0nox+9KwT+s5WCCku3jTim5RV4tVENob274nCwIaApXsYPKAUAZFBxKZ3Wyfjw==} + eslint-plugin-svelte@3.13.0: + resolution: {integrity: sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 @@ -6521,17 +6709,11 @@ packages: svelte: optional: true - eslint-plugin-unicorn@60.0.0: - resolution: {integrity: sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==} + eslint-plugin-unicorn@62.0.0: + resolution: {integrity: sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: - eslint: '>=9.29.0' - - eslint-plugin-unicorn@61.0.2: - resolution: {integrity: sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==} - engines: {node: ^20.10.0 || >=21.0.0} - peerDependencies: - eslint: '>=9.29.0' + eslint: '>=9.38.0' eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} @@ -6549,8 +6731,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.38.0: - resolution: {integrity: sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==} + eslint@9.39.1: + resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -6579,8 +6761,8 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@2.1.0: - resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==} + esrap@2.2.0: + resolution: {integrity: sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -6666,17 +6848,17 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - exiftool-vendored.exe@13.41.0: - resolution: {integrity: sha512-7XG0PjZCm8HVsVUQAD4b/eBtvYBuGkySf2qslqHlnSR6jU1xoD1AgEprb2bCPqwhw0Jn3xzZoo/ihDo4F6fMyA==} + exiftool-vendored.exe@13.42.0: + resolution: {integrity: sha512-6AFybe5IakduMWleuQBfep9OWGSVZSedt2uKL+LzufRsATp+beOF7tZyKtMztjb6VRH1GF/4F9EvBVam6zm70w==} os: [win32] - exiftool-vendored.pl@13.41.0: - resolution: {integrity: sha512-JqqRuB8TggIOC983oTnOunB/baseGYw8XCkn7ylFGOmEv7oTQAK3uUTZV76vXE1X6c5H6IdHYt0abSgi8Kzc4g==} + exiftool-vendored.pl@13.42.0: + resolution: {integrity: sha512-EF5IdxQNIJIvZjHf4bG4jnwAHVVSLkYZToo2q+Mm89kSuppKfRvHz/lngIxN0JALE8rFdC4zt6NWY/PKqRdCcg==} os: ['!win32'] hasBin: true - exiftool-vendored@31.3.0: - resolution: {integrity: sha512-JQeyRvh7cV81fm9eKej2btdVh2z2Ak/sx89c4OCykeQnhnI81hk9TTraBtborYA+WcLM20cwYMPmpaW/sMy5Qw==} + exiftool-vendored@33.5.0: + resolution: {integrity: sha512-7cCh6izwdmC5ZaCxpHFehnExIr2Yp7CJuxHg4WFiGcm81yyxXLtvSE+85ep9VsNwhlOtSpk+XxiqrlddjY5lAw==} engines: {node: '>=20.0.0'} expect-type@1.2.1: @@ -6686,14 +6868,18 @@ packages: exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} engines: {node: '>= 0.10.0'} express@5.1.0: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} + express@5.2.0: + resolution: {integrity: sha512-XdpJDLxfztVY59X0zPI6sibRiGcxhTPXRD3IhJmjKf2jwMvkRGV1j7loB8U+heeamoU3XvihAaGRTR4aXXUN3A==} + engines: {node: '>= 18'} + exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} @@ -6707,8 +6893,8 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fabric@6.7.1: - resolution: {integrity: sha512-dLxSmIvN4InJf4xOjbl1LFWh8WGOUIYtcuDIGs2IN0Z9lI0zGobfesDauyEhI1+owMLTPCCiEv01rpYXm7g2EQ==} + fabric@6.9.0: + resolution: {integrity: sha512-ILIbG4Us/41Z4rU8/gveN4Hb7NvgBorqV9xj+9Dl7YsXiyUPXdxV8+q5OvaNghmYzQoK1Am3m0wTvmovOxrJAg==} engines: {node: '>=16.20.0'} factory.ts@1.4.2: @@ -6790,21 +6976,21 @@ packages: file-source@0.6.1: resolution: {integrity: sha512-1R1KneL7eTXmXfKxC10V/9NeGOdbsAXJ+lQ//fvvcHUgtaZcZDWNJNblxAoVOyV1cj45pOtUrR3vZTBwqcW8XA==} - file-type@21.0.0: - resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} + file-type@21.1.0: + resolution: {integrity: sha512-boU4EHmP3JXkwDo4uhyBhTt5pPstxB6eEXKJBu2yu2l7aAMMm7QQYQEzssJmKReZYrFdFOJS8koVo6bXIBGDqA==} engines: {node: '>=20'} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} find-cache-dir@4.0.0: resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} @@ -6866,8 +7052,8 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} format@0.2.2: @@ -6885,8 +7071,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -7014,8 +7200,8 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true glob@11.0.3: @@ -7023,6 +7209,10 @@ packages: engines: {node: 20 || >=22} hasBin: true + glob@13.0.0: + resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} + engines: {node: 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -7039,8 +7229,8 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.4.0: - resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -7267,6 +7457,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} @@ -7349,9 +7543,9 @@ packages: engines: {node: '>=16.x'} hasBin: true - imagetools-core@8.0.0: - resolution: {integrity: sha512-5i4Cx5vrBpVdvT3gvkSGAzzkUCrg/5Jm54UwWbDUSTMp4AjDI4IxiC6dI4+X1PRJYi6eKqWuE+684NJY2iOn3w==} - engines: {node: '>=18.0.0'} + imagetools-core@9.1.0: + resolution: {integrity: sha512-xQjs+2vrxLnAjCq+omuNkd5UQTld9/bP8+YT0LyYTlKfuSQtgUBvqhUwGugzSAh6sCdN+LnROMuLswn5hZ9Fhg==} + engines: {node: '>=20.0.0'} immediate@3.3.0: resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} @@ -7403,6 +7597,9 @@ packages: inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + inquirer@8.2.7: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} @@ -7688,12 +7885,12 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true jsdom@20.0.3: @@ -7714,11 +7911,6 @@ packages: canvas: optional: true - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -7844,8 +8036,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - libphonenumber-js@1.12.9: - resolution: {integrity: sha512-VWwAdNeJgN7jFOD+wN4qx83DTPMVPPAUyx9/TUkBXKLiNkuWWk6anV0439tgdtwaJDrEdqkvdN22iA6J4bUCZg==} + libphonenumber-js@1.12.31: + resolution: {integrity: sha512-Z3IhgVgrqO1S5xPYM3K5XwbkDasU67/Vys4heW+lfSBALcUZjeIIzI8zCLifY+OCzSq+fpDdywMDa7z+4srJPQ==} lightningcss-android-arm64@1.30.2: resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} @@ -8042,8 +8234,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.1: - resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -8083,16 +8275,16 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@14.0.3: - resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} - engines: {node: ^18.17.0 || >=20.5.0} + make-fetch-happen@15.0.3: + resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} + engines: {node: ^20.17.0 || >=22.9.0} mapbox-gl@1.13.3: resolution: {integrity: sha512-p8lJFEiqmEQlyv+DQxFAOG/XPWN0Wp7j/Psq93Zywz7qt9CcUKFYDBOoOEKzqe6gudHVJY8/Bhqw6VDpX2lSBg==} engines: {node: '>=6.4.0'} - maplibre-gl@5.10.0: - resolution: {integrity: sha512-eLhlX8Fnpaoo7+uGqggZmXmZld6WrbzOJUPB7G8JB8XpminlTnrQTtXilMHduR8fsNVxrzD8yRRqEoajONc8LQ==} + maplibre-gl@5.13.0: + resolution: {integrity: sha512-UsIVP34rZdM4TjrjhwBAhbC3HT7AzFx9p/draiAPlLr8/THozZF6WmJnZ9ck4q94uO55z7P7zoGCh+AZVoagsQ==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} mark.js@8.11.1: @@ -8366,9 +8558,9 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -8435,9 +8627,9 @@ packages: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} engines: {node: '>=16 || 14 >=14.17'} - minipass-fetch@4.0.1: - resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} - engines: {node: ^18.17.0 || >=20.5.0} + minipass-fetch@5.0.0: + resolution: {integrity: sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==} + engines: {node: ^20.17.0 || >=22.9.0} minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} @@ -8542,8 +8734,8 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.23.0: - resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} + nan@2.23.1: + resolution: {integrity: sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -8652,16 +8844,16 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@11.5.0: - resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} - engines: {node: ^18.17.0 || >=20.5.0} + node-gyp@12.1.0: + resolution: {integrity: sha512-W+RYA8jBnhSr2vrTtlPYPc1K+CSjGpVDRZxcqJcERZ8ND3A1ThWPHRwctTx3qC3oW99jt726jhdz3Y6ky87J4g==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.26: - resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - nodemailer@7.0.10: - resolution: {integrity: sha512-Us/Se1WtT0ylXgNFfyFSx4LElllVLJXQjWi2Xz17xWw7amDKO2MLtFnVp1WACy7GkVGs+oBlRopVNUzlrGSw1w==} + nodemailer@7.0.11: + resolution: {integrity: sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==} engines: {node: '>=6.0.0'} nopt@1.0.10: @@ -8673,9 +8865,9 @@ packages: engines: {node: '>=6'} hasBin: true - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true normalize-path@3.0.0: @@ -8838,8 +9030,8 @@ packages: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} - p-map@7.0.3: - resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} engines: {node: '>=18'} p-queue@6.6.2: @@ -8930,8 +9122,8 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} path-source@0.1.3: @@ -9035,13 +9227,13 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.56.1: - resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + playwright-core@1.57.0: + resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} engines: {node: '>=18'} hasBin: true - playwright@1.56.1: - resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} + playwright@1.57.0: + resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} engines: {node: '>=18'} hasBin: true @@ -9573,8 +9765,8 @@ packages: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.7.1: + resolution: {integrity: sha512-RWKXE4qB3u5Z6yz7omJkjWwmTfLdcbv44jUVHC5NpfXwFGzvpQM798FGv/6WNK879tc+Cn0AAyherCl1KjbyZQ==} engines: {node: '>=14'} hasBin: true @@ -9598,9 +9790,9 @@ packages: resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} - proc-log@5.0.0: - resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} - engines: {node: ^18.17.0 || >=20.5.0} + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -9672,10 +9864,6 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -9718,12 +9906,12 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} raw-loader@4.0.2: @@ -9880,10 +10068,6 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} - hasBin: true - regjsparser@0.13.0: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true @@ -10025,8 +10209,8 @@ packages: rollup: optional: true - rollup@4.52.5: - resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -10053,10 +10237,14 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - runed@0.29.2: - resolution: {integrity: sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==} + runed@0.35.1: + resolution: {integrity: sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==} peerDependencies: + '@sveltejs/kit': ^2.21.0 svelte: ^5.7.0 + peerDependenciesMeta: + '@sveltejs/kit': + optional: true rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} @@ -10144,6 +10332,10 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + send@0.19.1: + resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} + engines: {node: '>= 0.8.0'} + send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -10193,8 +10385,8 @@ packages: resolution: {integrity: sha512-rLGSWeK2ufzCVx05wYd+xrWnOOdSV7xNUW5/XFgx3Bc02hBkpMlrd2F1dDII7/jhWzv0MSyBFh5uJIy9hLdfuw==} hasBin: true - sharp@0.34.4: - resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -10241,8 +10433,8 @@ packages: simple-get@3.1.1: resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} - simple-icons@15.18.0: - resolution: {integrity: sha512-lYpvaIuZZr6N50YSdYZQzrKccSSF3dqcgcoz2vMKVQCc/fJWD8nFszJVZz2tCDTSu082rqRYfuYRUPhjdixDAA==} + simple-icons@15.22.0: + resolution: {integrity: sha512-i/w5Ie4tENfGYbdCo2iJ+oies0vOFd8QXWHopKOUzudfLCvnmeheF2PpHp89Z2azpc+c2su3lMiWO/SpP+429A==} engines: {node: '>=0.12.18'} sirv@2.0.4: @@ -10370,9 +10562,9 @@ packages: resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==} engines: {node: '>=10.16.0'} - ssri@12.0.0: - resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} - engines: {node: ^18.17.0 || >=20.5.0} + ssri@13.0.0: + resolution: {integrity: sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==} + engines: {node: ^20.17.0 || >=22.9.0} stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -10458,8 +10650,8 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} - strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} engines: {node: '>=12'} strip-json-comments@2.0.1: @@ -10486,14 +10678,17 @@ packages: style-to-object@1.0.11: resolution: {integrity: sha512-5A560JmXr7wDyGLK12Nq/EYS38VkGlglVzkis1JEdbGWSnbQIEhZzTJhzURXN5/8WwwFCs/f/VVcmkTppbXLow==} + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + stylehacks@6.1.1: resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -10523,8 +10718,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.3.3: - resolution: {integrity: sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==} + svelte-check@4.3.4: + resolution: {integrity: sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -10543,8 +10738,8 @@ packages: svelte-gestures@5.2.2: resolution: {integrity: sha512-Y+chXPaSx8OsPoFppUwPk8PJzgrZ7xoDJKXeiEc7JBqyKKzXer9hlf8F9O34eFuAWB4/WQEvccACvyBplESL7A==} - svelte-highlight@7.8.4: - resolution: {integrity: sha512-aVp+Q0hH9kI7PlSDrklmFTF4Uj7wYj7UGuqkREnkXlqpEffxr2g6esZcMMaTgECdg5rb2mJqM88+nwS10ecoTg==} + svelte-highlight@7.9.0: + resolution: {integrity: sha512-226LBTtvTnM2L2JkQq8mZeKEeMfPLYyta7VxZatFT4UPX5zdHEerKeMTvrfbxm7MVTWc7TPThsNoVdhWC177KQ==} svelte-i18n@4.0.1: resolution: {integrity: sha512-jaykGlGT5PUaaq04JWbJREvivlCnALtT+m87Kbm0fxyYHynkQaxQMnIKHLm2WeIuBRoljzwgyvz0Z6/CMwfdmQ==} @@ -10579,14 +10774,14 @@ packages: peerDependencies: svelte: ^3.48.0 || ^4 || ^5 - svelte-toolbelt@0.9.3: - resolution: {integrity: sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==} + svelte-toolbelt@0.10.6: + resolution: {integrity: sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==} engines: {node: '>=18', pnpm: '>=8.7.0'} peerDependencies: svelte: ^5.30.2 - svelte@5.43.0: - resolution: {integrity: sha512-1sRxVbgJAB+UGzwkc3GUoiBSzEOf0jqzccMaVoI2+pI+kASUe9qubslxace8+Mzhqw19k4syTA5niCIJwfXpOA==} + svelte@5.45.2: + resolution: {integrity: sha512-yyXdW2u3H0H/zxxWoGwJoQlRgaSJLp+Vhktv12iRw2WRDlKqUPT54Fi0K/PkXqrdkcQ98aBazpy0AH4BCBVfoA==} engines: {node: '>=18'} svg-parser@2.0.4: @@ -10597,8 +10792,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - swagger-ui-dist@5.29.4: - resolution: {integrity: sha512-gJFDz/gyLOCQtWwAgqs6Rk78z9ONnqTnlW11gimG9nLap8drKa3AJBKpzIQMIjl5PD2Ix+Tn+mc/tfoT2tgsng==} + swagger-ui-dist@5.30.2: + resolution: {integrity: sha512-HWCg1DTNE/Nmapt+0m2EPXFwNKNeKK4PwMjkwveN/zn1cV2Kxi9SURd+m0SpdcSgWEK/O64sf8bzXdtUhigtHA==} swr@2.3.6: resolution: {integrity: sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==} @@ -10625,11 +10820,11 @@ packages: tabbable@6.3.0: resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} - tailwind-variants@3.1.1: - resolution: {integrity: sha512-ftLXe3krnqkMHsuBTEmaVUXYovXtPyTK7ckEfDRXS8PBZx0bAUas+A0jYxuKA5b8qg++wvQ3d2MQ7l/xeZxbZQ==} + tailwind-variants@3.2.2: + resolution: {integrity: sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==} engines: {node: '>=16.x', pnpm: '>=7.x'} peerDependencies: tailwind-merge: '>=3.0.0' @@ -10660,8 +10855,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tailwindcss@4.1.16: - resolution: {integrity: sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==} + tailwindcss@4.1.17: + resolution: {integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==} tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} @@ -10684,8 +10879,8 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} - tar@7.5.1: - resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==} + tar@7.5.2: + resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} engines: {node: '>=18'} terser-webpack-plugin@5.3.14: @@ -10713,8 +10908,8 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} - testcontainers@11.7.2: - resolution: {integrity: sha512-jeFzeyzLhIouRAbLnQNapJ2esBs/mvXkkYvO1/vSZehT3/7+Q557qaNxwKwMqAbfxfSh7gcx1OLlMsQUZ9JLdA==} + testcontainers@11.9.0: + resolution: {integrity: sha512-SQ6OqQUig7HcGVF72i+ZVIMvxPSpEz8cgC/B63ekqMzgf98DnveoBbOmqux/Wa5wQAQCt4mEPNMa/Jz7vMg9fQ==} text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} @@ -10851,10 +11046,6 @@ packages: peerDependencies: tslib: '2' - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -10937,18 +11128,13 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.46.2: - resolution: {integrity: sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==} + typescript-eslint@8.48.0: + resolution: {integrity: sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -11017,13 +11203,13 @@ packages: unified@9.2.2: resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - unique-filename@4.0.0: - resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} - engines: {node: ^18.17.0 || >=20.5.0} + unique-filename@5.0.0: + resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} + engines: {node: ^20.17.0 || >=22.9.0} - unique-slug@5.0.0: - resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} - engines: {node: ^18.17.0 || >=20.5.0} + unique-slug@6.0.0: + resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} + engines: {node: ^20.17.0 || >=22.9.0} unique-string@3.0.0: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} @@ -11074,13 +11260,13 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin-swc@1.5.8: - resolution: {integrity: sha512-6qVAQsCn/AMFiw7XGXkNC/q/Or4OpL0zRPertzLT1BoigjOQp0ktPxDWY4lc51FGwVbzW4V1BURaal1rpbJwSg==} + unplugin-swc@1.5.9: + resolution: {integrity: sha512-RKwK3yf0M+MN17xZfF14bdKqfx0zMXYdtOdxLiE6jHAoidupKq3jGdJYANyIM1X/VmABhh1WpdO+/f4+Ol89+g==} peerDependencies: '@swc/core': ^1.2.108 - unplugin@2.3.10: - resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} update-browserslist-db@1.1.4: @@ -11093,6 +11279,9 @@ packages: resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} engines: {node: '>=14.16'} + uplot@1.6.32: + resolution: {integrity: sha512-KIMVnG68zvu5XXUbC4LQEPnhwOxBuLyW1AHtpm6IKTXImkbLgkMy+jabjLgSLMasNuGGzQm/ep3tOkyTxpiQIw==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -11154,8 +11343,8 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - validator@13.15.20: - resolution: {integrity: sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==} + validator@13.15.23: + resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==} engines: {node: '>= 0.10'} value-equal@1.0.1: @@ -11183,9 +11372,9 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-imagetools@8.0.0: - resolution: {integrity: sha512-3bkkA0vQ57tMynsetY2j4QhCnZKrxFv0RScaZipzYgkjkkUBEmZL5UIVHOUHhVMfwCetAeM9e3DNwyPK1ff4xg==} - engines: {node: '>=18.0.0'} + vite-imagetools@9.0.2: + resolution: {integrity: sha512-FV5DXw4swU81t+g8JOLT+T7gKuBOXuVsZ0WGhi7y0R182+GfBYkcf6V9/T0Nweu/vn1X0DA2p5ePMnaGZlRl1A==} + engines: {node: '>=20.0.0'} vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} @@ -11200,8 +11389,8 @@ packages: vite: optional: true - vite@7.1.12: - resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} + vite@7.2.4: + resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -11362,18 +11551,8 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - webpack@5.100.2: - resolution: {integrity: sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - - webpack@5.102.1: - resolution: {integrity: sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==} + webpack@5.103.0: + resolution: {integrity: sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -11435,9 +11614,9 @@ packages: engines: {node: '>= 8'} hasBin: true - which@5.0.0: - resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} - engines: {node: ^18.17.0 || >=20.5.0} + which@6.0.0: + resolution: {integrity: sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true why-is-node-running@2.3.0: @@ -11568,8 +11747,8 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true @@ -11593,12 +11772,12 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.1: - resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} yoctocolors@2.1.2: @@ -11768,17 +11947,6 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular-devkit/core@19.2.15(chokidar@4.0.3)': - dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - jsonc-parser: 3.3.1 - picomatch: 4.0.2 - rxjs: 7.8.1 - source-map: 0.7.4 - optionalDependencies: - chokidar: 4.0.3 - '@angular-devkit/core@19.2.17(chokidar@4.0.3)': dependencies: ajv: 8.17.1 @@ -11790,11 +11958,22 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.15(@types/node@22.19.0)(chokidar@4.0.3)': + '@angular-devkit/core@19.2.19(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.15(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) - '@inquirer/prompts': 7.3.2(@types/node@22.19.0) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + jsonc-parser: 3.3.1 + picomatch: 4.0.2 + rxjs: 7.8.1 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@angular-devkit/schematics-cli@19.2.19(@types/node@24.10.1)(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.19(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.19(chokidar@4.0.3) + '@inquirer/prompts': 7.3.2(@types/node@24.10.1) ansi-colors: 4.1.3 symbol-observable: 4.0.0 yargs-parser: 21.1.1 @@ -11802,9 +11981,9 @@ snapshots: - '@types/node' - chokidar - '@angular-devkit/schematics@19.2.15(chokidar@4.0.3)': + '@angular-devkit/schematics@19.2.17(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.15(chokidar@4.0.3) + '@angular-devkit/core': 19.2.17(chokidar@4.0.3) jsonc-parser: 3.3.1 magic-string: 0.30.17 ora: 5.4.1 @@ -11812,9 +11991,9 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/schematics@19.2.17(chokidar@4.0.3)': + '@angular-devkit/schematics@19.2.19(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.17(chokidar@4.0.3) + '@angular-devkit/core': 19.2.19(chokidar@4.0.3) jsonc-parser: 3.3.1 magic-string: 0.30.17 ora: 5.4.1 @@ -11836,7 +12015,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-locate-window': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -11844,7 +12023,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.936.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -11853,366 +12032,381 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.936.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-sesv2@3.919.0': + '@aws-sdk/client-sesv2@3.939.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/credential-provider-node': 3.919.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.919.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/signature-v4-multi-region': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/credential-provider-node': 3.939.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.936.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/signature-v4-multi-region': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.936.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.919.0': + '@aws-sdk/client-sso@3.936.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.919.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.936.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.936.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.916.0': + '@aws-sdk/core@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@aws-sdk/xml-builder': 3.914.0 - '@smithy/core': 3.17.1 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/xml-builder': 3.930.0 + '@smithy/core': 3.18.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.916.0': + '@aws-sdk/credential-provider-env@3.936.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.916.0': + '@aws-sdk/credential-provider-http@3.936.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.4 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.919.0': + '@aws-sdk/credential-provider-ini@3.939.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/credential-provider-env': 3.916.0 - '@aws-sdk/credential-provider-http': 3.916.0 - '@aws-sdk/credential-provider-process': 3.916.0 - '@aws-sdk/credential-provider-sso': 3.919.0 - '@aws-sdk/credential-provider-web-identity': 3.919.0 - '@aws-sdk/nested-clients': 3.919.0 - '@aws-sdk/types': 3.914.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/credential-provider-env': 3.936.0 + '@aws-sdk/credential-provider-http': 3.936.0 + '@aws-sdk/credential-provider-login': 3.939.0 + '@aws-sdk/credential-provider-process': 3.936.0 + '@aws-sdk/credential-provider-sso': 3.939.0 + '@aws-sdk/credential-provider-web-identity': 3.939.0 + '@aws-sdk/nested-clients': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.919.0': + '@aws-sdk/credential-provider-login@3.939.0': dependencies: - '@aws-sdk/credential-provider-env': 3.916.0 - '@aws-sdk/credential-provider-http': 3.916.0 - '@aws-sdk/credential-provider-ini': 3.919.0 - '@aws-sdk/credential-provider-process': 3.916.0 - '@aws-sdk/credential-provider-sso': 3.919.0 - '@aws-sdk/credential-provider-web-identity': 3.919.0 - '@aws-sdk/types': 3.914.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/nested-clients': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.916.0': + '@aws-sdk/credential-provider-node@3.939.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-sso@3.919.0': - dependencies: - '@aws-sdk/client-sso': 3.919.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/token-providers': 3.919.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/credential-provider-env': 3.936.0 + '@aws-sdk/credential-provider-http': 3.936.0 + '@aws-sdk/credential-provider-ini': 3.939.0 + '@aws-sdk/credential-provider-process': 3.936.0 + '@aws-sdk/credential-provider-sso': 3.939.0 + '@aws-sdk/credential-provider-web-identity': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.919.0': + '@aws-sdk/credential-provider-process@3.936.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/nested-clients': 3.919.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.939.0': + dependencies: + '@aws-sdk/client-sso': 3.936.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/token-providers': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/middleware-host-header@3.914.0': + '@aws-sdk/credential-provider-web-identity@3.939.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/nested-clients': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/middleware-host-header@3.936.0': + dependencies: + '@aws-sdk/types': 3.936.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.914.0': + '@aws-sdk/middleware-logger@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.936.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.919.0': + '@aws-sdk/middleware-recursion-detection@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@aws/lambda-invoke-store': 0.1.1 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.936.0 + '@aws/lambda-invoke-store': 0.2.1 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.916.0': + '@aws-sdk/middleware-sdk-s3@3.939.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-arn-parser': 3.893.0 - '@smithy/core': 3.17.1 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.916.0': + '@aws-sdk/middleware-user-agent@3.936.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@smithy/core': 3.17.1 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@smithy/core': 3.18.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.919.0': + '@aws-sdk/nested-clients@3.939.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.919.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.936.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.936.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.914.0': + '@aws-sdk/region-config-resolver@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.936.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.916.0': + '@aws-sdk/signature-v4-multi-region@3.939.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/middleware-sdk-s3': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.919.0': + '@aws-sdk/token-providers@3.939.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/nested-clients': 3.919.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.936.0 + '@aws-sdk/nested-clients': 3.939.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.914.0': + '@aws-sdk/types@3.936.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/util-arn-parser@3.893.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.916.0': + '@aws-sdk/util-endpoints@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-endpoints': 3.2.3 + '@aws-sdk/types': 3.936.0 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-endpoints': 3.2.5 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.893.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.914.0': + '@aws-sdk/util-user-agent-browser@3.936.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 - bowser: 2.12.1 + '@aws-sdk/types': 3.936.0 + '@smithy/types': 4.9.0 + bowser: 2.13.0 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.916.0': + '@aws-sdk/util-user-agent-node@3.936.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/middleware-user-agent': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.914.0': + '@aws-sdk/xml-builder@3.930.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 fast-xml-parser: 5.2.5 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.1.1': {} + '@aws/lambda-invoke-store@0.2.1': {} '@babel/code-frame@7.27.1': dependencies: @@ -12258,7 +12452,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.27.0 + browserslist: 4.28.0 lru-cache: 5.1.1 semver: 6.3.1 @@ -13268,7 +13462,7 @@ snapshots: '@docsearch/css@4.2.0': {} - '@docsearch/react@4.2.0(@algolia/client-search@5.41.0)(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/react@4.2.0(@algolia/client-search@5.41.0)(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': dependencies: '@ai-sdk/react': 2.0.82(react@18.3.1)(zod@4.1.12) '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)(search-insights@2.17.3) @@ -13278,7 +13472,7 @@ snapshots: marked: 16.4.1 zod: 4.1.12 optionalDependencies: - '@types/react': 19.2.2 + '@types/react': 19.2.7 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) search-insights: 2.17.3 @@ -13319,24 +13513,24 @@ snapshots: '@docusaurus/logger': 3.9.2 '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.102.1) + babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.103.0) clean-css: 5.3.3 - copy-webpack-plugin: 11.0.0(webpack@5.102.1) - css-loader: 6.11.0(webpack@5.102.1) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.102.1) + copy-webpack-plugin: 11.0.0(webpack@5.103.0) + css-loader: 6.11.0(webpack@5.103.0) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.103.0) cssnano: 6.1.2(postcss@8.5.6) - file-loader: 6.2.0(webpack@5.102.1) + file-loader: 6.2.0(webpack@5.103.0) html-minifier-terser: 7.2.0 - mini-css-extract-plugin: 2.9.4(webpack@5.102.1) - null-loader: 4.0.1(webpack@5.102.1) + mini-css-extract-plugin: 2.9.4(webpack@5.103.0) + null-loader: 4.0.1(webpack@5.103.0) postcss: 8.5.6 - postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.9.3)(webpack@5.102.1) + postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.9.3)(webpack@5.103.0) postcss-preset-env: 10.4.0(postcss@8.5.6) - terser-webpack-plugin: 5.3.14(webpack@5.102.1) + terser-webpack-plugin: 5.3.14(webpack@5.103.0) tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) - webpack: 5.102.1 - webpackbar: 6.0.1(webpack@5.102.1) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) + webpack: 5.103.0 + webpackbar: 6.0.1(webpack@5.103.0) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -13352,7 +13546,7 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/bundler': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) @@ -13361,7 +13555,7 @@ snapshots: '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mdx-js/react': 3.1.1(@types/react@19.2.2)(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@18.3.1) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -13376,7 +13570,7 @@ snapshots: execa: 5.1.1 fs-extra: 11.3.2 html-tags: 3.3.1 - html-webpack-plugin: 5.6.4(webpack@5.102.1) + html-webpack-plugin: 5.6.4(webpack@5.103.0) leven: 3.1.0 lodash: 4.17.21 open: 8.4.2 @@ -13386,7 +13580,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.102.1) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.103.0) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) @@ -13395,9 +13589,9 @@ snapshots: tinypool: 1.1.1 tslib: 2.8.1 update-notifier: 6.0.2 - webpack: 5.102.1 + webpack: 5.103.0 webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 5.2.2(webpack@5.102.1) + webpack-dev-server: 5.2.2(webpack@5.103.0) webpack-merge: 6.0.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -13437,7 +13631,7 @@ snapshots: '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.5.0 - file-loader: 6.2.0(webpack@5.102.1) + file-loader: 6.2.0(webpack@5.103.0) fs-extra: 11.3.2 image-size: 2.0.2 mdast-util-mdx: 3.0.0 @@ -13453,9 +13647,9 @@ snapshots: tslib: 2.8.1 unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) vfile: 6.0.3 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@swc/core' - esbuild @@ -13467,7 +13661,7 @@ snapshots: dependencies: '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 - '@types/react': 19.2.2 + '@types/react': 19.2.7 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 react: 18.3.1 @@ -13481,13 +13675,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13503,7 +13697,7 @@ snapshots: tslib: 2.8.1 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -13522,13 +13716,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13536,14 +13730,14 @@ snapshots: '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.2 - js-yaml: 4.1.0 + js-yaml: 4.1.1 lodash: 4.17.21 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -13562,9 +13756,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13573,7 +13767,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -13592,9 +13786,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13619,9 +13813,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 @@ -13647,9 +13841,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -13673,9 +13867,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/gtag.js': 0.0.12 @@ -13700,9 +13894,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -13726,9 +13920,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13757,9 +13951,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13768,7 +13962,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' @@ -13787,22 +13981,22 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -13829,25 +14023,25 @@ snapshots: '@docusaurus/react-loadable@6.0.0(react@18.3.1)': dependencies: - '@types/react': 19.2.2 + '@types/react': 19.2.7 react: 18.3.1 - '@docusaurus/theme-classic@3.9.2(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/theme-classic@3.9.2(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.9.2 '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mdx-js/react': 3.1.1(@types/react@19.2.2)(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@18.3.1) clsx: 2.1.1 infima: 0.2.0-alpha.45 lodash: 4.17.21 @@ -13879,15 +14073,15 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 - '@types/react': 19.2.2 + '@types/react': 19.2.7 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 @@ -13903,13 +14097,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': dependencies: - '@docsearch/react': 4.2.0(@algolia/client-search@5.41.0)(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docsearch/react': 4.2.0(@algolia/client-search@5.41.0)(@types/react@19.2.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.9.2 '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13956,14 +14150,14 @@ snapshots: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 '@types/mdast': 4.0.4 - '@types/react': 19.2.2 + '@types/react': 19.2.7 commander: 5.1.0 joi: 17.13.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' utility-types: 3.11.0 - webpack: 5.102.1 + webpack: 5.103.0 webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -13992,7 +14186,7 @@ snapshots: '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 joi: 17.13.3 - js-yaml: 4.1.0 + js-yaml: 4.1.1 lodash: 4.17.21 tslib: 2.8.1 transitivePeerDependencies: @@ -14011,22 +14205,22 @@ snapshots: '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) escape-string-regexp: 4.0.0 execa: 5.1.1 - file-loader: 6.2.0(webpack@5.102.1) + file-loader: 6.2.0(webpack@5.103.0) fs-extra: 11.3.2 github-slugger: 1.5.0 globby: 11.1.0 gray-matter: 4.0.3 jiti: 1.21.7 - js-yaml: 4.1.0 + js-yaml: 4.1.1 lodash: 4.17.21 micromatch: 4.0.8 p-queue: 6.6.2 prompts: 2.4.2 resolve-pathname: 3.0.0 tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) utility-types: 3.11.0 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - '@swc/core' - esbuild @@ -14036,7 +14230,7 @@ snapshots: - uglify-js - webpack-cli - '@emnapi/runtime@1.5.0': + '@emnapi/runtime@1.7.1': dependencies: tslib: 2.8.1 optional: true @@ -14047,150 +14241,228 @@ snapshots: '@esbuild/aix-ppc64@0.25.12': optional: true + '@esbuild/aix-ppc64@0.27.0': + optional: true + '@esbuild/android-arm64@0.19.12': optional: true '@esbuild/android-arm64@0.25.12': optional: true + '@esbuild/android-arm64@0.27.0': + optional: true + '@esbuild/android-arm@0.19.12': optional: true '@esbuild/android-arm@0.25.12': optional: true + '@esbuild/android-arm@0.27.0': + optional: true + '@esbuild/android-x64@0.19.12': optional: true '@esbuild/android-x64@0.25.12': optional: true + '@esbuild/android-x64@0.27.0': + optional: true + '@esbuild/darwin-arm64@0.19.12': optional: true '@esbuild/darwin-arm64@0.25.12': optional: true + '@esbuild/darwin-arm64@0.27.0': + optional: true + '@esbuild/darwin-x64@0.19.12': optional: true '@esbuild/darwin-x64@0.25.12': optional: true + '@esbuild/darwin-x64@0.27.0': + optional: true + '@esbuild/freebsd-arm64@0.19.12': optional: true '@esbuild/freebsd-arm64@0.25.12': optional: true + '@esbuild/freebsd-arm64@0.27.0': + optional: true + '@esbuild/freebsd-x64@0.19.12': optional: true '@esbuild/freebsd-x64@0.25.12': optional: true + '@esbuild/freebsd-x64@0.27.0': + optional: true + '@esbuild/linux-arm64@0.19.12': optional: true '@esbuild/linux-arm64@0.25.12': optional: true + '@esbuild/linux-arm64@0.27.0': + optional: true + '@esbuild/linux-arm@0.19.12': optional: true '@esbuild/linux-arm@0.25.12': optional: true + '@esbuild/linux-arm@0.27.0': + optional: true + '@esbuild/linux-ia32@0.19.12': optional: true '@esbuild/linux-ia32@0.25.12': optional: true + '@esbuild/linux-ia32@0.27.0': + optional: true + '@esbuild/linux-loong64@0.19.12': optional: true '@esbuild/linux-loong64@0.25.12': optional: true + '@esbuild/linux-loong64@0.27.0': + optional: true + '@esbuild/linux-mips64el@0.19.12': optional: true '@esbuild/linux-mips64el@0.25.12': optional: true + '@esbuild/linux-mips64el@0.27.0': + optional: true + '@esbuild/linux-ppc64@0.19.12': optional: true '@esbuild/linux-ppc64@0.25.12': optional: true + '@esbuild/linux-ppc64@0.27.0': + optional: true + '@esbuild/linux-riscv64@0.19.12': optional: true '@esbuild/linux-riscv64@0.25.12': optional: true + '@esbuild/linux-riscv64@0.27.0': + optional: true + '@esbuild/linux-s390x@0.19.12': optional: true '@esbuild/linux-s390x@0.25.12': optional: true + '@esbuild/linux-s390x@0.27.0': + optional: true + '@esbuild/linux-x64@0.19.12': optional: true '@esbuild/linux-x64@0.25.12': optional: true + '@esbuild/linux-x64@0.27.0': + optional: true + '@esbuild/netbsd-arm64@0.25.12': optional: true + '@esbuild/netbsd-arm64@0.27.0': + optional: true + '@esbuild/netbsd-x64@0.19.12': optional: true '@esbuild/netbsd-x64@0.25.12': optional: true + '@esbuild/netbsd-x64@0.27.0': + optional: true + '@esbuild/openbsd-arm64@0.25.12': optional: true + '@esbuild/openbsd-arm64@0.27.0': + optional: true + '@esbuild/openbsd-x64@0.19.12': optional: true '@esbuild/openbsd-x64@0.25.12': optional: true + '@esbuild/openbsd-x64@0.27.0': + optional: true + '@esbuild/openharmony-arm64@0.25.12': optional: true + '@esbuild/openharmony-arm64@0.27.0': + optional: true + '@esbuild/sunos-x64@0.19.12': optional: true '@esbuild/sunos-x64@0.25.12': optional: true + '@esbuild/sunos-x64@0.27.0': + optional: true + '@esbuild/win32-arm64@0.19.12': optional: true '@esbuild/win32-arm64@0.25.12': optional: true + '@esbuild/win32-arm64@0.27.0': + optional: true + '@esbuild/win32-ia32@0.19.12': optional: true '@esbuild/win32-ia32@0.25.12': optional: true + '@esbuild/win32-ia32@0.27.0': + optional: true + '@esbuild/win32-x64@0.19.12': optional: true '@esbuild/win32-x64@0.25.12': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.38.0(jiti@2.6.1))': + '@esbuild/win32-x64@0.27.0': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))': dependencies: - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -14203,15 +14475,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.4.1': + '@eslint/config-helpers@0.4.2': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 - '@eslint/core@0.15.2': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/core@0.16.0': + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 @@ -14223,24 +14491,19 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.38.0': {} + '@eslint/js@9.39.1': {} '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.5': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.15.2 - levn: 0.4.1 - - '@eslint/plugin-kit@0.4.0': - dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 levn: 0.4.1 '@extism/extism@2.0.0-rc13': {} @@ -14254,7 +14517,7 @@ snapshots: '@fig/complete-commander@3.2.0(commander@11.1.0)': dependencies: commander: 11.1.0 - prettier: 3.6.2 + prettier: 3.7.1 '@floating-ui/core@1.7.3': dependencies: @@ -14293,13 +14556,13 @@ snapshots: dependencies: tslib: 2.8.1 - '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)': + '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) lodash: 4.17.21 - '@grpc/grpc-js@1.14.0': + '@grpc/grpc-js@1.14.2': dependencies: '@grpc/proto-loader': 0.8.0 '@js-sdsl/ordered-map': 4.4.2 @@ -14337,252 +14600,263 @@ snapshots: '@img/colour@1.0.0': {} - '@img/sharp-darwin-arm64@0.34.4': + '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.3 + '@img/sharp-libvips-darwin-arm64': 1.2.4 optional: true - '@img/sharp-darwin-x64@0.34.4': + '@img/sharp-darwin-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.3 + '@img/sharp-libvips-darwin-x64': 1.2.4 optional: true - '@img/sharp-libvips-darwin-arm64@1.2.3': + '@img/sharp-libvips-darwin-arm64@1.2.4': optional: true - '@img/sharp-libvips-darwin-x64@1.2.3': + '@img/sharp-libvips-darwin-x64@1.2.4': optional: true - '@img/sharp-libvips-linux-arm64@1.2.3': + '@img/sharp-libvips-linux-arm64@1.2.4': optional: true - '@img/sharp-libvips-linux-arm@1.2.3': + '@img/sharp-libvips-linux-arm@1.2.4': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.3': + '@img/sharp-libvips-linux-ppc64@1.2.4': optional: true - '@img/sharp-libvips-linux-s390x@1.2.3': + '@img/sharp-libvips-linux-riscv64@1.2.4': optional: true - '@img/sharp-libvips-linux-x64@1.2.3': + '@img/sharp-libvips-linux-s390x@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': + '@img/sharp-libvips-linux-x64@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.3': + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': optional: true - '@img/sharp-linux-arm64@0.34.4': + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.3 + '@img/sharp-libvips-linux-arm64': 1.2.4 optional: true - '@img/sharp-linux-arm@0.34.4': + '@img/sharp-linux-arm@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.3 + '@img/sharp-libvips-linux-arm': 1.2.4 optional: true - '@img/sharp-linux-ppc64@0.34.4': + '@img/sharp-linux-ppc64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.3 + '@img/sharp-libvips-linux-ppc64': 1.2.4 optional: true - '@img/sharp-linux-s390x@0.34.4': + '@img/sharp-linux-riscv64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.3 + '@img/sharp-libvips-linux-riscv64': 1.2.4 optional: true - '@img/sharp-linux-x64@0.34.4': + '@img/sharp-linux-s390x@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.3 + '@img/sharp-libvips-linux-s390x': 1.2.4 optional: true - '@img/sharp-linuxmusl-arm64@0.34.4': + '@img/sharp-linux-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 + '@img/sharp-libvips-linux-x64': 1.2.4 optional: true - '@img/sharp-linuxmusl-x64@0.34.4': + '@img/sharp-linuxmusl-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 optional: true - '@img/sharp-wasm32@0.34.4': + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.5.0 + '@emnapi/runtime': 1.7.1 optional: true - '@img/sharp-win32-arm64@0.34.4': + '@img/sharp-win32-arm64@0.34.5': optional: true - '@img/sharp-win32-ia32@0.34.4': + '@img/sharp-win32-ia32@0.34.5': optional: true - '@img/sharp-win32-x64@0.34.4': + '@img/sharp-win32-x64@0.34.5': optional: true '@immich/justified-layout-wasm@0.4.3': {} - '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.43.0)': + '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.45.2)': dependencies: - svelte: 5.43.0 + svelte: 5.45.2 - '@immich/ui@0.43.0(@internationalized/date@3.8.2)(svelte@5.43.0)': + '@immich/ui@0.49.3(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)': dependencies: - '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.43.0) + '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.45.2) + '@internationalized/date': 3.10.0 '@mdi/js': 7.4.47 - bits-ui: 2.9.8(@internationalized/date@3.8.2)(svelte@5.43.0) + bits-ui: 2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2) luxon: 3.7.2 - simple-icons: 15.18.0 - svelte: 5.43.0 - svelte-highlight: 7.8.4 - tailwind-merge: 3.3.1 - tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.16) - tailwindcss: 4.1.16 + simple-icons: 15.22.0 + svelte: 5.45.2 + svelte-highlight: 7.9.0 + tailwind-merge: 3.4.0 + tailwind-variants: 3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.17) + tailwindcss: 4.1.17 transitivePeerDependencies: - - '@internationalized/date' + - '@sveltejs/kit' - '@inquirer/checkbox@4.2.1(@types/node@22.19.0)': + '@inquirer/ansi@1.0.2': {} + + '@inquirer/checkbox@4.3.2(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.19.0) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.10.1) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/confirm@5.1.15(@types/node@22.19.0)': + '@inquirer/confirm@5.1.21(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/core@10.1.15(@types/node@22.19.0)': + '@inquirer/core@10.3.2(@types/node@24.10.1)': dependencies: - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.19.0) - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.10.1) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/editor@4.2.17(@types/node@22.19.0)': + '@inquirer/editor@4.2.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/external-editor': 1.0.2(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/external-editor': 1.0.3(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/expand@4.0.17(@types/node@22.19.0)': + '@inquirer/expand@4.0.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/external-editor@1.0.2(@types/node@22.19.0)': + '@inquirer/external-editor@1.0.3(@types/node@24.10.1)': dependencies: - chardet: 2.1.0 + chardet: 2.1.1 iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/figures@1.0.13': {} + '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.2.1(@types/node@22.19.0)': + '@inquirer/input@4.3.1(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/number@3.0.17(@types/node@22.19.0)': + '@inquirer/number@3.0.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/password@4.0.17(@types/node@22.19.0)': + '@inquirer/password@4.0.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/prompts@7.3.2(@types/node@22.19.0)': + '@inquirer/prompts@7.10.1(@types/node@24.10.1)': dependencies: - '@inquirer/checkbox': 4.2.1(@types/node@22.19.0) - '@inquirer/confirm': 5.1.15(@types/node@22.19.0) - '@inquirer/editor': 4.2.17(@types/node@22.19.0) - '@inquirer/expand': 4.0.17(@types/node@22.19.0) - '@inquirer/input': 4.2.1(@types/node@22.19.0) - '@inquirer/number': 3.0.17(@types/node@22.19.0) - '@inquirer/password': 4.0.17(@types/node@22.19.0) - '@inquirer/rawlist': 4.1.5(@types/node@22.19.0) - '@inquirer/search': 3.1.0(@types/node@22.19.0) - '@inquirer/select': 4.3.1(@types/node@22.19.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.10.1) + '@inquirer/confirm': 5.1.21(@types/node@24.10.1) + '@inquirer/editor': 4.2.23(@types/node@24.10.1) + '@inquirer/expand': 4.0.23(@types/node@24.10.1) + '@inquirer/input': 4.3.1(@types/node@24.10.1) + '@inquirer/number': 3.0.23(@types/node@24.10.1) + '@inquirer/password': 4.0.23(@types/node@24.10.1) + '@inquirer/rawlist': 4.1.11(@types/node@24.10.1) + '@inquirer/search': 3.2.2(@types/node@24.10.1) + '@inquirer/select': 4.4.2(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/prompts@7.8.0(@types/node@22.19.0)': + '@inquirer/prompts@7.3.2(@types/node@24.10.1)': dependencies: - '@inquirer/checkbox': 4.2.1(@types/node@22.19.0) - '@inquirer/confirm': 5.1.15(@types/node@22.19.0) - '@inquirer/editor': 4.2.17(@types/node@22.19.0) - '@inquirer/expand': 4.0.17(@types/node@22.19.0) - '@inquirer/input': 4.2.1(@types/node@22.19.0) - '@inquirer/number': 3.0.17(@types/node@22.19.0) - '@inquirer/password': 4.0.17(@types/node@22.19.0) - '@inquirer/rawlist': 4.1.5(@types/node@22.19.0) - '@inquirer/search': 3.1.0(@types/node@22.19.0) - '@inquirer/select': 4.3.1(@types/node@22.19.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.10.1) + '@inquirer/confirm': 5.1.21(@types/node@24.10.1) + '@inquirer/editor': 4.2.23(@types/node@24.10.1) + '@inquirer/expand': 4.0.23(@types/node@24.10.1) + '@inquirer/input': 4.3.1(@types/node@24.10.1) + '@inquirer/number': 3.0.23(@types/node@24.10.1) + '@inquirer/password': 4.0.23(@types/node@24.10.1) + '@inquirer/rawlist': 4.1.11(@types/node@24.10.1) + '@inquirer/search': 3.2.2(@types/node@24.10.1) + '@inquirer/select': 4.4.2(@types/node@24.10.1) optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/rawlist@4.1.5(@types/node@22.19.0)': + '@inquirer/rawlist@4.1.11(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/type': 3.0.8(@types/node@22.19.0) - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/search@3.1.0(@types/node@22.19.0)': + '@inquirer/search@3.2.2(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.19.0) - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.10.1) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/select@4.3.1(@types/node@22.19.0)': + '@inquirer/select@4.4.2(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.19.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.19.0) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.10.1) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@inquirer/type@3.0.8(@types/node@22.19.0)': + '@inquirer/type@3.0.10(@types/node@24.10.1)': optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@internationalized/date@3.8.2': + '@internationalized/date@3.10.0': dependencies: '@swc/helpers': 0.5.17 @@ -14618,7 +14892,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/yargs': 17.0.34 chalk: 4.1.2 @@ -14691,18 +14965,18 @@ snapshots: '@koa/router@14.0.0': dependencies: debug: 4.4.3 - http-errors: 2.0.0 + http-errors: 2.0.1 koa-compose: 4.1.0 path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color - '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': + '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@mdn/browser-compat-data': 6.0.27 - '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - browserslist: 4.27.0 + '@typescript-eslint/type-utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + browserslist: 4.28.0 transitivePeerDependencies: - eslint - supports-color @@ -14794,6 +15068,10 @@ snapshots: rw: 1.3.3 tinyqueue: 3.0.0 + '@maplibre/mlt@1.1.0': + dependencies: + '@mapbox/point-geometry': 1.1.0 + '@maplibre/vt-pbf@4.0.3': dependencies: '@mapbox/point-geometry': 1.1.0 @@ -14844,13 +15122,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1)': + '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.2 + '@types/react': 19.2.7 react: 18.3.1 - '@microsoft/tsdoc@0.15.1': {} + '@microsoft/tsdoc@0.16.0': {} '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': optional: true @@ -14872,52 +15150,51 @@ snapshots: '@namnode/store@0.1.0': {} - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(bullmq@5.62.1)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(bullmq@5.65.0)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) - bullmq: 5.62.1 + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) + bullmq: 5.65.0 tslib: 2.8.1 - '@nestjs/cli@11.0.10(@swc/core@1.14.0(@swc/helpers@0.5.17))(@types/node@22.19.0)': + '@nestjs/cli@11.0.13(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@24.10.1)': dependencies: - '@angular-devkit/core': 19.2.15(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.15(@types/node@22.19.0)(chokidar@4.0.3) - '@inquirer/prompts': 7.8.0(@types/node@22.19.0) - '@nestjs/schematics': 11.0.9(chokidar@4.0.3)(typescript@5.8.3) - ansis: 4.1.0 + '@angular-devkit/core': 19.2.19(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.19(chokidar@4.0.3) + '@angular-devkit/schematics-cli': 19.2.19(@types/node@24.10.1)(chokidar@4.0.3) + '@inquirer/prompts': 7.10.1(@types/node@24.10.1) + '@nestjs/schematics': 11.0.9(chokidar@4.0.3)(typescript@5.9.3) + ansis: 4.2.0 chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17))) - glob: 11.0.3 + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + glob: 13.0.0 node-emoji: 1.11.0 ora: 5.4.1 - tree-kill: 1.2.2 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 - typescript: 5.8.3 - webpack: 5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17)) + typescript: 5.9.3 + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/core': 1.14.0(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) transitivePeerDependencies: - '@types/node' - esbuild - uglify-js - webpack-cli - '@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - file-type: 21.0.0 + file-type: 21.1.0 iterare: 1.2.1 load-esm: 1.0.3 reflect-metadata: 0.2.2 @@ -14926,13 +15203,13 @@ snapshots: uid: 2.0.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.2 + class-validator: 0.14.3 transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -14942,21 +15219,21 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) - '@nestjs/websockets': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-socket.io@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) + '@nestjs/websockets': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-socket.io@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.2 + class-validator: 0.14.3 - '@nestjs/platform-express@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)': + '@nestjs/platform-express@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.5 express: 5.1.0 multer: 2.0.2 @@ -14965,10 +15242,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/platform-socket.io@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.8)(rxjs@7.8.2)': + '@nestjs/platform-socket.io@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.9)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/websockets': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-socket.io@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-socket.io@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) rxjs: 7.8.2 socket.io: 4.8.1 tslib: 2.8.1 @@ -14977,23 +15254,12 @@ snapshots: - supports-color - utf-8-validate - '@nestjs/schedule@6.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)': + '@nestjs/schedule@6.0.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.3.3 - '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.8.3)': - dependencies: - '@angular-devkit/core': 19.2.17(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.17(chokidar@4.0.3) - comment-json: 4.4.1 - jsonc-parser: 3.3.1 - pluralize: 8.0.0 - typescript: 5.8.3 - transitivePeerDependencies: - - chokidar - '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': dependencies: '@angular-devkit/core': 19.2.17(chokidar@4.0.3) @@ -15005,40 +15271,40 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.2.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)': + '@nestjs/swagger@11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)': dependencies: - '@microsoft/tsdoc': 0.15.1 - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2) - js-yaml: 4.1.0 + '@microsoft/tsdoc': 0.16.0 + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) + js-yaml: 4.1.1 lodash: 4.17.21 path-to-regexp: 8.3.0 reflect-metadata: 0.2.2 - swagger-ui-dist: 5.29.4 + swagger-ui-dist: 5.30.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.2 + class-validator: 0.14.3 - '@nestjs/testing@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-express@11.1.8)': + '@nestjs/testing@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) + '@nestjs/platform-express': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) - '@nestjs/websockets@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@nestjs/platform-socket.io@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/websockets@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-socket.io@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) iterare: 1.2.1 object-hash: 3.0.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-socket.io': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.8)(rxjs@7.8.2) + '@nestjs/platform-socket.io': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.9)(rxjs@7.8.2) '@noble/hashes@1.8.0': {} @@ -15054,17 +15320,17 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@npmcli/agent@3.0.0': + '@npmcli/agent@4.0.0': dependencies: agent-base: 7.1.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - lru-cache: 10.4.3 + lru-cache: 11.2.4 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color - '@npmcli/fs@4.0.0': + '@npmcli/fs@5.0.0': dependencies: semver: 7.7.3 @@ -15074,7 +15340,7 @@ snapshots: '@oazapfts/runtime@1.0.4': {} - '@opentelemetry/api-logs@0.207.0': + '@opentelemetry/api-logs@0.208.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -15087,102 +15353,102 @@ snapshots: '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.38.0 - '@opentelemetry/exporter-logs-otlp-grpc@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': dependencies: - '@grpc/grpc-js': 1.14.0 + '@grpc/grpc-js': 1.14.2 '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': dependencies: - '@grpc/grpc-js': 1.14.0 + '@grpc/grpc-js': 1.14.2 '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-prometheus@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': dependencies: - '@grpc/grpc-js': 1.14.0 + '@grpc/grpc-js': 1.14.2 '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) @@ -15192,81 +15458,81 @@ snapshots: '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/host-metrics@0.36.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 systeminformation: 5.23.8 - '@opentelemetry/instrumentation-http@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-http@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-ioredis@0.55.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-ioredis@0.56.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.38.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.54.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-nestjs-core@0.55.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.60.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-pg@0.61.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) - '@types/pg': 8.15.5 + '@types/pg': 8.15.6 '@types/pg-pool': 2.0.6 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 import-in-the-middle: 2.0.0 require-in-the-middle: 8.0.0 transitivePeerDependencies: - supports-color - '@opentelemetry/otlp-exporter-base@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-exporter-base@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-grpc-exporter-base@0.208.0(@opentelemetry/api@1.9.0)': dependencies: - '@grpc/grpc-js': 1.14.0 + '@grpc/grpc-js': 1.14.2 '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-transformer@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) protobufjs: 7.5.4 @@ -15287,12 +15553,12 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.38.0 - '@opentelemetry/sdk-logs@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) @@ -15302,31 +15568,31 @@ snapshots: '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-node@0.207.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-node@0.208.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 + '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-grpc': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-zipkin': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/propagator-b3': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/propagator-jaeger': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-node': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -15335,7 +15601,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0)': dependencies: @@ -15344,7 +15610,7 @@ snapshots: '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions@1.37.0': {} + '@opentelemetry/semantic-conventions@1.38.0': {} '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.0)': dependencies: @@ -15365,6 +15631,10 @@ snapshots: '@photo-sphere-viewer/video-plugin': 5.14.0(@photo-sphere-viewer/core@5.14.0) three: 0.180.0 + '@photo-sphere-viewer/markers-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)': + dependencies: + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/resolution-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/settings-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0))': dependencies: '@photo-sphere-viewer/core': 5.14.0 @@ -15386,9 +15656,9 @@ snapshots: '@pkgr/core@0.2.9': {} - '@playwright/test@1.56.1': + '@playwright/test@1.57.0': dependencies: - playwright: 1.56.1 + playwright: 1.57.0 '@pnpm/config.env-replace@1.1.0': {} @@ -15518,7 +15788,7 @@ snapshots: '@react-email/render@1.4.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: html-to-text: 9.0.5 - prettier: 3.6.2 + prettier: 3.7.1 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) react-promise-suspense: 0.3.4 @@ -15539,78 +15809,78 @@ snapshots: dependencies: react: 19.2.0 - '@rollup/pluginutils@5.3.0(rollup@4.52.5)': + '@rollup/pluginutils@5.3.0(rollup@4.53.3)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.52.5 + rollup: 4.53.3 - '@rollup/rollup-android-arm-eabi@4.52.5': + '@rollup/rollup-android-arm-eabi@4.53.3': optional: true - '@rollup/rollup-android-arm64@4.52.5': + '@rollup/rollup-android-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-arm64@4.52.5': + '@rollup/rollup-darwin-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-x64@4.52.5': + '@rollup/rollup-darwin-x64@4.53.3': optional: true - '@rollup/rollup-freebsd-arm64@4.52.5': + '@rollup/rollup-freebsd-arm64@4.53.3': optional: true - '@rollup/rollup-freebsd-x64@4.52.5': + '@rollup/rollup-freebsd-x64@4.53.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.5': + '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.5': + '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.5': + '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.5': + '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.5': + '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.5': + '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.5': + '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.5': + '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.5': + '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-musl@4.52.5': + '@rollup/rollup-linux-x64-musl@4.53.3': optional: true - '@rollup/rollup-openharmony-arm64@4.52.5': + '@rollup/rollup-openharmony-arm64@4.53.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.5': + '@rollup/rollup-win32-arm64-msvc@4.53.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.5': + '@rollup/rollup-win32-ia32-msvc@4.53.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.5': + '@rollup/rollup-win32-x64-gnu@4.53.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.5': + '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true '@scarf/scarf@1.4.0': {} @@ -15650,59 +15920,59 @@ snapshots: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 - '@smithy/abort-controller@4.2.3': + '@smithy/abort-controller@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/config-resolver@4.4.0': + '@smithy/config-resolver@4.4.3': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/core@3.17.1': + '@smithy/core@3.18.5': dependencies: - '@smithy/middleware-serde': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/middleware-serde': 4.2.6 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.2.3': + '@smithy/credential-provider-imds@4.2.5': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.4': + '@smithy/fetch-http-handler@5.3.6': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/querystring-builder': 4.2.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/hash-node@4.2.3': + '@smithy/hash-node@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.3': + '@smithy/invalid-dependency@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': @@ -15713,120 +15983,120 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.3': + '@smithy/middleware-content-length@4.2.5': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.3.5': + '@smithy/middleware-endpoint@4.3.12': dependencies: - '@smithy/core': 3.17.1 - '@smithy/middleware-serde': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-middleware': 4.2.3 + '@smithy/core': 3.18.5 + '@smithy/middleware-serde': 4.2.6 + '@smithy/node-config-provider': 4.3.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.5': + '@smithy/middleware-retry@4.4.12': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/service-error-classification': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/service-error-classification': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.3': + '@smithy/middleware-serde@4.2.6': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.3': + '@smithy/middleware-stack@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.3': + '@smithy/node-config-provider@4.3.5': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.4.3': + '@smithy/node-http-handler@4.4.5': dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/abort-controller': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/querystring-builder': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/property-provider@4.2.3': + '@smithy/property-provider@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/protocol-http@5.3.3': + '@smithy/protocol-http@5.3.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.2.3': + '@smithy/querystring-builder@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.2.3': + '@smithy/querystring-parser@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/service-error-classification@4.2.3': + '@smithy/service-error-classification@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 - '@smithy/shared-ini-file-loader@4.3.3': + '@smithy/shared-ini-file-loader@4.4.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/signature-v4@5.3.3': + '@smithy/signature-v4@5.3.5': dependencies: '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-uri-escape': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.9.1': + '@smithy/smithy-client@4.9.8': dependencies: - '@smithy/core': 3.17.1 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-stack': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.4 + '@smithy/core': 3.18.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-stack': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 tslib: 2.8.1 - '@smithy/types@4.8.0': + '@smithy/types@4.9.0': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.3': + '@smithy/url-parser@4.2.5': dependencies: - '@smithy/querystring-parser': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/querystring-parser': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/util-base64@4.3.0': @@ -15857,49 +16127,49 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.4': + '@smithy/util-defaults-mode-browser@4.3.11': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.6': + '@smithy/util-defaults-mode-node@4.2.14': dependencies: - '@smithy/config-resolver': 4.4.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-endpoints@3.2.3': + '@smithy/util-endpoints@3.2.5': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.2.3': + '@smithy/util-middleware@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-retry@4.2.3': + '@smithy/util-retry@4.2.5': dependencies: - '@smithy/service-error-classification': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/service-error-classification': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-stream@4.5.4': + '@smithy/util-stream@4.5.6': dependencies: - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.3 - '@smithy/types': 4.8.0 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-hex-encoding': 4.2.0 @@ -15937,37 +16207,37 @@ snapshots: '@standard-schema/spec@1.0.0': {} - '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': + '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': dependencies: acorn: 8.15.0 - '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.48.3(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))': + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))': dependencies: - '@sveltejs/kit': 2.48.3(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@sveltejs/kit': 2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) - '@sveltejs/enhanced-img@0.8.4(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(rollup@4.52.5)(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@sveltejs/enhanced-img@0.9.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(rollup@4.53.3)(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) magic-string: 0.30.21 - sharp: 0.34.4 - svelte: 5.43.0 - svelte-parse-markup: 0.1.5(svelte@5.43.0) - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vite-imagetools: 8.0.0(rollup@4.52.5) + sharp: 0.34.5 + svelte: 5.45.2 + svelte-parse-markup: 0.1.5(svelte@5.45.2) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) + vite-imagetools: 9.0.2(rollup@4.53.3) zimmerframe: 1.1.4 transitivePeerDependencies: - rollup - supports-color - '@sveltejs/kit@2.48.3(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: '@standard-schema/spec': 1.0.0 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 - devalue: 5.4.2 + devalue: 5.5.0 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 @@ -15975,29 +16245,29 @@ snapshots: sade: 1.8.1 set-cookie-parser: 2.7.2 sirv: 3.0.2 - svelte: 5.43.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + svelte: 5.45.2 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) optionalDependencies: '@opentelemetry/api': 1.9.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) debug: 4.4.3 - svelte: 5.43.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + svelte: 5.45.2 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)))(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) debug: 4.4.3 deepmerge: 4.3.1 magic-string: 0.30.21 - svelte: 5.43.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + svelte: 5.45.2 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) transitivePeerDependencies: - supports-color @@ -16094,51 +16364,51 @@ snapshots: - supports-color - typescript - '@swc/core-darwin-arm64@1.14.0': + '@swc/core-darwin-arm64@1.15.3': optional: true - '@swc/core-darwin-x64@1.14.0': + '@swc/core-darwin-x64@1.15.3': optional: true - '@swc/core-linux-arm-gnueabihf@1.14.0': + '@swc/core-linux-arm-gnueabihf@1.15.3': optional: true - '@swc/core-linux-arm64-gnu@1.14.0': + '@swc/core-linux-arm64-gnu@1.15.3': optional: true - '@swc/core-linux-arm64-musl@1.14.0': + '@swc/core-linux-arm64-musl@1.15.3': optional: true - '@swc/core-linux-x64-gnu@1.14.0': + '@swc/core-linux-x64-gnu@1.15.3': optional: true - '@swc/core-linux-x64-musl@1.14.0': + '@swc/core-linux-x64-musl@1.15.3': optional: true - '@swc/core-win32-arm64-msvc@1.14.0': + '@swc/core-win32-arm64-msvc@1.15.3': optional: true - '@swc/core-win32-ia32-msvc@1.14.0': + '@swc/core-win32-ia32-msvc@1.15.3': optional: true - '@swc/core-win32-x64-msvc@1.14.0': + '@swc/core-win32-x64-msvc@1.15.3': optional: true - '@swc/core@1.14.0(@swc/helpers@0.5.17)': + '@swc/core@1.15.3(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.14.0 - '@swc/core-darwin-x64': 1.14.0 - '@swc/core-linux-arm-gnueabihf': 1.14.0 - '@swc/core-linux-arm64-gnu': 1.14.0 - '@swc/core-linux-arm64-musl': 1.14.0 - '@swc/core-linux-x64-gnu': 1.14.0 - '@swc/core-linux-x64-musl': 1.14.0 - '@swc/core-win32-arm64-msvc': 1.14.0 - '@swc/core-win32-ia32-msvc': 1.14.0 - '@swc/core-win32-x64-msvc': 1.14.0 + '@swc/core-darwin-arm64': 1.15.3 + '@swc/core-darwin-x64': 1.15.3 + '@swc/core-linux-arm-gnueabihf': 1.15.3 + '@swc/core-linux-arm64-gnu': 1.15.3 + '@swc/core-linux-arm64-musl': 1.15.3 + '@swc/core-linux-x64-gnu': 1.15.3 + '@swc/core-linux-x64-musl': 1.15.3 + '@swc/core-win32-arm64-msvc': 1.15.3 + '@swc/core-win32-ia32-msvc': 1.15.3 + '@swc/core-win32-x64-msvc': 1.15.3 '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} @@ -16155,7 +16425,7 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/node@4.1.16': + '@tailwindcss/node@4.1.17': dependencies: '@jridgewell/remapping': 2.3.5 enhanced-resolve: 5.18.3 @@ -16163,75 +16433,75 @@ snapshots: lightningcss: 1.30.2 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.1.16 + tailwindcss: 4.1.17 - '@tailwindcss/oxide-android-arm64@4.1.16': + '@tailwindcss/oxide-android-arm64@4.1.17': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.16': + '@tailwindcss/oxide-darwin-arm64@4.1.17': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.16': + '@tailwindcss/oxide-darwin-x64@4.1.17': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.16': + '@tailwindcss/oxide-freebsd-x64@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.16': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.16': + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.16': + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.16': + '@tailwindcss/oxide-linux-x64-musl@4.1.17': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.16': + '@tailwindcss/oxide-wasm32-wasi@4.1.17': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.16': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.16': + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': optional: true - '@tailwindcss/oxide@4.1.16': + '@tailwindcss/oxide@4.1.17': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.16 - '@tailwindcss/oxide-darwin-arm64': 4.1.16 - '@tailwindcss/oxide-darwin-x64': 4.1.16 - '@tailwindcss/oxide-freebsd-x64': 4.1.16 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.16 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.16 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.16 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.16 - '@tailwindcss/oxide-linux-x64-musl': 4.1.16 - '@tailwindcss/oxide-wasm32-wasi': 4.1.16 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.16 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.16 + '@tailwindcss/oxide-android-arm64': 4.1.17 + '@tailwindcss/oxide-darwin-arm64': 4.1.17 + '@tailwindcss/oxide-darwin-x64': 4.1.17 + '@tailwindcss/oxide-freebsd-x64': 4.1.17 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.17 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.17 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.17 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.17 + '@tailwindcss/oxide-linux-x64-musl': 4.1.17 + '@tailwindcss/oxide-wasm32-wasi': 4.1.17 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.17 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.17 - '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@tailwindcss/vite@4.1.17(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: - '@tailwindcss/node': 4.1.16 - '@tailwindcss/oxide': 4.1.16 - tailwindcss: 4.1.16 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + '@tailwindcss/node': 4.1.17 + '@tailwindcss/oxide': 4.1.17 + tailwindcss: 4.1.17 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) - '@testing-library/dom@10.4.0': + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.27.1 '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 - chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 + picocolors: 1.1.1 pretty-format: 27.5.1 '@testing-library/jest-dom@6.9.1': @@ -16243,19 +16513,19 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/svelte@5.2.8(svelte@5.43.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@testing-library/svelte@5.2.9(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: - '@testing-library/dom': 10.4.0 - svelte: 5.43.0 + '@testing-library/dom': 10.4.1 + svelte: 5.45.2 optionalDependencies: - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) - '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: - '@testing-library/dom': 10.4.0 + '@testing-library/dom': 10.4.1 - '@tokenizer/inflate@0.2.7': + '@tokenizer/inflate@0.3.1': dependencies: debug: 4.4.3 fflate: 0.8.2 @@ -16291,9 +16561,9 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 - '@types/archiver@6.0.4': + '@types/archiver@7.0.0': dependencies: '@types/readdir-glob': 1.1.5 @@ -16303,16 +16573,16 @@ snapshots: '@types/bcrypt@6.0.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/braces@3.0.5': {} @@ -16333,21 +16603,21 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/compression@1.8.1': dependencies: '@types/express': 5.0.5 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.1.0 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/content-disposition@0.5.9': {} @@ -16364,11 +16634,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.5 '@types/keygrip': 1.0.6 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/cors@2.8.19': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/debug@4.1.12': dependencies: @@ -16378,13 +16648,13 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ssh2': 1.15.5 - '@types/dockerode@3.3.45': + '@types/dockerode@3.3.47': dependencies: '@types/docker-modem': 3.0.6 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ssh2': 1.15.5 '@types/dom-to-image@2.6.7': {} @@ -16407,14 +16677,14 @@ snapshots: '@types/express-serve-static-core@4.19.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -16440,7 +16710,7 @@ snapshots: '@types/fluent-ffmpeg@2.1.28': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/geojson-vt@3.2.5': dependencies: @@ -16472,7 +16742,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/inquirer@8.2.11': dependencies: @@ -16496,7 +16766,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/justified-layout@4.1.4': {} @@ -16515,7 +16785,7 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/leaflet@1.9.21': dependencies: @@ -16523,9 +16793,9 @@ snapshots: '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.17.20 + '@types/lodash': 4.17.21 - '@types/lodash@4.17.20': {} + '@types/lodash@4.17.21': {} '@types/luxon@3.7.1': {} @@ -16545,7 +16815,7 @@ snapshots: '@types/mock-fs@4.13.4': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ms@2.1.0': {} @@ -16555,7 +16825,7 @@ snapshots: '@types/node-forge@1.3.14': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/node@17.0.45': {} @@ -16567,19 +16837,14 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@22.19.0': - dependencies: - undici-types: 6.21.0 - - '@types/node@24.10.0': + '@types/node@24.10.1': dependencies: undici-types: 7.16.0 - optional: true - '@types/nodemailer@7.0.3': + '@types/nodemailer@7.0.4': dependencies: - '@aws-sdk/client-sesv2': 3.919.0 - '@types/node': 22.19.0 + '@aws-sdk/client-sesv2': 3.939.0 + '@types/node': 24.10.1 transitivePeerDependencies: - aws-crt @@ -16587,7 +16852,7 @@ snapshots: dependencies: '@types/keygrip': 1.0.6 '@types/koa': 3.0.0 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/parse5@5.0.3': {} @@ -16595,15 +16860,9 @@ snapshots: dependencies: '@types/pg': 8.15.6 - '@types/pg@8.15.5': - dependencies: - '@types/node': 22.19.0 - pg-protocol: 1.10.3 - pg-types: 2.2.0 - '@types/pg@8.15.6': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 pg-protocol: 1.10.3 pg-types: 2.2.0 @@ -16611,13 +16870,13 @@ snapshots: '@types/pngjs@6.0.5': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/prismjs@1.26.5': {} '@types/qrcode@1.5.6': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/qs@6.14.0': {} @@ -16626,27 +16885,27 @@ snapshots: '@types/react-router-config@5.0.11': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.2 + '@types/react': 19.2.7 '@types/react-router': 5.1.20 '@types/react-router-dom@5.3.3': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.2 + '@types/react': 19.2.7 '@types/react-router': 5.1.20 '@types/react-router@5.1.20': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.2 + '@types/react': 19.2.7 - '@types/react@19.2.2': + '@types/react@19.2.7': dependencies: - csstype: 3.1.3 + csstype: 3.2.3 '@types/readdir-glob@1.1.5': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/retry@0.12.2': {} @@ -16656,18 +16915,18 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/semver@7.7.1': {} '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/serve-index@1.9.4': dependencies: @@ -16676,20 +16935,20 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/send': 0.17.6 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ssh2-streams@0.1.13': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ssh2@0.5.52': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ssh2-streams': 0.1.13 '@types/ssh2@1.15.5': @@ -16700,8 +16959,8 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 22.19.0 - form-data: 4.0.4 + '@types/node': 24.10.1 + form-data: 4.0.5 '@types/supercluster@7.1.3': dependencies: @@ -16714,7 +16973,7 @@ snapshots: '@types/through@0.0.33': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/ua-parser-js@0.7.39': {} @@ -16722,13 +16981,13 @@ snapshots: '@types/unist@3.0.3': {} - '@types/validator@13.15.4': {} + '@types/validator@13.15.10': {} '@types/whatwg-mimetype@3.0.2': {} '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 '@types/yargs-parser@21.0.3': {} @@ -16736,15 +16995,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.48.0(@typescript-eslint/parser@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.2 - '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.2 - eslint: 9.38.0(jiti@2.6.1) + '@typescript-eslint/parser': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.48.0 + '@typescript-eslint/type-utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.48.0 + eslint: 9.39.1(jiti@2.6.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -16753,87 +17012,86 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.46.2 - '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.2 + '@typescript-eslint/scope-manager': 8.48.0 + '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.48.0 debug: 4.4.3 - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.46.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.48.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) - '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3) + '@typescript-eslint/types': 8.48.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.46.2': + '@typescript-eslint/scope-manager@8.48.0': dependencies: - '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/visitor-keys': 8.46.2 + '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/visitor-keys': 8.48.0 - '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.48.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.46.2': {} + '@typescript-eslint/types@8.48.0': {} - '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.48.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.46.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) - '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/visitor-keys': 8.46.2 + '@typescript-eslint/project-service': 8.48.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3) + '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/visitor-keys': 8.48.0 debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.3 + tinyglobby: 0.2.15 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.46.2 - '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - eslint: 9.38.0(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.48.0 + '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.46.2': + '@typescript-eslint/visitor-keys@8.48.0': dependencies: - '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/types': 8.48.0 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} '@vercel/oidc@3.0.3': {} - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -16848,26 +17106,7 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - transitivePeerDependencies: - - supports-color - - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.3 - debug: 4.4.3 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.1.7 - magic-string: 0.30.21 - magicast: 0.3.5 - std-env: 3.10.0 - test-exclude: 7.0.1 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -16879,21 +17118,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - - '@vitest/mocker@3.2.4(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': - dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -17001,21 +17232,21 @@ snapshots: '@xtuc/long@4.2.2': {} - '@zoom-image/core@0.41.3': + '@zoom-image/core@0.41.4': dependencies: '@namnode/store': 0.1.0 - '@zoom-image/svelte@0.3.7(svelte@5.43.0)': + '@zoom-image/svelte@0.3.8(svelte@5.45.2)': dependencies: - '@zoom-image/core': 0.41.3 - svelte: 5.43.0 + '@zoom-image/core': 0.41.4 + svelte: 5.45.2 abab@2.0.6: optional: true abbrev@1.1.1: {} - abbrev@3.0.1: {} + abbrev@4.0.0: {} abort-controller@3.0.0: dependencies: @@ -17028,7 +17259,7 @@ snapshots: accepts@2.0.0: dependencies: - mime-types: 3.0.1 + mime-types: 3.0.2 negotiator: 1.0.0 acorn-globals@7.0.1: @@ -17155,7 +17386,7 @@ snapshots: ansi-styles@6.2.3: {} - ansis@4.1.0: {} + ansis@4.2.0: {} any-promise@1.3.0: {} @@ -17170,7 +17401,7 @@ snapshots: archiver-utils@5.0.2: dependencies: - glob: 10.4.5 + glob: 10.5.0 graceful-fs: 4.2.11 is-stream: 2.0.1 lazystream: 1.0.1 @@ -17253,11 +17484,11 @@ snapshots: dependencies: immediate: 3.3.0 - autoprefixer@10.4.21(postcss@8.5.6): + autoprefixer@10.4.22(postcss@8.5.6): dependencies: - browserslist: 4.27.0 - caniuse-lite: 1.0.30001751 - fraction.js: 4.3.7 + browserslist: 4.28.0 + caniuse-lite: 1.0.30001757 + fraction.js: 5.3.4 normalize-range: 0.1.2 picocolors: 1.1.1 postcss: 8.5.6 @@ -17267,12 +17498,12 @@ snapshots: b4a@1.6.7: {} - babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.102.1): + babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.103.0): dependencies: '@babel/core': 7.28.5 find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.102.1 + webpack: 5.103.0 babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -17308,14 +17539,14 @@ snapshots: balanced-match@1.0.2: {} - bare-events@2.8.1: {} + bare-events@2.8.2: {} - bare-fs@4.5.0: + bare-fs@4.5.2: dependencies: - bare-events: 2.8.1 + bare-events: 2.8.2 bare-path: 3.0.0 - bare-stream: 2.7.0(bare-events@2.8.1) - bare-url: 2.3.1 + bare-stream: 2.7.0(bare-events@2.8.2) + bare-url: 2.3.2 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -17329,16 +17560,16 @@ snapshots: bare-os: 3.6.2 optional: true - bare-stream@2.7.0(bare-events@2.8.1): + bare-stream@2.7.0(bare-events@2.8.2): dependencies: streamx: 2.23.0 optionalDependencies: - bare-events: 2.8.1 + bare-events: 2.8.2 transitivePeerDependencies: - bare-abort-controller optional: true - bare-url@2.3.1: + bare-url@2.3.2: dependencies: bare-path: 3.0.0 optional: true @@ -17347,7 +17578,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.8.20: {} + baseline-browser-mapping@2.8.31: {} batch-cluster@15.0.1: {} @@ -17362,7 +17593,7 @@ snapshots: bcrypt@6.0.0: dependencies: node-addon-api: 8.5.0 - node-gyp: 11.5.0 + node-gyp: 12.1.0 node-gyp-build: 4.8.4 transitivePeerDependencies: - supports-color @@ -17371,16 +17602,18 @@ snapshots: binary-extensions@2.3.0: {} - bits-ui@2.9.8(@internationalized/date@3.8.2)(svelte@5.43.0): + bits-ui@2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 - '@internationalized/date': 3.8.2 + '@internationalized/date': 3.10.0 esm-env: 1.2.2 - runed: 0.29.2(svelte@5.43.0) - svelte: 5.43.0 - svelte-toolbelt: 0.9.3(svelte@5.43.0) + runed: 0.35.1(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2) + svelte: 5.45.2 + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2) tabbable: 6.3.0 + transitivePeerDependencies: + - '@sveltejs/kit' bl@4.1.0: dependencies: @@ -17388,33 +17621,33 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@1.20.3: + body-parser@1.20.4: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 + qs: 6.14.0 + raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: - supports-color - body-parser@2.2.0: + body-parser@2.2.1: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 4.4.3 - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.0 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.1 + raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -17426,7 +17659,7 @@ snapshots: boolbase@1.0.0: {} - bowser@2.12.1: {} + bowser@2.13.0: {} boxen@6.2.1: dependencies: @@ -17463,13 +17696,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.27.0: + browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.20 - caniuse-lite: 1.0.30001751 - electron-to-chromium: 1.5.243 - node-releases: 2.0.26 - update-browserslist-db: 1.1.4(browserslist@4.27.0) + baseline-browser-mapping: 2.8.31 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.260 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.28.0) buffer-crc32@1.0.0: {} @@ -17487,12 +17720,12 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - buildcheck@0.0.6: + buildcheck@0.0.7: optional: true builtin-modules@5.0.0: {} - bullmq@5.62.1: + bullmq@5.65.0: dependencies: cron-parser: 4.9.0 ioredis: 5.8.2 @@ -17522,20 +17755,19 @@ snapshots: cac@6.7.14: {} - cacache@19.0.1: + cacache@20.0.3: dependencies: - '@npmcli/fs': 4.0.0 + '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 - glob: 10.4.5 - lru-cache: 10.4.3 + glob: 13.0.0 + lru-cache: 11.2.4 minipass: 7.1.2 minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - p-map: 7.0.3 - ssri: 12.0.0 - tar: 7.5.1 - unique-filename: 4.0.0 + p-map: 7.0.4 + ssri: 13.0.0 + unique-filename: 5.0.0 cacheable-lookup@7.0.0: {} @@ -17583,17 +17815,17 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.27.0 - caniuse-lite: 1.0.30001751 + browserslist: 4.28.0 + caniuse-lite: 1.0.30001757 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001751: {} + caniuse-lite@1.0.30001757: {} canvas@2.11.2: dependencies: '@mapbox/node-pre-gyp': 1.0.11 - nan: 2.23.0 + nan: 2.23.1 simple-get: 3.1.1 transitivePeerDependencies: - encoding @@ -17603,7 +17835,7 @@ snapshots: canvas@2.11.2(encoding@0.1.13): dependencies: '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) - nan: 2.23.0 + nan: 2.23.1 simple-get: 3.1.1 transitivePeerDependencies: - encoding @@ -17639,7 +17871,7 @@ snapshots: character-reference-invalid@2.0.1: {} - chardet@2.1.0: {} + chardet@2.1.1: {} check-error@2.1.1: {} @@ -17688,7 +17920,7 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.0: {} + ci-info@4.3.1: {} citty@0.1.6: dependencies: @@ -17698,11 +17930,11 @@ snapshots: class-transformer@0.5.1: {} - class-validator@0.14.2: + class-validator@0.14.3: dependencies: - '@types/validator': 13.15.4 - libphonenumber-js: 1.12.9 - validator: 13.15.20 + '@types/validator': 13.15.10 + libphonenumber-js: 1.12.31 + validator: 13.15.23 clean-css@5.3.3: dependencies: @@ -17884,9 +18116,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -17899,15 +18129,15 @@ snapshots: cookie-signature@1.0.6: {} + cookie-signature@1.0.7: {} + cookie-signature@1.2.2: {} cookie@0.6.0: {} - cookie@0.7.1: {} - cookie@0.7.2: {} - cookie@1.0.2: {} + cookie@1.1.1: {} cookiejar@2.1.4: {} @@ -17916,7 +18146,7 @@ snapshots: depd: 2.0.0 keygrip: 1.1.0 - copy-webpack-plugin@11.0.0(webpack@5.102.1): + copy-webpack-plugin@11.0.0(webpack@5.103.0): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -17924,11 +18154,11 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.102.1 + webpack: 5.103.0 core-js-compat@3.46.0: dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 core-js-pure@3.46.0: {} @@ -17941,19 +18171,10 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@8.3.6(typescript@5.8.3): - dependencies: - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - optionalDependencies: - typescript: 5.8.3 - cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: @@ -17961,8 +18182,8 @@ snapshots: cpu-features@0.0.10: dependencies: - buildcheck: 0.0.6 - nan: 2.23.0 + buildcheck: 0.0.7 + nan: 2.23.1 optional: true crc-32@1.2.2: {} @@ -18007,7 +18228,7 @@ snapshots: postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.102.1): + css-loader@6.11.0(webpack@5.103.0): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -18018,9 +18239,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.3 optionalDependencies: - webpack: 5.102.1 + webpack: 5.103.0 - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.102.1): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.103.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 cssnano: 6.1.2(postcss@8.5.6) @@ -18028,7 +18249,7 @@ snapshots: postcss: 8.5.6 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.102.1 + webpack: 5.103.0 optionalDependencies: clean-css: 5.3.3 @@ -18076,8 +18297,8 @@ snapshots: cssnano-preset-advanced@6.1.2(postcss@8.5.6): dependencies: - autoprefixer: 10.4.21(postcss@8.5.6) - browserslist: 4.27.0 + autoprefixer: 10.4.22(postcss@8.5.6) + browserslist: 4.28.0 cssnano-preset-default: 6.1.2(postcss@8.5.6) postcss: 8.5.6 postcss-discard-unused: 6.0.5(postcss@8.5.6) @@ -18087,7 +18308,7 @@ snapshots: cssnano-preset-default@6.1.2(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 css-declaration-sorter: 7.3.0(postcss@8.5.6) cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 @@ -18150,7 +18371,7 @@ snapshots: rrweb-cssom: 0.8.0 optional: true - csstype@3.1.3: {} + csstype@3.2.3: {} d3-array@3.2.4: dependencies: @@ -18277,7 +18498,7 @@ snapshots: transitivePeerDependencies: - supports-color - devalue@5.4.2: {} + devalue@5.5.0: {} devlop@1.1.0: dependencies: @@ -18310,7 +18531,7 @@ snapshots: docker-compose@1.3.0: dependencies: - yaml: 2.8.1 + yaml: 2.8.2 docker-modem@5.0.6: dependencies: @@ -18324,7 +18545,7 @@ snapshots: dockerode@4.0.9: dependencies: '@balena/dockerignore': 1.0.2 - '@grpc/grpc-js': 1.14.0 + '@grpc/grpc-js': 1.14.2 '@grpc/proto-loader': 0.7.15 docker-modem: 5.0.6 protobufjs: 7.5.4 @@ -18333,9 +18554,9 @@ snapshots: transitivePeerDependencies: - supports-color - docusaurus-lunr-search@3.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + docusaurus-lunr-search@3.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) autocomplete.js: 0.37.1 clsx: 2.1.1 gauge: 3.0.2 @@ -18433,7 +18654,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.243: {} + electron-to-chromium@1.5.260: {} emoji-regex@10.6.0: {} @@ -18477,7 +18698,7 @@ snapshots: engine.io@6.6.4: dependencies: '@types/cors': 2.8.19 - '@types/node': 22.19.0 + '@types/node': 24.10.1 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -18620,6 +18841,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 + esbuild@0.27.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.0 + '@esbuild/android-arm': 0.27.0 + '@esbuild/android-arm64': 0.27.0 + '@esbuild/android-x64': 0.27.0 + '@esbuild/darwin-arm64': 0.27.0 + '@esbuild/darwin-x64': 0.27.0 + '@esbuild/freebsd-arm64': 0.27.0 + '@esbuild/freebsd-x64': 0.27.0 + '@esbuild/linux-arm': 0.27.0 + '@esbuild/linux-arm64': 0.27.0 + '@esbuild/linux-ia32': 0.27.0 + '@esbuild/linux-loong64': 0.27.0 + '@esbuild/linux-mips64el': 0.27.0 + '@esbuild/linux-ppc64': 0.27.0 + '@esbuild/linux-riscv64': 0.27.0 + '@esbuild/linux-s390x': 0.27.0 + '@esbuild/linux-x64': 0.27.0 + '@esbuild/netbsd-arm64': 0.27.0 + '@esbuild/netbsd-x64': 0.27.0 + '@esbuild/openbsd-arm64': 0.27.0 + '@esbuild/openbsd-x64': 0.27.0 + '@esbuild/openharmony-arm64': 0.27.0 + '@esbuild/sunos-x64': 0.27.0 + '@esbuild/win32-arm64': 0.27.0 + '@esbuild/win32-ia32': 0.27.0 + '@esbuild/win32-x64': 0.27.0 + escalade@3.2.0: {} escape-goat@4.0.0: {} @@ -18641,93 +18891,71 @@ snapshots: source-map: 0.6.1 optional: true - eslint-config-prettier@10.1.8(eslint@9.38.0(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)): dependencies: - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) - eslint-plugin-compat@6.0.2(eslint@9.38.0(jiti@2.6.1)): + eslint-plugin-compat@6.0.2(eslint@9.39.1(jiti@2.6.1)): dependencies: '@mdn/browser-compat-data': 5.7.6 ast-metadata-inferer: 0.8.1 - browserslist: 4.27.0 - caniuse-lite: 1.0.30001751 - eslint: 9.38.0(jiti@2.6.1) + browserslist: 4.28.0 + caniuse-lite: 1.0.30001757 + eslint: 9.39.1(jiti@2.6.1) find-up: 5.0.0 globals: 15.15.0 lodash.memoize: 4.1.2 semver: 7.7.3 - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.38.0(jiti@2.6.1)))(eslint@9.38.0(jiti@2.6.1))(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.1): dependencies: - eslint: 9.38.0(jiti@2.6.1) - prettier: 3.6.2 + eslint: 9.39.1(jiti@2.6.1) + prettier: 3.7.1 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.38.0(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-svelte@3.12.5(eslint@9.38.0(jiti@2.6.1))(svelte@5.43.0): + eslint-plugin-svelte@3.13.0(eslint@9.39.1(jiti@2.6.1))(svelte@5.45.2): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) esutils: 2.0.3 - globals: 16.4.0 + globals: 16.5.0 known-css-properties: 0.37.0 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6) postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.3 - svelte-eslint-parser: 1.4.0(svelte@5.43.0) + svelte-eslint-parser: 1.4.0(svelte@5.45.2) optionalDependencies: - svelte: 5.43.0 + svelte: 5.45.2 transitivePeerDependencies: - ts-node - eslint-plugin-unicorn@60.0.0(eslint@9.38.0(jiti@2.6.1)): + eslint-plugin-unicorn@62.0.0(eslint@9.39.1(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) - '@eslint/plugin-kit': 0.3.5 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@eslint/plugin-kit': 0.4.1 change-case: 5.4.4 - ci-info: 4.3.0 + ci-info: 4.3.1 clean-regexp: 1.0.0 core-js-compat: 3.46.0 - eslint: 9.38.0(jiti@2.6.1) + eslint: 9.39.1(jiti@2.6.1) esquery: 1.6.0 find-up-simple: 1.0.1 - globals: 16.4.0 + globals: 16.5.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 pluralize: 8.0.0 regexp-tree: 0.1.27 - regjsparser: 0.12.0 + regjsparser: 0.13.0 semver: 7.7.3 - strip-indent: 4.0.0 - - eslint-plugin-unicorn@61.0.2(eslint@9.38.0(jiti@2.6.1)): - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) - '@eslint/plugin-kit': 0.3.5 - change-case: 5.4.4 - ci-info: 4.3.0 - clean-regexp: 1.0.0 - core-js-compat: 3.46.0 - eslint: 9.38.0(jiti@2.6.1) - esquery: 1.6.0 - find-up-simple: 1.0.1 - globals: 16.4.0 - indent-string: 5.0.0 - is-builtin-module: 5.0.0 - jsesc: 3.1.0 - pluralize: 8.0.0 - regexp-tree: 0.1.27 - regjsparser: 0.12.0 - semver: 7.7.3 - strip-indent: 4.0.0 + strip-indent: 4.1.1 eslint-scope@5.1.1: dependencies: @@ -18743,16 +18971,16 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.38.0(jiti@2.6.1): + eslint@9.39.1(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.1 - '@eslint/core': 0.16.0 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.38.0 - '@eslint/plugin-kit': 0.4.0 + '@eslint/js': 9.39.1 + '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -18805,7 +19033,7 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.1.0: + esrap@2.2.0: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -18866,7 +19094,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 require-like: 0.1.2 event-emitter@0.3.5: @@ -18880,7 +19108,7 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.8.1 + bare-events: 2.8.2 transitivePeerDependencies: - bare-abort-controller @@ -18900,56 +19128,56 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exiftool-vendored.exe@13.41.0: + exiftool-vendored.exe@13.42.0: optional: true - exiftool-vendored.pl@13.41.0: {} + exiftool-vendored.pl@13.42.0: {} - exiftool-vendored@31.3.0: + exiftool-vendored@33.5.0: dependencies: '@photostructure/tz-lookup': 11.3.0 '@types/luxon': 3.7.1 batch-cluster: 15.0.1 - exiftool-vendored.pl: 13.41.0 + exiftool-vendored.pl: 13.42.0 he: 1.2.0 luxon: 3.7.2 optionalDependencies: - exiftool-vendored.exe: 13.41.0 + exiftool-vendored.exe: 13.42.0 expect-type@1.2.1: {} exponential-backoff@3.1.3: {} - express@4.21.2: + express@4.22.1: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.3 + body-parser: 1.20.4 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 + cookie: 0.7.2 + cookie-signature: 1.0.7 debug: 2.6.9 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.1 + finalhandler: 1.3.2 fresh: 0.5.2 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.13.0 + qs: 6.14.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.0 + send: 0.19.1 serve-static: 1.16.2 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 @@ -18959,8 +19187,8 @@ snapshots: express@5.1.0: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.0 + body-parser: 2.2.1 + content-disposition: 1.0.1 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 @@ -18968,11 +19196,44 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.1 fresh: 2.0.0 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 2.0.0 - mime-types: 3.0.1 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + express@5.2.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.1 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 @@ -19000,7 +19261,7 @@ snapshots: extend@3.0.2: {} - fabric@6.7.1: + fabric@6.9.0: optionalDependencies: canvas: 2.11.2 jsdom: 20.0.3(canvas@2.11.2) @@ -19073,19 +19334,19 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-loader@6.2.0(webpack@5.102.1): + file-loader@6.2.0(webpack@5.103.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.102.1 + webpack: 5.103.0 file-source@0.6.1: dependencies: stream-source: 0.3.5 - file-type@21.0.0: + file-type@21.1.0: dependencies: - '@tokenizer/inflate': 0.2.7 + '@tokenizer/inflate': 0.3.1 strtok3: 10.3.4 token-types: 6.1.1 uint8array-extras: 1.5.0 @@ -19096,19 +19357,19 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.1: + finalhandler@1.3.2: dependencies: debug: 2.6.9 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 unpipe: 1.0.0 transitivePeerDependencies: - supports-color - finalhandler@2.1.0: + finalhandler@2.1.1: dependencies: debug: 4.4.3 encodeurl: 2.0.0 @@ -19162,12 +19423,12 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17))): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 chokidar: 4.0.3 - cosmiconfig: 8.3.6(typescript@5.8.3) + cosmiconfig: 8.3.6(typescript@5.9.3) deepmerge: 4.3.1 fs-extra: 10.1.0 memfs: 3.5.3 @@ -19176,12 +19437,12 @@ snapshots: schema-utils: 3.3.0 semver: 7.7.3 tapable: 2.3.0 - typescript: 5.8.3 - webpack: 5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17)) + typescript: 5.9.3 + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) form-data-encoder@2.1.4: {} - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -19201,7 +19462,7 @@ snapshots: forwarded@0.2.0: {} - fraction.js@4.3.7: {} + fraction.js@5.3.4: {} fresh@0.5.2: {} @@ -19322,7 +19583,7 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 @@ -19338,7 +19599,13 @@ snapshots: minimatch: 10.1.1 minipass: 7.1.2 package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 + path-scurry: 2.0.1 + + glob@13.0.0: + dependencies: + minimatch: 10.1.1 + minipass: 7.1.2 + path-scurry: 2.0.1 glob@7.2.3: dependencies: @@ -19357,7 +19624,7 @@ snapshots: globals@15.15.0: {} - globals@16.4.0: {} + globals@16.5.0: {} globalyzer@0.1.0: {} @@ -19404,7 +19671,7 @@ snapshots: gray-matter@4.0.3: dependencies: - js-yaml: 3.14.1 + js-yaml: 3.14.2 kind-of: 6.0.3 section-matter: 1.0.0 strip-bom-string: 1.0.0 @@ -19669,7 +19936,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.4(webpack@5.102.1): + html-webpack-plugin@5.6.4(webpack@5.103.0): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -19677,7 +19944,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.0 optionalDependencies: - webpack: 5.102.1 + webpack: 5.103.0 htmlparser2@6.1.0: dependencies: @@ -19725,6 +19992,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-parser-js@0.5.10: {} http-proxy-agent@5.0.0: @@ -19797,6 +20072,7 @@ snapshots: iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 + optional: true iconv-lite@0.7.0: dependencies: @@ -19814,7 +20090,7 @@ snapshots: image-size@2.0.2: {} - imagetools-core@8.0.0: {} + imagetools-core@9.1.0: {} immediate@3.3.0: {} @@ -19855,9 +20131,11 @@ snapshots: inline-style-parser@0.2.4: {} - inquirer@8.2.7(@types/node@22.19.0): + inline-style-parser@0.2.7: {} + + inquirer@8.2.7(@types/node@24.10.1): dependencies: - '@inquirer/external-editor': 1.0.2(@types/node@22.19.0) + '@inquirer/external-editor': 1.0.3(@types/node@24.10.1) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -20071,7 +20349,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.19.0 + '@types/node': 24.10.1 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -20079,13 +20357,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -20112,12 +20390,12 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@3.14.1: + js-yaml@3.14.2: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -20132,7 +20410,7 @@ snapshots: decimal.js: 10.6.0 domexception: 4.0.0 escodegen: 2.1.0 - form-data: 4.0.4 + form-data: 4.0.5 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -20217,8 +20495,6 @@ snapshots: - utf-8-validate optional: true - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -20307,9 +20583,9 @@ snapshots: escape-html: 1.0.3 fresh: 0.5.2 http-assert: 1.5.0 - http-errors: 2.0.0 + http-errors: 2.0.1 koa-compose: 4.1.0 - mime-types: 3.0.1 + mime-types: 3.0.2 on-finished: 2.4.1 parseurl: 1.3.3 statuses: 2.0.2 @@ -20346,7 +20622,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.12.9: {} + libphonenumber-js@1.12.31: {} lightningcss-android-arm64@1.30.2: optional: true @@ -20494,7 +20770,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.1: {} + lru-cache@11.2.4: {} lru-cache@5.1.1: dependencies: @@ -20534,19 +20810,19 @@ snapshots: dependencies: semver: 7.7.3 - make-fetch-happen@14.0.3: + make-fetch-happen@15.0.3: dependencies: - '@npmcli/agent': 3.0.0 - cacache: 19.0.1 + '@npmcli/agent': 4.0.0 + cacache: 20.0.3 http-cache-semantics: 4.2.0 minipass: 7.1.2 - minipass-fetch: 4.0.1 + minipass-fetch: 5.0.0 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 negotiator: 1.0.0 - proc-log: 5.0.0 + proc-log: 6.1.0 promise-retry: 2.0.1 - ssri: 12.0.0 + ssri: 13.0.0 transitivePeerDependencies: - supports-color @@ -20575,7 +20851,7 @@ snapshots: tinyqueue: 2.0.3 vt-pbf: 3.1.3 - maplibre-gl@5.10.0: + maplibre-gl@5.13.0: dependencies: '@mapbox/geojson-rewind': 0.5.2 '@mapbox/jsonlint-lines-primitives': 2.0.2 @@ -20585,6 +20861,7 @@ snapshots: '@mapbox/vector-tile': 2.0.4 '@mapbox/whoots-js': 3.1.0 '@maplibre/maplibre-gl-style-spec': 24.3.1 + '@maplibre/mlt': 1.1.0 '@maplibre/vt-pbf': 4.0.3 '@types/geojson': 7946.0.16 '@types/geojson-vt': 3.2.5 @@ -21160,7 +21437,7 @@ snapshots: dependencies: mime-db: 1.52.0 - mime-types@3.0.1: + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -21181,11 +21458,11 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.4(webpack@5.102.1): + mini-css-extract-plugin@2.9.4(webpack@5.103.0): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 - webpack: 5.102.1 + webpack: 5.103.0 minimalistic-assert@1.0.1: {} @@ -21211,7 +21488,7 @@ snapshots: dependencies: minipass: 7.1.2 - minipass-fetch@4.0.1: + minipass-fetch@5.0.0: dependencies: minipass: 7.1.2 minipass-sized: 1.0.3 @@ -21319,7 +21596,7 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.23.0: + nan@2.23.1: optional: true nanoid@3.3.11: {} @@ -21343,39 +21620,39 @@ snapshots: neo-async@2.6.2: {} - nest-commander@3.20.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(@types/inquirer@8.2.11)(@types/node@22.19.0)(typescript@5.9.3): + nest-commander@3.20.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@types/inquirer@8.2.11)(@types/node@24.10.1)(typescript@5.9.3): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@types/inquirer': 8.2.11 commander: 11.1.0 cosmiconfig: 8.3.6(typescript@5.9.3) - inquirer: 8.2.7(@types/node@22.19.0) + inquirer: 8.2.7(@types/node@24.10.1) transitivePeerDependencies: - '@types/node' - typescript - nestjs-cls@5.4.3(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@5.4.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)(kysely@0.28.2)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(kysely@0.28.2)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) kysely: 0.28.2 reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-otel@7.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8): + nestjs-otel@7.0.1(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9): dependencies: - '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(@nestjs/websockets@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(@nestjs/websockets@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': 1.9.0 '@opentelemetry/host-metrics': 0.36.0(@opentelemetry/api@1.9.0) response-time: 2.3.4 @@ -21425,24 +21702,24 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@11.5.0: + node-gyp@12.1.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 graceful-fs: 4.2.11 - make-fetch-happen: 14.0.3 - nopt: 8.1.0 - proc-log: 5.0.0 + make-fetch-happen: 15.0.3 + nopt: 9.0.0 + proc-log: 6.1.0 semver: 7.7.3 - tar: 7.5.1 + tar: 7.5.2 tinyglobby: 0.2.15 - which: 5.0.0 + which: 6.0.0 transitivePeerDependencies: - supports-color - node-releases@2.0.26: {} + node-releases@2.0.27: {} - nodemailer@7.0.10: {} + nodemailer@7.0.11: {} nopt@1.0.10: dependencies: @@ -21452,9 +21729,9 @@ snapshots: dependencies: abbrev: 1.1.1 - nopt@8.1.0: + nopt@9.0.0: dependencies: - abbrev: 3.0.1 + abbrev: 4.0.0 normalize-path@3.0.0: {} @@ -21483,11 +21760,11 @@ snapshots: dependencies: boolbase: 1.0.0 - null-loader@4.0.1(webpack@5.102.1): + null-loader@4.0.1(webpack@5.103.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.102.1 + webpack: 5.103.0 nwsapi@2.2.22: optional: true @@ -21534,7 +21811,7 @@ snapshots: koa: 3.1.1 nanoid: 5.1.6 quick-lru: 7.3.0 - raw-body: 3.0.1 + raw-body: 3.0.2 transitivePeerDependencies: - supports-color @@ -21623,7 +21900,7 @@ snapshots: p-limit@4.0.0: dependencies: - yocto-queue: 1.2.1 + yocto-queue: 1.2.2 p-locate@4.1.0: dependencies: @@ -21641,7 +21918,7 @@ snapshots: dependencies: aggregate-error: 3.1.0 - p-map@7.0.3: {} + p-map@7.0.4: {} p-queue@6.6.2: dependencies: @@ -21739,9 +22016,9 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-scurry@2.0.0: + path-scurry@2.0.1: dependencies: - lru-cache: 11.2.1 + lru-cache: 11.2.4 minipass: 7.1.2 path-source@0.1.3: @@ -21833,11 +22110,11 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 - playwright-core@1.56.1: {} + playwright-core@1.57.0: {} - playwright@1.56.1: + playwright@1.57.0: dependencies: - playwright-core: 1.56.1 + playwright-core: 1.57.0 optionalDependencies: fsevents: 2.3.2 @@ -21899,7 +22176,7 @@ snapshots: postcss-colormin@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 caniuse-api: 3.0.0 colord: 2.9.3 postcss: 8.5.6 @@ -21907,7 +22184,7 @@ snapshots: postcss-convert-values@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -22021,21 +22298,21 @@ snapshots: optionalDependencies: postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 - yaml: 2.8.1 + yaml: 2.8.2 - postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.9.3)(webpack@5.102.1): + postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.9.3)(webpack@5.103.0): dependencies: cosmiconfig: 8.3.6(typescript@5.9.3) jiti: 1.21.7 postcss: 8.5.6 semver: 7.7.3 - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - typescript @@ -22058,7 +22335,7 @@ snapshots: postcss-merge-rules@6.1.1(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 caniuse-api: 3.0.0 cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 @@ -22078,7 +22355,7 @@ snapshots: postcss-minify-params@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -22152,7 +22429,7 @@ snapshots: postcss-normalize-unicode@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -22228,8 +22505,8 @@ snapshots: '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.6) '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.6) '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.6) - autoprefixer: 10.4.21(postcss@8.5.6) - browserslist: 4.27.0 + autoprefixer: 10.4.22(postcss@8.5.6) + browserslist: 4.28.0 css-blank-pseudo: 7.0.1(postcss@8.5.6) css-has-pseudo: 7.0.3(postcss@8.5.6) css-prefers-color-scheme: 10.0.0(postcss@8.5.6) @@ -22273,7 +22550,7 @@ snapshots: postcss-reduce-initial@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 caniuse-api: 3.0.0 postcss: 8.5.6 @@ -22359,21 +22636,21 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-organize-imports@4.3.0(prettier@3.6.2)(typescript@5.9.3): + prettier-plugin-organize-imports@4.3.0(prettier@3.7.1)(typescript@5.9.3): dependencies: - prettier: 3.6.2 + prettier: 3.7.1 typescript: 5.9.3 - prettier-plugin-sort-json@4.1.1(prettier@3.6.2): + prettier-plugin-sort-json@4.1.1(prettier@3.7.1): dependencies: - prettier: 3.6.2 + prettier: 3.7.1 - prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.43.0): + prettier-plugin-svelte@3.4.0(prettier@3.7.1)(svelte@5.45.2): dependencies: - prettier: 3.6.2 - svelte: 5.43.0 + prettier: 3.7.1 + svelte: 5.45.2 - prettier@3.6.2: {} + prettier@3.7.1: {} pretty-error@4.0.0: dependencies: @@ -22396,7 +22673,7 @@ snapshots: prismjs@1.30.0: {} - proc-log@5.0.0: {} + proc-log@6.1.0: {} process-nextick-args@2.0.1: {} @@ -22450,7 +22727,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.19.0 + '@types/node': 24.10.1 long: 5.3.2 protocol-buffers-schema@3.6.0: {} @@ -22484,10 +22761,6 @@ snapshots: pngjs: 5.0.0 yargs: 15.4.1 - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -22520,25 +22793,25 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.2: + raw-body@2.5.3: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.1: + raw-body@3.0.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.7.0 unpipe: 1.0.0 - raw-loader@4.0.2(webpack@5.102.1): + raw-loader@4.0.2(webpack@5.103.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.102.1 + webpack: 5.103.0 rc@1.2.8: dependencies: @@ -22569,7 +22842,7 @@ snapshots: glob: 11.0.3 jiti: 2.4.2 log-symbols: 7.0.1 - mime-types: 3.0.1 + mime-types: 3.0.2 normalize-path: 3.0.0 nypm: 0.6.0 ora: 8.2.0 @@ -22591,11 +22864,11 @@ snapshots: dependencies: react: 18.3.1 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.102.1): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.103.0): dependencies: '@babel/runtime': 7.28.4 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - webpack: 5.102.1 + webpack: 5.103.0 react-promise-suspense@0.3.4: dependencies: @@ -22744,10 +23017,6 @@ snapshots: regjsgen@0.8.0: {} - regjsparser@0.12.0: - dependencies: - jsesc: 3.0.2 - regjsparser@0.13.0: dependencies: jsesc: 3.1.0 @@ -22916,41 +23185,41 @@ snapshots: robust-predicates@3.0.2: {} - rollup-plugin-visualizer@6.0.5(rollup@4.52.5): + rollup-plugin-visualizer@6.0.5(rollup@4.53.3): dependencies: open: 8.4.2 picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: - rollup: 4.52.5 + rollup: 4.53.3 - rollup@4.52.5: + rollup@4.53.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.5 - '@rollup/rollup-android-arm64': 4.52.5 - '@rollup/rollup-darwin-arm64': 4.52.5 - '@rollup/rollup-darwin-x64': 4.52.5 - '@rollup/rollup-freebsd-arm64': 4.52.5 - '@rollup/rollup-freebsd-x64': 4.52.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 - '@rollup/rollup-linux-arm-musleabihf': 4.52.5 - '@rollup/rollup-linux-arm64-gnu': 4.52.5 - '@rollup/rollup-linux-arm64-musl': 4.52.5 - '@rollup/rollup-linux-loong64-gnu': 4.52.5 - '@rollup/rollup-linux-ppc64-gnu': 4.52.5 - '@rollup/rollup-linux-riscv64-gnu': 4.52.5 - '@rollup/rollup-linux-riscv64-musl': 4.52.5 - '@rollup/rollup-linux-s390x-gnu': 4.52.5 - '@rollup/rollup-linux-x64-gnu': 4.52.5 - '@rollup/rollup-linux-x64-musl': 4.52.5 - '@rollup/rollup-openharmony-arm64': 4.52.5 - '@rollup/rollup-win32-arm64-msvc': 4.52.5 - '@rollup/rollup-win32-ia32-msvc': 4.52.5 - '@rollup/rollup-win32-x64-gnu': 4.52.5 - '@rollup/rollup-win32-x64-msvc': 4.52.5 + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 router@2.2.0: @@ -22981,10 +23250,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 - runed@0.29.2(svelte@5.43.0): + runed@0.35.1(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2): dependencies: + dequal: 2.0.3 esm-env: 1.2.2 - svelte: 5.43.0 + lz-string: 1.5.0 + svelte: 5.45.2 + optionalDependencies: + '@sveltejs/kit': 2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) rw@1.3.3: {} @@ -23091,6 +23364,24 @@ snapshots: transitivePeerDependencies: - supports-color + send@0.19.1: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + send@1.2.0: dependencies: debug: 4.4.3 @@ -23098,8 +23389,8 @@ snapshots: escape-html: 1.0.3 etag: 1.8.1 fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 + http-errors: 2.0.1 + mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 @@ -23183,36 +23474,38 @@ snapshots: stream-source: 0.3.5 text-encoding: 0.6.4 - sharp@0.34.4: + sharp@0.34.5: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 node-addon-api: 8.5.0 - node-gyp: 11.5.0 + node-gyp: 12.1.0 semver: 7.7.3 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.4 - '@img/sharp-darwin-x64': 0.34.4 - '@img/sharp-libvips-darwin-arm64': 1.2.3 - '@img/sharp-libvips-darwin-x64': 1.2.3 - '@img/sharp-libvips-linux-arm': 1.2.3 - '@img/sharp-libvips-linux-arm64': 1.2.3 - '@img/sharp-libvips-linux-ppc64': 1.2.3 - '@img/sharp-libvips-linux-s390x': 1.2.3 - '@img/sharp-libvips-linux-x64': 1.2.3 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - '@img/sharp-linux-arm': 0.34.4 - '@img/sharp-linux-arm64': 0.34.4 - '@img/sharp-linux-ppc64': 0.34.4 - '@img/sharp-linux-s390x': 0.34.4 - '@img/sharp-linux-x64': 0.34.4 - '@img/sharp-linuxmusl-arm64': 0.34.4 - '@img/sharp-linuxmusl-x64': 0.34.4 - '@img/sharp-wasm32': 0.34.4 - '@img/sharp-win32-arm64': 0.34.4 - '@img/sharp-win32-ia32': 0.34.4 - '@img/sharp-win32-x64': 0.34.4 + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 transitivePeerDependencies: - supports-color @@ -23268,7 +23561,7 @@ snapshots: simple-concat: 1.0.1 optional: true - simple-icons@15.18.0: {} + simple-icons@15.22.0: {} sirv@2.0.4: dependencies: @@ -23432,9 +23725,9 @@ snapshots: bcrypt-pbkdf: 1.0.2 optionalDependencies: cpu-features: 0.0.10 - nan: 2.23.0 + nan: 2.23.1 - ssri@12.0.0: + ssri@13.0.0: dependencies: minipass: 7.1.2 @@ -23519,9 +23812,7 @@ snapshots: dependencies: min-indent: 1.0.1 - strip-indent@4.0.0: - dependencies: - min-indent: 1.0.1 + strip-indent@4.1.1: {} strip-json-comments@2.0.1: {} @@ -23545,20 +23836,24 @@ snapshots: dependencies: inline-style-parser: 0.2.4 + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + stylehacks@6.1.1(postcss@8.5.6): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 postcss: 8.5.6 postcss-selector-parser: 6.1.2 - sucrase@3.35.0: + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 + tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 superagent@10.2.3: @@ -23567,7 +23862,7 @@ snapshots: cookiejar: 2.1.4 debug: 4.4.3 fast-safe-stringify: 2.1.1 - form-data: 4.0.4 + form-data: 4.0.5 formidable: 3.5.4 methods: 1.1.2 mime: 2.6.0 @@ -23600,19 +23895,19 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.3.3(picomatch@4.0.3)(svelte@5.43.0)(typescript@5.9.3): + svelte-check@4.3.4(picomatch@4.0.3)(svelte@5.45.2)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.43.0 + svelte: 5.45.2 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.4.0(svelte@5.43.0): + svelte-eslint-parser@1.4.0(svelte@5.45.2): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -23621,15 +23916,15 @@ snapshots: postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.43.0 + svelte: 5.45.2 svelte-gestures@5.2.2: {} - svelte-highlight@7.8.4: + svelte-highlight@7.9.0: dependencies: highlight.js: 11.11.1 - svelte-i18n@4.0.1(svelte@5.43.0): + svelte-i18n@4.0.1(svelte@5.45.2): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -23637,45 +23932,48 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.18 sade: 1.8.1 - svelte: 5.43.0 + svelte: 5.45.2 tiny-glob: 0.2.9 - svelte-maplibre@1.2.5(svelte@5.43.0): + svelte-maplibre@1.2.5(svelte@5.45.2): dependencies: d3-geo: 3.1.1 dequal: 2.0.3 just-compare: 2.3.0 - maplibre-gl: 5.10.0 + maplibre-gl: 5.13.0 pmtiles: 3.2.1 - svelte: 5.43.0 + svelte: 5.45.2 - svelte-parse-markup@0.1.5(svelte@5.43.0): + svelte-parse-markup@0.1.5(svelte@5.45.2): dependencies: - svelte: 5.43.0 + svelte: 5.45.2 - svelte-persisted-store@0.12.0(svelte@5.43.0): + svelte-persisted-store@0.12.0(svelte@5.45.2): dependencies: - svelte: 5.43.0 + svelte: 5.45.2 - svelte-toolbelt@0.9.3(svelte@5.43.0): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2): dependencies: clsx: 2.1.1 - runed: 0.29.2(svelte@5.43.0) - style-to-object: 1.0.11 - svelte: 5.43.0 + runed: 0.35.1(@sveltejs/kit@2.49.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)))(svelte@5.45.2) + style-to-object: 1.0.14 + svelte: 5.45.2 + transitivePeerDependencies: + - '@sveltejs/kit' - svelte@5.43.0: + svelte@5.45.2: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) '@types/estree': 1.0.8 acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 + devalue: 5.5.0 esm-env: 1.2.2 - esrap: 2.1.0 + esrap: 2.2.0 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 @@ -23693,7 +23991,7 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swagger-ui-dist@5.29.4: + swagger-ui-dist@5.30.2: dependencies: '@scarf/scarf': 1.4.0 @@ -23716,29 +24014,29 @@ snapshots: tabbable@6.3.0: {} - tailwind-merge@3.3.1: {} + tailwind-merge@3.4.0: {} - tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.16): + tailwind-variants@3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.17): dependencies: - tailwindcss: 4.1.16 + tailwindcss: 4.1.17 optionalDependencies: - tailwind-merge: 3.3.1 + tailwind-merge: 3.4.0 - tailwindcss-email-variants@3.0.5(tailwindcss@3.4.18(yaml@2.8.1)): + tailwindcss-email-variants@3.0.5(tailwindcss@3.4.18(yaml@2.8.2)): dependencies: - tailwindcss: 3.4.18(yaml@2.8.1) + tailwindcss: 3.4.18(yaml@2.8.2) - tailwindcss-mso@2.0.3(tailwindcss@3.4.18(yaml@2.8.1)): + tailwindcss-mso@2.0.3(tailwindcss@3.4.18(yaml@2.8.2)): dependencies: - tailwindcss: 3.4.18(yaml@2.8.1) + tailwindcss: 3.4.18(yaml@2.8.2) - tailwindcss-preset-email@1.4.1(tailwindcss@3.4.18(yaml@2.8.1)): + tailwindcss-preset-email@1.4.1(tailwindcss@3.4.18(yaml@2.8.2)): dependencies: - tailwindcss: 3.4.18(yaml@2.8.1) - tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.18(yaml@2.8.1)) - tailwindcss-mso: 2.0.3(tailwindcss@3.4.18(yaml@2.8.1)) + tailwindcss: 3.4.18(yaml@2.8.2) + tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.18(yaml@2.8.2)) + tailwindcss-mso: 2.0.3(tailwindcss@3.4.18(yaml@2.8.2)) - tailwindcss@3.4.18(yaml@2.8.1): + tailwindcss@3.4.18(yaml@2.8.2): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -23757,16 +24055,16 @@ snapshots: postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) postcss-js: 4.1.0(postcss@8.5.6) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.11 - sucrase: 3.35.0 + sucrase: 3.35.1 transitivePeerDependencies: - tsx - yaml - tailwindcss@4.1.16: {} + tailwindcss@4.1.17: {} tapable@2.3.0: {} @@ -23782,7 +24080,7 @@ snapshots: pump: 3.0.3 tar-stream: 3.1.7 optionalDependencies: - bare-fs: 4.5.0 + bare-fs: 4.5.2 bare-path: 3.0.0 transitivePeerDependencies: - bare-abort-controller @@ -23813,7 +24111,7 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - tar@7.5.1: + tar@7.5.2: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -23821,25 +24119,25 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - terser-webpack-plugin@5.3.14(@swc/core@1.14.0(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17))): + terser-webpack-plugin@5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.0 - webpack: 5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: - '@swc/core': 1.14.0(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) - terser-webpack-plugin@5.3.14(webpack@5.102.1): + terser-webpack-plugin@5.3.14(webpack@5.103.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.0 - webpack: 5.102.1 + webpack: 5.103.0 terser@5.44.0: dependencies: @@ -23851,13 +24149,13 @@ snapshots: test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 + glob: 10.5.0 minimatch: 9.0.5 - testcontainers@11.7.2: + testcontainers@11.9.0: dependencies: '@balena/dockerignore': 1.0.2 - '@types/dockerode': 3.3.45 + '@types/dockerode': 3.3.47 archiver: 7.0.1 async-lock: 1.4.1 byline: 5.0.0 @@ -23997,8 +24295,6 @@ snapshots: dependencies: tslib: 2.8.1 - tree-kill@1.2.2: {} - trim-lines@3.0.1: {} trough@1.0.5: {} @@ -24057,7 +24353,7 @@ snapshots: dependencies: content-type: 1.0.5 media-typer: 1.1.0 - mime-types: 3.0.1 + mime-types: 3.0.2 type@2.7.3: {} @@ -24067,19 +24363,17 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.38.0(jiti@2.6.1) + '@typescript-eslint/eslint-plugin': 8.48.0(@typescript-eslint/parser@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} - typescript@5.9.3: {} ua-is-frozen@0.1.2: {} @@ -24105,8 +24399,7 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.16.0: - optional: true + undici-types@7.16.0: {} undici@7.16.0: {} @@ -24143,11 +24436,11 @@ snapshots: trough: 1.0.5 vfile: 4.2.1 - unique-filename@4.0.0: + unique-filename@5.0.0: dependencies: - unique-slug: 5.0.0 + unique-slug: 6.0.0 - unique-slug@5.0.0: + unique-slug@6.0.0: dependencies: imurmurhash: 0.1.4 @@ -24210,25 +24503,25 @@ snapshots: unpipe@1.0.0: {} - unplugin-swc@1.5.8(@swc/core@1.14.0(@swc/helpers@0.5.17))(rollup@4.52.5): + unplugin-swc@1.5.9(@swc/core@1.15.3(@swc/helpers@0.5.17))(rollup@4.53.3): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - '@swc/core': 1.14.0(@swc/helpers@0.5.17) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) load-tsconfig: 0.2.5 - unplugin: 2.3.10 + unplugin: 2.3.11 transitivePeerDependencies: - rollup - unplugin@2.3.10: + unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 acorn: 8.15.0 picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.1.4(browserslist@4.27.0): + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -24249,18 +24542,20 @@ snapshots: semver-diff: 4.0.0 xdg-basedir: 5.1.0 + uplot@1.6.32: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.102.1 + webpack: 5.103.0 optionalDependencies: - file-loader: 6.2.0(webpack@5.102.1) + file-loader: 6.2.0(webpack@5.103.0) url-parse@1.5.10: dependencies: @@ -24303,7 +24598,7 @@ snapshots: uuid@8.3.2: {} - validator@13.15.20: {} + validator@13.15.23: {} value-equal@1.0.1: {} @@ -24338,22 +24633,22 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-imagetools@8.0.0(rollup@4.52.5): + vite-imagetools@9.0.2(rollup@4.53.3): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - imagetools-core: 8.0.0 - sharp: 0.34.4 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + imagetools-core: 9.1.0 + sharp: 0.34.5 transitivePeerDependencies: - rollup - supports-color - vite-node@3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -24368,83 +24663,46 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript - vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.5 + rollup: 4.53.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.1 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 terser: 5.44.0 - yaml: 2.8.1 + yaml: 2.8.2 - vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): - dependencies: - esbuild: 0.25.12 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.52.5 - tinyglobby: 0.2.15 + vitefu@1.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)): optionalDependencies: - '@types/node': 24.10.0 - fsevents: 2.3.3 - jiti: 2.6.1 - lightningcss: 1.30.2 - terser: 5.44.0 - yaml: 2.8.1 + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) - vitefu@1.1.1(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): - optionalDependencies: - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - - vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): + vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)): dependencies: - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -24462,12 +24720,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.19.0 + '@types/node': 24.10.1 happy-dom: 20.0.10 jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) transitivePeerDependencies: @@ -24484,11 +24742,11 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -24506,56 +24764,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.19.0 - happy-dom: 20.0.10 - jsdom: 26.1.0(canvas@2.11.2) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): - dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.0 - debug: 4.4.3 - expect-type: 1.2.1 - magic-string: 0.30.21 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 24.10.0 + '@types/node': 24.10.1 happy-dom: 20.0.10 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: @@ -24628,18 +24842,18 @@ snapshots: - bufferutil - utf-8-validate - webpack-dev-middleware@7.4.5(webpack@5.102.1): + webpack-dev-middleware@7.4.5(webpack@5.103.0): dependencies: colorette: 2.0.20 memfs: 4.50.0 - mime-types: 3.0.1 + mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.102.1 + webpack: 5.103.0 - webpack-dev-server@5.2.2(webpack@5.102.1): + webpack-dev-server@5.2.2(webpack@5.103.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -24655,7 +24869,7 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.2.0 @@ -24667,10 +24881,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(webpack@5.102.1) + webpack-dev-middleware: 7.4.5(webpack@5.103.0) ws: 8.18.3 optionalDependencies: - webpack: 5.102.1 + webpack: 5.103.0 transitivePeerDependencies: - bufferutil - debug @@ -24695,7 +24909,7 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17)): + webpack@5.103.0: dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -24705,7 +24919,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.15.0 acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.27.0 + browserslist: 4.28.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.3 es-module-lexer: 1.7.0 @@ -24719,7 +24933,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.14.0(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.14.0(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -24727,7 +24941,7 @@ snapshots: - esbuild - uglify-js - webpack@5.102.1: + webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -24737,7 +24951,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.15.0 acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.27.0 + browserslist: 4.28.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.3 es-module-lexer: 1.7.0 @@ -24751,7 +24965,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(webpack@5.102.1) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -24759,7 +24973,7 @@ snapshots: - esbuild - uglify-js - webpackbar@6.0.1(webpack@5.102.1): + webpackbar@6.0.1(webpack@5.103.0): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 @@ -24768,7 +24982,7 @@ snapshots: markdown-table: 2.0.0 pretty-time: 1.1.0 std-env: 3.10.0 - webpack: 5.102.1 + webpack: 5.103.0 wrap-ansi: 7.0.0 websocket-driver@0.7.4: @@ -24821,7 +25035,7 @@ snapshots: dependencies: isexe: 2.0.0 - which@5.0.0: + which@6.0.0: dependencies: isexe: 3.1.1 @@ -24912,7 +25126,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} + yaml@2.8.2: {} yargs-parser@18.1.3: dependencies: @@ -24947,9 +25161,9 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.2.1: {} + yocto-queue@1.2.2: {} - yoctocolors-cjs@2.1.2: {} + yoctocolors-cjs@2.1.3: {} yoctocolors@2.1.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d5629d2323..33aaa744b0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -28,7 +28,7 @@ onlyBuiltDependencies: - bcrypt overrides: canvas: 2.11.2 - sharp: ^0.34.4 + sharp: ^0.34.5 packageExtensions: nestjs-kysely: dependencies: diff --git a/server/.nvmrc b/server/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/server/.nvmrc +++ b/server/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/server/Dockerfile b/server/Dockerfile index 0bb7fc6be5..267253ccd9 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/immich-app/base-server-dev:202511041104@sha256:7558931a4a71989e7fd9fa3e1ba6c28da15891867310edda8c58236171839f2f AS builder +FROM ghcr.io/immich-app/base-server-dev:202511261514@sha256:cbcca5851fd11042463f09797e6d6068d94adbb108749e62aa69159df59c0591 AS builder ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ COREPACK_HOME=/tmp \ @@ -50,12 +50,14 @@ RUN --mount=type=cache,id=pnpm-cli,target=/buildcache/pnpm-store \ FROM builder AS plugins -COPY --from=ghcr.io/jdx/mise:2025.11.3 /usr/local/bin/mise /usr/local/bin/mise +COPY --from=ghcr.io/jdx/mise:2025.11.3@sha256:ac26f5978c0e2783f3e68e58ce75eddb83e41b89bf8747c503bac2aa9baf22c5 /usr/local/bin/mise /usr/local/bin/mise WORKDIR /usr/src/app COPY ./plugins/mise.toml ./plugins/ ENV MISE_TRUSTED_CONFIG_PATHS=/usr/src/app/plugins/mise.toml -RUN mise install --cd plugins +ENV MISE_DATA_DIR=/buildcache/mise +RUN --mount=type=cache,id=mise-tools,target=/buildcache/mise \ + mise install --cd plugins COPY ./plugins ./plugins/ # Build plugins @@ -64,9 +66,10 @@ RUN --mount=type=cache,id=pnpm-plugins,target=/buildcache/pnpm-store \ --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ + --mount=type=cache,id=mise-tools,target=/buildcache/mise \ cd plugins && mise run build -FROM ghcr.io/immich-app/base-server-prod:202511041104@sha256:57c0379977fd5521d83cdf661aecd1497c83a9a661ebafe0a5243a09fc1064cb +FROM ghcr.io/immich-app/base-server-prod:202511261514@sha256:c04c1c38dd90e53455b180aedf93c3c63474c8d20ffe2c6d7a3a61a2181e6d29 WORKDIR /usr/src/app ENV NODE_ENV=production \ diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev index 133b8a835d..5a71d61e2a 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -1,5 +1,5 @@ # dev build -FROM ghcr.io/immich-app/base-server-dev:202511041104@sha256:7558931a4a71989e7fd9fa3e1ba6c28da15891867310edda8c58236171839f2f AS dev +FROM ghcr.io/immich-app/base-server-dev:202511261514@sha256:cbcca5851fd11042463f09797e6d6068d94adbb108749e62aa69159df59c0591 AS dev ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ @@ -44,18 +44,18 @@ FROM dev-container-server AS dev-container-mobile USER root # Enable multiarch for arm64 if necessary RUN if [ "$(dpkg --print-architecture)" = "arm64" ]; then \ - dpkg --add-architecture amd64 && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - gnupg \ - qemu-user-static \ - libc6:amd64 \ - libstdc++6:amd64 \ - libgcc1:amd64; \ + dpkg --add-architecture amd64 && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + gnupg \ + qemu-user-static \ + libc6:amd64 \ + libstdc++6:amd64 \ + libgcc1:amd64; \ else \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - gnupg; \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + gnupg; \ fi # Flutter SDK diff --git a/server/bin/immich-dev b/server/bin/immich-dev index 28a0443be7..84c5eea8da 100755 --- a/server/bin/immich-dev +++ b/server/bin/immich-dev @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [ "$IMMICH_ENV" != "development" ]; then +if [[ "$IMMICH_ENV" == "production" ]]; then echo "This command can only be run in development environments" exit 1 fi diff --git a/server/package.json b/server/package.json index a252a53b8a..915e45c116 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "immich", - "version": "2.2.3", + "version": "2.3.1", "description": "", "author": "", "private": true, @@ -45,14 +45,14 @@ "@nestjs/websockets": "^11.0.4", "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.0.0", - "@opentelemetry/exporter-prometheus": "^0.207.0", - "@opentelemetry/instrumentation-http": "^0.207.0", - "@opentelemetry/instrumentation-ioredis": "^0.55.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.54.0", - "@opentelemetry/instrumentation-pg": "^0.60.0", + "@opentelemetry/exporter-prometheus": "^0.208.0", + "@opentelemetry/instrumentation-http": "^0.208.0", + "@opentelemetry/instrumentation-ioredis": "^0.56.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.55.0", + "@opentelemetry/instrumentation-pg": "^0.61.0", "@opentelemetry/resources": "^2.0.1", "@opentelemetry/sdk-metrics": "^2.0.1", - "@opentelemetry/sdk-node": "^0.207.0", + "@opentelemetry/sdk-node": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.34.0", "@react-email/components": "^0.5.0", "@react-email/render": "^1.1.2", @@ -70,7 +70,7 @@ "cookie": "^1.0.2", "cookie-parser": "^1.4.7", "cron": "4.3.3", - "exiftool-vendored": "^31.1.0", + "exiftool-vendored": "^33.0.0", "express": "^5.1.0", "fast-glob": "^3.3.2", "fluent-ffmpeg": "^2.1.2", @@ -78,6 +78,7 @@ "handlebars": "^4.7.8", "i18n-iso-countries": "^7.6.0", "ioredis": "^5.8.2", + "jose": "^5.10.0", "js-yaml": "^4.1.0", "jsonwebtoken": "^9.0.2", "kysely": "0.28.2", @@ -104,7 +105,7 @@ "sanitize-filename": "^1.6.3", "sanitize-html": "^2.14.0", "semver": "^7.6.2", - "sharp": "^0.34.4", + "sharp": "^0.34.5", "sirv": "^3.0.0", "socket.io": "^4.8.1", "tailwindcss-preset-email": "^1.4.0", @@ -119,7 +120,7 @@ "@nestjs/schematics": "^11.0.0", "@nestjs/testing": "^11.0.4", "@swc/core": "^1.4.14", - "@types/archiver": "^6.0.0", + "@types/archiver": "^7.0.0", "@types/async-lock": "^1.4.2", "@types/bcrypt": "^6.0.0", "@types/body-parser": "^1.19.6", @@ -133,7 +134,7 @@ "@types/luxon": "^3.6.2", "@types/mock-fs": "^4.13.1", "@types/multer": "^2.0.0", - "@types/node": "^22.19.0", + "@types/node": "^24.10.1", "@types/nodemailer": "^7.0.0", "@types/picomatch": "^4.0.0", "@types/pngjs": "^6.0.5", @@ -147,10 +148,10 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", + "eslint-plugin-unicorn": "^62.0.0", "globals": "^16.0.0", "mock-fs": "^5.2.0", - "node-gyp": "^11.2.0", + "node-gyp": "^12.0.0", "pngjs": "^7.0.0", "prettier": "^3.0.2", "prettier-plugin-organize-imports": "^4.0.0", @@ -165,9 +166,9 @@ "vitest": "^3.0.0" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" }, "overrides": { - "sharp": "^0.34.4" + "sharp": "^0.34.5" } } diff --git a/server/src/app.common.ts b/server/src/app.common.ts new file mode 100644 index 0000000000..934c13343f --- /dev/null +++ b/server/src/app.common.ts @@ -0,0 +1,87 @@ +import { NestExpressApplication } from '@nestjs/platform-express'; +import { json } from 'body-parser'; +import compression from 'compression'; +import cookieParser from 'cookie-parser'; +import { existsSync } from 'node:fs'; +import sirv from 'sirv'; +import { excludePaths, serverVersion } from 'src/constants'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; +import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; +import { ConfigRepository } from 'src/repositories/config.repository'; +import { LoggingRepository } from 'src/repositories/logging.repository'; +import { bootstrapTelemetry } from 'src/repositories/telemetry.repository'; +import { ApiService } from 'src/services/api.service'; +import { useSwagger } from 'src/utils/misc'; + +export function configureTelemetry() { + const { telemetry } = new ConfigRepository().getEnv(); + if (telemetry.metrics.size > 0) { + bootstrapTelemetry(telemetry.apiPort); + } +} + +export async function configureExpress( + app: NestExpressApplication, + { + permitSwaggerWrite = true, + ssr, + }: { + /** + * Whether to allow swagger module to write to the specs.json + * This is not desirable when the API is not available + * @default true + */ + permitSwaggerWrite?: boolean; + /** + * Service to use for server-side rendering + */ + ssr: typeof ApiService | typeof MaintenanceWorkerService; + }, +) { + const configRepository = app.get(ConfigRepository); + const { environment, host, port, resourcePaths, network } = configRepository.getEnv(); + + const logger = await app.resolve(LoggingRepository); + logger.setContext('Bootstrap'); + app.useLogger(logger); + + app.set('trust proxy', ['loopback', ...network.trustedProxies]); + app.set('etag', 'strong'); + app.use(cookieParser()); + app.use(json({ limit: '10mb' })); + + if (configRepository.isDev()) { + app.enableCors(); + } + + app.setGlobalPrefix('api', { exclude: excludePaths }); + app.useWebSocketAdapter(new WebSocketAdapter(app)); + + useSwagger(app, { write: configRepository.isDev() && permitSwaggerWrite }); + + if (existsSync(resourcePaths.web.root)) { + // copied from https://github.com/sveltejs/kit/blob/679b5989fe62e3964b9a73b712d7b41831aa1f07/packages/adapter-node/src/handler.js#L46 + // provides serving of precompressed assets and caching of immutable assets + app.use( + sirv(resourcePaths.web.root, { + etag: true, + gzip: true, + brotli: true, + extensions: [], + setHeaders: (res, pathname) => { + if (pathname.startsWith(`/_app/immutable`) && res.statusCode === 200) { + res.setHeader('cache-control', 'public,max-age=31536000,immutable'); + } + }, + }), + ); + } + + app.use(app.get(ssr).ssr(excludePaths)); + app.use(compression()); + + const server = await (host ? app.listen(port, host) : app.listen(port)); + server.requestTimeout = 24 * 60 * 60 * 1000; + + logger.log(`Immich Server is listening on ${await app.getUrl()} [v${serverVersion}] [${environment}] `); +} diff --git a/server/src/app.module.ts b/server/src/app.module.ts index f80a47bb77..caa4ea4b6e 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -9,15 +9,21 @@ import { commandsAndQuestions } from 'src/commands'; import { IWorker } from 'src/constants'; import { controllers } from 'src/controllers'; import { ImmichWorker } from 'src/enum'; +import { MaintenanceAuthGuard } from 'src/maintenance/maintenance-auth.guard'; +import { MaintenanceWebsocketRepository } from 'src/maintenance/maintenance-websocket.repository'; +import { MaintenanceWorkerController } from 'src/maintenance/maintenance-worker.controller'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; import { AuthGuard } from 'src/middleware/auth.guard'; import { ErrorInterceptor } from 'src/middleware/error.interceptor'; import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor'; import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter'; import { LoggingInterceptor } from 'src/middleware/logging.interceptor'; import { repositories } from 'src/repositories'; +import { AppRepository } from 'src/repositories/app.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; import { EventRepository } from 'src/repositories/event.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; +import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository'; import { WebsocketRepository } from 'src/repositories/websocket.repository'; import { services } from 'src/services'; @@ -28,27 +34,27 @@ import { getKyselyConfig } from 'src/utils/database'; const common = [...repositories, ...services, GlobalExceptionFilter]; -export const middleware = [ - FileUploadInterceptor, +const commonMiddleware = [ { provide: APP_FILTER, useClass: GlobalExceptionFilter }, { provide: APP_PIPE, useValue: new ValidationPipe({ transform: true, whitelist: true }) }, { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor }, { provide: APP_INTERCEPTOR, useClass: ErrorInterceptor }, - { provide: APP_GUARD, useClass: AuthGuard }, ]; +const apiMiddleware = [FileUploadInterceptor, ...commonMiddleware, { provide: APP_GUARD, useClass: AuthGuard }]; + const configRepository = new ConfigRepository(); const { bull, cls, database, otel } = configRepository.getEnv(); -const imports = [ - BullModule.forRoot(bull.config), - BullModule.registerQueue(...bull.queues), +const commonImports = [ ClsModule.forRoot(cls.config), - OpenTelemetryModule.forRoot(otel), KyselyModule.forRoot(getKyselyConfig(database.config)), + OpenTelemetryModule.forRoot(otel), ]; -class BaseModule implements OnModuleInit, OnModuleDestroy { +const bullImports = [BullModule.forRoot(bull.config), BullModule.registerQueue(...bull.queues)]; + +export class BaseModule implements OnModuleInit, OnModuleDestroy { constructor( @Inject(IWorker) private worker: ImmichWorker, logger: LoggingRepository, @@ -85,20 +91,44 @@ class BaseModule implements OnModuleInit, OnModuleDestroy { } @Module({ - imports: [...imports, ScheduleModule.forRoot()], + imports: [...bullImports, ...commonImports, ScheduleModule.forRoot()], controllers: [...controllers], - providers: [...common, ...middleware, { provide: IWorker, useValue: ImmichWorker.Api }], + providers: [...common, ...apiMiddleware, { provide: IWorker, useValue: ImmichWorker.Api }], }) export class ApiModule extends BaseModule {} @Module({ - imports: [...imports], + imports: [...commonImports], + controllers: [MaintenanceWorkerController], + providers: [ + ConfigRepository, + LoggingRepository, + SystemMetadataRepository, + AppRepository, + MaintenanceWebsocketRepository, + MaintenanceWorkerService, + ...commonMiddleware, + { provide: APP_GUARD, useClass: MaintenanceAuthGuard }, + { provide: IWorker, useValue: ImmichWorker.Maintenance }, + ], +}) +export class MaintenanceModule { + constructor( + @Inject(IWorker) private worker: ImmichWorker, + logger: LoggingRepository, + ) { + logger.setAppName(this.worker); + } +} + +@Module({ + imports: [...bullImports, ...commonImports], providers: [...common, { provide: IWorker, useValue: ImmichWorker.Microservices }, SchedulerRegistry], }) export class MicroservicesModule extends BaseModule {} @Module({ - imports: [...imports], + imports: [...bullImports, ...commonImports], providers: [...common, ...commandsAndQuestions, SchedulerRegistry], }) export class ImmichAdminModule implements OnModuleDestroy { diff --git a/server/src/commands/index.ts b/server/src/commands/index.ts index 46a8d13e35..2aef2e8c8b 100644 --- a/server/src/commands/index.ts +++ b/server/src/commands/index.ts @@ -1,5 +1,6 @@ import { GrantAdminCommand, PromptEmailQuestion, RevokeAdminCommand } from 'src/commands/grant-admin'; import { ListUsersCommand } from 'src/commands/list-users.command'; +import { DisableMaintenanceModeCommand, EnableMaintenanceModeCommand } from 'src/commands/maintenance-mode'; import { ChangeMediaLocationCommand, PromptConfirmMoveQuestions, @@ -16,6 +17,8 @@ export const commandsAndQuestions = [ PromptEmailQuestion, EnablePasswordLoginCommand, DisablePasswordLoginCommand, + EnableMaintenanceModeCommand, + DisableMaintenanceModeCommand, EnableOAuthLogin, DisableOAuthLogin, ListUsersCommand, diff --git a/server/src/commands/maintenance-mode.ts b/server/src/commands/maintenance-mode.ts new file mode 100644 index 0000000000..3416acf05d --- /dev/null +++ b/server/src/commands/maintenance-mode.ts @@ -0,0 +1,37 @@ +import { Command, CommandRunner } from 'nest-commander'; +import { CliService } from 'src/services/cli.service'; + +@Command({ + name: 'enable-maintenance-mode', + description: 'Enable maintenance mode or regenerate the maintenance token', +}) +export class EnableMaintenanceModeCommand extends CommandRunner { + constructor(private service: CliService) { + super(); + } + + async run(): Promise { + const { authUrl, alreadyEnabled } = await this.service.enableMaintenanceMode(); + + console.info(alreadyEnabled ? 'The server is already in maintenance mode!' : 'Maintenance mode has been enabled.'); + console.info(`\nLog in using the following URL:\n${authUrl}`); + } +} + +@Command({ + name: 'disable-maintenance-mode', + description: 'Disable maintenance mode', +}) +export class DisableMaintenanceModeCommand extends CommandRunner { + constructor(private service: CliService) { + super(); + } + + async run(): Promise { + const { alreadyDisabled } = await this.service.disableMaintenanceMode(); + + console.log( + alreadyDisabled ? 'The server is already out of maintenance mode!' : 'Maintenance mode has been disabled.', + ); + } +} diff --git a/server/src/constants.ts b/server/src/constants.ts index d624557c54..33f8e3b4c5 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -150,6 +150,7 @@ export const endpointTags: Record = { 'Queues and background jobs are used for processing tasks asynchronously. Queues can be paused and resumed as needed.', [ApiTag.Libraries]: 'An external library is made up of input file paths or expressions that are scanned for asset files. Discovered files are automatically imported. Assets much be unique within a library, but can be duplicated across libraries. Each user has a default upload library, and can have one or more external libraries.', + [ApiTag.Maintenance]: 'Maintenance mode allows you to put Immich in a read-only state to perform various operations.', [ApiTag.Map]: 'Map endpoints include supplemental functionality related to geolocation, such as reverse geocoding and retrieving map markers for assets with geolocation data.', [ApiTag.Memories]: @@ -162,6 +163,8 @@ export const endpointTags: Record = { 'A person is a collection of faces, which can be favorited and named. A person can also be merged into another person. People are automatically created via the face recognition job.', [ApiTag.Plugins]: 'A plugin is an installed module that makes filters and actions available for the workflow feature.', + [ApiTag.Queues]: + 'Queues and background jobs are used for processing tasks asynchronously. Queues can be paused and resumed as needed.', [ApiTag.Search]: 'Endpoints related to searching assets via text, smart search, optical character recognition (OCR), and other filters like person, album, and other metadata. Search endpoints usually support pagination and sorting.', [ApiTag.Server]: diff --git a/server/src/controllers/asset-media.controller.spec.ts b/server/src/controllers/asset-media.controller.spec.ts index eb594fbe47..c2f6aeacef 100644 --- a/server/src/controllers/asset-media.controller.spec.ts +++ b/server/src/controllers/asset-media.controller.spec.ts @@ -85,19 +85,6 @@ describe(AssetMediaController.name, () => { expect(body).toEqual(factory.responses.badRequest(['metadata must be valid JSON'])); }); - it('should validate iCloudId is a string', async () => { - const { status, body } = await request(ctx.getHttpServer()) - .post('/assets') - .attach('assetData', assetData, filename) - .field({ - ...makeUploadDto(), - metadata: JSON.stringify([{ key: AssetMetadataKey.MobileApp, value: { iCloudId: 123 } }]), - }); - - expect(status).toBe(400); - expect(body).toEqual(factory.responses.badRequest(['metadata.0.value.iCloudId must be a string'])); - }); - it('should require `deviceAssetId`', async () => { const { status, body } = await request(ctx.getHttpServer()) .post('/assets') diff --git a/server/src/controllers/index.ts b/server/src/controllers/index.ts index c0c0461fb3..6ba3d38a73 100644 --- a/server/src/controllers/index.ts +++ b/server/src/controllers/index.ts @@ -11,6 +11,7 @@ import { DuplicateController } from 'src/controllers/duplicate.controller'; import { FaceController } from 'src/controllers/face.controller'; import { JobController } from 'src/controllers/job.controller'; import { LibraryController } from 'src/controllers/library.controller'; +import { MaintenanceController } from 'src/controllers/maintenance.controller'; import { MapController } from 'src/controllers/map.controller'; import { MemoryController } from 'src/controllers/memory.controller'; import { NotificationAdminController } from 'src/controllers/notification-admin.controller'; @@ -19,6 +20,7 @@ import { OAuthController } from 'src/controllers/oauth.controller'; import { PartnerController } from 'src/controllers/partner.controller'; import { PersonController } from 'src/controllers/person.controller'; import { PluginController } from 'src/controllers/plugin.controller'; +import { QueueController } from 'src/controllers/queue.controller'; import { SearchController } from 'src/controllers/search.controller'; import { ServerController } from 'src/controllers/server.controller'; import { SessionController } from 'src/controllers/session.controller'; @@ -49,6 +51,7 @@ export const controllers = [ FaceController, JobController, LibraryController, + MaintenanceController, MapController, MemoryController, NotificationController, @@ -57,6 +60,7 @@ export const controllers = [ PartnerController, PersonController, PluginController, + QueueController, SearchController, ServerController, SessionController, diff --git a/server/src/controllers/job.controller.ts b/server/src/controllers/job.controller.ts index 977f1e0f1e..783d5a3133 100644 --- a/server/src/controllers/job.controller.ts +++ b/server/src/controllers/job.controller.ts @@ -1,10 +1,12 @@ import { Body, Controller, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Endpoint, HistoryBuilder } from 'src/decorators'; +import { AuthDto } from 'src/dtos/auth.dto'; import { JobCreateDto } from 'src/dtos/job.dto'; -import { QueueCommandDto, QueueNameParamDto, QueueResponseDto, QueuesResponseDto } from 'src/dtos/queue.dto'; +import { QueueResponseLegacyDto, QueuesResponseLegacyDto } from 'src/dtos/queue-legacy.dto'; +import { QueueCommandDto, QueueNameParamDto } from 'src/dtos/queue.dto'; import { ApiTag, Permission } from 'src/enum'; -import { Authenticated } from 'src/middleware/auth.guard'; +import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { JobService } from 'src/services/job.service'; import { QueueService } from 'src/services/queue.service'; @@ -21,10 +23,10 @@ export class JobController { @Endpoint({ summary: 'Retrieve queue counts and status', description: 'Retrieve the counts of the current queue, as well as the current status.', - history: new HistoryBuilder().added('v1').beta('v1').stable('v2'), + history: new HistoryBuilder().added('v1').beta('v1').stable('v2').deprecated('v2.4.0'), }) - getQueuesLegacy(): Promise { - return this.queueService.getAll(); + getQueuesLegacy(@Auth() auth: AuthDto): Promise { + return this.queueService.getAllLegacy(auth); } @Post() @@ -46,9 +48,12 @@ export class JobController { summary: 'Run jobs', description: 'Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets.', - history: new HistoryBuilder().added('v1').beta('v1').stable('v2'), + history: new HistoryBuilder().added('v1').beta('v1').stable('v2').deprecated('v2.4.0'), }) - runQueueCommandLegacy(@Param() { name }: QueueNameParamDto, @Body() dto: QueueCommandDto): Promise { - return this.queueService.runCommand(name, dto); + runQueueCommandLegacy( + @Param() { name }: QueueNameParamDto, + @Body() dto: QueueCommandDto, + ): Promise { + return this.queueService.runCommandLegacy(name, dto); } } diff --git a/server/src/controllers/maintenance.controller.ts b/server/src/controllers/maintenance.controller.ts new file mode 100644 index 0000000000..7b2aa17582 --- /dev/null +++ b/server/src/controllers/maintenance.controller.ts @@ -0,0 +1,49 @@ +import { BadRequestException, Body, Controller, Post, Res } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { Response } from 'express'; +import { Endpoint, HistoryBuilder } from 'src/decorators'; +import { AuthDto } from 'src/dtos/auth.dto'; +import { MaintenanceAuthDto, MaintenanceLoginDto, SetMaintenanceModeDto } from 'src/dtos/maintenance.dto'; +import { ApiTag, ImmichCookie, MaintenanceAction, Permission } from 'src/enum'; +import { Auth, Authenticated, GetLoginDetails } from 'src/middleware/auth.guard'; +import { LoginDetails } from 'src/services/auth.service'; +import { MaintenanceService } from 'src/services/maintenance.service'; +import { respondWithCookie } from 'src/utils/response'; + +@ApiTags(ApiTag.Maintenance) +@Controller('admin/maintenance') +export class MaintenanceController { + constructor(private service: MaintenanceService) {} + + @Post('login') + @Endpoint({ + summary: 'Log into maintenance mode', + description: 'Login with maintenance token or cookie to receive current information and perform further actions.', + history: new HistoryBuilder().added('v2.3.0').alpha('v2.3.0'), + }) + maintenanceLogin(@Body() _dto: MaintenanceLoginDto): MaintenanceAuthDto { + throw new BadRequestException('Not in maintenance mode'); + } + + @Post() + @Endpoint({ + summary: 'Set maintenance mode', + description: 'Put Immich into or take it out of maintenance mode', + history: new HistoryBuilder().added('v2.3.0').alpha('v2.3.0'), + }) + @Authenticated({ permission: Permission.Maintenance, admin: true }) + async setMaintenanceMode( + @Auth() auth: AuthDto, + @Body() dto: SetMaintenanceModeDto, + @GetLoginDetails() loginDetails: LoginDetails, + @Res({ passthrough: true }) res: Response, + ): Promise { + if (dto.action === MaintenanceAction.Start) { + const { jwt } = await this.service.startMaintenance(auth.user.name); + return respondWithCookie(res, undefined, { + isSecure: loginDetails.isSecure, + values: [{ key: ImmichCookie.MaintenanceToken, value: jwt }], + }); + } + } +} diff --git a/server/src/controllers/queue.controller.ts b/server/src/controllers/queue.controller.ts new file mode 100644 index 0000000000..1d8d918c5f --- /dev/null +++ b/server/src/controllers/queue.controller.ts @@ -0,0 +1,85 @@ +import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Put, Query } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { Endpoint, HistoryBuilder } from 'src/decorators'; +import { AuthDto } from 'src/dtos/auth.dto'; +import { + QueueDeleteDto, + QueueJobResponseDto, + QueueJobSearchDto, + QueueNameParamDto, + QueueResponseDto, + QueueUpdateDto, +} from 'src/dtos/queue.dto'; +import { ApiTag, Permission } from 'src/enum'; +import { Auth, Authenticated } from 'src/middleware/auth.guard'; +import { QueueService } from 'src/services/queue.service'; + +@ApiTags(ApiTag.Queues) +@Controller('queues') +export class QueueController { + constructor(private service: QueueService) {} + + @Get() + @Authenticated({ permission: Permission.QueueRead, admin: true }) + @Endpoint({ + summary: 'List all queues', + description: 'Retrieves a list of queues.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + getQueues(@Auth() auth: AuthDto): Promise { + return this.service.getAll(auth); + } + + @Get(':name') + @Authenticated({ permission: Permission.QueueRead, admin: true }) + @Endpoint({ + summary: 'Retrieve a queue', + description: 'Retrieves a specific queue by its name.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + getQueue(@Auth() auth: AuthDto, @Param() { name }: QueueNameParamDto): Promise { + return this.service.get(auth, name); + } + + @Put(':name') + @Authenticated({ permission: Permission.QueueUpdate, admin: true }) + @Endpoint({ + summary: 'Update a queue', + description: 'Change the paused status of a specific queue.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + updateQueue( + @Auth() auth: AuthDto, + @Param() { name }: QueueNameParamDto, + @Body() dto: QueueUpdateDto, + ): Promise { + return this.service.update(auth, name, dto); + } + + @Get(':name/jobs') + @Authenticated({ permission: Permission.QueueJobRead, admin: true }) + @Endpoint({ + summary: 'Retrieve queue jobs', + description: 'Retrieves a list of queue jobs from the specified queue.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + getQueueJobs( + @Auth() auth: AuthDto, + @Param() { name }: QueueNameParamDto, + @Query() dto: QueueJobSearchDto, + ): Promise { + return this.service.searchJobs(auth, name, dto); + } + + @Delete(':name/jobs') + @Authenticated({ permission: Permission.QueueJobDelete, admin: true }) + @HttpCode(HttpStatus.NO_CONTENT) + @Endpoint({ + summary: 'Empty a queue', + description: 'Removes all jobs from the specified queue.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + emptyQueue(@Auth() auth: AuthDto, @Param() { name }: QueueNameParamDto, @Body() dto: QueueDeleteDto): Promise { + return this.service.emptyQueue(auth, name, dto); + } +} diff --git a/server/src/cores/storage.core.ts b/server/src/cores/storage.core.ts index 25573cb08e..96623092f1 100644 --- a/server/src/cores/storage.core.ts +++ b/server/src/cores/storage.core.ts @@ -305,7 +305,7 @@ export class StorageCore { return this.assetRepository.update({ id, encodedVideoPath: newPath }); } case AssetPathType.Sidecar: { - return this.assetRepository.update({ id, sidecarPath: newPath }); + return this.assetRepository.upsertFile({ assetId: id, type: AssetFileType.Sidecar, path: newPath }); } case PersonPathType.Face: { return this.personRepository.update({ id, thumbnailPath: newPath }); diff --git a/server/src/database.ts b/server/src/database.ts index 4aa69127ff..a3c38ae61e 100644 --- a/server/src/database.ts +++ b/server/src/database.ts @@ -122,7 +122,6 @@ export type Asset = { originalFileName: string; originalPath: string; ownerId: string; - sidecarPath: string | null; type: AssetType; }; @@ -156,13 +155,6 @@ export type StorageAsset = { encodedVideoPath: string | null; }; -export type SidecarWriteAsset = { - id: string; - sidecarPath: string | null; - originalPath: string; - tags: Array<{ value: string }>; -}; - export type Stack = { id: string; primaryAssetId: string; @@ -309,14 +301,14 @@ export type Workflow = Selectable & { export type WorkflowFilter = Selectable & { workflowId: string; - filterId: string; + pluginFilterId: string; filterConfig: FilterConfig | null; order: number; }; export type WorkflowAction = Selectable & { workflowId: string; - actionId: string; + pluginActionId: string; actionConfig: ActionConfig | null; order: number; }; @@ -347,7 +339,6 @@ export const columns = { 'asset.originalFileName', 'asset.originalPath', 'asset.ownerId', - 'asset.sidecarPath', 'asset.type', ], assetFiles: ['asset_file.id', 'asset_file.path', 'asset_file.type'], diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index 1716c327f3..e228cd8f9f 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -124,7 +124,6 @@ export type MapAsset = { originalPath: string; owner?: User | null; ownerId: string; - sidecarPath: string | null; stack?: Stack | null; stackId: string | null; tags?: Tag[]; diff --git a/server/src/dtos/asset.dto.ts b/server/src/dtos/asset.dto.ts index dc43a0200c..03d1e31fb9 100644 --- a/server/src/dtos/asset.dto.ts +++ b/server/src/dtos/asset.dto.ts @@ -19,7 +19,6 @@ import { import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; import { AssetMetadataKey, AssetType, AssetVisibility } from 'src/enum'; import { AssetStats } from 'src/repositories/asset.repository'; -import { AssetMetadata, AssetMetadataItem } from 'src/types'; import { IsNotSiblingOf, Optional, ValidateBoolean, ValidateEnum, ValidateUUID } from 'src/validation'; export class DeviceIdDto { @@ -154,23 +153,12 @@ export class AssetMetadataUpsertDto { items!: AssetMetadataUpsertItemDto[]; } -export class AssetMetadataUpsertItemDto implements AssetMetadataItem { +export class AssetMetadataUpsertItemDto { @ValidateEnum({ enum: AssetMetadataKey, name: 'AssetMetadataKey' }) key!: AssetMetadataKey; @IsObject() - @ValidateNested() - @Type((options) => { - switch (options?.object.key) { - case AssetMetadataKey.MobileApp: { - return AssetMetadataMobileAppDto; - } - default: { - return Object; - } - } - }) - value!: AssetMetadata[AssetMetadataKey]; + value!: object; } export class AssetMetadataMobileAppDto { diff --git a/server/src/dtos/maintenance.dto.ts b/server/src/dtos/maintenance.dto.ts new file mode 100644 index 0000000000..fe6960c0a4 --- /dev/null +++ b/server/src/dtos/maintenance.dto.ts @@ -0,0 +1,16 @@ +import { MaintenanceAction } from 'src/enum'; +import { ValidateEnum, ValidateString } from 'src/validation'; + +export class SetMaintenanceModeDto { + @ValidateEnum({ enum: MaintenanceAction, name: 'MaintenanceAction' }) + action!: MaintenanceAction; +} + +export class MaintenanceLoginDto { + @ValidateString({ optional: true }) + token?: string; +} + +export class MaintenanceAuthDto { + username!: string; +} diff --git a/server/src/dtos/queue-legacy.dto.ts b/server/src/dtos/queue-legacy.dto.ts new file mode 100644 index 0000000000..79155e3f74 --- /dev/null +++ b/server/src/dtos/queue-legacy.dto.ts @@ -0,0 +1,89 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { QueueResponseDto, QueueStatisticsDto } from 'src/dtos/queue.dto'; +import { QueueName } from 'src/enum'; + +export class QueueStatusLegacyDto { + isActive!: boolean; + isPaused!: boolean; +} + +export class QueueResponseLegacyDto { + @ApiProperty({ type: QueueStatusLegacyDto }) + queueStatus!: QueueStatusLegacyDto; + + @ApiProperty({ type: QueueStatisticsDto }) + jobCounts!: QueueStatisticsDto; +} + +export class QueuesResponseLegacyDto implements Record { + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.ThumbnailGeneration]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.MetadataExtraction]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.VideoConversion]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.SmartSearch]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.StorageTemplateMigration]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Migration]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.BackgroundTask]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Search]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.DuplicateDetection]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.FaceDetection]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.FacialRecognition]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Sidecar]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Library]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Notification]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.BackupDatabase]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Ocr]!: QueueResponseLegacyDto; + + @ApiProperty({ type: QueueResponseLegacyDto }) + [QueueName.Workflow]!: QueueResponseLegacyDto; +} + +export const mapQueueLegacy = (response: QueueResponseDto): QueueResponseLegacyDto => { + return { + queueStatus: { + isPaused: response.isPaused, + isActive: response.statistics.active > 0, + }, + jobCounts: response.statistics, + }; +}; + +export const mapQueuesLegacy = (responses: QueueResponseDto[]): QueuesResponseLegacyDto => { + const legacy = new QueuesResponseLegacyDto(); + + for (const response of responses) { + legacy[response.name] = mapQueueLegacy(response); + } + + return legacy; +}; diff --git a/server/src/dtos/queue.dto.ts b/server/src/dtos/queue.dto.ts index df00c5cfc2..38a4a4ac6b 100644 --- a/server/src/dtos/queue.dto.ts +++ b/server/src/dtos/queue.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { QueueCommand, QueueName } from 'src/enum'; +import { HistoryBuilder, Property } from 'src/decorators'; +import { JobName, QueueCommand, QueueJobStatus, QueueName } from 'src/enum'; import { ValidateBoolean, ValidateEnum } from 'src/validation'; export class QueueNameParamDto { @@ -15,6 +16,46 @@ export class QueueCommandDto { force?: boolean; // TODO: this uses undefined as a third state, which should be refactored to be more explicit } +export class QueueUpdateDto { + @ValidateBoolean({ optional: true }) + isPaused?: boolean; +} + +export class QueueDeleteDto { + @ValidateBoolean({ optional: true }) + @Property({ + description: 'If true, will also remove failed jobs from the queue.', + history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), + }) + failed?: boolean; +} + +export class QueueJobSearchDto { + @ValidateEnum({ enum: QueueJobStatus, name: 'QueueJobStatus', optional: true, each: true }) + status?: QueueJobStatus[]; +} +export class QueueJobResponseDto { + id?: string; + + @ValidateEnum({ enum: JobName, name: 'JobName' }) + name!: JobName; + + data!: object; + + @ApiProperty({ type: 'integer' }) + timestamp!: number; +} + +export class QueueResponseDto { + @ValidateEnum({ enum: QueueName, name: 'QueueName' }) + name!: QueueName; + + @ValidateBoolean() + isPaused!: boolean; + + statistics!: QueueStatisticsDto; +} + export class QueueStatisticsDto { @ApiProperty({ type: 'integer' }) active!: number; @@ -29,69 +70,3 @@ export class QueueStatisticsDto { @ApiProperty({ type: 'integer' }) paused!: number; } - -export class QueueStatusDto { - isActive!: boolean; - isPaused!: boolean; -} - -export class QueueResponseDto { - @ApiProperty({ type: QueueStatisticsDto }) - jobCounts!: QueueStatisticsDto; - - @ApiProperty({ type: QueueStatusDto }) - queueStatus!: QueueStatusDto; -} - -export class QueuesResponseDto implements Record { - @ApiProperty({ type: QueueResponseDto }) - [QueueName.ThumbnailGeneration]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.MetadataExtraction]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.VideoConversion]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.SmartSearch]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.StorageTemplateMigration]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Migration]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.BackgroundTask]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Search]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.DuplicateDetection]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.FaceDetection]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.FacialRecognition]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Sidecar]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Library]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Notification]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.BackupDatabase]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Ocr]!: QueueResponseDto; - - @ApiProperty({ type: QueueResponseDto }) - [QueueName.Workflow]!: QueueResponseDto; -} diff --git a/server/src/dtos/server.dto.ts b/server/src/dtos/server.dto.ts index d7589c8a29..e98cb2edf6 100644 --- a/server/src/dtos/server.dto.ts +++ b/server/src/dtos/server.dto.ts @@ -154,6 +154,7 @@ export class ServerConfigDto { publicUsers!: boolean; mapDarkStyleUrl!: string; mapLightStyleUrl!: string; + maintenanceMode!: boolean; } export class ServerFeaturesDto { diff --git a/server/src/dtos/sync.dto.ts b/server/src/dtos/sync.dto.ts index c936ec52cc..d6a557e2c5 100644 --- a/server/src/dtos/sync.dto.ts +++ b/server/src/dtos/sync.dto.ts @@ -50,6 +50,7 @@ export class AssetDeltaSyncResponseDto { export const extraSyncModels: Function[] = []; export const ExtraModel = (): ClassDecorator => { + // eslint-disable-next-line unicorn/consistent-function-scoping return (object: Function) => { extraSyncModels.push(object); }; diff --git a/server/src/dtos/workflow.dto.ts b/server/src/dtos/workflow.dto.ts index 307440945d..7bfb90e11f 100644 --- a/server/src/dtos/workflow.dto.ts +++ b/server/src/dtos/workflow.dto.ts @@ -7,7 +7,7 @@ import { Optional, ValidateBoolean, ValidateEnum } from 'src/validation'; export class WorkflowFilterItemDto { @IsUUID() - filterId!: string; + pluginFilterId!: string; @IsObject() @Optional() @@ -16,7 +16,7 @@ export class WorkflowFilterItemDto { export class WorkflowActionItemDto { @IsUUID() - actionId!: string; + pluginActionId!: string; @IsObject() @Optional() @@ -86,7 +86,7 @@ export class WorkflowResponseDto { export class WorkflowFilterResponseDto { id!: string; workflowId!: string; - filterId!: string; + pluginFilterId!: string; filterConfig!: FilterConfig | null; order!: number; } @@ -94,7 +94,7 @@ export class WorkflowFilterResponseDto { export class WorkflowActionResponseDto { id!: string; workflowId!: string; - actionId!: string; + pluginActionId!: string; actionConfig!: ActionConfig | null; order!: number; } @@ -103,7 +103,7 @@ export function mapWorkflowFilter(filter: WorkflowFilter): WorkflowFilterRespons return { id: filter.id, workflowId: filter.workflowId, - filterId: filter.filterId, + pluginFilterId: filter.pluginFilterId, filterConfig: filter.filterConfig, order: filter.order, }; @@ -113,7 +113,7 @@ export function mapWorkflowAction(action: WorkflowAction): WorkflowActionRespons return { id: action.id, workflowId: action.workflowId, - actionId: action.actionId, + pluginActionId: action.pluginActionId, actionConfig: action.actionConfig, order: action.order, }; diff --git a/server/src/enum.ts b/server/src/enum.ts index 6055ee85bf..9d0a2c0426 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -5,6 +5,7 @@ export enum AuthType { export enum ImmichCookie { AccessToken = 'immich_access_token', + MaintenanceToken = 'immich_maintenance_token', AuthType = 'immich_auth_type', IsAuthenticated = 'immich_is_authenticated', SharedLinkToken = 'immich_shared_link_token', @@ -43,6 +44,7 @@ export enum AssetFileType { FullSize = 'fullsize', Preview = 'preview', Thumbnail = 'thumbnail', + Sidecar = 'sidecar', } export enum AlbumUserRole { @@ -146,6 +148,8 @@ export enum Permission { TimelineRead = 'timeline.read', TimelineDownload = 'timeline.download', + Maintenance = 'maintenance', + MemoryCreate = 'memory.create', MemoryRead = 'memory.read', MemoryUpdate = 'memory.update', @@ -245,6 +249,14 @@ export enum Permission { UserProfileImageUpdate = 'userProfileImage.update', UserProfileImageDelete = 'userProfileImage.delete', + QueueRead = 'queue.read', + QueueUpdate = 'queue.update', + + QueueJobCreate = 'queueJob.create', + QueueJobRead = 'queueJob.read', + QueueJobUpdate = 'queueJob.update', + QueueJobDelete = 'queueJob.delete', + WorkflowCreate = 'workflow.create', WorkflowRead = 'workflow.read', WorkflowUpdate = 'workflow.update', @@ -285,6 +297,7 @@ export enum SystemMetadataKey { FacialRecognitionState = 'facial-recognition-state', MemoriesState = 'memories-state', AdminOnboarding = 'admin-onboarding', + MaintenanceMode = 'maintenance-mode', SystemConfig = 'system-config', SystemFlags = 'system-flags', VersionCheckState = 'version-check-state', @@ -477,6 +490,7 @@ export enum ImmichEnvironment { export enum ImmichWorker { Api = 'api', + Maintenance = 'maintenance', Microservices = 'microservices', } @@ -538,6 +552,15 @@ export enum QueueName { Workflow = 'workflow', } +export enum QueueJobStatus { + Active = 'active', + Failed = 'failed', + Complete = 'completed', + Delayed = 'delayed', + Waiting = 'waiting', + Paused = 'paused', +} + export enum JobName { AssetDelete = 'AssetDelete', AssetDeleteCheck = 'AssetDeleteCheck', @@ -619,9 +642,13 @@ export enum JobName { export enum QueueCommand { Start = 'start', + /** @deprecated Use `updateQueue` instead */ Pause = 'pause', + /** @deprecated Use `updateQueue` instead */ Resume = 'resume', + /** @deprecated Use `emptyQueue` instead */ Empty = 'empty', + /** @deprecated Use `emptyQueue` instead */ ClearFailed = 'clear-failed', } @@ -655,6 +682,15 @@ export enum DatabaseLock { MemoryCreation = 777, } +export enum MaintenanceAction { + Start = 'start', + End = 'end', +} + +export enum ExitCode { + AppRestart = 7, +} + export enum SyncRequestType { AlbumsV1 = 'AlbumsV1', AlbumUsersV1 = 'AlbumUsersV1', @@ -801,6 +837,7 @@ export enum ApiTag { Faces = 'Faces', Jobs = 'Jobs', Libraries = 'Libraries', + Maintenance = 'Maintenance (admin)', Map = 'Map', Memories = 'Memories', Notifications = 'Notifications', @@ -808,6 +845,7 @@ export enum ApiTag { Partners = 'Partners', People = 'People', Plugins = 'Plugins', + Queues = 'Queues', Search = 'Search', Server = 'Server', Sessions = 'Sessions', diff --git a/server/src/main.ts b/server/src/main.ts index 68ea396e7a..47185e846f 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -1,61 +1,151 @@ +import { Kysely } from 'kysely'; import { CommandFactory } from 'nest-commander'; import { ChildProcess, fork } from 'node:child_process'; import { dirname, join } from 'node:path'; import { Worker } from 'node:worker_threads'; +import { PostgresError } from 'postgres'; import { ImmichAdminModule } from 'src/app.module'; -import { ImmichWorker, LogLevel } from 'src/enum'; +import { ExitCode, ImmichWorker, LogLevel, SystemMetadataKey } from 'src/enum'; import { ConfigRepository } from 'src/repositories/config.repository'; +import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; +import { type DB } from 'src/schema'; +import { getKyselyConfig } from 'src/utils/database'; -const immichApp = process.argv[2]; -if (immichApp) { - process.argv.splice(2, 1); -} +/** + * Manages worker lifecycle + */ +class Workers { + /** + * Currently running workers + */ + workers: Partial Promise | void }>> = {}; -let apiProcess: ChildProcess | undefined; + /** + * Fail-safe in case anything dies during restart + */ + restarting = false; -const onError = (name: string, error: Error) => { - console.error(`${name} worker error: ${error}, stack: ${error.stack}`); -}; + /** + * Boot all enabled workers + */ + async bootstrap() { + const isMaintenanceMode = await this.isMaintenanceMode(); + const { workers } = new ConfigRepository().getEnv(); -const onExit = (name: string, exitCode: number | null) => { - if (exitCode !== 0) { - console.error(`${name} worker exited with code ${exitCode}`); - - if (apiProcess && name !== ImmichWorker.Api) { - console.error('Killing api process'); - apiProcess.kill('SIGTERM'); - apiProcess = undefined; + if (isMaintenanceMode) { + this.startWorker(ImmichWorker.Maintenance); + } else { + for (const worker of workers) { + this.startWorker(worker); + } } } - process.exit(exitCode); -}; + /** + * Initialise a short-lived Nest application to build configuration + * @returns System configuration + */ + private async isMaintenanceMode(): Promise { + const { database } = new ConfigRepository().getEnv(); + const kysely = new Kysely(getKyselyConfig(database.config)); + const systemMetadataRepository = new SystemMetadataRepository(kysely); -function bootstrapWorker(name: ImmichWorker) { - console.log(`Starting ${name} worker`); + try { + const value = await systemMetadataRepository.get(SystemMetadataKey.MaintenanceMode); + return value?.isMaintenanceMode || false; + } catch (error) { + // Table doesn't exist (migrations haven't run yet) + if (error instanceof PostgresError && error.code === '42P01') { + return false; + } - // eslint-disable-next-line unicorn/prefer-module - const basePath = dirname(__filename); - const workerFile = join(basePath, 'workers', `${name}.js`); - - let worker: Worker | ChildProcess; - if (name === ImmichWorker.Api) { - worker = fork(workerFile, [], { - execArgv: process.execArgv.map((arg) => (arg.startsWith('--inspect') ? '--inspect=0.0.0.0:9231' : arg)), - }); - apiProcess = worker; - } else { - worker = new Worker(workerFile); + throw error; + } finally { + await kysely.destroy(); + } } - worker.on('error', (error) => onError(name, error)); - worker.on('exit', (exitCode) => onExit(name, exitCode)); + /** + * Start an individual worker + * @param name Worker + */ + private startWorker(name: ImmichWorker) { + console.log(`Starting ${name} worker`); + + // eslint-disable-next-line unicorn/prefer-module + const basePath = dirname(__filename); + const workerFile = join(basePath, 'workers', `${name}.js`); + + let anyWorker: Worker | ChildProcess; + let kill: (signal?: NodeJS.Signals) => Promise | void; + + if (name === ImmichWorker.Api) { + const worker = fork(workerFile, [], { + execArgv: process.execArgv.map((arg) => (arg.startsWith('--inspect') ? '--inspect=0.0.0.0:9231' : arg)), + }); + + kill = (signal) => void worker.kill(signal); + anyWorker = worker; + } else { + const worker = new Worker(workerFile); + + kill = async () => void (await worker.terminate()); + anyWorker = worker; + } + + anyWorker.on('error', (error) => this.onError(name, error)); + anyWorker.on('exit', (exitCode) => this.onExit(name, exitCode)); + + this.workers[name] = { kill }; + } + + onError(name: ImmichWorker, error: Error) { + console.error(`${name} worker error: ${error}, stack: ${error.stack}`); + } + + onExit(name: ImmichWorker, exitCode: number | null) { + // restart immich server + if (exitCode === ExitCode.AppRestart || this.restarting) { + this.restarting = true; + + console.info(`${name} worker shutdown for restart`); + delete this.workers[name]; + + // once all workers shut down, bootstrap again + if (Object.keys(this.workers).length === 0) { + void this.bootstrap(); + this.restarting = false; + } + + return; + } + + // shutdown the entire process + delete this.workers[name]; + + if (exitCode !== 0) { + console.error(`${name} worker exited with code ${exitCode}`); + + if (this.workers[ImmichWorker.Api] && name !== ImmichWorker.Api) { + console.error('Killing api process'); + void this.workers[ImmichWorker.Api].kill('SIGTERM'); + } + } + + process.exit(exitCode); + } } -function bootstrap() { +function main() { + const immichApp = process.argv[2]; + if (immichApp) { + process.argv.splice(2, 1); + } + if (immichApp === 'immich-admin') { process.title = 'immich_admin_cli'; process.env.IMMICH_LOG_LEVEL = LogLevel.Warn; + return CommandFactory.run(ImmichAdminModule); } @@ -72,10 +162,7 @@ function bootstrap() { } process.title = 'immich'; - const { workers } = new ConfigRepository().getEnv(); - for (const worker of workers) { - bootstrapWorker(worker); - } + void new Workers().bootstrap(); } -void bootstrap(); +void main(); diff --git a/server/src/maintenance/maintenance-auth.guard.ts b/server/src/maintenance/maintenance-auth.guard.ts new file mode 100644 index 0000000000..08aaad516b --- /dev/null +++ b/server/src/maintenance/maintenance-auth.guard.ts @@ -0,0 +1,58 @@ +import { + CanActivate, + ExecutionContext, + Injectable, + SetMetadata, + applyDecorators, + createParamDecorator, +} from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import { Request } from 'express'; +import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto'; +import { MetadataKey } from 'src/enum'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; +import { LoggingRepository } from 'src/repositories/logging.repository'; + +export const MaintenanceRoute = (options = {}): MethodDecorator => { + const decorators: MethodDecorator[] = [SetMetadata(MetadataKey.AuthRoute, options)]; + return applyDecorators(...decorators); +}; + +export interface MaintenanceAuthRequest extends Request { + auth?: MaintenanceAuthDto; +} + +export interface MaintenanceAuthenticatedRequest extends Request { + auth: MaintenanceAuthDto; +} + +export const MaintenanceAuth = createParamDecorator((data, context: ExecutionContext): MaintenanceAuthDto => { + return context.switchToHttp().getRequest().auth; +}); + +@Injectable() +export class MaintenanceAuthGuard implements CanActivate { + constructor( + private logger: LoggingRepository, + private reflector: Reflector, + private service: MaintenanceWorkerService, + ) { + this.logger.setContext(MaintenanceAuthGuard.name); + } + + async canActivate(context: ExecutionContext): Promise { + const targets = [context.getHandler()]; + const options = this.reflector.getAllAndOverride<{ _emptyObject: never } | undefined>( + MetadataKey.AuthRoute, + targets, + ); + if (!options) { + return true; + } + + const request = context.switchToHttp().getRequest(); + request.auth = await this.service.authenticate(request.headers); + + return true; + } +} diff --git a/server/src/maintenance/maintenance-websocket.repository.ts b/server/src/maintenance/maintenance-websocket.repository.ts new file mode 100644 index 0000000000..5d8368cf69 --- /dev/null +++ b/server/src/maintenance/maintenance-websocket.repository.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@nestjs/common'; +import { + OnGatewayConnection, + OnGatewayDisconnect, + OnGatewayInit, + WebSocketGateway, + WebSocketServer, +} from '@nestjs/websockets'; +import { Server, Socket } from 'socket.io'; +import { AppRepository } from 'src/repositories/app.repository'; +import { AppRestartEvent, ArgsOf } from 'src/repositories/event.repository'; +import { LoggingRepository } from 'src/repositories/logging.repository'; + +export const serverEvents = ['AppRestart'] as const; +export type ServerEvents = (typeof serverEvents)[number]; + +export interface ClientEventMap { + AppRestartV1: [AppRestartEvent]; +} + +@WebSocketGateway({ + cors: true, + path: '/api/socket.io', + transports: ['websocket'], +}) +@Injectable() +export class MaintenanceWebsocketRepository implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit { + @WebSocketServer() + private websocketServer?: Server; + + constructor( + private logger: LoggingRepository, + private appRepository: AppRepository, + ) { + this.logger.setContext(MaintenanceWebsocketRepository.name); + } + + afterInit(websocketServer: Server) { + this.logger.log('Initialized websocket server'); + websocketServer.on('AppRestart', () => this.appRepository.exitApp()); + } + + clientBroadcast(event: T, ...data: ClientEventMap[T]) { + this.websocketServer?.emit(event, ...data); + } + + serverSend(event: T, ...args: ArgsOf): void { + this.logger.debug(`Server event: ${event} (send)`); + this.websocketServer?.serverSideEmit(event, ...args); + } + + handleConnection(client: Socket) { + this.logger.log(`Websocket Connect: ${client.id}`); + } + + handleDisconnect(client: Socket) { + this.logger.log(`Websocket Disconnect: ${client.id}`); + } +} diff --git a/server/src/maintenance/maintenance-worker.controller.ts b/server/src/maintenance/maintenance-worker.controller.ts new file mode 100644 index 0000000000..e6143b771a --- /dev/null +++ b/server/src/maintenance/maintenance-worker.controller.ts @@ -0,0 +1,43 @@ +import { Body, Controller, Get, Post, Req, Res } from '@nestjs/common'; +import { Request, Response } from 'express'; +import { MaintenanceAuthDto, MaintenanceLoginDto, SetMaintenanceModeDto } from 'src/dtos/maintenance.dto'; +import { ServerConfigDto } from 'src/dtos/server.dto'; +import { ImmichCookie, MaintenanceAction } from 'src/enum'; +import { MaintenanceRoute } from 'src/maintenance/maintenance-auth.guard'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; +import { GetLoginDetails } from 'src/middleware/auth.guard'; +import { LoginDetails } from 'src/services/auth.service'; +import { respondWithCookie } from 'src/utils/response'; + +@Controller() +export class MaintenanceWorkerController { + constructor(private service: MaintenanceWorkerService) {} + + @Get('server/config') + getServerConfig(): Promise { + return this.service.getSystemConfig(); + } + + @Post('admin/maintenance/login') + async maintenanceLogin( + @Req() request: Request, + @Body() dto: MaintenanceLoginDto, + @GetLoginDetails() loginDetails: LoginDetails, + @Res({ passthrough: true }) res: Response, + ): Promise { + const token = dto.token ?? request.cookies[ImmichCookie.MaintenanceToken]; + const auth = await this.service.login(token); + return respondWithCookie(res, auth, { + isSecure: loginDetails.isSecure, + values: [{ key: ImmichCookie.MaintenanceToken, value: token }], + }); + } + + @Post('admin/maintenance') + @MaintenanceRoute() + async setMaintenanceMode(@Body() dto: SetMaintenanceModeDto): Promise { + if (dto.action === MaintenanceAction.End) { + await this.service.endMaintenance(); + } + } +} diff --git a/server/src/maintenance/maintenance-worker.service.spec.ts b/server/src/maintenance/maintenance-worker.service.spec.ts new file mode 100644 index 0000000000..dd5b984214 --- /dev/null +++ b/server/src/maintenance/maintenance-worker.service.spec.ts @@ -0,0 +1,128 @@ +import { UnauthorizedException } from '@nestjs/common'; +import { SignJWT } from 'jose'; +import { SystemMetadataKey } from 'src/enum'; +import { MaintenanceWebsocketRepository } from 'src/maintenance/maintenance-websocket.repository'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; +import { automock, getMocks, ServiceMocks } from 'test/utils'; + +describe(MaintenanceWorkerService.name, () => { + let sut: MaintenanceWorkerService; + let mocks: ServiceMocks; + let maintenanceWorkerRepositoryMock: MaintenanceWebsocketRepository; + + beforeEach(() => { + mocks = getMocks(); + maintenanceWorkerRepositoryMock = automock(MaintenanceWebsocketRepository, { args: [mocks.logger], strict: false }); + sut = new MaintenanceWorkerService( + mocks.logger as never, + mocks.app, + mocks.config, + mocks.systemMetadata as never, + maintenanceWorkerRepositoryMock, + ); + }); + + it('should work', () => { + expect(sut).toBeDefined(); + }); + + describe('getSystemConfig', () => { + it('should respond the server is in maintenance mode', async () => { + await expect(sut.getSystemConfig()).resolves.toMatchObject( + expect.objectContaining({ + maintenanceMode: true, + }), + ); + + expect(mocks.systemMetadata.get).toHaveBeenCalled(); + }); + }); + + describe('logSecret', () => { + const RE_LOGIN_URL = /https:\/\/my.immich.app\/maintenance\?token=([A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*)/; + + it('should log a valid login URL', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + await expect(sut.logSecret()).resolves.toBeUndefined(); + expect(mocks.logger.log).toHaveBeenCalledWith(expect.stringMatching(RE_LOGIN_URL)); + + const [url] = mocks.logger.log.mock.lastCall!; + const token = RE_LOGIN_URL.exec(url)![1]; + + await expect(sut.login(token)).resolves.toEqual( + expect.objectContaining({ + username: 'immich-admin', + }), + ); + }); + }); + + describe('authenticate', () => { + it('should fail without a cookie', async () => { + await expect(sut.authenticate({})).rejects.toThrowError(new UnauthorizedException('Missing JWT Token')); + }); + + it('should parse cookie properly', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + + await expect( + sut.authenticate({ + cookie: 'immich_maintenance_token=invalid-jwt', + }), + ).rejects.toThrowError(new UnauthorizedException('Invalid JWT Token')); + }); + }); + + describe('login', () => { + it('should fail without token', async () => { + await expect(sut.login()).rejects.toThrowError(new UnauthorizedException('Missing JWT Token')); + }); + + it('should fail with expired JWT', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + + const jwt = await new SignJWT({}) + .setProtectedHeader({ alg: 'HS256' }) + .setIssuedAt() + .setExpirationTime('0s') + .sign(new TextEncoder().encode('secret')); + + await expect(sut.login(jwt)).rejects.toThrowError(new UnauthorizedException('Invalid JWT Token')); + }); + + it('should succeed with valid JWT', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + + const jwt = await new SignJWT({ _mockValue: true }) + .setProtectedHeader({ alg: 'HS256' }) + .setIssuedAt() + .setExpirationTime('4h') + .sign(new TextEncoder().encode('secret')); + + await expect(sut.login(jwt)).resolves.toEqual( + expect.objectContaining({ + _mockValue: true, + }), + ); + }); + }); + + describe('endMaintenance', () => { + it('should set maintenance mode', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + await expect(sut.endMaintenance()).resolves.toBeUndefined(); + + expect(mocks.systemMetadata.set).toHaveBeenCalledWith(SystemMetadataKey.MaintenanceMode, { + isMaintenanceMode: false, + }); + + expect(maintenanceWorkerRepositoryMock.clientBroadcast).toHaveBeenCalledWith('AppRestartV1', { + isMaintenanceMode: false, + }); + + expect(maintenanceWorkerRepositoryMock.serverSend).toHaveBeenCalledWith('AppRestart', { + isMaintenanceMode: false, + }); + }); + }); +}); diff --git a/server/src/maintenance/maintenance-worker.service.ts b/server/src/maintenance/maintenance-worker.service.ts new file mode 100644 index 0000000000..c03231c274 --- /dev/null +++ b/server/src/maintenance/maintenance-worker.service.ts @@ -0,0 +1,161 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { parse } from 'cookie'; +import { NextFunction, Request, Response } from 'express'; +import { jwtVerify } from 'jose'; +import { readFileSync } from 'node:fs'; +import { IncomingHttpHeaders } from 'node:http'; +import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto'; +import { ImmichCookie, SystemMetadataKey } from 'src/enum'; +import { MaintenanceWebsocketRepository } from 'src/maintenance/maintenance-websocket.repository'; +import { AppRepository } from 'src/repositories/app.repository'; +import { ConfigRepository } from 'src/repositories/config.repository'; +import { LoggingRepository } from 'src/repositories/logging.repository'; +import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; +import { type ApiService as _ApiService } from 'src/services/api.service'; +import { type BaseService as _BaseService } from 'src/services/base.service'; +import { type ServerService as _ServerService } from 'src/services/server.service'; +import { MaintenanceModeState } from 'src/types'; +import { getConfig } from 'src/utils/config'; +import { createMaintenanceLoginUrl } from 'src/utils/maintenance'; +import { getExternalDomain } from 'src/utils/misc'; + +/** + * This service is available inside of maintenance mode to manage maintenance mode + */ +@Injectable() +export class MaintenanceWorkerService { + constructor( + protected logger: LoggingRepository, + private appRepository: AppRepository, + private configRepository: ConfigRepository, + private systemMetadataRepository: SystemMetadataRepository, + private maintenanceWorkerRepository: MaintenanceWebsocketRepository, + ) { + this.logger.setContext(this.constructor.name); + } + + /** + * {@link _BaseService.configRepos} + */ + private get configRepos() { + return { + configRepo: this.configRepository, + metadataRepo: this.systemMetadataRepository, + logger: this.logger, + }; + } + + /** + * {@link _BaseService.prototype.getConfig} + */ + private getConfig(options: { withCache: boolean }) { + return getConfig(this.configRepos, options); + } + + /** + * {@link _ServerService.getSystemConfig} + */ + async getSystemConfig() { + const config = await this.getConfig({ withCache: false }); + + return { + loginPageMessage: config.server.loginPageMessage, + trashDays: config.trash.days, + userDeleteDelay: config.user.deleteDelay, + oauthButtonText: config.oauth.buttonText, + isInitialized: true, + isOnboarded: true, + externalDomain: config.server.externalDomain, + publicUsers: config.server.publicUsers, + mapDarkStyleUrl: config.map.darkStyle, + mapLightStyleUrl: config.map.lightStyle, + maintenanceMode: true, + }; + } + + /** + * {@link _ApiService.ssr} + */ + ssr(excludePaths: string[]) { + const { resourcePaths } = this.configRepository.getEnv(); + + let index = ''; + try { + index = readFileSync(resourcePaths.web.indexHtml).toString(); + } catch { + this.logger.warn(`Unable to open ${resourcePaths.web.indexHtml}, skipping SSR.`); + } + + return (request: Request, res: Response, next: NextFunction) => { + if ( + request.url.startsWith('/api') || + request.method.toLowerCase() !== 'get' || + excludePaths.some((item) => request.url.startsWith(item)) + ) { + return next(); + } + + const maintenancePath = '/maintenance'; + if (!request.url.startsWith(maintenancePath)) { + const params = new URLSearchParams(); + params.set('continue', request.path); + return res.redirect(`${maintenancePath}?${params}`); + } + + res.status(200).type('text/html').header('Cache-Control', 'no-store').send(index); + }; + } + + private async secret(): Promise { + const state = (await this.systemMetadataRepository.get(SystemMetadataKey.MaintenanceMode)) as { + secret: string; + }; + + return state.secret; + } + + async logSecret(): Promise { + const { server } = await this.getConfig({ withCache: true }); + + const baseUrl = getExternalDomain(server); + const url = await createMaintenanceLoginUrl( + baseUrl, + { + username: 'immich-admin', + }, + await this.secret(), + ); + + this.logger.log(`\n\n🚧 Immich is in maintenance mode, you can log in using the following URL:\n${url}\n`); + } + + async authenticate(headers: IncomingHttpHeaders): Promise { + const jwtToken = parse(headers.cookie || '')[ImmichCookie.MaintenanceToken]; + return this.login(jwtToken); + } + + async login(jwt?: string): Promise { + if (!jwt) { + throw new UnauthorizedException('Missing JWT Token'); + } + + const secret = await this.secret(); + + try { + const result = await jwtVerify(jwt, new TextEncoder().encode(secret)); + return result.payload; + } catch { + throw new UnauthorizedException('Invalid JWT Token'); + } + } + + async endMaintenance(): Promise { + const state: MaintenanceModeState = { isMaintenanceMode: false as const }; + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state); + + // => corresponds to notification.service.ts#onAppRestart + this.maintenanceWorkerRepository.clientBroadcast('AppRestartV1', state); + this.maintenanceWorkerRepository.serverSend('AppRestart', state); + this.appRepository.exitApp(); + } +} diff --git a/server/src/queries/asset.job.repository.sql b/server/src/queries/asset.job.repository.sql index ebfd1a08c9..d1b4e5a72e 100644 --- a/server/src/queries/asset.job.repository.sql +++ b/server/src/queries/asset.job.repository.sql @@ -20,8 +20,23 @@ limit -- AssetJobRepository.getForSidecarWriteJob select "id", - "sidecarPath", "originalPath", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 + ) as agg + ) as "files", ( select coalesce(json_agg(agg), '[]') @@ -39,21 +54,36 @@ select from "asset" where - "asset"."id" = $1::uuid + "asset"."id" = $2::uuid limit - $2 + $3 -- AssetJobRepository.getForSidecarCheckJob select "id", - "sidecarPath", - "originalPath" + "originalPath", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 + ) as agg + ) as "files" from "asset" where - "asset"."id" = $1::uuid + "asset"."id" = $2::uuid limit - $2 + $3 -- AssetJobRepository.streamForThumbnailJob select @@ -158,7 +188,6 @@ select "asset"."originalFileName", "asset"."originalPath", "asset"."ownerId", - "asset"."sidecarPath", "asset"."type", ( select @@ -173,11 +202,27 @@ select "asset_face"."assetId" = "asset"."id" and "asset_face"."deletedAt" is null ) as agg - ) as "faces" + ) as "faces", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 + ) as agg + ) as "files" from "asset" where - "asset"."id" = $1 + "asset"."id" = $2 -- AssetJobRepository.getAlbumThumbnailFiles select @@ -322,9 +367,9 @@ select "asset"."libraryId", "asset"."ownerId", "asset"."livePhotoVideoId", - "asset"."sidecarPath", "asset"."encodedVideoPath", "asset"."originalPath", + "asset"."isOffline", to_json("asset_exif") as "exifInfo", ( select @@ -433,18 +478,33 @@ select "asset"."checksum", "asset"."originalPath", "asset"."isExternal", - "asset"."sidecarPath", "asset"."originalFileName", "asset"."livePhotoVideoId", "asset"."fileCreatedAt", "asset_exif"."timeZone", - "asset_exif"."fileSizeInByte" + "asset_exif"."fileSizeInByte", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 + ) as agg + ) as "files" from "asset" inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId" where "asset"."deletedAt" is null - and "asset"."id" = $1 + and "asset"."id" = $2 -- AssetJobRepository.streamForStorageTemplateJob select @@ -454,12 +514,27 @@ select "asset"."checksum", "asset"."originalPath", "asset"."isExternal", - "asset"."sidecarPath", "asset"."originalFileName", "asset"."livePhotoVideoId", "asset"."fileCreatedAt", "asset_exif"."timeZone", - "asset_exif"."fileSizeInByte" + "asset_exif"."fileSizeInByte", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 + ) as agg + ) as "files" from "asset" inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId" @@ -481,11 +556,15 @@ select from "asset" where - ( - "asset"."sidecarPath" = $1 - or "asset"."sidecarPath" is null + not exists ( + select + "asset_file"."id" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + and "asset_file"."type" = $1 ) - and "asset"."visibility" != $2 -- AssetJobRepository.streamForDetectFacesJob select diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 6cf3ec2f54..01cc6a7a89 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -216,6 +216,34 @@ from limit 3 +-- AssetRepository.getForCopy +select + "id", + "stackId", + "originalPath", + "isFavorite", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset_file"."id", + "asset_file"."path", + "asset_file"."type" + from + "asset_file" + where + "asset_file"."assetId" = "asset"."id" + ) as agg + ) as "files" +from + "asset" +where + "id" = $1::uuid +limit + $2 + -- AssetRepository.getById select "asset".* diff --git a/server/src/repositories/app.repository.ts b/server/src/repositories/app.repository.ts new file mode 100644 index 0000000000..e6181ef7f3 --- /dev/null +++ b/server/src/repositories/app.repository.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import { ExitCode } from 'src/enum'; + +@Injectable() +export class AppRepository { + private closeFn?: () => Promise; + + exitApp() { + /* eslint-disable unicorn/no-process-exit */ + void this.closeFn?.().finally(() => process.exit(ExitCode.AppRestart)); + + // in exceptional circumstance, the application may hang + setTimeout(() => process.exit(ExitCode.AppRestart), 2000); + /* eslint-enable unicorn/no-process-exit */ + } + + setCloseFn(fn: () => Promise) { + this.closeFn = fn; + } +} diff --git a/server/src/repositories/asset-job.repository.ts b/server/src/repositories/asset-job.repository.ts index 8d54e93c87..de994b08cd 100644 --- a/server/src/repositories/asset-job.repository.ts +++ b/server/src/repositories/asset-job.repository.ts @@ -6,7 +6,6 @@ import { Asset, columns } from 'src/database'; import { DummyValue, GenerateSql } from 'src/decorators'; import { AssetFileType, AssetType, AssetVisibility } from 'src/enum'; import { DB } from 'src/schema'; -import { StorageAsset } from 'src/types'; import { anyUuid, asUuid, @@ -40,7 +39,8 @@ export class AssetJobRepository { return this.db .selectFrom('asset') .where('asset.id', '=', asUuid(id)) - .select(['id', 'sidecarPath', 'originalPath']) + .select(['id', 'originalPath']) + .select((eb) => withFiles(eb, AssetFileType.Sidecar)) .select((eb) => jsonArrayFrom( eb @@ -59,7 +59,8 @@ export class AssetJobRepository { return this.db .selectFrom('asset') .where('asset.id', '=', asUuid(id)) - .select(['id', 'sidecarPath', 'originalPath']) + .select(['id', 'originalPath']) + .select((eb) => withFiles(eb, AssetFileType.Sidecar)) .limit(1) .executeTakeFirst(); } @@ -122,6 +123,7 @@ export class AssetJobRepository { .selectFrom('asset') .select(columns.asset) .select(withFaces) + .select((eb) => withFiles(eb, AssetFileType.Sidecar)) .where('asset.id', '=', id) .executeTakeFirst(); } @@ -228,9 +230,9 @@ export class AssetJobRepository { 'asset.libraryId', 'asset.ownerId', 'asset.livePhotoVideoId', - 'asset.sidecarPath', 'asset.encodedVideoPath', 'asset.originalPath', + 'asset.isOffline', ]) .$call(withExif) .select(withFacesAndPeople) @@ -306,26 +308,24 @@ export class AssetJobRepository { 'asset.checksum', 'asset.originalPath', 'asset.isExternal', - 'asset.sidecarPath', 'asset.originalFileName', 'asset.livePhotoVideoId', 'asset.fileCreatedAt', 'asset_exif.timeZone', 'asset_exif.fileSizeInByte', ]) + .select((eb) => withFiles(eb, AssetFileType.Sidecar)) .where('asset.deletedAt', 'is', null); } @GenerateSql({ params: [DummyValue.UUID] }) - getForStorageTemplateJob(id: string): Promise { - return this.storageTemplateAssetQuery().where('asset.id', '=', id).executeTakeFirst() as Promise< - StorageAsset | undefined - >; + getForStorageTemplateJob(id: string) { + return this.storageTemplateAssetQuery().where('asset.id', '=', id).executeTakeFirst(); } @GenerateSql({ params: [], stream: true }) streamForStorageTemplateJob() { - return this.storageTemplateAssetQuery().stream() as AsyncIterableIterator; + return this.storageTemplateAssetQuery().stream(); } @GenerateSql({ params: [DummyValue.DATE], stream: true }) @@ -343,9 +343,18 @@ export class AssetJobRepository { .selectFrom('asset') .select(['asset.id']) .$if(!force, (qb) => - qb.where((eb) => eb.or([eb('asset.sidecarPath', '=', ''), eb('asset.sidecarPath', 'is', null)])), + qb.where((eb) => + eb.not( + eb.exists( + eb + .selectFrom('asset_file') + .select('asset_file.id') + .whereRef('asset_file.assetId', '=', 'asset.id') + .where('asset_file.type', '=', AssetFileType.Sidecar), + ), + ), + ), ) - .where('asset.visibility', '!=', AssetVisibility.Hidden) .stream(); } diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index d3d9ada80f..4b8cbd7a7a 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -11,7 +11,6 @@ import { AssetExifTable } from 'src/schema/tables/asset-exif.table'; import { AssetFileTable } from 'src/schema/tables/asset-file.table'; import { AssetJobStatusTable } from 'src/schema/tables/asset-job-status.table'; import { AssetTable } from 'src/schema/tables/asset.table'; -import { AssetMetadataItem } from 'src/types'; import { anyUuid, asUuid, @@ -224,7 +223,7 @@ export class AssetRepository { .execute(); } - upsertMetadata(id: string, items: AssetMetadataItem[]) { + upsertMetadata(id: string, items: Array<{ key: AssetMetadataKey; value: object }>) { return this.db .insertInto('asset_metadata') .values(items.map((item) => ({ assetId: id, ...item }))) @@ -397,6 +396,17 @@ export class AssetRepository { return this.db.selectFrom('asset_file').select(['assetId', 'path']).limit(sql.lit(3)).execute(); } + @GenerateSql({ params: [DummyValue.UUID] }) + getForCopy(id: string) { + return this.db + .selectFrom('asset') + .select(['id', 'stackId', 'originalPath', 'isFavorite']) + .select(withFiles) + .where('id', '=', asUuid(id)) + .limit(1) + .executeTakeFirst(); + } + @GenerateSql({ params: [DummyValue.UUID] }) getById(id: string, { exifInfo, faces, files, library, owner, smartSearch, stack, tags }: GetByIdsRelations = {}) { return this.db @@ -843,6 +853,10 @@ export class AssetRepository { .execute(); } + async deleteFile({ assetId, type }: { assetId: string; type: AssetFileType }): Promise { + await this.db.deleteFrom('asset_file').where('assetId', '=', asUuid(assetId)).where('type', '=', type).execute(); + } + async deleteFiles(files: Pick, 'id'>[]): Promise { if (files.length === 0) { return; diff --git a/server/src/repositories/config.repository.spec.ts b/server/src/repositories/config.repository.spec.ts index 99cba43b99..1641850583 100644 --- a/server/src/repositories/config.repository.spec.ts +++ b/server/src/repositories/config.repository.spec.ts @@ -257,7 +257,7 @@ describe('getEnv', () => { expect(telemetry).toEqual({ apiPort: 8081, microservicesPort: 8082, - metrics: new Set([]), + metrics: new Set(), }); }); diff --git a/server/src/repositories/config.repository.ts b/server/src/repositories/config.repository.ts index 05d4bd2ac3..60ec021b3b 100644 --- a/server/src/repositories/config.repository.ts +++ b/server/src/repositories/config.repository.ts @@ -249,7 +249,7 @@ const getEnv = (): EnvData => { prefix: 'immich_bull', connection: { ...redisConfig }, defaultJobOptions: { - attempts: 3, + attempts: 1, removeOnComplete: true, removeOnFail: false, }, diff --git a/server/src/repositories/database.repository.ts b/server/src/repositories/database.repository.ts index 842576fafb..0fbaabf930 100644 --- a/server/src/repositories/database.repository.ts +++ b/server/src/repositories/database.repository.ts @@ -403,7 +403,6 @@ export class DatabaseRepository { .set((eb) => ({ originalPath: eb.fn('REGEXP_REPLACE', ['originalPath', source, target]), encodedVideoPath: eb.fn('REGEXP_REPLACE', ['encodedVideoPath', source, target]), - sidecarPath: eb.fn('REGEXP_REPLACE', ['sidecarPath', source, target]), })) .execute(); diff --git a/server/src/repositories/event.repository.ts b/server/src/repositories/event.repository.ts index 80d411c5ae..fbc281ccb3 100644 --- a/server/src/repositories/event.repository.ts +++ b/server/src/repositories/event.repository.ts @@ -26,6 +26,7 @@ type EventMap = { // app events AppBootstrap: []; AppShutdown: []; + AppRestart: [AppRestartEvent]; ConfigInit: [{ newConfig: SystemConfig }]; // config events @@ -96,6 +97,10 @@ type EventMap = { WebsocketConnect: [{ userId: string }]; }; +export type AppRestartEvent = { + isMaintenanceMode: boolean; +}; + type JobSuccessEvent = { job: JobItem; response?: JobStatus }; type JobErrorEvent = { job: JobItem; error: Error | any }; diff --git a/server/src/repositories/index.ts b/server/src/repositories/index.ts index c69536a327..c59110d674 100644 --- a/server/src/repositories/index.ts +++ b/server/src/repositories/index.ts @@ -3,6 +3,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository'; import { AlbumUserRepository } from 'src/repositories/album-user.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AppRepository } from 'src/repositories/app.repository'; import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { AuditRepository } from 'src/repositories/audit.repository'; @@ -56,6 +57,7 @@ export const repositories = [ AlbumUserRepository, AuditRepository, ApiKeyRepository, + AppRepository, AssetRepository, AssetJobRepository, ConfigRepository, diff --git a/server/src/repositories/job.repository.ts b/server/src/repositories/job.repository.ts index cf2799a4cf..b12accb68e 100644 --- a/server/src/repositories/job.repository.ts +++ b/server/src/repositories/job.repository.ts @@ -5,11 +5,12 @@ import { JobsOptions, Queue, Worker } from 'bullmq'; import { ClassConstructor } from 'class-transformer'; import { setTimeout } from 'node:timers/promises'; import { JobConfig } from 'src/decorators'; -import { JobName, JobStatus, MetadataKey, QueueCleanType, QueueName } from 'src/enum'; +import { QueueJobResponseDto, QueueJobSearchDto } from 'src/dtos/queue.dto'; +import { JobName, JobStatus, MetadataKey, QueueCleanType, QueueJobStatus, QueueName } from 'src/enum'; import { ConfigRepository } from 'src/repositories/config.repository'; import { EventRepository } from 'src/repositories/event.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; -import { JobCounts, JobItem, JobOf, QueueStatus } from 'src/types'; +import { JobCounts, JobItem, JobOf } from 'src/types'; import { getKeyByValue, getMethodNames, ImmichStartupError } from 'src/utils/misc'; type JobMapItem = { @@ -115,13 +116,14 @@ export class JobRepository { worker.concurrency = concurrency; } - async getQueueStatus(name: QueueName): Promise { + async isActive(name: QueueName): Promise { const queue = this.getQueue(name); + const count = await queue.getActiveCount(); + return count > 0; + } - return { - isActive: !!(await queue.getActiveCount()), - isPaused: await queue.isPaused(), - }; + async isPaused(name: QueueName): Promise { + return this.getQueue(name).isPaused(); } pause(name: QueueName) { @@ -192,17 +194,28 @@ export class JobRepository { } async waitForQueueCompletion(...queues: QueueName[]): Promise { - let activeQueue: QueueStatus | undefined; - do { - const statuses = await Promise.all(queues.map((name) => this.getQueueStatus(name))); - activeQueue = statuses.find((status) => status.isActive); - } while (activeQueue); - { - this.logger.verbose(`Waiting for ${activeQueue} queue to stop...`); + const getPending = async () => { + const results = await Promise.all(queues.map(async (name) => ({ pending: await this.isActive(name), name }))); + return results.filter(({ pending }) => pending).map(({ name }) => name); + }; + + let pending = await getPending(); + + while (pending.length > 0) { + this.logger.verbose(`Waiting for ${pending[0]} queue to stop...`); await setTimeout(1000); + pending = await getPending(); } } + async searchJobs(name: QueueName, dto: QueueJobSearchDto): Promise { + const jobs = await this.getQueue(name).getJobs(dto.status ?? Object.values(QueueJobStatus), 0, 1000); + return jobs.map((job) => { + const { id, name, timestamp, data } = job; + return { id, name: name as JobName, timestamp, data }; + }); + } + private getJobOptions(item: JobItem): JobsOptions | null { switch (item.name) { case JobName.NotifyAlbumUpdate: { diff --git a/server/src/repositories/media.repository.ts b/server/src/repositories/media.repository.ts index d98e018efb..a8e96709ff 100644 --- a/server/src/repositories/media.repository.ts +++ b/server/src/repositories/media.repository.ts @@ -121,6 +121,23 @@ export class MediaRepository { } } + async copyTagGroup(tagGroup: string, source: string, target: string): Promise { + try { + await exiftool.write( + target, + {}, + { + ignoreMinorErrors: true, + writeArgs: ['-TagsFromFile', source, `-${tagGroup}:all>${tagGroup}:all`, '-overwrite_original'], + }, + ); + return true; + } catch (error: any) { + this.logger.warn(`Could not copy tag data to image: ${error.message}`); + return false; + } + } + decodeImage(input: string | Buffer, options: DecodeToBufferOptions) { return this.getImageDecodingPipeline(input, options).raw().toBuffer({ resolveWithObject: true }); } diff --git a/server/src/repositories/oauth.repository.ts b/server/src/repositories/oauth.repository.ts index 58b1144647..a42955ba10 100644 --- a/server/src/repositories/oauth.repository.ts +++ b/server/src/repositories/oauth.repository.ts @@ -24,9 +24,8 @@ export class OAuthRepository { } async authorize(config: OAuthConfig, redirectUrl: string, state?: string, codeChallenge?: string) { - const { buildAuthorizationUrl, randomState, randomPKCECodeVerifier, calculatePKCECodeChallenge } = await import( - 'openid-client' - ); + const { buildAuthorizationUrl, randomState, randomPKCECodeVerifier, calculatePKCECodeChallenge } = + await import('openid-client'); const client = await this.getClient(config); state ??= randomState(); diff --git a/server/src/repositories/ocr.repository.ts b/server/src/repositories/ocr.repository.ts index 1da9a96ec5..a39f0d368c 100644 --- a/server/src/repositories/ocr.repository.ts +++ b/server/src/repositories/ocr.repository.ts @@ -45,12 +45,12 @@ export class OcrRepository { textScore: DummyValue.NUMBER, }, ], + DummyValue.STRING, ], }) - upsert(assetId: string, ocrDataList: Insertable[]) { + upsert(assetId: string, ocrDataList: Insertable[], searchText: string) { let query = this.db.with('deleted_ocr', (db) => db.deleteFrom('asset_ocr').where('assetId', '=', assetId)); if (ocrDataList.length > 0) { - const searchText = ocrDataList.map((item) => item.text.trim()).join(' '); (query as any) = query .with('inserted_ocr', (db) => db.insertInto('asset_ocr').values(ocrDataList)) .with('inserted_search', (db) => diff --git a/server/src/repositories/websocket.repository.ts b/server/src/repositories/websocket.repository.ts index 030659772d..d87bf76351 100644 --- a/server/src/repositories/websocket.repository.ts +++ b/server/src/repositories/websocket.repository.ts @@ -12,11 +12,11 @@ import { AuthDto } from 'src/dtos/auth.dto'; import { NotificationDto } from 'src/dtos/notification.dto'; import { ReleaseNotification, ServerVersionResponseDto } from 'src/dtos/server.dto'; import { SyncAssetExifV1, SyncAssetV1 } from 'src/dtos/sync.dto'; -import { ArgsOf, EventRepository } from 'src/repositories/event.repository'; +import { AppRestartEvent, ArgsOf, EventRepository } from 'src/repositories/event.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { handlePromiseError } from 'src/utils/misc'; -export const serverEvents = ['ConfigUpdate'] as const; +export const serverEvents = ['ConfigUpdate', 'AppRestart'] as const; export type ServerEvents = (typeof serverEvents)[number]; export interface ClientEventMap { @@ -36,6 +36,7 @@ export interface ClientEventMap { on_session_delete: [string]; AssetUploadReadyV1: [{ asset: SyncAssetV1; exif: SyncAssetExifV1 }]; + AppRestartV1: [AppRestartEvent]; } export type AuthFn = (client: Socket) => Promise; diff --git a/server/src/schema/migrations/1764483051488-OCRBigramsForCJK.ts b/server/src/schema/migrations/1764483051488-OCRBigramsForCJK.ts new file mode 100644 index 0000000000..3f5cb5fa8f --- /dev/null +++ b/server/src/schema/migrations/1764483051488-OCRBigramsForCJK.ts @@ -0,0 +1,31 @@ +import { Kysely, sql } from 'kysely'; +import { tokenizeForSearch } from 'src/utils/database'; + +export async function up(db: Kysely): Promise { + await sql`truncate ${sql.table('ocr_search')}`.execute(db); + + let lastAssetId: string | undefined; + while (true) { + const rows = await db + .selectFrom('asset_ocr') + .select(['assetId', sql`string_agg(text, ' ')`.as('text')]) + .$if(lastAssetId !== undefined, (qb) => qb.where('assetId', '>', lastAssetId)) + .groupBy('assetId') + .orderBy('assetId') + .limit(5000) + .execute(); + + if (rows.length === 0) { + break; + } + + await db + .insertInto('ocr_search') + .values(rows.map(({ assetId, text }) => ({ assetId, text: tokenizeForSearch(text).join(' ') }))) + .execute(); + + lastAssetId = rows.at(-1)!.assetId; + } +} + +export async function down(): Promise {} diff --git a/server/src/schema/migrations/1764698859174-SidecarInAssetFile.ts b/server/src/schema/migrations/1764698859174-SidecarInAssetFile.ts new file mode 100644 index 0000000000..183a77832e --- /dev/null +++ b/server/src/schema/migrations/1764698859174-SidecarInAssetFile.ts @@ -0,0 +1,24 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`INSERT INTO "asset_file" ("assetId", "path", "type") + SELECT + id, "sidecarPath", 'sidecar' + FROM "asset" + WHERE "sidecarPath" IS NOT NULL AND "sidecarPath" != '';`.execute(db); + + await sql`ALTER TABLE "asset" DROP COLUMN "sidecarPath";`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`ALTER TABLE "asset" ADD "sidecarPath" character varying;`.execute(db); + + await sql` + UPDATE "asset" + SET "sidecarPath" = "asset_file"."path" + FROM "asset_file" + WHERE "asset"."id" = "asset_file"."assetId" AND "asset_file"."type" = 'sidecar'; + `.execute(db); + + await sql`DELETE FROM "asset_file" WHERE "type" = 'sidecar';`.execute(db); +} diff --git a/server/src/schema/migrations/1764705680041-ChangeWorkflowTableColumnsName.ts b/server/src/schema/migrations/1764705680041-ChangeWorkflowTableColumnsName.ts new file mode 100644 index 0000000000..c495d2a8e2 --- /dev/null +++ b/server/src/schema/migrations/1764705680041-ChangeWorkflowTableColumnsName.ts @@ -0,0 +1,27 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`DROP INDEX "workflow_filter_filterId_idx";`.execute(db); + await sql`DROP INDEX "workflow_action_actionId_idx";`.execute(db); + await sql`ALTER TABLE "workflow_filter" DROP CONSTRAINT "workflow_filter_filterId_fkey";`.execute(db); + await sql`ALTER TABLE "workflow_action" DROP CONSTRAINT "workflow_action_actionId_fkey";`.execute(db); + await sql`ALTER TABLE "workflow_filter" RENAME COLUMN "filterId" TO "pluginFilterId";`.execute(db); + await sql`ALTER TABLE "workflow_action" RENAME COLUMN "actionId" TO "pluginActionId";`.execute(db); + await sql`ALTER TABLE "workflow_filter" ADD CONSTRAINT "workflow_filter_pluginFilterId_fkey" FOREIGN KEY ("pluginFilterId") REFERENCES "plugin_filter" ("id") ON UPDATE CASCADE ON DELETE CASCADE;`.execute(db); + await sql`ALTER TABLE "workflow_action" ADD CONSTRAINT "workflow_action_pluginActionId_fkey" FOREIGN KEY ("pluginActionId") REFERENCES "plugin_action" ("id") ON UPDATE CASCADE ON DELETE CASCADE;`.execute(db); + await sql`CREATE INDEX "workflow_filter_pluginFilterId_idx" ON "workflow_filter" ("pluginFilterId");`.execute(db); + await sql`CREATE INDEX "workflow_action_pluginActionId_idx" ON "workflow_action" ("pluginActionId");`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`DROP INDEX "workflow_filter_pluginFilterId_idx";`.execute(db); + await sql`DROP INDEX "workflow_action_pluginActionId_idx";`.execute(db); + await sql`ALTER TABLE "workflow_filter" DROP CONSTRAINT "workflow_filter_pluginFilterId_fkey";`.execute(db); + await sql`ALTER TABLE "workflow_action" DROP CONSTRAINT "workflow_action_pluginActionId_fkey";`.execute(db); + await sql`ALTER TABLE "workflow_filter" RENAME COLUMN "pluginFilterId" TO "filterId";`.execute(db); + await sql`ALTER TABLE "workflow_action" RENAME COLUMN "pluginActionId" TO "actionId";`.execute(db); + await sql`ALTER TABLE "workflow_filter" ADD CONSTRAINT "workflow_filter_filterId_fkey" FOREIGN KEY ("filterId") REFERENCES "plugin_filter" ("id") ON UPDATE CASCADE ON DELETE CASCADE;`.execute(db); + await sql`ALTER TABLE "workflow_action" ADD CONSTRAINT "workflow_action_actionId_fkey" FOREIGN KEY ("actionId") REFERENCES "plugin_action" ("id") ON UPDATE CASCADE ON DELETE CASCADE;`.execute(db); + await sql`CREATE INDEX "workflow_filter_filterId_idx" ON "workflow_filter" ("filterId");`.execute(db); + await sql`CREATE INDEX "workflow_action_actionId_idx" ON "workflow_action" ("actionId");`.execute(db); +} diff --git a/server/src/schema/tables/asset-metadata.table.ts b/server/src/schema/tables/asset-metadata.table.ts index 486101408d..d529d6ad7b 100644 --- a/server/src/schema/tables/asset-metadata.table.ts +++ b/server/src/schema/tables/asset-metadata.table.ts @@ -12,7 +12,6 @@ import { Timestamp, UpdateDateColumn, } from 'src/sql-tools'; -import { AssetMetadata, AssetMetadataItem } from 'src/types'; @UpdatedAtTrigger('asset_metadata_updated_at') @Table('asset_metadata') @@ -22,7 +21,7 @@ import { AssetMetadata, AssetMetadataItem } from 'src/types'; referencingOldTableAs: 'old', when: 'pg_trigger_depth() = 0', }) -export class AssetMetadataTable implements AssetMetadataItem { +export class AssetMetadataTable { @ForeignKeyColumn(() => AssetTable, { onUpdate: 'CASCADE', onDelete: 'CASCADE', @@ -33,10 +32,10 @@ export class AssetMetadataTable; diff --git a/server/src/schema/tables/asset.table.ts b/server/src/schema/tables/asset.table.ts index e92e01a1bd..b28fc99e4a 100644 --- a/server/src/schema/tables/asset.table.ts +++ b/server/src/schema/tables/asset.table.ts @@ -105,9 +105,6 @@ export class AssetTable { @Column({ index: true }) originalFileName!: string; - @Column({ nullable: true }) - sidecarPath!: string | null; - @Column({ type: 'bytea', nullable: true }) thumbhash!: Buffer | null; diff --git a/server/src/schema/tables/workflow.table.ts b/server/src/schema/tables/workflow.table.ts index 8f7c9adb0d..62a5531d8e 100644 --- a/server/src/schema/tables/workflow.table.ts +++ b/server/src/schema/tables/workflow.table.ts @@ -38,7 +38,7 @@ export class WorkflowTable { } @Index({ columns: ['workflowId', 'order'] }) -@Index({ columns: ['filterId'] }) +@Index({ columns: ['pluginFilterId'] }) @Table('workflow_filter') export class WorkflowFilterTable { @PrimaryGeneratedColumn('uuid') @@ -48,7 +48,7 @@ export class WorkflowFilterTable { workflowId!: Generated; @ForeignKeyColumn(() => PluginFilterTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE' }) - filterId!: string; + pluginFilterId!: string; @Column({ type: 'jsonb', nullable: true }) filterConfig!: FilterConfig | null; @@ -58,7 +58,7 @@ export class WorkflowFilterTable { } @Index({ columns: ['workflowId', 'order'] }) -@Index({ columns: ['actionId'] }) +@Index({ columns: ['pluginActionId'] }) @Table('workflow_action') export class WorkflowActionTable { @PrimaryGeneratedColumn('uuid') @@ -68,7 +68,7 @@ export class WorkflowActionTable { workflowId!: Generated; @ForeignKeyColumn(() => PluginActionTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE' }) - actionId!: string; + pluginActionId!: string; @Column({ type: 'jsonb', nullable: true }) actionConfig!: ActionConfig | null; diff --git a/server/src/services/album.service.spec.ts b/server/src/services/album.service.spec.ts index fa8a9c6450..03be834354 100644 --- a/server/src/services/album.service.spec.ts +++ b/server/src/services/album.service.spec.ts @@ -669,7 +669,7 @@ describe(AlbumService.name, () => { }); it('should not allow a shared user with viewer access to add assets', async () => { - mocks.access.album.checkSharedAlbumAccess.mockResolvedValue(new Set([])); + mocks.access.album.checkSharedAlbumAccess.mockResolvedValue(new Set()); mocks.album.getById.mockResolvedValue(_.cloneDeep(albumStub.sharedWithUser)); await expect( diff --git a/server/src/services/api.service.ts b/server/src/services/api.service.ts index 0ec2a65f92..ed1b4095d6 100644 --- a/server/src/services/api.service.ts +++ b/server/src/services/api.service.ts @@ -11,7 +11,7 @@ import { SharedLinkService } from 'src/services/shared-link.service'; import { VersionService } from 'src/services/version.service'; import { OpenGraphTags } from 'src/utils/misc'; -const render = (index: string, meta: OpenGraphTags) => { +export const render = (index: string, meta: OpenGraphTags) => { const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) => item ? sanitizeHtml(item, { allowedTags: [] }) : '', ); diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index f32385b937..95eb8b3c97 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -174,7 +174,6 @@ const assetEntity = Object.freeze({ longitude: 10.703_075, }, livePhotoVideoId: null, - sidecarPath: null, } as MapAsset); const existingAsset = Object.freeze({ @@ -188,7 +187,6 @@ const existingAsset = Object.freeze({ const sidecarAsset = Object.freeze({ ...existingAsset, - sidecarPath: 'sidecar-path', checksum: Buffer.from('_getExistingAssetWithSideCar', 'utf8'), }) as MapAsset; @@ -721,18 +719,22 @@ describe(AssetMediaService.name, () => { expect(mocks.asset.update).toHaveBeenCalledWith( expect.objectContaining({ id: existingAsset.id, - sidecarPath: null, originalFileName: 'photo1.jpeg', originalPath: 'fake_path/photo1.jpeg', }), ); expect(mocks.asset.create).toHaveBeenCalledWith( expect.objectContaining({ - sidecarPath: null, originalFileName: 'existing-filename.jpeg', originalPath: 'fake_path/asset_1.jpeg', }), ); + expect(mocks.asset.deleteFile).toHaveBeenCalledWith( + expect.objectContaining({ + assetId: existingAsset.id, + type: AssetFileType.Sidecar, + }), + ); expect(mocks.asset.updateAll).toHaveBeenCalledWith([copiedAsset.id], { deletedAt: expect.any(Date), @@ -769,6 +771,13 @@ describe(AssetMediaService.name, () => { deletedAt: expect.any(Date), status: AssetStatus.Trashed, }); + expect(mocks.asset.upsertFile).toHaveBeenCalledWith( + expect.objectContaining({ + assetId: existingAsset.id, + path: sidecarFile.originalPath, + type: AssetFileType.Sidecar, + }), + ); expect(mocks.user.updateUsage).toHaveBeenCalledWith(authStub.user1.user.id, updatedFile.size); expect(mocks.storage.utimes).toHaveBeenCalledWith( updatedFile.originalPath, @@ -798,6 +807,12 @@ describe(AssetMediaService.name, () => { deletedAt: expect.any(Date), status: AssetStatus.Trashed, }); + expect(mocks.asset.deleteFile).toHaveBeenCalledWith( + expect.objectContaining({ + assetId: existingAsset.id, + type: AssetFileType.Sidecar, + }), + ); expect(mocks.user.updateUsage).toHaveBeenCalledWith(authStub.user1.user.id, updatedFile.size); expect(mocks.storage.utimes).toHaveBeenCalledWith( updatedFile.originalPath, @@ -827,6 +842,9 @@ describe(AssetMediaService.name, () => { expect(mocks.asset.create).not.toHaveBeenCalled(); expect(mocks.asset.updateAll).not.toHaveBeenCalled(); + expect(mocks.asset.upsertFile).not.toHaveBeenCalled(); + expect(mocks.asset.deleteFile).not.toHaveBeenCalled(); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.FileDelete, data: { files: [updatedFile.originalPath, undefined] }, diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 4db60c349f..d2e1c14210 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -21,7 +21,16 @@ import { UploadFieldName, } from 'src/dtos/asset-media.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { AssetStatus, AssetType, AssetVisibility, CacheControl, JobName, Permission, StorageFolder } from 'src/enum'; +import { + AssetFileType, + AssetStatus, + AssetType, + AssetVisibility, + CacheControl, + JobName, + Permission, + StorageFolder, +} from 'src/enum'; import { AuthRequest } from 'src/middleware/auth.guard'; import { BaseService } from 'src/services/base.service'; import { UploadFile, UploadRequest } from 'src/types'; @@ -354,9 +363,12 @@ export class AssetMediaService extends BaseService { duration: dto.duration || null, livePhotoVideoId: null, - sidecarPath: sidecarPath || null, }); + await (sidecarPath + ? this.assetRepository.upsertFile({ assetId, type: AssetFileType.Sidecar, path: sidecarPath }) + : this.assetRepository.deleteFile({ assetId, type: AssetFileType.Sidecar })); + await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); await this.assetRepository.upsertExif({ assetId, fileSizeInByte: file.size }); await this.jobRepository.queue({ @@ -384,7 +396,6 @@ export class AssetMediaService extends BaseService { localDateTime: asset.localDateTime, fileModifiedAt: asset.fileModifiedAt, livePhotoVideoId: asset.livePhotoVideoId, - sidecarPath: asset.sidecarPath, }); const { size } = await this.storageRepository.stat(created.originalPath); @@ -414,7 +425,6 @@ export class AssetMediaService extends BaseService { visibility: dto.visibility ?? AssetVisibility.Timeline, livePhotoVideoId: dto.livePhotoVideoId, originalFileName: dto.filename || file.originalName, - sidecarPath: sidecarFile?.originalPath, }); if (dto.metadata) { @@ -422,6 +432,11 @@ export class AssetMediaService extends BaseService { } if (sidecarFile) { + await this.assetRepository.upsertFile({ + assetId: asset.id, + path: sidecarFile.originalPath, + type: AssetFileType.Sidecar, + }); await this.storageRepository.utimes(sidecarFile.originalPath, new Date(), new Date(dto.fileModifiedAt)); } await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); diff --git a/server/src/services/asset.service.spec.ts b/server/src/services/asset.service.spec.ts index 4b0086c957..878721e0a7 100755 --- a/server/src/services/asset.service.spec.ts +++ b/server/src/services/asset.service.spec.ts @@ -585,8 +585,6 @@ describe(AssetService.name, () => { '/uploads/user-id/webp/path.ext', '/uploads/user-id/thumbs/path.jpg', '/uploads/user-id/fullsize/path.webp', - assetWithFace.encodedVideoPath, - assetWithFace.sidecarPath, assetWithFace.originalPath, ], }, @@ -648,8 +646,6 @@ describe(AssetService.name, () => { '/uploads/user-id/webp/path.ext', '/uploads/user-id/thumbs/path.jpg', '/uploads/user-id/fullsize/path.webp', - undefined, - undefined, 'fake_path/asset_1.jpeg', ], }, @@ -676,8 +672,6 @@ describe(AssetService.name, () => { '/uploads/user-id/webp/path.ext', '/uploads/user-id/thumbs/path.jpg', '/uploads/user-id/fullsize/path.webp', - undefined, - undefined, 'fake_path/asset_1.jpeg', ], }, diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index 23cc6791dd..32c6526394 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -2,6 +2,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import _ from 'lodash'; import { DateTime, Duration } from 'luxon'; import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants'; +import { AssetFile } from 'src/database'; import { OnJob } from 'src/decorators'; import { AssetResponseDto, MapAsset, SanitizedAssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; import { @@ -18,7 +19,16 @@ import { } from 'src/dtos/asset.dto'; import { AuthDto } from 'src/dtos/auth.dto'; import { AssetOcrResponseDto } from 'src/dtos/ocr.dto'; -import { AssetMetadataKey, AssetStatus, AssetVisibility, JobName, JobStatus, Permission, QueueName } from 'src/enum'; +import { + AssetFileType, + AssetMetadataKey, + AssetStatus, + AssetVisibility, + JobName, + JobStatus, + Permission, + QueueName, +} from 'src/enum'; import { BaseService } from 'src/services/base.service'; import { ISidecarWriteJob, JobItem, JobOf } from 'src/types'; import { requireElevatedPermission } from 'src/utils/access'; @@ -197,8 +207,8 @@ export class AssetService extends BaseService { }: AssetCopyDto, ) { await this.requireAccess({ auth, permission: Permission.AssetCopy, ids: [sourceId, targetId] }); - const sourceAsset = await this.assetRepository.getById(sourceId); - const targetAsset = await this.assetRepository.getById(targetId); + const sourceAsset = await this.assetRepository.getForCopy(sourceId); + const targetAsset = await this.assetRepository.getForCopy(targetId); if (!sourceAsset || !targetAsset) { throw new BadRequestException('Both assets must exist'); @@ -252,19 +262,25 @@ export class AssetService extends BaseService { sourceAsset, targetAsset, }: { - sourceAsset: { sidecarPath: string | null }; - targetAsset: { id: string; sidecarPath: string | null; originalPath: string }; + sourceAsset: { files: AssetFile[] }; + targetAsset: { id: string; files: AssetFile[]; originalPath: string }; }) { - if (!sourceAsset.sidecarPath) { + const { sidecarFile: sourceFile } = getAssetFiles(sourceAsset.files); + if (!sourceFile?.path) { return; } - if (targetAsset.sidecarPath) { - await this.storageRepository.unlink(targetAsset.sidecarPath); + const { sidecarFile: targetFile } = getAssetFiles(targetAsset.files ?? []); + if (targetFile?.path) { + await this.storageRepository.unlink(targetFile.path); } - await this.storageRepository.copyFile(sourceAsset.sidecarPath, `${targetAsset.originalPath}.xmp`); - await this.assetRepository.update({ id: targetAsset.id, sidecarPath: `${targetAsset.originalPath}.xmp` }); + await this.storageRepository.copyFile(sourceFile.path, `${targetAsset.originalPath}.xmp`); + await this.assetRepository.upsertFile({ + assetId: targetAsset.id, + path: `${targetAsset.originalPath}.xmp`, + type: AssetFileType.Sidecar, + }); await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: targetAsset.id } }); } @@ -344,14 +360,14 @@ export class AssetService extends BaseService { } } - const { fullsizeFile, previewFile, thumbnailFile } = getAssetFiles(asset.files ?? []); + const { fullsizeFile, previewFile, thumbnailFile, sidecarFile } = getAssetFiles(asset.files ?? []); const files = [thumbnailFile?.path, previewFile?.path, fullsizeFile?.path, asset.encodedVideoPath]; - if (deleteOnDisk) { - files.push(asset.sidecarPath, asset.originalPath); + if (deleteOnDisk && !asset.isOffline) { + files.push(sidecarFile?.path, asset.originalPath); } - await this.jobRepository.queue({ name: JobName.FileDelete, data: { files } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: files.filter(Boolean) } }); return JobStatus.Success; } diff --git a/server/src/services/backup.service.spec.ts b/server/src/services/backup.service.spec.ts index 8aa20aa868..9e25fbaf2e 100644 --- a/server/src/services/backup.service.spec.ts +++ b/server/src/services/backup.service.spec.ts @@ -153,6 +153,37 @@ describe(BackupService.name, () => { mocks.storage.createWriteStream.mockReturnValue(new PassThrough()); }); + it('should sanitize DB_URL (remove uselibpqcompat) before calling pg_dumpall', async () => { + // create a service instance with a URL connection that includes libpqcompat + const dbUrl = 'postgresql://postgres:pwd@host:5432/immich?sslmode=require&uselibpqcompat=true'; + const configMock = { + getEnv: () => ({ database: { config: { connectionType: 'url', url: dbUrl }, skipMigrations: false } }), + getWorker: () => ImmichWorker.Api, + isDev: () => false, + } as unknown as any; + + ({ sut, mocks } = newTestService(BackupService, { config: configMock })); + + mocks.storage.readdir.mockResolvedValue([]); + mocks.process.spawn.mockReturnValue(mockSpawn(0, 'data', '')); + mocks.storage.rename.mockResolvedValue(); + mocks.storage.unlink.mockResolvedValue(); + mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.backupEnabled); + mocks.storage.createWriteStream.mockReturnValue(new PassThrough()); + mocks.database.getPostgresVersion.mockResolvedValue('14.10'); + + await sut.handleBackupDatabase(); + + expect(mocks.process.spawn).toHaveBeenCalled(); + const call = mocks.process.spawn.mock.calls[0]; + const args = call[1] as string[]; + // ['--dbname', '', '--clean', '--if-exists'] + expect(args[0]).toBe('--dbname'); + const passedUrl = args[1]; + expect(passedUrl).not.toContain('uselibpqcompat'); + expect(passedUrl).toContain('sslmode=require'); + }); + it('should run a database backup successfully', async () => { const result = await sut.handleBackupDatabase(); expect(result).toBe(JobStatus.Success); diff --git a/server/src/services/backup.service.ts b/server/src/services/backup.service.ts index 6f8cc0e34a..2ff3e5dd3e 100644 --- a/server/src/services/backup.service.ts +++ b/server/src/services/backup.service.ts @@ -61,7 +61,7 @@ export class BackupService extends BaseService { const newBackupStyle = file.match(/immich-db-backup-\d{8}T\d{6}-v.*-pg.*\.sql\.gz$/); return oldBackupStyle || newBackupStyle; }) - .sort() + .toSorted() .toReversed(); const toDelete = backups.slice(config.keepLastAmount); @@ -81,8 +81,16 @@ export class BackupService extends BaseService { const isUrlConnection = config.connectionType === 'url'; + let connectionUrl: string = isUrlConnection ? config.url : ''; + if (URL.canParse(connectionUrl)) { + // remove known bad url parameters for pg_dumpall + const url = new URL(connectionUrl); + url.searchParams.delete('uselibpqcompat'); + connectionUrl = url.toString(); + } + const databaseParams = isUrlConnection - ? ['--dbname', config.url] + ? ['--dbname', connectionUrl] : [ '--username', config.username, @@ -118,7 +126,7 @@ export class BackupService extends BaseService { { env: { PATH: process.env.PATH, - PGPASSWORD: isUrlConnection ? new URL(config.url).password : config.password, + PGPASSWORD: isUrlConnection ? new URL(connectionUrl).password : config.password, }, }, ); diff --git a/server/src/services/base.service.ts b/server/src/services/base.service.ts index 2c6d07b635..9c422818b3 100644 --- a/server/src/services/base.service.ts +++ b/server/src/services/base.service.ts @@ -10,6 +10,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository'; import { AlbumUserRepository } from 'src/repositories/album-user.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AppRepository } from 'src/repositories/app.repository'; import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { AuditRepository } from 'src/repositories/audit.repository'; @@ -66,6 +67,7 @@ export const BASE_SERVICE_DEPENDENCIES = [ AlbumRepository, AlbumUserRepository, ApiKeyRepository, + AppRepository, AssetRepository, AssetJobRepository, AuditRepository, @@ -123,6 +125,7 @@ export class BaseService { protected albumRepository: AlbumRepository, protected albumUserRepository: AlbumUserRepository, protected apiKeyRepository: ApiKeyRepository, + protected appRepository: AppRepository, protected assetRepository: AssetRepository, protected assetJobRepository: AssetJobRepository, protected auditRepository: AuditRepository, diff --git a/server/src/services/cli.service.spec.ts b/server/src/services/cli.service.spec.ts index 1140d44601..49fa5cf5b8 100644 --- a/server/src/services/cli.service.spec.ts +++ b/server/src/services/cli.service.spec.ts @@ -1,3 +1,5 @@ +import { jwtVerify } from 'jose'; +import { SystemMetadataKey } from 'src/enum'; import { CliService } from 'src/services/cli.service'; import { factory } from 'test/small.factory'; import { newTestService, ServiceMocks } from 'test/utils'; @@ -80,6 +82,82 @@ describe(CliService.name, () => { }); }); + describe('disableMaintenanceMode', () => { + it('should not do anything if not in maintenance mode', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + await expect(sut.disableMaintenanceMode()).resolves.toEqual({ + alreadyDisabled: true, + }); + + expect(mocks.systemMetadata.set).toHaveBeenCalledTimes(0); + expect(mocks.event.emit).toHaveBeenCalledTimes(0); + }); + + it('should disable maintenance mode', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + await expect(sut.disableMaintenanceMode()).resolves.toEqual({ + alreadyDisabled: false, + }); + + expect(mocks.systemMetadata.set).toHaveBeenCalledWith(SystemMetadataKey.MaintenanceMode, { + isMaintenanceMode: false, + }); + }); + }); + + describe('enableMaintenanceMode', () => { + it('should not do anything if in maintenance mode', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + await expect(sut.enableMaintenanceMode()).resolves.toEqual( + expect.objectContaining({ + alreadyEnabled: true, + }), + ); + + expect(mocks.systemMetadata.set).toHaveBeenCalledTimes(0); + expect(mocks.event.emit).toHaveBeenCalledTimes(0); + }); + + it('should enable maintenance mode', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + await expect(sut.enableMaintenanceMode()).resolves.toEqual( + expect.objectContaining({ + alreadyEnabled: false, + }), + ); + + expect(mocks.systemMetadata.set).toHaveBeenCalledWith(SystemMetadataKey.MaintenanceMode, { + isMaintenanceMode: true, + secret: expect.stringMatching(/^\w{128}$/), + }); + }); + + const RE_LOGIN_URL = /https:\/\/my.immich.app\/maintenance\?token=([A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*)/; + + it('should return a valid login URL', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + + const result = await sut.enableMaintenanceMode(); + + expect(result).toEqual( + expect.objectContaining({ + authUrl: expect.stringMatching(RE_LOGIN_URL), + alreadyEnabled: true, + }), + ); + + const token = RE_LOGIN_URL.exec(result.authUrl)![1]; + + await expect(jwtVerify(token, new TextEncoder().encode('secret'))).resolves.toEqual( + expect.objectContaining({ + payload: expect.objectContaining({ + username: 'cli-admin', + }), + }), + ); + }); + }); + describe('disableOAuthLogin', () => { it('should disable oauth login', async () => { await sut.disableOAuthLogin(); diff --git a/server/src/services/cli.service.ts b/server/src/services/cli.service.ts index 38144e95b4..3d248edc7a 100644 --- a/server/src/services/cli.service.ts +++ b/server/src/services/cli.service.ts @@ -1,8 +1,12 @@ import { Injectable } from '@nestjs/common'; import { isAbsolute } from 'node:path'; import { SALT_ROUNDS } from 'src/constants'; +import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto'; import { UserAdminResponseDto, mapUserAdmin } from 'src/dtos/user.dto'; +import { SystemMetadataKey } from 'src/enum'; import { BaseService } from 'src/services/base.service'; +import { createMaintenanceLoginUrl, generateMaintenanceSecret, sendOneShotAppRestart } from 'src/utils/maintenance'; +import { getExternalDomain } from 'src/utils/misc'; @Injectable() export class CliService extends BaseService { @@ -38,6 +42,63 @@ export class CliService extends BaseService { await this.updateConfig(config); } + async disableMaintenanceMode(): Promise<{ alreadyDisabled: boolean }> { + const currentState = await this.systemMetadataRepository + .get(SystemMetadataKey.MaintenanceMode) + .then((state) => state ?? { isMaintenanceMode: false as const }); + + if (!currentState.isMaintenanceMode) { + return { + alreadyDisabled: true, + }; + } + + const state = { isMaintenanceMode: false as const }; + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state); + + sendOneShotAppRestart(state); + + return { + alreadyDisabled: false, + }; + } + + async enableMaintenanceMode(): Promise<{ authUrl: string; alreadyEnabled: boolean }> { + const { server } = await this.getConfig({ withCache: true }); + const baseUrl = getExternalDomain(server); + + const payload: MaintenanceAuthDto = { + username: 'cli-admin', + }; + + const state = await this.systemMetadataRepository + .get(SystemMetadataKey.MaintenanceMode) + .then((state) => state ?? { isMaintenanceMode: false as const }); + + if (state.isMaintenanceMode) { + return { + authUrl: await createMaintenanceLoginUrl(baseUrl, payload, state.secret), + alreadyEnabled: true, + }; + } + + const secret = generateMaintenanceSecret(); + + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, { + isMaintenanceMode: true, + secret, + }); + + sendOneShotAppRestart({ + isMaintenanceMode: true, + }); + + return { + authUrl: await createMaintenanceLoginUrl(baseUrl, payload, secret), + alreadyEnabled: false, + }; + } + async grantAdminAccess(email: string): Promise { const user = await this.userRepository.getByEmail(email); if (!user) { diff --git a/server/src/services/index.ts b/server/src/services/index.ts index 9d09bdaa53..eeb8424048 100644 --- a/server/src/services/index.ts +++ b/server/src/services/index.ts @@ -14,6 +14,7 @@ import { DownloadService } from 'src/services/download.service'; import { DuplicateService } from 'src/services/duplicate.service'; import { JobService } from 'src/services/job.service'; import { LibraryService } from 'src/services/library.service'; +import { MaintenanceService } from 'src/services/maintenance.service'; import { MapService } from 'src/services/map.service'; import { MediaService } from 'src/services/media.service'; import { MemoryService } from 'src/services/memory.service'; @@ -63,6 +64,7 @@ export const services = [ DuplicateService, JobService, LibraryService, + MaintenanceService, MapService, MediaService, MemoryService, diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index 64f0915698..dbff1ca467 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -278,7 +278,7 @@ describe(LibraryService.name, () => { mocks.library.get.mockResolvedValue(library); mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.asset.getLibraryAssetCount.mockResolvedValue(1); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 1n }); const response = await sut.handleQueueSyncAssets({ id: library.id }); @@ -296,7 +296,7 @@ describe(LibraryService.name, () => { mocks.library.get.mockResolvedValue(library); mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.asset.getLibraryAssetCount.mockResolvedValue(0); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 1n }); const response = await sut.handleQueueSyncAssets({ id: library.id }); @@ -311,7 +311,7 @@ describe(LibraryService.name, () => { mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external])); mocks.asset.getLibraryAssetCount.mockResolvedValue(1); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(0) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 0n }); mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external])); const response = await sut.handleQueueSyncAssets({ id: library.id }); diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 5f78fa3629..841fa4743c 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -223,7 +223,14 @@ export class LibraryService extends BaseService { ownerId: dto.ownerId, name: dto.name ?? 'New External Library', importPaths: dto.importPaths ?? [], - exclusionPatterns: dto.exclusionPatterns ?? ['**/@eaDir/**', '**/._*', '**/#recycle/**', '**/#snapshot/**'], + exclusionPatterns: dto.exclusionPatterns ?? [ + '**/@eaDir/**', + '**/._*', + '**/#recycle/**', + '**/#snapshot/**', + '**/.stversions/**', + '**/.stfolder/**', + ], }); return mapLibrary(library); } diff --git a/server/src/services/maintenance.service.spec.ts b/server/src/services/maintenance.service.spec.ts new file mode 100644 index 0000000000..cc497a6ea4 --- /dev/null +++ b/server/src/services/maintenance.service.spec.ts @@ -0,0 +1,109 @@ +import { SystemMetadataKey } from 'src/enum'; +import { MaintenanceService } from 'src/services/maintenance.service'; +import { newTestService, ServiceMocks } from 'test/utils'; + +describe(MaintenanceService.name, () => { + let sut: MaintenanceService; + let mocks: ServiceMocks; + + beforeEach(() => { + ({ sut, mocks } = newTestService(MaintenanceService)); + }); + + it('should work', () => { + expect(sut).toBeDefined(); + }); + + describe('getMaintenanceMode', () => { + it('should return false if state unknown', async () => { + mocks.systemMetadata.get.mockResolvedValue(null); + + await expect(sut.getMaintenanceMode()).resolves.toEqual({ + isMaintenanceMode: false, + }); + + expect(mocks.systemMetadata.get).toHaveBeenCalled(); + }); + + it('should return false if disabled', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + + await expect(sut.getMaintenanceMode()).resolves.toEqual({ + isMaintenanceMode: false, + }); + + expect(mocks.systemMetadata.get).toHaveBeenCalled(); + }); + + it('should return true if enabled', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: '' }); + + await expect(sut.getMaintenanceMode()).resolves.toEqual({ + isMaintenanceMode: true, + secret: '', + }); + + expect(mocks.systemMetadata.get).toHaveBeenCalled(); + }); + }); + + describe('startMaintenance', () => { + it('should set maintenance mode and return a secret', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + + await expect(sut.startMaintenance('admin')).resolves.toMatchObject({ + jwt: expect.any(String), + }); + + expect(mocks.systemMetadata.set).toHaveBeenCalledWith(SystemMetadataKey.MaintenanceMode, { + isMaintenanceMode: true, + secret: expect.stringMatching(/^\w{128}$/), + }); + + expect(mocks.event.emit).toHaveBeenCalledWith('AppRestart', { + isMaintenanceMode: true, + }); + }); + }); + + describe('createLoginUrl', () => { + it('should fail outside of maintenance mode without secret', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: false }); + + await expect( + sut.createLoginUrl({ + username: '', + }), + ).rejects.toThrowError('Not in maintenance mode'); + }); + + it('should generate a login url with JWT', async () => { + mocks.systemMetadata.get.mockResolvedValue({ isMaintenanceMode: true, secret: 'secret' }); + + await expect( + sut.createLoginUrl({ + username: '', + }), + ).resolves.toEqual( + expect.stringMatching( + /^https:\/\/my.immich.app\/maintenance\?token=[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$/, + ), + ); + + expect(mocks.systemMetadata.get).toHaveBeenCalledTimes(2); + }); + + it('should use the given secret', async () => { + await expect( + sut.createLoginUrl( + { + username: '', + }, + 'secret', + ), + ).resolves.toEqual(expect.stringMatching(/./)); + + expect(mocks.systemMetadata.get).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/server/src/services/maintenance.service.ts b/server/src/services/maintenance.service.ts new file mode 100644 index 0000000000..e6808300bc --- /dev/null +++ b/server/src/services/maintenance.service.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@nestjs/common'; +import { OnEvent } from 'src/decorators'; +import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto'; +import { SystemMetadataKey } from 'src/enum'; +import { BaseService } from 'src/services/base.service'; +import { MaintenanceModeState } from 'src/types'; +import { createMaintenanceLoginUrl, generateMaintenanceSecret, signMaintenanceJwt } from 'src/utils/maintenance'; +import { getExternalDomain } from 'src/utils/misc'; + +/** + * This service is available outside of maintenance mode to manage maintenance mode + */ +@Injectable() +export class MaintenanceService extends BaseService { + getMaintenanceMode(): Promise { + return this.systemMetadataRepository + .get(SystemMetadataKey.MaintenanceMode) + .then((state) => state ?? { isMaintenanceMode: false }); + } + + async startMaintenance(username: string): Promise<{ jwt: string }> { + const secret = generateMaintenanceSecret(); + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, { isMaintenanceMode: true, secret }); + await this.eventRepository.emit('AppRestart', { isMaintenanceMode: true }); + + return { + jwt: await signMaintenanceJwt(secret, { + username, + }), + }; + } + + @OnEvent({ name: 'AppRestart', server: true }) + onRestart(): void { + this.appRepository.exitApp(); + } + + async createLoginUrl(auth: MaintenanceAuthDto, secret?: string): Promise { + const { server } = await this.getConfig({ withCache: true }); + const baseUrl = getExternalDomain(server); + + if (!secret) { + const state = await this.getMaintenanceMode(); + if (!state.isMaintenanceMode) { + throw new Error('Not in maintenance mode'); + } + + secret = state.secret; + } + + return await createMaintenanceLoginUrl(baseUrl, auth, secret); + } +} diff --git a/server/src/services/media.service.spec.ts b/server/src/services/media.service.spec.ts index ad52b0e8b0..8617930534 100644 --- a/server/src/services/media.service.spec.ts +++ b/server/src/services/media.service.spec.ts @@ -865,6 +865,7 @@ describe(MediaService.name, () => { mocks.systemMetadata.get.mockResolvedValue({ image: { fullsize: { enabled: false } } }); mocks.media.extract.mockResolvedValue({ buffer: extractedBuffer, format: RawExtractedFormat.Jpeg }); mocks.media.getImageDimensions.mockResolvedValue({ width: 3840, height: 2160 }); + mocks.media.copyTagGroup.mockResolvedValue(true); mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.panoramaTif); @@ -890,6 +891,13 @@ describe(MediaService.name, () => { }, expect.any(String), ); + + expect(mocks.media.copyTagGroup).toHaveBeenCalledTimes(2); + expect(mocks.media.copyTagGroup).toHaveBeenCalledWith( + 'XMP-GPano', + assetStub.panoramaTif.originalPath, + expect.any(String), + ); }); it('should respect encoding options when generating full-size preview', async () => { diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index 6caa682f5e..9027e89d66 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -174,8 +174,10 @@ export class MediaService extends BaseService { thumbhash: Buffer; }; if (asset.type === AssetType.Video || asset.originalFileName.toLowerCase().endsWith('.gif')) { + this.logger.verbose(`Thumbnail generation for video ${id} ${asset.originalPath}`); generated = await this.generateVideoThumbnails(asset); } else if (asset.type === AssetType.Image) { + this.logger.verbose(`Thumbnail generation for image ${id} ${asset.originalPath}`); generated = await this.generateImageThumbnails(asset); } else { this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video`); @@ -316,6 +318,16 @@ export class MediaService extends BaseService { const outputs = await Promise.all(promises); + if (asset.exifInfo.projectionType === 'EQUIRECTANGULAR') { + const promises = [ + this.mediaRepository.copyTagGroup('XMP-GPano', asset.originalPath, previewPath), + fullsizePath + ? this.mediaRepository.copyTagGroup('XMP-GPano', asset.originalPath, fullsizePath) + : Promise.resolve(), + ]; + await Promise.all(promises); + } + return { previewPath, thumbnailPath, fullsizePath, thumbhash: outputs[0] as Buffer }; } @@ -551,7 +563,7 @@ export class MediaService extends BaseService { private getMainStream(streams: T[]): T { return streams .filter((stream) => stream.codecName !== 'unknown') - .sort((stream1, stream2) => stream2.bitrate - stream1.bitrate)[0]; + .toSorted((stream1, stream2) => stream2.bitrate - stream1.bitrate)[0]; } private getTranscodeTarget( diff --git a/server/src/services/memory.service.ts b/server/src/services/memory.service.ts index 1d39169f3e..8e91c232f7 100644 --- a/server/src/services/memory.service.ts +++ b/server/src/services/memory.service.ts @@ -6,7 +6,7 @@ import { AuthDto } from 'src/dtos/auth.dto'; import { MemoryCreateDto, MemoryResponseDto, MemorySearchDto, MemoryUpdateDto, mapMemory } from 'src/dtos/memory.dto'; import { DatabaseLock, JobName, MemoryType, Permission, QueueName, SystemMetadataKey } from 'src/enum'; import { BaseService } from 'src/services/base.service'; -import { addAssets, getMyPartnerIds, removeAssets } from 'src/utils/asset.util'; +import { addAssets, removeAssets } from 'src/utils/asset.util'; const DAYS = 3; @@ -15,15 +15,6 @@ export class MemoryService extends BaseService { @OnJob({ name: JobName.MemoryGenerate, queue: QueueName.BackgroundTask }) async onMemoriesCreate() { const users = await this.userRepository.getList({ withDeleted: false }); - const usersIds = await Promise.all( - users.map((user) => - getMyPartnerIds({ - userId: user.id, - repository: this.partnerRepository, - timelineEnabled: true, - }), - ), - ); await this.databaseRepository.withLock(DatabaseLock.MemoryCreation, async () => { const state = await this.systemMetadataRepository.get(SystemMetadataKey.MemoriesState); @@ -38,7 +29,7 @@ export class MemoryService extends BaseService { } try { - await Promise.all(users.map((owner, i) => this.createOnThisDayMemories(owner.id, usersIds[i], target))); + await Promise.all(users.map((owner) => this.createOnThisDayMemories(owner.id, target))); } catch (error) { this.logger.error(`Failed to create memories for ${target.toISO()}: ${error}`); } @@ -51,10 +42,10 @@ export class MemoryService extends BaseService { }); } - private async createOnThisDayMemories(ownerId: string, userIds: string[], target: DateTime) { + private async createOnThisDayMemories(ownerId: string, target: DateTime) { const showAt = target.startOf('day').toISO(); const hideAt = target.endOf('day').toISO(); - const memories = await this.assetRepository.getByDayOfYear([ownerId, ...userIds], target); + const memories = await this.assetRepository.getByDayOfYear([ownerId], target); await Promise.all( memories.map(({ year, assets }) => this.memoryRepository.create( diff --git a/server/src/services/metadata.service.spec.ts b/server/src/services/metadata.service.spec.ts index 220216a2c8..46d6fe7abc 100644 --- a/server/src/services/metadata.service.spec.ts +++ b/server/src/services/metadata.service.spec.ts @@ -4,7 +4,16 @@ import { randomBytes } from 'node:crypto'; import { Stats } from 'node:fs'; import { defaults } from 'src/config'; import { MapAsset } from 'src/dtos/asset-response.dto'; -import { AssetType, AssetVisibility, ExifOrientation, ImmichWorker, JobName, JobStatus, SourceType } from 'src/enum'; +import { + AssetFileType, + AssetType, + AssetVisibility, + ExifOrientation, + ImmichWorker, + JobName, + JobStatus, + SourceType, +} from 'src/enum'; import { ImmichTags } from 'src/repositories/metadata.repository'; import { firstDateTime, MetadataService } from 'src/services/metadata.service'; import { assetStub } from 'test/fixtures/asset.stub'; @@ -15,17 +24,24 @@ import { tagStub } from 'test/fixtures/tag.stub'; import { factory } from 'test/small.factory'; import { makeStream, newTestService, ServiceMocks } from 'test/utils'; +const removeNonSidecarFiles = (asset: any) => { + return { + ...asset, + files: asset.files.filter((file: any) => file.type === AssetFileType.Sidecar), + }; +}; + const forSidecarJob = ( asset: { id?: string; originalPath?: string; - sidecarPath?: string | null; + files?: { id: string; type: AssetFileType; path: string }[]; } = {}, ) => { return { id: factory.uuid(), originalPath: '/path/to/IMG_123.jpg', - sidecarPath: null, + files: [], ...asset, }; }; @@ -166,7 +182,7 @@ describe(MetadataService.name, () => { it('should handle a date in a sidecar file', async () => { const originalDate = new Date('2023-11-21T16:13:17.517Z'); const sidecarDate = new Date('2022-01-01T00:00:00.000Z'); - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.sidecar); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.sidecar)); mockReadTags({ CreationDate: originalDate.toISOString() }, { CreationDate: sidecarDate.toISOString() }); await sut.handleMetadataExtraction({ id: assetStub.image.id }); @@ -185,7 +201,7 @@ describe(MetadataService.name, () => { it('should take the file modification date when missing exif and earlier than creation date', async () => { const fileCreatedAt = new Date('2022-01-01T00:00:00.000Z'); const fileModifiedAt = new Date('2021-01-01T00:00:00.000Z'); - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mocks.storage.stat.mockResolvedValue({ size: 123_456, mtime: fileModifiedAt, @@ -211,7 +227,7 @@ describe(MetadataService.name, () => { it('should take the file creation date when missing exif and earlier than modification date', async () => { const fileCreatedAt = new Date('2021-01-01T00:00:00.000Z'); const fileModifiedAt = new Date('2022-01-01T00:00:00.000Z'); - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mocks.storage.stat.mockResolvedValue({ size: 123_456, mtime: fileModifiedAt, @@ -234,7 +250,7 @@ describe(MetadataService.name, () => { it('should determine dateTimeOriginal regardless of the server time zone', async () => { process.env.TZ = 'America/Los_Angeles'; - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.sidecar); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.sidecar)); mockReadTags({ DateTimeOriginal: '2022:01:01 00:00:00' }); await sut.handleMetadataExtraction({ id: assetStub.image.id }); @@ -252,7 +268,7 @@ describe(MetadataService.name, () => { }); it('should handle lists of numbers', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mocks.storage.stat.mockResolvedValue({ size: 123_456, mtime: assetStub.image.fileModifiedAt, @@ -305,7 +321,7 @@ describe(MetadataService.name, () => { }); it('should apply reverse geocoding', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.withLocation); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.withLocation)); mocks.systemMetadata.get.mockResolvedValue({ reverseGeocoding: { enabled: true } }); mocks.map.reverseGeocode.mockResolvedValue({ city: 'City', state: 'State', country: 'Country' }); mocks.storage.stat.mockResolvedValue({ @@ -334,7 +350,7 @@ describe(MetadataService.name, () => { }); it('should discard latitude and longitude on null island', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.withLocation); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.withLocation)); mockReadTags({ GPSLatitude: 0, GPSLongitude: 0, @@ -346,7 +362,7 @@ describe(MetadataService.name, () => { }); it('should extract tags from TagsList', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ TagsList: ['Parent'] }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -356,7 +372,7 @@ describe(MetadataService.name, () => { }); it('should extract hierarchy from TagsList', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ TagsList: ['Parent/Child'] }); mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert); mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert); @@ -376,7 +392,7 @@ describe(MetadataService.name, () => { }); it('should extract tags from Keywords as a string', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ Keywords: 'Parent' }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -386,7 +402,7 @@ describe(MetadataService.name, () => { }); it('should extract tags from Keywords as a list', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ Keywords: ['Parent'] }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -396,7 +412,7 @@ describe(MetadataService.name, () => { }); it('should extract tags from Keywords as a list with a number', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ Keywords: ['Parent', 2024] }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -407,7 +423,7 @@ describe(MetadataService.name, () => { }); it('should extract hierarchal tags from Keywords', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ Keywords: 'Parent/Child' }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -426,7 +442,7 @@ describe(MetadataService.name, () => { }); it('should ignore Keywords when TagsList is present', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ Keywords: 'Child', TagsList: ['Parent/Child'] }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -445,7 +461,7 @@ describe(MetadataService.name, () => { }); it('should extract hierarchy from HierarchicalSubject', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ HierarchicalSubject: ['Parent|Child', 'TagA'] }); mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert); mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert); @@ -466,7 +482,7 @@ describe(MetadataService.name, () => { }); it('should extract tags from HierarchicalSubject as a list with a number', async () => { - mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image)); mockReadTags({ HierarchicalSubject: ['Parent', 2024] }); mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert); @@ -1017,12 +1033,51 @@ describe(MetadataService.name, () => { ); }); - it('should ignore duration from exif data', async () => { + it('should use Duration from exif', async () => { mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image); - mockReadTags({}, { Duration: { Value: 123 } }); + mockReadTags({ Duration: 123 }, {}); await sut.handleMetadataExtraction({ id: assetStub.image.id }); - expect(mocks.asset.update).toHaveBeenCalledWith(expect.objectContaining({ duration: null })); + + expect(mocks.metadata.readTags).toHaveBeenCalledTimes(1); + expect(mocks.asset.update).toHaveBeenCalledWith(expect.objectContaining({ duration: '00:02:03.000' })); + }); + + it('should prefer Duration from exif over sidecar', async () => { + mocks.assetJob.getForMetadataExtraction.mockResolvedValue({ + ...assetStub.image, + files: [ + { + id: 'some-id', + type: AssetFileType.Sidecar, + path: '/path/to/something', + }, + ], + }); + + mockReadTags({ Duration: 123 }, { Duration: 456 }); + + await sut.handleMetadataExtraction({ id: assetStub.image.id }); + + expect(mocks.metadata.readTags).toHaveBeenCalledTimes(2); + expect(mocks.asset.update).toHaveBeenCalledWith(expect.objectContaining({ duration: '00:02:03.000' })); + }); + + it('should ignore Duration from exif for videos', async () => { + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.video); + mockReadTags({ Duration: 123 }, {}); + mocks.media.probe.mockResolvedValue({ + ...probeStub.videoStreamH264, + format: { + ...probeStub.videoStreamH264.format, + duration: 456, + }, + }); + + await sut.handleMetadataExtraction({ id: assetStub.video.id }); + + expect(mocks.metadata.readTags).toHaveBeenCalledTimes(1); + expect(mocks.asset.update).toHaveBeenCalledWith(expect.objectContaining({ duration: '00:07:36.000' })); }); it('should trim whitespace from description', async () => { @@ -1504,18 +1559,25 @@ describe(MetadataService.name, () => { }); it('should detect a new sidecar at .jpg.xmp', async () => { - const asset = forSidecarJob({ originalPath: '/path/to/IMG_123.jpg' }); + const asset = forSidecarJob({ originalPath: '/path/to/IMG_123.jpg', files: [] }); mocks.assetJob.getForSidecarCheckJob.mockResolvedValue(asset); mocks.storage.checkFileExists.mockResolvedValueOnce(true); await expect(sut.handleSidecarCheck({ id: asset.id })).resolves.toBe(JobStatus.Success); - expect(mocks.asset.update).toHaveBeenCalledWith({ id: asset.id, sidecarPath: `/path/to/IMG_123.jpg.xmp` }); + expect(mocks.asset.upsertFile).toHaveBeenCalledWith({ + assetId: asset.id, + type: AssetFileType.Sidecar, + path: '/path/to/IMG_123.jpg.xmp', + }); }); it('should detect a new sidecar at .xmp', async () => { - const asset = forSidecarJob({ originalPath: '/path/to/IMG_123.jpg' }); + const asset = forSidecarJob({ + originalPath: '/path/to/IMG_123.jpg', + files: [], + }); mocks.assetJob.getForSidecarCheckJob.mockResolvedValue(asset); mocks.storage.checkFileExists.mockResolvedValueOnce(false); @@ -1523,33 +1585,44 @@ describe(MetadataService.name, () => { await expect(sut.handleSidecarCheck({ id: asset.id })).resolves.toBe(JobStatus.Success); - expect(mocks.asset.update).toHaveBeenCalledWith({ id: asset.id, sidecarPath: '/path/to/IMG_123.xmp' }); + expect(mocks.asset.upsertFile).toHaveBeenCalledWith({ + assetId: asset.id, + type: AssetFileType.Sidecar, + path: '/path/to/IMG_123.xmp', + }); }); - it('should unset sidecar path if file does not exist anymore', async () => { - const asset = forSidecarJob({ originalPath: '/path/to/IMG_123.jpg', sidecarPath: '/path/to/IMG_123.jpg.xmp' }); + it('should unset sidecar path if file no longer exist', async () => { + const asset = forSidecarJob({ + originalPath: '/path/to/IMG_123.jpg', + files: [{ id: 'sidecar', path: '/path/to/IMG_123.jpg.xmp', type: AssetFileType.Sidecar }], + }); mocks.assetJob.getForSidecarCheckJob.mockResolvedValue(asset); mocks.storage.checkFileExists.mockResolvedValue(false); await expect(sut.handleSidecarCheck({ id: asset.id })).resolves.toBe(JobStatus.Success); - expect(mocks.asset.update).toHaveBeenCalledWith({ id: asset.id, sidecarPath: null }); + expect(mocks.asset.deleteFile).toHaveBeenCalledWith({ assetId: asset.id, type: AssetFileType.Sidecar }); }); it('should do nothing if the sidecar file still exists', async () => { - const asset = forSidecarJob({ originalPath: '/path/to/IMG_123.jpg', sidecarPath: '/path/to/IMG_123.jpg' }); + const asset = forSidecarJob({ + originalPath: '/path/to/IMG_123.jpg', + files: [{ id: 'sidecar', path: '/path/to/IMG_123.jpg.xmp', type: AssetFileType.Sidecar }], + }); mocks.assetJob.getForSidecarCheckJob.mockResolvedValue(asset); mocks.storage.checkFileExists.mockResolvedValueOnce(true); await expect(sut.handleSidecarCheck({ id: asset.id })).resolves.toBe(JobStatus.Skipped); - expect(mocks.asset.update).not.toHaveBeenCalled(); + expect(mocks.asset.upsertFile).not.toHaveBeenCalled(); + expect(mocks.asset.deleteFile).not.toHaveBeenCalled(); }); }); describe('handleSidecarWrite', () => { - it('should skip assets that do not exist anymore', async () => { + it('should skip assets that no longer exist', async () => { mocks.assetJob.getForSidecarWriteJob.mockResolvedValue(void 0); await expect(sut.handleSidecarWrite({ id: 'asset-123' })).resolves.toBe(JobStatus.Failed); expect(mocks.metadata.writeTags).not.toHaveBeenCalled(); @@ -1578,7 +1651,7 @@ describe(MetadataService.name, () => { dateTimeOriginal: date, }), ).resolves.toBe(JobStatus.Success); - expect(mocks.metadata.writeTags).toHaveBeenCalledWith(asset.sidecarPath, { + expect(mocks.metadata.writeTags).toHaveBeenCalledWith(asset.files[0].path, { Description: description, ImageDescription: description, DateTimeOriginal: date, diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index 746f62a944..4d6d4c190f 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -8,9 +8,10 @@ import { constants } from 'node:fs/promises'; import { join, parse } from 'node:path'; import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants'; import { StorageCore } from 'src/cores/storage.core'; -import { Asset, AssetFace } from 'src/database'; +import { Asset, AssetFace, AssetFile } from 'src/database'; import { OnEvent, OnJob } from 'src/decorators'; import { + AssetFileType, AssetType, AssetVisibility, DatabaseLock, @@ -29,6 +30,7 @@ import { AssetFaceTable } from 'src/schema/tables/asset-face.table'; import { PersonTable } from 'src/schema/tables/person.table'; import { BaseService } from 'src/services/base.service'; import { JobItem, JobOf } from 'src/types'; +import { getAssetFiles } from 'src/utils/asset.util'; import { isAssetChecksumConstraint } from 'src/utils/database'; import { isFaceImportEnabled } from 'src/utils/misc'; import { upsertTags } from 'src/utils/tag'; @@ -37,7 +39,6 @@ import { upsertTags } from 'src/utils/tag'; const EXIF_DATE_TAGS: Array = [ 'SubSecDateTimeOriginal', 'SubSecCreateDate', - 'SubSecMediaCreateDate', 'DateTimeOriginal', 'CreationDate', 'CreateDate', @@ -291,7 +292,7 @@ export class MetadataService extends BaseService { this.assetRepository.upsertExif(exifData), this.assetRepository.update({ id: asset.id, - duration: exifTags.Duration?.toString() ?? null, + duration: this.getDuration(exifTags), localDateTime: dates.localDateTime, fileCreatedAt: dates.dateTimeOriginal ?? undefined, fileModifiedAt: stats.mtime, @@ -360,17 +361,21 @@ export class MetadataService extends BaseService { break; } - const isChanged = sidecarPath !== asset.sidecarPath; + const { sidecarFile } = getAssetFiles(asset.files); + + const isChanged = sidecarPath !== sidecarFile?.path; this.logger.debug( - `Sidecar check found old=${asset.sidecarPath}, new=${sidecarPath} will ${isChanged ? 'update' : 'do nothing for'} asset ${asset.id}: ${asset.originalPath}`, + `Sidecar check found old=${sidecarFile?.path}, new=${sidecarPath} will ${isChanged ? 'update' : 'do nothing for'} asset ${asset.id}: ${asset.originalPath}`, ); if (!isChanged) { return JobStatus.Skipped; } - await this.assetRepository.update({ id: asset.id, sidecarPath }); + await (sidecarPath === null + ? this.assetRepository.deleteFile({ assetId: asset.id, type: AssetFileType.Sidecar }) + : this.assetRepository.upsertFile({ assetId: asset.id, type: AssetFileType.Sidecar, path: sidecarPath })); return JobStatus.Success; } @@ -395,7 +400,9 @@ export class MetadataService extends BaseService { const tagsList = (asset.tags || []).map((tag) => tag.value); - const sidecarPath = asset.sidecarPath || `${asset.originalPath}.xmp`; + const { sidecarFile } = getAssetFiles(asset.files); + const sidecarPath = sidecarFile?.path || `${asset.originalPath}.xmp`; + const exif = _.omitBy( { Description: description, @@ -415,18 +422,19 @@ export class MetadataService extends BaseService { await this.metadataRepository.writeTags(sidecarPath, exif); - if (!asset.sidecarPath) { - await this.assetRepository.update({ id, sidecarPath }); + if (asset.files.length === 0) { + await this.assetRepository.upsertFile({ assetId: id, type: AssetFileType.Sidecar, path: sidecarPath }); } return JobStatus.Success; } - private getSidecarCandidates({ sidecarPath, originalPath }: { sidecarPath: string | null; originalPath: string }) { + private getSidecarCandidates({ files, originalPath }: { files: AssetFile[]; originalPath: string }) { const candidates: string[] = []; - if (sidecarPath) { - candidates.push(sidecarPath); + const { sidecarFile } = getAssetFiles(files); + if (sidecarFile?.path) { + candidates.push(sidecarFile.path); } const assetPath = parse(originalPath); @@ -457,26 +465,12 @@ export class MetadataService extends BaseService { return { width, height }; } - private getExifTags(asset: { - originalPath: string; - sidecarPath: string | null; - type: AssetType; - }): Promise { - if (!asset.sidecarPath && asset.type === AssetType.Image) { - return this.metadataRepository.readTags(asset.originalPath); - } + private async getExifTags(asset: { originalPath: string; files: AssetFile[]; type: AssetType }): Promise { + const { sidecarFile } = getAssetFiles(asset.files); - return this.mergeExifTags(asset); - } - - private async mergeExifTags(asset: { - originalPath: string; - sidecarPath: string | null; - type: AssetType; - }): Promise { const [mediaTags, sidecarTags, videoTags] = await Promise.all([ this.metadataRepository.readTags(asset.originalPath), - asset.sidecarPath ? this.metadataRepository.readTags(asset.sidecarPath) : null, + sidecarFile ? this.metadataRepository.readTags(sidecarFile.path) : null, asset.type === AssetType.Video ? this.getVideoTags(asset.originalPath) : null, ]); @@ -492,7 +486,11 @@ export class MetadataService extends BaseService { } // prefer duration from video tags - delete mediaTags.Duration; + if (videoTags) { + delete mediaTags.Duration; + } + + // never use duration from sidecar delete sidecarTags?.Duration; return { ...mediaTags, ...videoTags, ...sidecarTags }; @@ -934,6 +932,20 @@ export class MetadataService extends BaseService { return bitsPerSample; } + private getDuration(tags: ImmichTags): string | null { + const duration = tags.Duration; + + if (typeof duration === 'string') { + return duration; + } + + if (typeof duration === 'number') { + return Duration.fromObject({ seconds: duration }).toFormat('hh:mm:ss.SSS'); + } + + return null; + } + private async getVideoTags(originalPath: string) { const { videoStreams, format } = await this.mediaRepository.probe(originalPath); @@ -961,7 +973,7 @@ export class MetadataService extends BaseService { } if (format.duration) { - tags.Duration = Duration.fromObject({ seconds: format.duration }).toFormat('hh:mm:ss.SSS'); + tags.Duration = format.duration; } return tags; diff --git a/server/src/services/notification.service.ts b/server/src/services/notification.service.ts index 8276f141a0..ee87fcf775 100644 --- a/server/src/services/notification.service.ts +++ b/server/src/services/notification.service.ts @@ -114,6 +114,15 @@ export class NotificationService extends BaseService { this.websocketRepository.serverSend('ConfigUpdate', { oldConfig, newConfig }); } + @OnEvent({ name: 'AppRestart' }) + onAppRestart(state: ArgOf<'AppRestart'>) { + this.websocketRepository.clientBroadcast('AppRestartV1', { + isMaintenanceMode: state.isMaintenanceMode, + }); + + this.websocketRepository.serverSend('AppRestart', state); + } + @OnEvent({ name: 'ConfigValidate', priority: -100 }) async onConfigValidate({ oldConfig, newConfig }: ArgOf<'ConfigValidate'>) { try { diff --git a/server/src/services/ocr.service.spec.ts b/server/src/services/ocr.service.spec.ts index 6eedba1a5f..404f423cac 100644 --- a/server/src/services/ocr.service.spec.ts +++ b/server/src/services/ocr.service.spec.ts @@ -12,8 +12,21 @@ describe(OcrService.name, () => { ({ sut, mocks } = newTestService(OcrService)); mocks.config.getWorker.mockReturnValue(ImmichWorker.Microservices); + mocks.assetJob.getForOcr.mockResolvedValue({ + visibility: AssetVisibility.Timeline, + previewFile: assetStub.image.files[1].path, + }); }); + const mockOcrResult = (...texts: string[]) => { + mocks.machineLearning.ocr.mockResolvedValue({ + box: texts.flatMap((_, i) => Array.from({ length: 8 }, (_, j) => i * 10 + j)), + boxScore: texts.map(() => 0.9), + text: texts, + textScore: texts.map(() => 0.95), + }); + }; + it('should work', () => { expect(sut).toBeDefined(); }); @@ -72,10 +85,6 @@ describe(OcrService.name, () => { text: ['One Two Three', 'Four Five'], textScore: [0.95, 0.85], }); - mocks.assetJob.getForOcr.mockResolvedValue({ - visibility: AssetVisibility.Timeline, - previewFile: assetStub.image.files[1].path, - }); expect(await sut.handleOcr({ id: assetStub.image.id })).toEqual(JobStatus.Success); @@ -88,36 +97,40 @@ describe(OcrService.name, () => { maxResolution: 736, }), ); - expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, [ - { - assetId: assetStub.image.id, - boxScore: 0.9, - text: 'One Two Three', - textScore: 0.95, - x1: 10, - y1: 20, - x2: 30, - y2: 40, - x3: 50, - y3: 60, - x4: 70, - y4: 80, - }, - { - assetId: assetStub.image.id, - boxScore: 0.8, - text: 'Four Five', - textScore: 0.85, - x1: 90, - y1: 100, - x2: 110, - y2: 120, - x3: 130, - y3: 140, - x4: 150, - y4: 160, - }, - ]); + expect(mocks.ocr.upsert).toHaveBeenCalledWith( + assetStub.image.id, + [ + { + assetId: assetStub.image.id, + boxScore: 0.9, + text: 'One Two Three', + textScore: 0.95, + x1: 10, + y1: 20, + x2: 30, + y2: 40, + x3: 50, + y3: 60, + x4: 70, + y4: 80, + }, + { + assetId: assetStub.image.id, + boxScore: 0.8, + text: 'Four Five', + textScore: 0.85, + x1: 90, + y1: 100, + x2: 110, + y2: 120, + x3: 130, + y3: 140, + x4: 150, + y4: 160, + }, + ], + 'One Two Three Four Five', + ); }); it('should apply config settings', async () => { @@ -133,11 +146,7 @@ describe(OcrService.name, () => { }, }, }); - mocks.machineLearning.ocr.mockResolvedValue({ box: [], boxScore: [], text: [], textScore: [] }); - mocks.assetJob.getForOcr.mockResolvedValue({ - visibility: AssetVisibility.Timeline, - previewFile: assetStub.image.files[1].path, - }); + mockOcrResult(); expect(await sut.handleOcr({ id: assetStub.image.id })).toEqual(JobStatus.Success); @@ -150,7 +159,7 @@ describe(OcrService.name, () => { maxResolution: 1500, }), ); - expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, []); + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, [], ''); }); it('should skip invisible assets', async () => { @@ -173,5 +182,83 @@ describe(OcrService.name, () => { expect(mocks.machineLearning.ocr).not.toHaveBeenCalled(); expect(mocks.ocr.upsert).not.toHaveBeenCalled(); }); + + describe('search tokenization', () => { + it('should generate bigrams for Chinese text', async () => { + mockOcrResult('機器學習'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), '機器 器學 學習'); + }); + + it('should generate bigrams for Japanese text', async () => { + mockOcrResult('テスト'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), 'テス スト'); + }); + + it('should generate bigrams for Korean text', async () => { + mockOcrResult('한국어'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), '한국 국어'); + }); + + it('should pass through Latin text unchanged', async () => { + mockOcrResult('Hello World'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), 'Hello World'); + }); + + it('should handle mixed CJK and Latin text', async () => { + mockOcrResult('機器學習Model'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), '機器 器學 學習 Model'); + }); + + it('should handle year followed by CJK', async () => { + mockOcrResult('2024年レポート'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith( + assetStub.image.id, + expect.any(Array), + '2024 年レ レポ ポー ート', + ); + }); + + it('should join multiple OCR boxes', async () => { + mockOcrResult('機器', 'Learning'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), '機器 Learning'); + }); + + it('should normalize whitespace', async () => { + mockOcrResult(' Hello World '); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), 'Hello World'); + }); + + it('should keep single CJK characters', async () => { + mockOcrResult('A', '中', 'B'); + + await sut.handleOcr({ id: assetStub.image.id }); + + expect(mocks.ocr.upsert).toHaveBeenCalledWith(assetStub.image.id, expect.any(Array), 'A 中 B'); + }); + }); }); }); diff --git a/server/src/services/ocr.service.ts b/server/src/services/ocr.service.ts index cba57e5bc7..d92d399dba 100644 --- a/server/src/services/ocr.service.ts +++ b/server/src/services/ocr.service.ts @@ -5,6 +5,7 @@ import { AssetVisibility, JobName, JobStatus, QueueName } from 'src/enum'; import { OCR } from 'src/repositories/machine-learning.repository'; import { BaseService } from 'src/services/base.service'; import { JobItem, JobOf } from 'src/types'; +import { tokenizeForSearch } from 'src/utils/database'; import { isOcrEnabled } from 'src/utils/misc'; @Injectable() @@ -53,8 +54,8 @@ export class OcrService extends BaseService { } const ocrResults = await this.machineLearningRepository.ocr(asset.previewFile, machineLearning.ocr); - - await this.ocrRepository.upsert(id, this.parseOcrResults(id, ocrResults)); + const { ocrDataList, searchText } = this.parseOcrResults(id, ocrResults); + await this.ocrRepository.upsert(id, ocrDataList, searchText); await this.assetRepository.upsertJobStatus({ assetId: id, ocrAt: new Date() }); @@ -64,7 +65,9 @@ export class OcrService extends BaseService { private parseOcrResults(id: string, { box, boxScore, text, textScore }: OCR) { const ocrDataList = []; + const searchTokens = []; for (let i = 0; i < text.length; i++) { + const rawText = text[i]; const boxOffset = i * 8; ocrDataList.push({ assetId: id, @@ -78,9 +81,11 @@ export class OcrService extends BaseService { y4: box[boxOffset + 7], boxScore: boxScore[i], textScore: textScore[i], - text: text[i], + text: rawText, }); + searchTokens.push(...tokenizeForSearch(rawText)); } - return ocrDataList; + + return { ocrDataList, searchText: searchTokens.join(' ') }; } } diff --git a/server/src/services/plugin.service.ts b/server/src/services/plugin.service.ts index 28d1ac56ca..9336f0003a 100644 --- a/server/src/services/plugin.service.ts +++ b/server/src/services/plugin.service.ts @@ -247,9 +247,9 @@ export class PluginService extends BaseService { private async executeFilters(workflowFilters: WorkflowFilter[], context: WorkflowContext): Promise { for (const workflowFilter of workflowFilters) { - const filter = await this.pluginRepository.getFilter(workflowFilter.filterId); + const filter = await this.pluginRepository.getFilter(workflowFilter.pluginFilterId); if (!filter) { - this.logger.error(`Filter ${workflowFilter.filterId} not found`); + this.logger.error(`Filter ${workflowFilter.pluginFilterId} not found`); return false; } @@ -291,9 +291,9 @@ export class PluginService extends BaseService { private async executeActions(workflowActions: WorkflowAction[], context: WorkflowContext): Promise { for (const workflowAction of workflowActions) { - const action = await this.pluginRepository.getAction(workflowAction.actionId); + const action = await this.pluginRepository.getAction(workflowAction.pluginActionId); if (!action) { - throw new Error(`Action ${workflowAction.actionId} not found`); + throw new Error(`Action ${workflowAction.pluginActionId} not found`); } const pluginInstance = this.loadedPlugins.get(action.pluginId); diff --git a/server/src/services/queue.service.spec.ts b/server/src/services/queue.service.spec.ts index 5dce9476e2..f5cf20413e 100644 --- a/server/src/services/queue.service.spec.ts +++ b/server/src/services/queue.service.spec.ts @@ -2,6 +2,7 @@ import { BadRequestException } from '@nestjs/common'; import { defaults, SystemConfig } from 'src/config'; import { ImmichWorker, JobName, QueueCommand, QueueName } from 'src/enum'; import { QueueService } from 'src/services/queue.service'; +import { factory } from 'test/small.factory'; import { newTestService, ServiceMocks } from 'test/utils'; describe(QueueService.name, () => { @@ -52,80 +53,64 @@ describe(QueueService.name, () => { describe('getAllJobStatus', () => { it('should get all job statuses', async () => { - mocks.job.getJobCounts.mockResolvedValue({ - active: 1, - completed: 1, - failed: 1, - delayed: 1, - waiting: 1, - paused: 1, - }); - mocks.job.getQueueStatus.mockResolvedValue({ - isActive: true, - isPaused: true, - }); + const stats = factory.queueStatistics({ active: 1 }); + const expected = { jobCounts: stats, queueStatus: { isActive: true, isPaused: true } }; - const expectedJobStatus = { - jobCounts: { - active: 1, - completed: 1, - delayed: 1, - failed: 1, - waiting: 1, - paused: 1, - }, - queueStatus: { - isActive: true, - isPaused: true, - }, - }; + mocks.job.getJobCounts.mockResolvedValue(stats); + mocks.job.isPaused.mockResolvedValue(true); - await expect(sut.getAll()).resolves.toEqual({ - [QueueName.BackgroundTask]: expectedJobStatus, - [QueueName.DuplicateDetection]: expectedJobStatus, - [QueueName.SmartSearch]: expectedJobStatus, - [QueueName.MetadataExtraction]: expectedJobStatus, - [QueueName.Search]: expectedJobStatus, - [QueueName.StorageTemplateMigration]: expectedJobStatus, - [QueueName.Migration]: expectedJobStatus, - [QueueName.ThumbnailGeneration]: expectedJobStatus, - [QueueName.VideoConversion]: expectedJobStatus, - [QueueName.FaceDetection]: expectedJobStatus, - [QueueName.FacialRecognition]: expectedJobStatus, - [QueueName.Sidecar]: expectedJobStatus, - [QueueName.Library]: expectedJobStatus, - [QueueName.Notification]: expectedJobStatus, - [QueueName.BackupDatabase]: expectedJobStatus, - [QueueName.Ocr]: expectedJobStatus, - [QueueName.Workflow]: expectedJobStatus, + await expect(sut.getAllLegacy(factory.auth())).resolves.toEqual({ + [QueueName.BackgroundTask]: expected, + [QueueName.DuplicateDetection]: expected, + [QueueName.SmartSearch]: expected, + [QueueName.MetadataExtraction]: expected, + [QueueName.Search]: expected, + [QueueName.StorageTemplateMigration]: expected, + [QueueName.Migration]: expected, + [QueueName.ThumbnailGeneration]: expected, + [QueueName.VideoConversion]: expected, + [QueueName.FaceDetection]: expected, + [QueueName.FacialRecognition]: expected, + [QueueName.Sidecar]: expected, + [QueueName.Library]: expected, + [QueueName.Notification]: expected, + [QueueName.BackupDatabase]: expected, + [QueueName.Ocr]: expected, + [QueueName.Workflow]: expected, }); }); }); describe('handleCommand', () => { it('should handle a pause command', async () => { - await sut.runCommand(QueueName.MetadataExtraction, { command: QueueCommand.Pause, force: false }); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); + + await sut.runCommandLegacy(QueueName.MetadataExtraction, { command: QueueCommand.Pause, force: false }); expect(mocks.job.pause).toHaveBeenCalledWith(QueueName.MetadataExtraction); }); it('should handle a resume command', async () => { - await sut.runCommand(QueueName.MetadataExtraction, { command: QueueCommand.Resume, force: false }); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); + + await sut.runCommandLegacy(QueueName.MetadataExtraction, { command: QueueCommand.Resume, force: false }); expect(mocks.job.resume).toHaveBeenCalledWith(QueueName.MetadataExtraction); }); it('should handle an empty command', async () => { - await sut.runCommand(QueueName.MetadataExtraction, { command: QueueCommand.Empty, force: false }); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); + + await sut.runCommandLegacy(QueueName.MetadataExtraction, { command: QueueCommand.Empty, force: false }); expect(mocks.job.empty).toHaveBeenCalledWith(QueueName.MetadataExtraction); }); it('should not start a job that is already running', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: true, isPaused: false }); + mocks.job.isActive.mockResolvedValue(true); await expect( - sut.runCommand(QueueName.VideoConversion, { command: QueueCommand.Start, force: false }), + sut.runCommandLegacy(QueueName.VideoConversion, { command: QueueCommand.Start, force: false }), ).rejects.toBeInstanceOf(BadRequestException); expect(mocks.job.queue).not.toHaveBeenCalled(); @@ -133,33 +118,37 @@ describe(QueueService.name, () => { }); it('should handle a start video conversion command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.VideoConversion, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.VideoConversion, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetEncodeVideoQueueAll, data: { force: false } }); }); it('should handle a start storage template migration command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.StorageTemplateMigration, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.StorageTemplateMigration, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.StorageTemplateMigration }); }); it('should handle a start smart search command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.SmartSearch, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.SmartSearch, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.SmartSearchQueueAll, data: { force: false } }); }); it('should handle a start metadata extraction command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.MetadataExtraction, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.MetadataExtraction, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetExtractMetadataQueueAll, @@ -168,17 +157,19 @@ describe(QueueService.name, () => { }); it('should handle a start sidecar command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.Sidecar, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.Sidecar, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.SidecarQueueAll, data: { force: false } }); }); it('should handle a start thumbnail generation command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.ThumbnailGeneration, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.ThumbnailGeneration, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetGenerateThumbnailsQueueAll, @@ -187,34 +178,37 @@ describe(QueueService.name, () => { }); it('should handle a start face detection command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.FaceDetection, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.FaceDetection, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetDetectFacesQueueAll, data: { force: false } }); }); it('should handle a start facial recognition command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.FacialRecognition, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.FacialRecognition, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.FacialRecognitionQueueAll, data: { force: false } }); }); it('should handle a start backup database command', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); + mocks.job.getJobCounts.mockResolvedValue(factory.queueStatistics()); - await sut.runCommand(QueueName.BackupDatabase, { command: QueueCommand.Start, force: false }); + await sut.runCommandLegacy(QueueName.BackupDatabase, { command: QueueCommand.Start, force: false }); expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.DatabaseBackup, data: { force: false } }); }); it('should throw a bad request when an invalid queue is used', async () => { - mocks.job.getQueueStatus.mockResolvedValue({ isActive: false, isPaused: false }); + mocks.job.isActive.mockResolvedValue(false); await expect( - sut.runCommand(QueueName.BackgroundTask, { command: QueueCommand.Start, force: false }), + sut.runCommandLegacy(QueueName.BackgroundTask, { command: QueueCommand.Start, force: false }), ).rejects.toBeInstanceOf(BadRequestException); expect(mocks.job.queue).not.toHaveBeenCalled(); diff --git a/server/src/services/queue.service.ts b/server/src/services/queue.service.ts index bea665e8fd..cdfa2ad2ed 100644 --- a/server/src/services/queue.service.ts +++ b/server/src/services/queue.service.ts @@ -2,7 +2,21 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { ClassConstructor } from 'class-transformer'; import { SystemConfig } from 'src/config'; import { OnEvent } from 'src/decorators'; -import { QueueCommandDto, QueueResponseDto, QueuesResponseDto } from 'src/dtos/queue.dto'; +import { AuthDto } from 'src/dtos/auth.dto'; +import { + mapQueueLegacy, + mapQueuesLegacy, + QueueResponseLegacyDto, + QueuesResponseLegacyDto, +} from 'src/dtos/queue-legacy.dto'; +import { + QueueCommandDto, + QueueDeleteDto, + QueueJobResponseDto, + QueueJobSearchDto, + QueueResponseDto, + QueueUpdateDto, +} from 'src/dtos/queue.dto'; import { BootstrapEventPriority, CronJob, @@ -86,7 +100,7 @@ export class QueueService extends BaseService { this.services = services; } - async runCommand(name: QueueName, dto: QueueCommandDto): Promise { + async runCommandLegacy(name: QueueName, dto: QueueCommandDto): Promise { this.logger.debug(`Handling command: queue=${name},command=${dto.command},force=${dto.force}`); switch (dto.command) { @@ -117,28 +131,60 @@ export class QueueService extends BaseService { } } + const response = await this.getByName(name); + + return mapQueueLegacy(response); + } + + async getAll(_auth: AuthDto): Promise { + return Promise.all(Object.values(QueueName).map((name) => this.getByName(name))); + } + + async getAllLegacy(auth: AuthDto): Promise { + const responses = await this.getAll(auth); + return mapQueuesLegacy(responses); + } + + get(auth: AuthDto, name: QueueName): Promise { return this.getByName(name); } - async getAll(): Promise { - const response = new QueuesResponseDto(); - for (const name of Object.values(QueueName)) { - response[name] = await this.getByName(name); + async update(auth: AuthDto, name: QueueName, dto: QueueUpdateDto): Promise { + if (dto.isPaused === true) { + if (name === QueueName.BackgroundTask) { + throw new BadRequestException(`The BackgroundTask queue cannot be paused`); + } + await this.jobRepository.pause(name); } - return response; + + if (dto.isPaused === false) { + await this.jobRepository.resume(name); + } + + return this.getByName(name); } - async getByName(name: QueueName): Promise { - const [jobCounts, queueStatus] = await Promise.all([ - this.jobRepository.getJobCounts(name), - this.jobRepository.getQueueStatus(name), - ]); + searchJobs(auth: AuthDto, name: QueueName, dto: QueueJobSearchDto): Promise { + return this.jobRepository.searchJobs(name, dto); + } - return { jobCounts, queueStatus }; + async emptyQueue(auth: AuthDto, name: QueueName, dto: QueueDeleteDto) { + await this.jobRepository.empty(name); + if (dto.failed) { + await this.jobRepository.clear(name, QueueCleanType.Failed); + } + } + + private async getByName(name: QueueName): Promise { + const [statistics, isPaused] = await Promise.all([ + this.jobRepository.getJobCounts(name), + this.jobRepository.isPaused(name), + ]); + return { name, isPaused, statistics }; } private async start(name: QueueName, { force }: QueueCommandDto): Promise { - const { isActive } = await this.jobRepository.getQueueStatus(name); + const isActive = await this.jobRepository.isActive(name); if (isActive) { throw new BadRequestException(`Job is already running`); } diff --git a/server/src/services/server.service.spec.ts b/server/src/services/server.service.spec.ts index 8e39f09c62..6e1187a900 100644 --- a/server/src/services/server.service.spec.ts +++ b/server/src/services/server.service.spec.ts @@ -166,6 +166,7 @@ describe(ServerService.name, () => { publicUsers: true, mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json', mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json', + maintenanceMode: false, }); expect(mocks.systemMetadata.get).toHaveBeenCalled(); }); diff --git a/server/src/services/server.service.ts b/server/src/services/server.service.ts index 5c3669dcbb..af4d706061 100644 --- a/server/src/services/server.service.ts +++ b/server/src/services/server.service.ts @@ -130,6 +130,7 @@ export class ServerService extends BaseService { publicUsers: config.server.publicUsers, mapDarkStyleUrl: config.map.darkStyle, mapLightStyleUrl: config.map.lightStyle, + maintenanceMode: false, }; } diff --git a/server/src/services/storage-template.service.ts b/server/src/services/storage-template.service.ts index 1d38bf7011..864207bf05 100644 --- a/server/src/services/storage-template.service.ts +++ b/server/src/services/storage-template.service.ts @@ -6,10 +6,20 @@ import sanitize from 'sanitize-filename'; import { StorageCore } from 'src/cores/storage.core'; import { OnEvent, OnJob } from 'src/decorators'; import { SystemConfigTemplateStorageOptionDto } from 'src/dtos/system-config.dto'; -import { AssetPathType, AssetType, DatabaseLock, JobName, JobStatus, QueueName, StorageFolder } from 'src/enum'; +import { + AssetFileType, + AssetPathType, + AssetType, + DatabaseLock, + JobName, + JobStatus, + QueueName, + StorageFolder, +} from 'src/enum'; import { ArgOf } from 'src/repositories/event.repository'; import { BaseService } from 'src/services/base.service'; import { JobOf, StorageAsset } from 'src/types'; +import { getAssetFile } from 'src/utils/asset.util'; import { getLivePhotoMotionFilename } from 'src/utils/file'; const storageTokens = { @@ -196,7 +206,7 @@ export class StorageTemplateService extends BaseService { } return this.databaseRepository.withLock(DatabaseLock.StorageTemplateMigration, async () => { - const { id, sidecarPath, originalPath, checksum, fileSizeInByte } = asset; + const { id, originalPath, checksum, fileSizeInByte } = asset; const oldPath = originalPath; const newPath = await this.getTemplatePath(asset, metadata); @@ -213,6 +223,8 @@ export class StorageTemplateService extends BaseService { newPath, assetInfo: { sizeInBytes: fileSizeInByte, checksum }, }); + + const sidecarPath = getAssetFile(asset.files, AssetFileType.Sidecar)?.path; if (sidecarPath) { await this.storageCore.moveFile({ entityId: id, diff --git a/server/src/services/tag.service.spec.ts b/server/src/services/tag.service.spec.ts index 6a630de6a1..6bb92abd8c 100644 --- a/server/src/services/tag.service.spec.ts +++ b/server/src/services/tag.service.spec.ts @@ -217,7 +217,7 @@ describe(TagService.name, () => { describe('addAssets', () => { it('should handle invalid ids', async () => { - mocks.tag.getAssetIds.mockResolvedValue(new Set([])); + mocks.tag.getAssetIds.mockResolvedValue(new Set()); await expect(sut.addAssets(authStub.admin, 'tag-1', { ids: ['asset-1'] })).resolves.toEqual([ { id: 'asset-1', success: false, error: 'no_permission' }, ]); diff --git a/server/src/services/workflow.service.ts b/server/src/services/workflow.service.ts index ae72187d7d..301931421f 100644 --- a/server/src/services/workflow.service.ts +++ b/server/src/services/workflow.service.ts @@ -78,13 +78,13 @@ export class WorkflowService extends BaseService { } private async validateAndMapFilters( - filters: Array<{ filterId: string; filterConfig?: any }>, + filters: Array<{ pluginFilterId: string; filterConfig?: any }>, requiredContext: PluginContext, ) { for (const dto of filters) { - const filter = await this.pluginRepository.getFilter(dto.filterId); + const filter = await this.pluginRepository.getFilter(dto.pluginFilterId); if (!filter) { - throw new BadRequestException(`Invalid filter ID: ${dto.filterId}`); + throw new BadRequestException(`Invalid filter ID: ${dto.pluginFilterId}`); } if (!filter.supportedContexts.includes(requiredContext)) { @@ -95,20 +95,20 @@ export class WorkflowService extends BaseService { } return filters.map((dto, index) => ({ - filterId: dto.filterId, + pluginFilterId: dto.pluginFilterId, filterConfig: dto.filterConfig || null, order: index, })); } private async validateAndMapActions( - actions: Array<{ actionId: string; actionConfig?: any }>, + actions: Array<{ pluginActionId: string; actionConfig?: any }>, requiredContext: PluginContext, ) { for (const dto of actions) { - const action = await this.pluginRepository.getAction(dto.actionId); + const action = await this.pluginRepository.getAction(dto.pluginActionId); if (!action) { - throw new BadRequestException(`Invalid action ID: ${dto.actionId}`); + throw new BadRequestException(`Invalid action ID: ${dto.pluginActionId}`); } if (!action.supportedContexts.includes(requiredContext)) { throw new BadRequestException( @@ -118,7 +118,7 @@ export class WorkflowService extends BaseService { } return actions.map((dto, index) => ({ - actionId: dto.actionId, + pluginActionId: dto.pluginActionId, actionConfig: dto.actionConfig || null, order: index, })); diff --git a/server/src/sql-tools/helpers.ts b/server/src/sql-tools/helpers.ts index 12586f27b2..2ef35ce9ba 100644 --- a/server/src/sql-tools/helpers.ts +++ b/server/src/sql-tools/helpers.ts @@ -46,7 +46,7 @@ export const setIsEqual = (source: Set, target: Set) => source.size === target.size && [...source].every((x) => target.has(x)); export const haveEqualColumns = (sourceColumns?: string[], targetColumns?: string[]) => { - return setIsEqual(new Set(sourceColumns ?? []), new Set(targetColumns ?? [])); + return setIsEqual(new Set(sourceColumns), new Set(targetColumns)); }; export const haveEqualOverrides = (source: T, target: T) => { diff --git a/server/src/types.ts b/server/src/types.ts index ad947e3774..a33dba490c 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -1,10 +1,9 @@ import { SystemConfig } from 'src/config'; import { VECTOR_EXTENSIONS } from 'src/constants'; -import { Asset } from 'src/database'; +import { Asset, AssetFile } from 'src/database'; import { UploadFieldName } from 'src/dtos/asset-media.dto'; import { AuthDto } from 'src/dtos/auth.dto'; import { - AssetMetadataKey, AssetOrder, AssetType, DatabaseSslMode, @@ -291,11 +290,6 @@ export interface JobCounts { paused: number; } -export interface QueueStatus { - isActive: boolean; - isPaused: boolean; -} - export type JobItem = // Audit | { name: JobName.AuditTableCleanup; data?: IBaseJob } @@ -481,8 +475,8 @@ export type StorageAsset = { fileCreatedAt: Date; originalPath: string; originalFileName: string; - sidecarPath: string | null; fileSizeInByte: number | null; + files: AssetFile[]; }; export type OnThisDayData = { year: number }; @@ -493,6 +487,7 @@ export interface MemoryData { export type VersionCheckMetadata = { checkedAt: string; releaseVersion: string }; export type SystemFlags = { mountChecks: Record }; +export type MaintenanceModeState = { isMaintenanceMode: true; secret: string } | { isMaintenanceMode: false }; export type MemoriesState = { /** memories have already been created through this date */ lastOnThisDayDate: string; @@ -503,6 +498,7 @@ export interface SystemMetadata extends Record; @@ -566,12 +562,3 @@ export interface UserMetadata extends Record = { - key: T; - value: AssetMetadata[T]; -}; - -export interface AssetMetadata extends Record> { - [AssetMetadataKey.MobileApp]: { iCloudId: string }; -} diff --git a/server/src/utils/asset.util.ts b/server/src/utils/asset.util.ts index 629b3bf819..f3f807c829 100644 --- a/server/src/utils/asset.util.ts +++ b/server/src/utils/asset.util.ts @@ -21,6 +21,7 @@ export const getAssetFiles = (files: AssetFile[]) => ({ fullsizeFile: getAssetFile(files, AssetFileType.FullSize), previewFile: getAssetFile(files, AssetFileType.Preview), thumbnailFile: getAssetFile(files, AssetFileType.Thumbnail), + sidecarFile: getAssetFile(files, AssetFileType.Sidecar), }); export const addAssets = async ( diff --git a/server/src/utils/database.ts b/server/src/utils/database.ts index 0cc3788f1a..f8dbd5e78c 100644 --- a/server/src/utils/database.ts +++ b/server/src/utils/database.ts @@ -306,6 +306,46 @@ export function withTagId(qb: SelectQueryBuilder, tagId: stri ); } +const isCJK = (c: number): boolean => + (c >= 0x4e_00 && c <= 0x9f_ff) || + (c >= 0xac_00 && c <= 0xd7_af) || + (c >= 0x30_40 && c <= 0x30_9f) || + (c >= 0x30_a0 && c <= 0x30_ff) || + (c >= 0x34_00 && c <= 0x4d_bf); + +export const tokenizeForSearch = (text: string): string[] => { + /* eslint-disable unicorn/prefer-code-point */ + const tokens: string[] = []; + let i = 0; + while (i < text.length) { + const c = text.charCodeAt(i); + if (c <= 32) { + i++; + continue; + } + + const start = i; + if (isCJK(c)) { + while (i < text.length && isCJK(text.charCodeAt(i))) { + i++; + } + if (i - start === 1) { + tokens.push(text[start]); + } else { + for (let k = start; k < i - 1; k++) { + tokens.push(text[k] + text[k + 1]); + } + } + } else { + while (i < text.length && text.charCodeAt(i) > 32 && !isCJK(text.charCodeAt(i))) { + i++; + } + tokens.push(text.slice(start, i)); + } + } + return tokens; +}; + const joinDeduplicationPlugin = new DeduplicateJoinsPlugin(); /** TODO: This should only be used for search-related queries, not as a general purpose query builder */ @@ -391,7 +431,7 @@ export function searchAssetBuilder(kysely: Kysely, options: AssetSearchBuild .$if(!!options.ocr, (qb) => qb .innerJoin('ocr_search', 'asset.id', 'ocr_search.assetId') - .where(() => sql`f_unaccent(ocr_search.text) %>> f_unaccent(${options.ocr!})`), + .where(() => sql`f_unaccent(ocr_search.text) %>> f_unaccent(${tokenizeForSearch(options.ocr!).join(' ')})`), ) .$if(!!options.type, (qb) => qb.where('asset.type', '=', options.type!)) .$if(options.isFavorite !== undefined, (qb) => qb.where('asset.isFavorite', '=', options.isFavorite!)) diff --git a/server/src/utils/maintenance.ts b/server/src/utils/maintenance.ts new file mode 100644 index 0000000000..22de2e4083 --- /dev/null +++ b/server/src/utils/maintenance.ts @@ -0,0 +1,74 @@ +import { createAdapter } from '@socket.io/redis-adapter'; +import Redis from 'ioredis'; +import { SignJWT } from 'jose'; +import { randomBytes } from 'node:crypto'; +import { Server as SocketIO } from 'socket.io'; +import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto'; +import { ConfigRepository } from 'src/repositories/config.repository'; +import { AppRestartEvent } from 'src/repositories/event.repository'; + +export function sendOneShotAppRestart(state: AppRestartEvent): void { + const server = new SocketIO(); + const { redis } = new ConfigRepository().getEnv(); + const pubClient = new Redis(redis); + const subClient = pubClient.duplicate(); + server.adapter(createAdapter(pubClient, subClient)); + + /** + * Keep trying until we manage to stop Immich + * + * Sometimes there appear to be communication + * issues between to the other servers. + * + * This issue only occurs with this method. + */ + async function tryTerminate() { + while (true) { + try { + const responses = await server.serverSideEmitWithAck('AppRestart', state); + if (responses.length > 0) { + return; + } + } catch (error) { + console.error(error); + console.error('Encountered an error while telling Immich to stop.'); + } + + console.info( + "\nIt doesn't appear that Immich stopped, trying again in a moment.\nIf Immich is already not running, you can ignore this error.", + ); + + await new Promise((r) => setTimeout(r, 1e3)); + } + } + + // => corresponds to notification.service.ts#onAppRestart + server.emit('AppRestartV1', state, () => { + void tryTerminate().finally(() => { + pubClient.disconnect(); + subClient.disconnect(); + }); + }); +} + +export async function createMaintenanceLoginUrl( + baseUrl: string, + auth: MaintenanceAuthDto, + secret: string, +): Promise { + return `${baseUrl}/maintenance?token=${await signMaintenanceJwt(secret, auth)}`; +} + +export async function signMaintenanceJwt(secret: string, data: MaintenanceAuthDto): Promise { + const alg = 'HS256'; + + return await new SignJWT({ ...data }) + .setProtectedHeader({ alg }) + .setIssuedAt() + .setExpirationTime('4h') + .sign(new TextEncoder().encode(secret)); +} + +export function generateMaintenanceSecret(): string { + return randomBytes(64).toString('hex'); +} diff --git a/server/src/utils/media.ts b/server/src/utils/media.ts index f678a32b0f..b2ffb9ac8b 100644 --- a/server/src/utils/media.ts +++ b/server/src/utils/media.ts @@ -704,8 +704,7 @@ export class QsvSwDecodeConfig extends BaseHWConfig { } getBitrateOptions() { - const options = []; - options.push(`-${this.useCQP() ? 'q:v' : 'global_quality:v'} ${this.config.crf}`); + const options = [`-${this.useCQP() ? 'q:v' : 'global_quality:v'} ${this.config.crf}`]; const bitrates = this.getBitrateDistribution(); if (bitrates.max > 0) { options.push(`-maxrate ${bitrates.max}${bitrates.unit}`, `-bufsize ${bitrates.max * 2}${bitrates.unit}`); diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index eb548eab74..08f1401d50 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -139,7 +139,7 @@ function sortKeys(target: T): T { } const result: Partial = {}; - const keys = Object.keys(target).sort() as Array; + const keys = Object.keys(target).toSorted() as Array; for (const key of keys) { result[key] = sortKeys(target[key]); } @@ -178,10 +178,7 @@ const patchOpenAPI = (document: OpenAPIObject) => { throw new Error(`Invalid number format: ${schemaName}.${key}=float (use double instead). `); } } - - if (schema.required) { - schema.required = schema.required.sort(); - } + schema.required?.sort(); } } } diff --git a/server/src/utils/response.ts b/server/src/utils/response.ts index c5f51c385c..d5356285f0 100644 --- a/server/src/utils/response.ts +++ b/server/src/utils/response.ts @@ -15,6 +15,7 @@ export const respondWithCookie = (res: Response, body: T, { isSecure, values const cookieOptions: Record = { [ImmichCookie.AuthType]: defaults, [ImmichCookie.AccessToken]: defaults, + [ImmichCookie.MaintenanceToken]: { ...defaults, maxAge: Duration.fromObject({ days: 1 }).toMillis() }, [ImmichCookie.OAuthState]: defaults, [ImmichCookie.OAuthCodeVerifier]: defaults, // no httpOnly so that the client can know the auth state diff --git a/server/src/workers/api.ts b/server/src/workers/api.ts index f56adf3b68..99c08c0fa7 100644 --- a/server/src/workers/api.ts +++ b/server/src/workers/api.ts @@ -1,69 +1,22 @@ import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; -import { json } from 'body-parser'; -import compression from 'compression'; -import cookieParser from 'cookie-parser'; -import { existsSync } from 'node:fs'; -import sirv from 'sirv'; +import { configureExpress, configureTelemetry } from 'src/app.common'; import { ApiModule } from 'src/app.module'; -import { excludePaths, serverVersion } from 'src/constants'; -import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; -import { ConfigRepository } from 'src/repositories/config.repository'; -import { LoggingRepository } from 'src/repositories/logging.repository'; -import { bootstrapTelemetry } from 'src/repositories/telemetry.repository'; +import { AppRepository } from 'src/repositories/app.repository'; import { ApiService } from 'src/services/api.service'; -import { isStartUpError, useSwagger } from 'src/utils/misc'; +import { isStartUpError } from 'src/utils/misc'; + async function bootstrap() { process.title = 'immich-api'; - const { telemetry, network } = new ConfigRepository().getEnv(); - if (telemetry.metrics.size > 0) { - bootstrapTelemetry(telemetry.apiPort); - } + configureTelemetry(); const app = await NestFactory.create(ApiModule, { bufferLogs: true }); - const logger = await app.resolve(LoggingRepository); - const configRepository = app.get(ConfigRepository); + app.get(AppRepository).setCloseFn(() => app.close()); - const { environment, host, port, resourcePaths } = configRepository.getEnv(); - - logger.setContext('Bootstrap'); - app.useLogger(logger); - app.set('trust proxy', ['loopback', ...network.trustedProxies]); - app.set('etag', 'strong'); - app.use(cookieParser()); - app.use(json({ limit: '10mb' })); - if (configRepository.isDev()) { - app.enableCors(); - } - app.useWebSocketAdapter(new WebSocketAdapter(app)); - useSwagger(app, { write: configRepository.isDev() }); - - app.setGlobalPrefix('api', { exclude: excludePaths }); - if (existsSync(resourcePaths.web.root)) { - // copied from https://github.com/sveltejs/kit/blob/679b5989fe62e3964b9a73b712d7b41831aa1f07/packages/adapter-node/src/handler.js#L46 - // provides serving of precompressed assets and caching of immutable assets - app.use( - sirv(resourcePaths.web.root, { - etag: true, - gzip: true, - brotli: true, - extensions: [], - setHeaders: (res, pathname) => { - if (pathname.startsWith(`/_app/immutable`) && res.statusCode === 200) { - res.setHeader('cache-control', 'public,max-age=31536000,immutable'); - } - }, - }), - ); - } - app.use(app.get(ApiService).ssr(excludePaths)); - app.use(compression()); - - const server = await (host ? app.listen(port, host) : app.listen(port)); - server.requestTimeout = 24 * 60 * 60 * 1000; - - logger.log(`Immich Server is listening on ${await app.getUrl()} [v${serverVersion}] [${environment}] `); + void configureExpress(app, { + ssr: ApiService, + }); } bootstrap().catch((error) => { diff --git a/server/src/workers/maintenance.ts b/server/src/workers/maintenance.ts new file mode 100644 index 0000000000..fcfe990121 --- /dev/null +++ b/server/src/workers/maintenance.ts @@ -0,0 +1,29 @@ +import { NestFactory } from '@nestjs/core'; +import { NestExpressApplication } from '@nestjs/platform-express'; +import { configureExpress, configureTelemetry } from 'src/app.common'; +import { MaintenanceModule } from 'src/app.module'; +import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; +import { AppRepository } from 'src/repositories/app.repository'; +import { isStartUpError } from 'src/utils/misc'; + +async function bootstrap() { + process.title = 'immich-maintenance'; + configureTelemetry(); + + const app = await NestFactory.create(MaintenanceModule, { bufferLogs: true }); + app.get(AppRepository).setCloseFn(() => app.close()); + void configureExpress(app, { + permitSwaggerWrite: false, + ssr: MaintenanceWorkerService, + }); + + void app.get(MaintenanceWorkerService).logSecret(); +} + +bootstrap().catch((error) => { + if (!isStartUpError(error)) { + console.error(error); + } + // eslint-disable-next-line unicorn/no-process-exit + process.exit(1); +}); diff --git a/server/src/workers/microservices.ts b/server/src/workers/microservices.ts index 40a85a276d..8f06b4b0b1 100644 --- a/server/src/workers/microservices.ts +++ b/server/src/workers/microservices.ts @@ -3,6 +3,7 @@ import { isMainThread } from 'node:worker_threads'; import { MicroservicesModule } from 'src/app.module'; import { serverVersion } from 'src/constants'; import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; +import { AppRepository } from 'src/repositories/app.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { bootstrapTelemetry } from 'src/repositories/telemetry.repository'; @@ -17,6 +18,7 @@ export async function bootstrap() { const app = await NestFactory.create(MicroservicesModule, { bufferLogs: true }); const logger = await app.resolve(LoggingRepository); const configRepository = app.get(ConfigRepository); + app.get(AppRepository).setCloseFn(() => app.close()); const { environment, host } = configRepository.getEnv(); diff --git a/server/test/fixtures/asset.stub.ts b/server/test/fixtures/asset.stub.ts index 0fd2189268..f5935d5d0e 100644 --- a/server/test/fixtures/asset.stub.ts +++ b/server/test/fixtures/asset.stub.ts @@ -24,6 +24,18 @@ const fullsizeFile: AssetFile = { path: '/uploads/user-id/fullsize/path.webp', }; +const sidecarFileWithExt: AssetFile = { + id: 'sidecar-with-ext', + type: AssetFileType.Sidecar, + path: '/original/path.ext.xmp', +}; + +const sidecarFileWithoutExt: AssetFile = { + id: 'sidecar-without-ext', + type: AssetFileType.Sidecar, + path: '/original/path.xmp', +}; + const files: AssetFile[] = [fullsizeFile, previewFile, thumbnailFile]; export const stackStub = (stackId: string, assets: (MapAsset & { exifInfo: Exif })[]) => { @@ -51,8 +63,8 @@ export const assetStub = { fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'), originalPath: '/original/path.jpg', originalFileName: 'IMG_123.jpg', - sidecarPath: null, fileSizeInByte: 12_345, + files: [], ...asset, }), noResizePath: Object.freeze({ @@ -81,7 +93,6 @@ export const assetStub = { sharedLinks: [], faces: [], exifInfo: {} as Exif, - sidecarPath: null, deletedAt: null, isExternal: false, duplicateId: null, @@ -117,7 +128,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'IMG_456.jpg', faces: [], - sidecarPath: null, isExternal: false, exifInfo: { fileSizeInByte: 123_000, @@ -157,7 +167,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.ext', faces: [], - sidecarPath: null, deletedAt: null, duplicateId: null, isOffline: false, @@ -194,7 +203,6 @@ export const assetStub = { originalFileName: 'asset-id.jpg', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, exifImageHeight: 1000, @@ -243,7 +251,6 @@ export const assetStub = { originalFileName: 'asset-id.jpg', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, exifImageHeight: 3840, @@ -285,7 +292,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.jpg', faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, exifImageHeight: 3840, @@ -328,7 +334,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.jpg', faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, exifImageHeight: 3840, @@ -367,7 +372,6 @@ export const assetStub = { originalFileName: 'asset-id.jpg', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, exifImageHeight: 3840, @@ -409,7 +413,6 @@ export const assetStub = { originalFileName: 'asset-id.jpg', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, } as Exif, @@ -448,7 +451,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.ext', faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, } as Exif, @@ -490,7 +492,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.ext', faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, } as Exif, @@ -526,7 +527,6 @@ export const assetStub = { livePhotoVideoId: null, sharedLinks: [], faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 100_000, exifImageHeight: 2160, @@ -553,6 +553,7 @@ export const assetStub = { fileSizeInByte: 100_000, timeZone: `America/New_York`, }, + files: [] as AssetFile[], libraryId: null, visibility: AssetVisibility.Hidden, } as MapAsset & { faces: AssetFace[]; files: AssetFile[]; exifInfo: Exif }), @@ -573,7 +574,7 @@ export const assetStub = { files, faces: [] as AssetFace[], visibility: AssetVisibility.Timeline, - } as MapAsset & { faces: AssetFace[] }), + } as MapAsset & { faces: AssetFace[]; files: AssetFile[] }), livePhotoWithOriginalFileName: Object.freeze({ id: 'live-photo-still-asset', @@ -589,10 +590,11 @@ export const assetStub = { fileSizeInByte: 25_000, timeZone: `America/New_York`, }, + files: [] as AssetFile[], libraryId: null, faces: [] as AssetFace[], visibility: AssetVisibility.Timeline, - } as MapAsset & { faces: AssetFace[] }), + } as MapAsset & { faces: AssetFace[]; files: AssetFile[] }), withLocation: Object.freeze({ id: 'asset-with-favorite-id', @@ -605,7 +607,6 @@ export const assetStub = { deviceId: 'device-id', checksum: Buffer.from('file hash', 'utf8'), originalPath: '/original/path.ext', - sidecarPath: null, type: AssetType.Image, files: [previewFile], thumbhash: null, @@ -652,7 +653,7 @@ export const assetStub = { thumbhash: null, checksum: Buffer.from('file hash', 'utf8'), type: AssetType.Image, - files: [previewFile], + files: [previewFile, sidecarFileWithExt], encodedVideoPath: null, createdAt: new Date('2023-02-23T05:06:29.716Z'), updatedAt: new Date('2023-02-23T05:06:29.716Z'), @@ -665,7 +666,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.ext', faces: [], - sidecarPath: '/original/path.ext.xmp', deletedAt: null, duplicateId: null, isOffline: false, @@ -688,7 +688,7 @@ export const assetStub = { thumbhash: null, checksum: Buffer.from('file hash', 'utf8'), type: AssetType.Image, - files: [previewFile], + files: [previewFile, sidecarFileWithoutExt], encodedVideoPath: null, createdAt: new Date('2023-02-23T05:06:29.716Z'), updatedAt: new Date('2023-02-23T05:06:29.716Z'), @@ -701,7 +701,6 @@ export const assetStub = { sharedLinks: [], originalFileName: 'asset-id.ext', faces: [], - sidecarPath: '/original/path.xmp', deletedAt: null, duplicateId: null, isOffline: false, @@ -734,7 +733,6 @@ export const assetStub = { livePhotoVideoId: null, sharedLinks: [], faces: [], - sidecarPath: null, exifInfo: { fileSizeInByte: 100_000, } as Exif, @@ -776,7 +774,6 @@ export const assetStub = { originalFileName: 'photo.jpg', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, } as Exif, @@ -812,7 +809,6 @@ export const assetStub = { originalFileName: 'asset-id.dng', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, profileDescription: 'Adobe RGB', @@ -853,7 +849,6 @@ export const assetStub = { originalFileName: 'asset-id.hif', faces: [], deletedAt: null, - sidecarPath: null, exifInfo: { fileSizeInByte: 5000, profileDescription: 'Adobe RGB', diff --git a/server/test/medium/specs/services/asset.service.spec.ts b/server/test/medium/specs/services/asset.service.spec.ts index b3fc481708..13bc1ca9a9 100644 --- a/server/test/medium/specs/services/asset.service.spec.ts +++ b/server/test/medium/specs/services/asset.service.spec.ts @@ -1,14 +1,17 @@ import { Kysely } from 'kysely'; -import { JobName, SharedLinkType } from 'src/enum'; +import { AssetFileType, JobName, SharedLinkType } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; +import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; +import { EventRepository } from 'src/repositories/event.repository'; import { JobRepository } from 'src/repositories/job.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { SharedLinkAssetRepository } from 'src/repositories/shared-link-asset.repository'; import { SharedLinkRepository } from 'src/repositories/shared-link.repository'; import { StackRepository } from 'src/repositories/stack.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; +import { UserRepository } from 'src/repositories/user.repository'; import { DB } from 'src/schema'; import { AssetService } from 'src/services/asset.service'; import { newMediumService } from 'test/medium.factory'; @@ -20,8 +23,16 @@ let defaultDatabase: Kysely; const setup = (db?: Kysely) => { return newMediumService(AssetService, { database: db || defaultDatabase, - real: [AssetRepository, AlbumRepository, AccessRepository, SharedLinkAssetRepository, StackRepository], - mock: [LoggingRepository, JobRepository, StorageRepository], + real: [ + AssetRepository, + AssetJobRepository, + AlbumRepository, + AccessRepository, + SharedLinkAssetRepository, + StackRepository, + UserRepository, + ], + mock: [EventRepository, LoggingRepository, JobRepository, StorageRepository], }); }; @@ -184,7 +195,15 @@ describe(AssetService.name, () => { jobRepo.queue.mockResolvedValue(); const { user } = await ctx.newUser(); - const { asset: oldAsset } = await ctx.newAsset({ ownerId: user.id, sidecarPath: '/path/to/my/sidecar.xmp' }); + + const { asset: oldAsset } = await ctx.newAsset({ ownerId: user.id }); + + await ctx.newAssetFile({ + assetId: oldAsset.id, + path: '/path/to/my/sidecar.xmp', + type: AssetFileType.Sidecar, + }); + const { asset: newAsset } = await ctx.newAsset({ ownerId: user.id }); await ctx.newExif({ assetId: oldAsset.id, description: 'foo' }); @@ -202,4 +221,51 @@ describe(AssetService.name, () => { }); }); }); + + describe('delete', () => { + it('should delete asset', async () => { + const { sut, ctx } = setup(); + ctx.getMock(EventRepository).emit.mockResolvedValue(); + ctx.getMock(JobRepository).queue.mockResolvedValue(); + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id }); + const thumbnailPath = '/path/to/thumbnail.jpg'; + const previewPath = '/path/to/preview.jpg'; + const sidecarPath = '/path/to/sidecar.xmp'; + await Promise.all([ + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: thumbnailPath }), + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: previewPath }), + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Sidecar, path: sidecarPath }), + ]); + + await sut.handleAssetDeletion({ id: asset.id, deleteOnDisk: true }); + + expect(ctx.getMock(JobRepository).queue).toHaveBeenCalledWith({ + name: JobName.FileDelete, + data: { files: [thumbnailPath, previewPath, sidecarPath, asset.originalPath] }, + }); + }); + + it('should not delete offline assets', async () => { + const { sut, ctx } = setup(); + ctx.getMock(EventRepository).emit.mockResolvedValue(); + ctx.getMock(JobRepository).queue.mockResolvedValue(); + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id, isOffline: true }); + const thumbnailPath = '/path/to/thumbnail.jpg'; + const previewPath = '/path/to/preview.jpg'; + await Promise.all([ + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: thumbnailPath }), + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: previewPath }), + ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Sidecar, path: `/path/to/sidecar.xmp` }), + ]); + + await sut.handleAssetDeletion({ id: asset.id, deleteOnDisk: true }); + + expect(ctx.getMock(JobRepository).queue).toHaveBeenCalledWith({ + name: JobName.FileDelete, + data: { files: [thumbnailPath, previewPath] }, + }); + }); + }); }); diff --git a/server/test/medium/specs/services/metadata.service.spec.ts b/server/test/medium/specs/services/metadata.service.spec.ts index 5d44079be5..1d144e9c9c 100644 --- a/server/test/medium/specs/services/metadata.service.spec.ts +++ b/server/test/medium/specs/services/metadata.service.spec.ts @@ -82,7 +82,11 @@ describe(MetadataService.name, () => { process.env.TZ = serverTimeZone ?? undefined; const { filePath } = await createTestFile(exifData); - mocks.assetJob.getForMetadataExtraction.mockResolvedValue({ id: 'asset-1', originalPath: filePath } as any); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue({ + id: 'asset-1', + originalPath: filePath, + files: [], + } as any); await sut.handleMetadataExtraction({ id: 'asset-1' }); diff --git a/server/test/medium/specs/services/workflow.service.spec.ts b/server/test/medium/specs/services/workflow.service.spec.ts index af12019ef6..1fddc2a7cf 100644 --- a/server/test/medium/specs/services/workflow.service.spec.ts +++ b/server/test/medium/specs/services/workflow.service.spec.ts @@ -7,6 +7,7 @@ import { WorkflowRepository } from 'src/repositories/workflow.repository'; import { DB } from 'src/schema'; import { WorkflowService } from 'src/services/workflow.service'; import { newMediumService } from 'test/medium.factory'; +import { factory } from 'test/small.factory'; import { getKyselyDB } from 'test/utils'; let defaultDatabase: Kysely; @@ -77,7 +78,7 @@ describe(WorkflowService.name, () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -103,7 +104,7 @@ describe(WorkflowService.name, () => { it('should create a workflow with filters and actions', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -112,13 +113,13 @@ describe(WorkflowService.name, () => { enabled: true, filters: [ { - filterId: testFilterId, + pluginFilterId: testFilterId, filterConfig: { key: 'value' }, }, ], actions: [ { - actionId: testActionId, + pluginActionId: testActionId, actionConfig: { action: 'test' }, }, ], @@ -136,7 +137,7 @@ describe(WorkflowService.name, () => { expect(workflow.filters[0]).toMatchObject({ id: expect.any(String), workflowId: workflow.id, - filterId: testFilterId, + pluginFilterId: testFilterId, filterConfig: { key: 'value' }, order: 0, }); @@ -145,7 +146,7 @@ describe(WorkflowService.name, () => { expect(workflow.actions[0]).toMatchObject({ id: expect.any(String), workflowId: workflow.id, - actionId: testActionId, + pluginActionId: testActionId, actionConfig: { action: 'test' }, order: 0, }); @@ -154,7 +155,7 @@ describe(WorkflowService.name, () => { it('should throw error when creating workflow with invalid filter', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); await expect( sut.create(auth, { @@ -162,12 +163,7 @@ describe(WorkflowService.name, () => { name: 'invalid-workflow', description: 'A workflow with invalid filter', enabled: true, - filters: [ - { - filterId: '66da82df-e424-4bf4-b6f3-5d8e71620dae', - filterConfig: { key: 'value' }, - }, - ], + filters: [{ pluginFilterId: factory.uuid(), filterConfig: { key: 'value' } }], actions: [], }), ).rejects.toThrow('Invalid filter ID'); @@ -176,7 +172,7 @@ describe(WorkflowService.name, () => { it('should throw error when creating workflow with invalid action', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); await expect( sut.create(auth, { @@ -185,12 +181,7 @@ describe(WorkflowService.name, () => { description: 'A workflow with invalid action', enabled: true, filters: [], - actions: [ - { - actionId: '66da82df-e424-4bf4-b6f3-5d8e71620dae', - actionConfig: { action: 'test' }, - }, - ], + actions: [{ pluginActionId: factory.uuid(), actionConfig: { action: 'test' } }], }), ).rejects.toThrow('Invalid action ID'); }); @@ -198,7 +189,7 @@ describe(WorkflowService.name, () => { it('should throw error when filter does not support trigger context', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); // Create a plugin with a filter that only supports Album context const pluginRepo = new PluginRepository(defaultDatabase); @@ -229,7 +220,7 @@ describe(WorkflowService.name, () => { name: 'invalid-context-workflow', description: 'A workflow with context mismatch', enabled: true, - filters: [{ filterId: result.filters[0].id }], + filters: [{ pluginFilterId: result.filters[0].id }], actions: [], }), ).rejects.toThrow('does not support asset context'); @@ -238,7 +229,7 @@ describe(WorkflowService.name, () => { it('should throw error when action does not support trigger context', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); // Create a plugin with an action that only supports Person context const pluginRepo = new PluginRepository(defaultDatabase); @@ -270,7 +261,7 @@ describe(WorkflowService.name, () => { description: 'A workflow with context mismatch', enabled: true, filters: [], - actions: [{ actionId: result.actions[0].id }], + actions: [{ pluginActionId: result.actions[0].id }], }), ).rejects.toThrow('does not support asset context'); }); @@ -278,7 +269,7 @@ describe(WorkflowService.name, () => { it('should create workflow with multiple filters and actions in correct order', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -286,13 +277,13 @@ describe(WorkflowService.name, () => { description: 'A workflow with multiple filters and actions', enabled: true, filters: [ - { filterId: testFilterId, filterConfig: { step: 1 } }, - { filterId: testFilterId, filterConfig: { step: 2 } }, + { pluginFilterId: testFilterId, filterConfig: { step: 1 } }, + { pluginFilterId: testFilterId, filterConfig: { step: 2 } }, ], actions: [ - { actionId: testActionId, actionConfig: { step: 1 } }, - { actionId: testActionId, actionConfig: { step: 2 } }, - { actionId: testActionId, actionConfig: { step: 3 } }, + { pluginActionId: testActionId, actionConfig: { step: 1 } }, + { pluginActionId: testActionId, actionConfig: { step: 2 } }, + { pluginActionId: testActionId, actionConfig: { step: 3 } }, ], }); @@ -313,7 +304,7 @@ describe(WorkflowService.name, () => { it('should return all workflows for a user', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow1 = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -347,7 +338,7 @@ describe(WorkflowService.name, () => { it('should return empty array when user has no workflows', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflows = await sut.getAll(auth); @@ -358,8 +349,8 @@ describe(WorkflowService.name, () => { const { sut, ctx } = setup(); const { user: user1 } = await ctx.newUser(); const { user: user2 } = await ctx.newUser(); - const auth1 = { user: { id: user1.id } } as any; - const auth2 = { user: { id: user2.id } } as any; + const auth1 = factory.auth({ user: user1 }); + const auth2 = factory.auth({ user: user2 }); await sut.create(auth1, { triggerType: PluginTriggerType.AssetCreate, @@ -380,15 +371,15 @@ describe(WorkflowService.name, () => { it('should return a specific workflow by id', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, name: 'test-workflow', description: 'A test workflow', enabled: true, - filters: [{ filterId: testFilterId, filterConfig: { key: 'value' } }], - actions: [{ actionId: testActionId, actionConfig: { action: 'test' } }], + filters: [{ pluginFilterId: testFilterId, filterConfig: { key: 'value' } }], + actions: [{ pluginActionId: testActionId, actionConfig: { action: 'test' } }], }); const workflow = await sut.get(auth, created.id); @@ -406,7 +397,7 @@ describe(WorkflowService.name, () => { it('should throw error when workflow does not exist', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); await expect(sut.get(auth, '66da82df-e424-4bf4-b6f3-5d8e71620dae')).rejects.toThrow(); }); @@ -415,8 +406,8 @@ describe(WorkflowService.name, () => { const { sut, ctx } = setup(); const { user: user1 } = await ctx.newUser(); const { user: user2 } = await ctx.newUser(); - const auth1 = { user: { id: user1.id } } as any; - const auth2 = { user: { id: user2.id } } as any; + const auth1 = factory.auth({ user: user1 }); + const auth2 = factory.auth({ user: user2 }); const workflow = await sut.create(auth1, { triggerType: PluginTriggerType.AssetCreate, @@ -435,7 +426,7 @@ describe(WorkflowService.name, () => { it('should update workflow basic fields', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -463,21 +454,21 @@ describe(WorkflowService.name, () => { it('should update workflow filters', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, name: 'test-workflow', description: 'Test', enabled: true, - filters: [{ filterId: testFilterId, filterConfig: { old: 'config' } }], + filters: [{ pluginFilterId: testFilterId, filterConfig: { old: 'config' } }], actions: [], }); const updated = await sut.update(auth, created.id, { filters: [ - { filterId: testFilterId, filterConfig: { new: 'config' } }, - { filterId: testFilterId, filterConfig: { second: 'filter' } }, + { pluginFilterId: testFilterId, filterConfig: { new: 'config' } }, + { pluginFilterId: testFilterId, filterConfig: { second: 'filter' } }, ], }); @@ -489,7 +480,7 @@ describe(WorkflowService.name, () => { it('should update workflow actions', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -497,13 +488,13 @@ describe(WorkflowService.name, () => { description: 'Test', enabled: true, filters: [], - actions: [{ actionId: testActionId, actionConfig: { old: 'config' } }], + actions: [{ pluginActionId: testActionId, actionConfig: { old: 'config' } }], }); const updated = await sut.update(auth, created.id, { actions: [ - { actionId: testActionId, actionConfig: { new: 'config' } }, - { actionId: testActionId, actionConfig: { second: 'action' } }, + { pluginActionId: testActionId, actionConfig: { new: 'config' } }, + { pluginActionId: testActionId, actionConfig: { second: 'action' } }, ], }); @@ -515,14 +506,14 @@ describe(WorkflowService.name, () => { it('should clear filters when updated with empty array', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, name: 'test-workflow', description: 'Test', enabled: true, - filters: [{ filterId: testFilterId, filterConfig: { key: 'value' } }], + filters: [{ pluginFilterId: testFilterId, filterConfig: { key: 'value' } }], actions: [], }); @@ -536,7 +527,7 @@ describe(WorkflowService.name, () => { it('should throw error when no fields to update', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -553,21 +544,17 @@ describe(WorkflowService.name, () => { it('should throw error when updating non-existent workflow', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); - await expect( - sut.update(auth, 'non-existent-id', { - name: 'updated-name', - }), - ).rejects.toThrow(); + await expect(sut.update(auth, factory.uuid(), { name: 'updated-name' })).rejects.toThrow(); }); it('should throw error when user does not have access to update workflow', async () => { const { sut, ctx } = setup(); const { user: user1 } = await ctx.newUser(); const { user: user2 } = await ctx.newUser(); - const auth1 = { user: { id: user1.id } } as any; - const auth2 = { user: { id: user2.id } } as any; + const auth1 = factory.auth({ user: user1 }); + const auth2 = factory.auth({ user: user2 }); const workflow = await sut.create(auth1, { triggerType: PluginTriggerType.AssetCreate, @@ -588,7 +575,7 @@ describe(WorkflowService.name, () => { it('should throw error when updating with invalid filter', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -601,7 +588,7 @@ describe(WorkflowService.name, () => { await expect( sut.update(auth, created.id, { - filters: [{ filterId: 'invalid-filter-id', filterConfig: {} }], + filters: [{ pluginFilterId: factory.uuid(), filterConfig: {} }], }), ).rejects.toThrow(); }); @@ -609,7 +596,7 @@ describe(WorkflowService.name, () => { it('should throw error when updating with invalid action', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const created = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -621,9 +608,7 @@ describe(WorkflowService.name, () => { }); await expect( - sut.update(auth, created.id, { - actions: [{ actionId: 'invalid-action-id', actionConfig: {} }], - }), + sut.update(auth, created.id, { actions: [{ pluginActionId: factory.uuid(), actionConfig: {} }] }), ).rejects.toThrow(); }); }); @@ -632,7 +617,7 @@ describe(WorkflowService.name, () => { it('should delete a workflow', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, @@ -651,15 +636,15 @@ describe(WorkflowService.name, () => { it('should delete workflow with filters and actions', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); const workflow = await sut.create(auth, { triggerType: PluginTriggerType.AssetCreate, name: 'test-workflow', description: 'Test', enabled: true, - filters: [{ filterId: testFilterId, filterConfig: {} }], - actions: [{ actionId: testActionId, actionConfig: {} }], + filters: [{ pluginFilterId: testFilterId, filterConfig: {} }], + actions: [{ pluginActionId: testActionId, actionConfig: {} }], }); await sut.delete(auth, workflow.id); @@ -670,17 +655,17 @@ describe(WorkflowService.name, () => { it('should throw error when deleting non-existent workflow', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); - const auth = { user: { id: user.id } } as any; + const auth = factory.auth({ user }); - await expect(sut.delete(auth, 'non-existent-id')).rejects.toThrow(); + await expect(sut.delete(auth, factory.uuid())).rejects.toThrow(); }); it('should throw error when user does not have access to delete workflow', async () => { const { sut, ctx } = setup(); const { user: user1 } = await ctx.newUser(); const { user: user2 } = await ctx.newUser(); - const auth1 = { user: { id: user1.id } } as any; - const auth2 = { user: { id: user2.id } } as any; + const auth1 = factory.auth({ user: user1 }); + const auth2 = factory.auth({ user: user2 }); const workflow = await sut.create(auth1, { triggerType: PluginTriggerType.AssetCreate, diff --git a/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts b/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts index d44c088f17..d533afadf1 100644 --- a/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts +++ b/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts @@ -176,7 +176,7 @@ describe(SyncRequestType.PartnerAssetExifsV1, () => { const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetExifsV1]); expect(newResponse).toEqual([ { - ack: expect.stringMatching(new RegExp(`${SyncEntityType.PartnerAssetExifBackfillV1}\\|.+?\\|.+`)), + ack: expect.stringMatching(new RegExp(String.raw`${SyncEntityType.PartnerAssetExifBackfillV1}\|.+?\|.+`)), data: expect.objectContaining({ assetId: assetUser3.id, }), @@ -226,7 +226,7 @@ describe(SyncRequestType.PartnerAssetExifsV1, () => { const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetExifsV1]); expect(newResponse).toEqual([ { - ack: expect.stringMatching(new RegExp(`${SyncEntityType.PartnerAssetExifBackfillV1}\\|.+?\\|.+`)), + ack: expect.stringMatching(new RegExp(String.raw`${SyncEntityType.PartnerAssetExifBackfillV1}\|.+?\|.+`)), data: expect.objectContaining({ assetId: assetUser3.id, }), diff --git a/server/test/repositories/asset.repository.mock.ts b/server/test/repositories/asset.repository.mock.ts index e735b37564..5ba77ddc2f 100644 --- a/server/test/repositories/asset.repository.mock.ts +++ b/server/test/repositories/asset.repository.mock.ts @@ -10,6 +10,7 @@ export const newAssetRepositoryMock = (): Mocked Promise.resolve()), queueAll: vitest.fn().mockImplementation(() => Promise.resolve()), - getQueueStatus: vitest.fn(), + isActive: vitest.fn(), + isPaused: vitest.fn(), getJobCounts: vitest.fn(), clear: vitest.fn(), waitForQueueCompletion: vitest.fn(), diff --git a/server/test/repositories/media.repository.mock.ts b/server/test/repositories/media.repository.mock.ts index c6ab11aaa1..b6b1e82b52 100644 --- a/server/test/repositories/media.repository.mock.ts +++ b/server/test/repositories/media.repository.mock.ts @@ -6,6 +6,7 @@ export const newMediaRepositoryMock = (): Mocked Promise.resolve()), writeExif: vitest.fn().mockImplementation(() => Promise.resolve()), + copyTagGroup: vitest.fn().mockImplementation(() => Promise.resolve()), generateThumbhash: vitest.fn().mockResolvedValue(Buffer.from('')), decodeImage: vitest.fn().mockResolvedValue({ data: Buffer.from(''), info: {} }), extract: vitest.fn().mockResolvedValue(null), diff --git a/server/test/repositories/storage.repository.mock.ts b/server/test/repositories/storage.repository.mock.ts index 31451da82f..b45e93d8b9 100644 --- a/server/test/repositories/storage.repository.mock.ts +++ b/server/test/repositories/storage.repository.mock.ts @@ -38,6 +38,7 @@ export const makeMockWatcher = return () => close(); } + // eslint-disable-next-line unicorn/consistent-function-scoping return () => Promise.resolve(); }; diff --git a/server/test/small.factory.ts b/server/test/small.factory.ts index ea0df585ea..13cccce176 100644 --- a/server/test/small.factory.ts +++ b/server/test/small.factory.ts @@ -8,13 +8,22 @@ import { Memory, Partner, Session, - SidecarWriteAsset, User, UserAdmin, } from 'src/database'; import { MapAsset } from 'src/dtos/asset-response.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { AssetStatus, AssetType, AssetVisibility, MemoryType, Permission, UserMetadataKey, UserStatus } from 'src/enum'; +import { QueueStatisticsDto } from 'src/dtos/queue.dto'; +import { + AssetFileType, + AssetStatus, + AssetType, + AssetVisibility, + MemoryType, + Permission, + UserMetadataKey, + UserStatus, +} from 'src/enum'; import { OnThisDayData, UserMetadataItem } from 'src/types'; import { v4, v7 } from 'uuid'; @@ -139,6 +148,16 @@ const sessionFactory = (session: Partial = {}) => ({ ...session, }); +const queueStatisticsFactory = (dto?: Partial) => ({ + active: 0, + completed: 0, + failed: 0, + delayed: 0, + waiting: 0, + paused: 0, + ...dto, +}); + const stackFactory = () => ({ id: newUuid(), ownerId: newUuid(), @@ -226,7 +245,6 @@ const assetFactory = (asset: Partial = {}) => ({ originalFileName: 'IMG_123.jpg', originalPath: `/data/12/34/IMG_123.jpg`, ownerId: newUuid(), - sidecarPath: null, stackId: null, thumbhash: null, type: AssetType.Image, @@ -301,12 +319,17 @@ const versionHistoryFactory = () => ({ version: '1.123.45', }); -const assetSidecarWriteFactory = (asset: Partial = {}) => ({ +const assetSidecarWriteFactory = () => ({ id: newUuid(), - sidecarPath: '/path/to/original-path.jpg.xmp', originalPath: '/path/to/original-path.jpg.xmp', tags: [], - ...asset, + files: [ + { + id: newUuid(), + path: '/path/to/original-path.jpg.xmp', + type: AssetFileType.Sidecar, + }, + ], }); const assetOcrFactory = ( @@ -353,6 +376,7 @@ export const factory = { library: libraryFactory, memory: memoryFactory, partner: partnerFactory, + queueStatistics: queueStatisticsFactory, session: sessionFactory, stack: stackFactory, user: userFactory, diff --git a/server/test/utils.ts b/server/test/utils.ts index d584cf5398..77853f897a 100644 --- a/server/test/utils.ts +++ b/server/test/utils.ts @@ -19,6 +19,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository'; import { AlbumUserRepository } from 'src/repositories/album-user.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AppRepository } from 'src/repositories/app.repository'; import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { AuditRepository } from 'src/repositories/audit.repository'; @@ -212,6 +213,7 @@ export type ServiceOverrides = { album: AlbumRepository; albumUser: AlbumUserRepository; apiKey: ApiKeyRepository; + app: AppRepository; audit: AuditRepository; asset: AssetRepository; assetJob: AssetJobRepository; @@ -271,10 +273,7 @@ type Constructor> = { new (...deps: Args): Type; }; -export const newTestService = ( - Service: Constructor, - overrides: Partial = {}, -) => { +export const getMocks = () => { const loggerMock = { setContext: () => {} }; const configMock = { getEnv: () => ({}) }; @@ -291,6 +290,7 @@ export const newTestService = ( albumUser: automock(AlbumUserRepository), asset: newAssetRepositoryMock(), assetJob: automock(AssetJobRepository), + app: automock(AppRepository, { strict: false }), config: newConfigRepositoryMock(), database: newDatabaseRepositoryMock(), downloadRepository: automock(DownloadRepository, { strict: false }), @@ -338,6 +338,15 @@ export const newTestService = ( workflow: automock(WorkflowRepository, { strict: true }), }; + return mocks; +}; + +export const newTestService = ( + Service: Constructor, + overrides: Partial = {}, +) => { + const mocks = getMocks(); + const sut = new Service( overrides.logger || (mocks.logger as As), overrides.access || (mocks.access as IAccessRepository as AccessRepository), @@ -345,6 +354,7 @@ export const newTestService = ( overrides.album || (mocks.album as As), overrides.albumUser || (mocks.albumUser as As), overrides.apiKey || (mocks.apiKey as As), + overrides.app || (mocks.app as As), overrides.asset || (mocks.asset as As), overrides.assetJob || (mocks.assetJob as As), overrides.audit || (mocks.audit as As), diff --git a/web/.nvmrc b/web/.nvmrc index 0a492611a0..9e2934aa34 100644 --- a/web/.nvmrc +++ b/web/.nvmrc @@ -1 +1 @@ -24.11.0 +24.11.1 diff --git a/web/package.json b/web/package.json index 2a93230c24..2e7b740153 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "immich-web", - "version": "2.2.3", + "version": "2.3.1", "license": "GNU Affero General Public License version 3", "type": "module", "scripts": { @@ -11,13 +11,13 @@ "preview": "vite preview", "check:svelte": "svelte-check --no-tsconfig --fail-on-warnings", "check:typescript": "tsc --noEmit", - "check:watch": "npm run check:svelte -- --watch", - "check:code": "npm run format && npm run lint:p && npm run check:svelte && npm run check:typescript", - "check:all": "npm run check:code && npm run test:cov", + "check:watch": "pnpm run check:svelte --watch", + "check:code": "pnpm run format && pnpm run lint && pnpm run check:svelte && pnpm run check:typescript", + "check:all": "pnpm run check:code && pnpm run test:cov", "lint": "eslint . --max-warnings 0 --concurrency 4", - "lint:fix": "npm run lint -- --fix", + "lint:fix": "pnpm run lint --fix", "format": "prettier --check .", - "format:fix": "prettier --write . && npm run format:i18n", + "format:fix": "prettier --write . && pnpm run format:i18n", "format:i18n": "pnpm dlx sort-json ../i18n/*.json", "test": "vitest --run", "test:cov": "vitest --coverage", @@ -28,14 +28,15 @@ "@formatjs/icu-messageformat-parser": "^2.9.8", "@immich/justified-layout-wasm": "^0.4.3", "@immich/sdk": "file:../open-api/typescript-sdk", - "@immich/ui": "^0.43.0", + "@immich/ui": "^0.49.2", "@mapbox/mapbox-gl-rtl-text": "0.2.3", "@mdi/js": "^7.4.47", - "@photo-sphere-viewer/core": "^5.11.5", - "@photo-sphere-viewer/equirectangular-video-adapter": "^5.11.5", - "@photo-sphere-viewer/resolution-plugin": "^5.11.5", - "@photo-sphere-viewer/settings-plugin": "^5.11.5", - "@photo-sphere-viewer/video-plugin": "^5.11.5", + "@photo-sphere-viewer/core": "^5.14.0", + "@photo-sphere-viewer/equirectangular-video-adapter": "^5.14.0", + "@photo-sphere-viewer/markers-plugin": "^5.14.0", + "@photo-sphere-viewer/resolution-plugin": "^5.14.0", + "@photo-sphere-viewer/settings-plugin": "^5.14.0", + "@photo-sphere-viewer/video-plugin": "^5.14.0", "@types/geojson": "^7946.0.16", "@zoom-image/core": "^0.41.0", "@zoom-image/svelte": "^0.3.0", @@ -60,7 +61,8 @@ "svelte-maplibre": "^1.2.5", "svelte-persisted-store": "^0.12.0", "tabbable": "^6.2.0", - "thumbhash": "^0.1.1" + "thumbhash": "^0.1.1", + "uplot": "^1.6.32" }, "devDependencies": { "@eslint/js": "^9.36.0", @@ -68,7 +70,7 @@ "@koddsson/eslint-plugin-tscompat": "^0.2.0", "@socket.io/component-emitter": "^3.1.0", "@sveltejs/adapter-static": "^3.0.8", - "@sveltejs/enhanced-img": "^0.8.0", + "@sveltejs/enhanced-img": "^0.9.0", "@sveltejs/kit": "^2.27.1", "@sveltejs/vite-plugin-svelte": "6.2.1", "@tailwindcss/vite": "^4.1.7", @@ -87,7 +89,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-compat": "^6.0.2", "eslint-plugin-svelte": "^3.12.4", - "eslint-plugin-unicorn": "^61.0.2", + "eslint-plugin-unicorn": "^62.0.0", "factory.ts": "^1.4.1", "globals": "^16.0.0", "happy-dom": "^20.0.0", @@ -96,7 +98,7 @@ "prettier-plugin-sort-json": "^4.1.1", "prettier-plugin-svelte": "^3.3.3", "rollup-plugin-visualizer": "^6.0.0", - "svelte": "5.43.0", + "svelte": "5.45.2", "svelte-check": "^4.1.5", "svelte-eslint-parser": "^1.3.3", "tailwindcss": "^4.1.7", @@ -106,6 +108,6 @@ "vitest": "^3.0.0" }, "volta": { - "node": "24.11.0" + "node": "24.11.1" } } diff --git a/web/src/app.css b/web/src/app.css index f66743f736..bf7601f63b 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -76,14 +76,6 @@ --immich-dark-gray: 33 33 33; } - *, - ::after, - ::before, - ::backdrop, - ::file-selector-button { - border-color: rgb(var(--immich-ui-default-border)); - } - button:not(:disabled), [role='button']:not(:disabled) { cursor: pointer; diff --git a/web/src/lib/actions/shortcut.ts b/web/src/lib/actions/shortcut.ts index f7b3009403..8f01ce8924 100644 --- a/web/src/lib/actions/shortcut.ts +++ b/web/src/lib/actions/shortcut.ts @@ -39,13 +39,17 @@ export const shortcutLabel = (shortcut: Shortcut) => { /** Determines whether an event should be ignored. The event will be ignored if: * - The element dispatching the event is not the same as the element which the event listener is attached to * - The element dispatching the event is an input field + * - The element dispatching the event is a map canvas */ export const shouldIgnoreEvent = (event: KeyboardEvent | ClipboardEvent): boolean => { if (event.target === event.currentTarget) { return false; } const type = (event.target as HTMLInputElement).type; - return ['textarea', 'text', 'date', 'datetime-local', 'email', 'password'].includes(type); + return ( + ['textarea', 'text', 'date', 'datetime-local', 'email', 'password'].includes(type) || + (event.target instanceof HTMLCanvasElement && event.target.classList.contains('maplibregl-canvas')) + ); }; export const matchesShortcut = (event: KeyboardEvent, shortcut: Shortcut) => { diff --git a/web/src/lib/actions/zoom-image.ts b/web/src/lib/actions/zoom-image.ts index 29074fc7b0..e67d3e1928 100644 --- a/web/src/lib/actions/zoom-image.ts +++ b/web/src/lib/actions/zoom-image.ts @@ -2,7 +2,7 @@ import { photoZoomState } from '$lib/stores/zoom-image.store'; import { useZoomImageWheel } from '@zoom-image/svelte'; import { get } from 'svelte/store'; -export const zoomImageAction = (node: HTMLElement) => { +export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolean }) => { const { createZoomImage, zoomImageState, setZoomImageState } = useZoomImageWheel(); createZoomImage(node, { @@ -14,9 +14,32 @@ export const zoomImageAction = (node: HTMLElement) => { setZoomImageState(state); } + // Store original event handlers so we can prevent them when disabled + const wheelHandler = (event: WheelEvent) => { + if (options?.disabled) { + event.stopImmediatePropagation(); + } + }; + + const pointerDownHandler = (event: PointerEvent) => { + if (options?.disabled) { + event.stopImmediatePropagation(); + } + }; + + // Add handlers at capture phase with higher priority + node.addEventListener('wheel', wheelHandler, { capture: true }); + node.addEventListener('pointerdown', pointerDownHandler, { capture: true }); + const unsubscribes = [photoZoomState.subscribe(setZoomImageState), zoomImageState.subscribe(photoZoomState.set)]; + return { + update(newOptions?: { disabled?: boolean }) { + options = newOptions; + }, destroy() { + node.removeEventListener('wheel', wheelHandler, { capture: true }); + node.removeEventListener('pointerdown', pointerDownHandler, { capture: true }); for (const unsubscribe of unsubscribes) { unsubscribe(); } diff --git a/web/src/lib/assets/empty-folders.svg b/web/src/lib/assets/empty-folders.svg new file mode 100644 index 0000000000..b4a58cf245 --- /dev/null +++ b/web/src/lib/assets/empty-folders.svg @@ -0,0 +1 @@ + diff --git a/web/src/lib/components/ActionButton.svelte b/web/src/lib/components/ActionButton.svelte index 37bc09fb73..e0e7e1eff7 100644 --- a/web/src/lib/components/ActionButton.svelte +++ b/web/src/lib/components/ActionButton.svelte @@ -1,16 +1,14 @@ {#if action.$if?.() ?? true} - + onAction(action)} /> {/if} diff --git a/web/src/lib/components/HeaderButton.svelte b/web/src/lib/components/HeaderButton.svelte index 9021d2d1cb..c4189c06c0 100644 --- a/web/src/lib/components/HeaderButton.svelte +++ b/web/src/lib/components/HeaderButton.svelte @@ -1,18 +1,17 @@ {#if action.$if?.() ?? true} - {/if} diff --git a/web/src/lib/components/jobs/JobTile.svelte b/web/src/lib/components/QueueCard.svelte similarity index 65% rename from web/src/lib/components/jobs/JobTile.svelte rename to web/src/lib/components/QueueCard.svelte index 64a6db5b7f..f57fb984a2 100644 --- a/web/src/lib/components/jobs/JobTile.svelte +++ b/web/src/lib/components/QueueCard.svelte @@ -1,11 +1,15 @@ + +
+ {#if data[0].length === 0} + + {/if} +
diff --git a/web/src/lib/components/QueuePanel.svelte b/web/src/lib/components/QueuePanel.svelte new file mode 100644 index 0000000000..177cbf33c3 --- /dev/null +++ b/web/src/lib/components/QueuePanel.svelte @@ -0,0 +1,132 @@ + + +
+ {#each queueList as [queueName, props] (queueName)} + {@const queue = queues.find(({ name }) => name === queueName)} + {#if queue} + handleCommand(queueName, command)} {...props} /> + {/if} + {/each} +
diff --git a/web/src/lib/components/jobs/StorageMigrationDescription.svelte b/web/src/lib/components/QueueStorageMigrationDescription.svelte similarity index 100% rename from web/src/lib/components/jobs/StorageMigrationDescription.svelte rename to web/src/lib/components/QueueStorageMigrationDescription.svelte diff --git a/web/src/lib/components/TableButton.svelte b/web/src/lib/components/TableButton.svelte index 4bd82e4dd9..e2aead4b22 100644 --- a/web/src/lib/components/TableButton.svelte +++ b/web/src/lib/components/TableButton.svelte @@ -1,16 +1,14 @@ {#if action.$if?.() ?? true} - + onAction(action)} /> {/if} diff --git a/web/src/lib/components/admin-settings/MaintenanceSettings.svelte b/web/src/lib/components/admin-settings/MaintenanceSettings.svelte new file mode 100644 index 0000000000..592091c62a --- /dev/null +++ b/web/src/lib/components/admin-settings/MaintenanceSettings.svelte @@ -0,0 +1,35 @@ + + +
+
+
+ +
+
+
diff --git a/web/src/lib/components/admin-settings/StorageTemplateSettings.svelte b/web/src/lib/components/admin-settings/StorageTemplateSettings.svelte index 3dbf697de1..e119e8d8b0 100644 --- a/web/src/lib/components/admin-settings/StorageTemplateSettings.svelte +++ b/web/src/lib/components/admin-settings/StorageTemplateSettings.svelte @@ -254,7 +254,7 @@ values={{ job: $t('admin.storage_template_migration_job') }} > {#snippet children({ message })} - + {message} {/snippet} diff --git a/web/src/lib/components/album-page/album-shared-link.svelte b/web/src/lib/components/album-page/album-shared-link.svelte index 1b6db6ff69..a9e3471241 100644 --- a/web/src/lib/components/album-page/album-shared-link.svelte +++ b/web/src/lib/components/album-page/album-shared-link.svelte @@ -32,7 +32,7 @@ .filter(Boolean) .join(' • '); - const SharedLinkActions = $derived(getSharedLinkActions($t, sharedLink)); + const { ViewQrCode, Copy } = $derived(getSharedLinkActions($t, sharedLink));
@@ -41,7 +41,7 @@ {getShareProperties()}
- - + +
diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte index a7c9243e64..2d05580d62 100644 --- a/web/src/lib/components/album-page/album-viewer.svelte +++ b/web/src/lib/components/album-page/album-viewer.svelte @@ -98,7 +98,7 @@ {#snippet leading()} - + {/snippet} diff --git a/web/src/lib/components/album-page/albums-list.svelte b/web/src/lib/components/album-page/albums-list.svelte index bb826110b7..e4b588af8f 100644 --- a/web/src/lib/components/album-page/albums-list.svelte +++ b/web/src/lib/components/album-page/albums-list.svelte @@ -33,7 +33,6 @@ import { groupBy } from 'lodash-es'; import { onMount, type Snippet } from 'svelte'; import { t } from 'svelte-i18n'; - import { run } from 'svelte/legacy'; interface Props { ownedAlbums?: AlbumResponseDto[]; @@ -128,65 +127,45 @@ }, }; - let albums: AlbumResponseDto[] = $state([]); - let filteredAlbums: AlbumResponseDto[] = $state([]); - let groupedAlbums: AlbumGroup[] = $state([]); + let albums = $derived.by(() => { + switch (userSettings.filter) { + case AlbumFilter.Owned: { + return ownedAlbums; + } + case AlbumFilter.Shared: { + return sharedAlbums; + } + default: { + const nonOwnedAlbums = sharedAlbums.filter((album) => album.ownerId !== $user.id); + return nonOwnedAlbums.length > 0 ? ownedAlbums.concat(nonOwnedAlbums) : ownedAlbums; + } + } + }); + const normalizedSearchQuery = $derived(normalizeSearchString(searchQuery)); + let filteredAlbums = $derived( + normalizedSearchQuery + ? albums.filter(({ albumName }) => normalizeSearchString(albumName).includes(normalizedSearchQuery)) + : albums, + ); - let albumGroupOption: string = $state(AlbumGroupBy.None); + let albumGroupOption = $derived(getSelectedAlbumGroupOption(userSettings)); + let groupedAlbums = $derived.by(() => { + const groupFunc = groupOptions[albumGroupOption] ?? groupOptions[AlbumGroupBy.None]; + const groupedAlbums = groupFunc(stringToSortOrder(userSettings.groupOrder), filteredAlbums); - let albumToShare: AlbumResponseDto | null = $state(null); + return groupedAlbums.map((group) => ({ + id: group.id, + name: group.name, + albums: sortAlbums(group.albums, { sortBy: userSettings.sortBy, orderBy: userSettings.sortOrder }), + })); + }); let contextMenuPosition: ContextMenuPosition = $state({ x: 0, y: 0 }); let selectedAlbum: AlbumResponseDto | undefined = $state(); let isOpen = $state(false); - // Step 1: Filter between Owned and Shared albums, or both. - run(() => { - switch (userSettings.filter) { - case AlbumFilter.Owned: { - albums = ownedAlbums; - break; - } - case AlbumFilter.Shared: { - albums = sharedAlbums; - break; - } - default: { - const userId = $user.id; - const nonOwnedAlbums = sharedAlbums.filter((album) => album.ownerId !== userId); - albums = nonOwnedAlbums.length > 0 ? ownedAlbums.concat(nonOwnedAlbums) : ownedAlbums; - } - } - }); - - // Step 2: Filter using the given search query. - run(() => { - if (searchQuery) { - const searchAlbumNormalized = normalizeSearchString(searchQuery); - - filteredAlbums = albums.filter((album) => { - return normalizeSearchString(album.albumName).includes(searchAlbumNormalized); - }); - } else { - filteredAlbums = albums; - } - }); - - // Step 3: Group albums. - run(() => { - albumGroupOption = getSelectedAlbumGroupOption(userSettings); - const groupFunc = groupOptions[albumGroupOption] ?? groupOptions[AlbumGroupBy.None]; - groupedAlbums = groupFunc(stringToSortOrder(userSettings.groupOrder), filteredAlbums); - }); - - // Step 4: Sort albums amongst each group. - run(() => { - groupedAlbums = groupedAlbums.map((group) => ({ - id: group.id, - name: group.name, - albums: sortAlbums(group.albums, { sortBy: userSettings.sortBy, orderBy: userSettings.sortOrder }), - })); - + // TODO get rid of this + $effect(() => { albumGroupIds = groupedAlbums.map(({ id }) => id); }); @@ -231,7 +210,7 @@ const result = await modalManager.show(AlbumShareModal, { album: selectedAlbum }); switch (result?.action) { case 'sharedUsers': { - await handleAddUsers(result.data); + await handleAddUsers(selectedAlbum, result.data); break; } @@ -300,22 +279,17 @@ updateRecentAlbumInfo(album); }; - const handleAddUsers = async (albumUsers: AlbumUserAddDto[]) => { - if (!albumToShare) { - return; - } + const handleAddUsers = async (album: AlbumResponseDto, albumUsers: AlbumUserAddDto[]) => { try { - const album = await addUsersToAlbum({ - id: albumToShare.id, + const updatedAlbum = await addUsersToAlbum({ + id: album.id, addUsersDto: { albumUsers, }, }); - updateAlbumInfo(album); + updateAlbumInfo(updatedAlbum); } catch (error) { handleError(error, $t('errors.unable_to_add_album_users')); - } finally { - albumToShare = null; } }; diff --git a/web/src/lib/components/asset-viewer/activity-viewer.svelte b/web/src/lib/components/asset-viewer/activity-viewer.svelte index 73b311769a..d688b2e9dd 100644 --- a/web/src/lib/components/asset-viewer/activity-viewer.svelte +++ b/web/src/lib/components/asset-viewer/activity-viewer.svelte @@ -52,7 +52,7 @@ let innerHeight: number = $state(0); let activityHeight: number = $state(0); let chatHeight: number = $state(0); - let divHeight: number = $state(0); + let divHeight = $derived(innerHeight - activityHeight); let previousAssetId: string | undefined = $state(assetId); let message = $state(''); let isSendingMessage = $state(false); @@ -96,11 +96,7 @@ } isSendingMessage = false; }; - $effect(() => { - if (innerHeight && activityHeight) { - divHeight = innerHeight - activityHeight; - } - }); + $effect(() => { if (assetId && previousAssetId != assetId) { previousAssetId = assetId; diff --git a/web/src/lib/components/asset-viewer/album-list-item.svelte b/web/src/lib/components/asset-viewer/album-list-item.svelte index 21b9b385d8..da0df21839 100644 --- a/web/src/lib/components/asset-viewer/album-list-item.svelte +++ b/web/src/lib/components/asset-viewer/album-list-item.svelte @@ -35,15 +35,13 @@ }); }; - let albumNameArray: string[] = $state(['', '', '']); - // This part of the code is responsible for splitting album name into 3 parts where part 2 is the search query // It is used to highlight the search query in the album name - $effect(() => { + const albumNameArray: string[] = $derived.by(() => { let { albumName } = album; let findIndex = normalizeSearchString(albumName).indexOf(normalizeSearchString(searchQuery)); let findLength = searchQuery.length; - albumNameArray = [ + return [ albumName.slice(0, findIndex), albumName.slice(findIndex, findIndex + findLength), albumName.slice(findIndex + findLength), diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte index 7daade6379..0dad2793bf 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte @@ -25,12 +25,12 @@ import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import { AppRoute } from '$lib/constants'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; + import { handleReplaceAsset } from '$lib/services/asset.service'; import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; import { user } from '$lib/stores/user.store'; import { photoZoomState } from '$lib/stores/zoom-image.store'; import { getAssetJobName, getSharedLink } from '$lib/utils'; import { canCopyImageToClipboard } from '$lib/utils/asset-utils'; - import { openFileUploadDialog } from '$lib/utils/file-uploader'; import { toTimelineAsset } from '$lib/utils/timeline-util'; import { AssetJobName, @@ -227,7 +227,7 @@ openFileUploadDialog({ multiple: false, assetId: asset.id })} + onClick={() => handleReplaceAsset(asset.id)} text={$t('replace_with_upload')} /> {#if !asset.isArchived && !asset.isTrashed} diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 8ff7a00710..b657f34ece 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -1,16 +1,19 @@ + +
+ {:else if isShowEditor && selectedEditType === 'crop'} {:else} @@ -522,6 +541,7 @@ {playOriginalVideo} /> {/if} + {#if $slideshowState === SlideshowState.None && isShared && ((album && album.isActivityEnabled) || activityManager.commentCount > 0) && !activityManager.isLoading}
{/if} + + {#if $slideshowState === SlideshowState.None && asset.type === AssetTypeEnum.Image && !isShowEditor && ocrManager.hasOcrData} +
+ +
+ {/if} {/key} {/if} diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index a9c447e498..60913ff47b 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -23,6 +23,7 @@ import { Icon, IconButton, LoadingSpinner, modalManager } from '@immich/ui'; import { mdiCalendar, + mdiCamera, mdiCameraIris, mdiClose, mdiEye, @@ -372,9 +373,9 @@ - {#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.fNumber} + {#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.exposureTime || asset.exifInfo?.iso}
-
+
{#if asset.exifInfo?.make || asset.exifInfo?.model} @@ -395,20 +396,34 @@

{/if} +
+ {#if asset.exifInfo.exposureTime} +

{`${asset.exifInfo.exposureTime} s`}

+ {/if} + + {#if asset.exifInfo.iso} +

{`ISO ${asset.exifInfo.iso}`}

+ {/if} +
+
+
+ {/if} + + {#if asset.exifInfo?.lensModel || asset.exifInfo?.fNumber || asset.exifInfo?.focalLength} +
+
+ +
{#if asset.exifInfo?.lensModel} - +

+ + {asset.exifInfo.lensModel} + +

{/if}
@@ -416,19 +431,9 @@

ƒ/{asset.exifInfo.fNumber.toLocaleString($locale)}

{/if} - {#if asset.exifInfo.exposureTime} -

{`${asset.exifInfo.exposureTime} s`}

- {/if} - {#if asset.exifInfo.focalLength}

{`${asset.exifInfo.focalLength.toLocaleString($locale)} mm`}

{/if} - - {#if asset.exifInfo.iso} -

- {`ISO ${asset.exifInfo.iso}`} -

- {/if}
@@ -503,7 +508,7 @@ {/if} {#if albums.length > 0} -
+

{$t('appears_in')}

{#each albums as album (album.id)} diff --git a/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte b/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte index 7334aab4d4..08ba43526d 100644 --- a/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte +++ b/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte @@ -7,11 +7,12 @@ import { t } from 'svelte-i18n'; import { fade } from 'svelte/transition'; - interface Props { + type Props = { asset: AssetResponseDto; - } + zoomToggle?: (() => void) | null; + }; - const { asset }: Props = $props(); + let { asset, zoomToggle = $bindable() }: Props = $props(); const loadAssetData = async (id: string) => { const data = await viewAsset({ ...authManager.params, id, size: AssetMediaSize.Preview }); @@ -24,6 +25,7 @@ {:then [data, { default: PhotoSphereViewer }]} + import type { OcrBox } from '$lib/utils/ocr-utils'; + import { calculateBoundingBoxDimensions } from '$lib/utils/ocr-utils'; + + type Props = { + ocrBox: OcrBox; + }; + + let { ocrBox }: Props = $props(); + + const dimensions = $derived(calculateBoundingBoxDimensions(ocrBox.points)); + + const transform = $derived( + `translate(${dimensions.minX}px, ${dimensions.minY}px) rotate(${dimensions.rotation}deg) skew(${dimensions.skewX}deg, ${dimensions.skewY}deg)`, + ); + + const transformOrigin = $derived( + `${dimensions.centerX - dimensions.minX}px ${dimensions.centerY - dimensions.minY}px`, + ); + + +
+ +
+ + +
+ {ocrBox.text} +
+
diff --git a/web/src/lib/components/asset-viewer/ocr-button.svelte b/web/src/lib/components/asset-viewer/ocr-button.svelte new file mode 100644 index 0000000000..9f8966e64a --- /dev/null +++ b/web/src/lib/components/asset-viewer/ocr-button.svelte @@ -0,0 +1,17 @@ + + + ocrManager.toggleOcrBoundingBox()} +/> diff --git a/web/src/lib/components/asset-viewer/photo-sphere-viewer-adapter.svelte b/web/src/lib/components/asset-viewer/photo-sphere-viewer-adapter.svelte index cd9a010f78..2e5d0d85c5 100644 --- a/web/src/lib/components/asset-viewer/photo-sphere-viewer-adapter.svelte +++ b/web/src/lib/components/asset-viewer/photo-sphere-viewer-adapter.svelte @@ -1,5 +1,8 @@ +
diff --git a/web/src/lib/components/asset-viewer/photo-viewer.spec.ts b/web/src/lib/components/asset-viewer/photo-viewer.spec.ts index 9e9f8fae62..fd1a40e4db 100644 --- a/web/src/lib/components/asset-viewer/photo-viewer.spec.ts +++ b/web/src/lib/components/asset-viewer/photo-viewer.spec.ts @@ -1,7 +1,7 @@ import { getAnimateMock } from '$lib/__mocks__/animate.mock'; import PhotoViewer from '$lib/components/asset-viewer/photo-viewer.svelte'; import * as utils from '$lib/utils'; -import { AssetMediaSize } from '@immich/sdk'; +import { AssetMediaSize, AssetTypeEnum } from '@immich/sdk'; import { assetFactory } from '@test-data/factories/asset-factory'; import { sharedLinkFactory } from '@test-data/factories/shared-link-factory'; import { render } from '@testing-library/svelte'; @@ -65,7 +65,11 @@ describe('PhotoViewer component', () => { }); it('loads the thumbnail', () => { - const asset = assetFactory.build({ originalPath: 'image.jpg', originalMimeType: 'image/jpeg' }); + const asset = assetFactory.build({ + originalPath: 'image.jpg', + originalMimeType: 'image/jpeg', + type: AssetTypeEnum.Image, + }); render(PhotoViewer, { asset }); expect(getAssetThumbnailUrlSpy).toBeCalledWith({ @@ -76,16 +80,89 @@ describe('PhotoViewer component', () => { expect(getAssetOriginalUrlSpy).not.toBeCalled(); }); - it('loads the original image for gifs', () => { - const asset = assetFactory.build({ originalPath: 'image.gif', originalMimeType: 'image/gif' }); + it('loads the thumbnail image for static gifs', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + }); + render(PhotoViewer, { asset }); + + expect(getAssetThumbnailUrlSpy).toBeCalledWith({ + id: asset.id, + size: AssetMediaSize.Preview, + cacheKey: asset.thumbhash, + }); + expect(getAssetOriginalUrlSpy).not.toBeCalled(); + }); + + it('loads the thumbnail image for static webp images', () => { + const asset = assetFactory.build({ + originalPath: 'image.webp', + originalMimeType: 'image/webp', + type: AssetTypeEnum.Image, + }); + render(PhotoViewer, { asset }); + + expect(getAssetThumbnailUrlSpy).toBeCalledWith({ + id: asset.id, + size: AssetMediaSize.Preview, + cacheKey: asset.thumbhash, + }); + expect(getAssetOriginalUrlSpy).not.toBeCalled(); + }); + + it('loads the original image for animated gifs', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + duration: '2.0', + }); render(PhotoViewer, { asset }); expect(getAssetThumbnailUrlSpy).not.toBeCalled(); expect(getAssetOriginalUrlSpy).toBeCalledWith({ id: asset.id, cacheKey: asset.thumbhash }); }); - it('loads original for shared link when download permission is true and showMetadata permission is true', () => { - const asset = assetFactory.build({ originalPath: 'image.gif', originalMimeType: 'image/gif' }); + it('loads the original image for animated webp images', () => { + const asset = assetFactory.build({ + originalPath: 'image.webp', + originalMimeType: 'image/webp', + type: AssetTypeEnum.Image, + duration: '2.0', + }); + render(PhotoViewer, { asset }); + + expect(getAssetThumbnailUrlSpy).not.toBeCalled(); + expect(getAssetOriginalUrlSpy).toBeCalledWith({ id: asset.id, cacheKey: asset.thumbhash }); + }); + + it('not loads original static image in shared link even when download permission is true and showMetadata permission is true', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + }); + const sharedLink = sharedLinkFactory.build({ allowDownload: true, showMetadata: true, assets: [asset] }); + render(PhotoViewer, { asset, sharedLink }); + + expect(getAssetThumbnailUrlSpy).toBeCalledWith({ + id: asset.id, + size: AssetMediaSize.Preview, + cacheKey: asset.thumbhash, + }); + + expect(getAssetOriginalUrlSpy).not.toBeCalled(); + }); + + it('loads original animated image in shared link when download permission is true and showMetadata permission is true', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + duration: '2.0', + }); const sharedLink = sharedLinkFactory.build({ allowDownload: true, showMetadata: true, assets: [asset] }); render(PhotoViewer, { asset, sharedLink }); @@ -93,8 +170,13 @@ describe('PhotoViewer component', () => { expect(getAssetOriginalUrlSpy).toBeCalledWith({ id: asset.id, cacheKey: asset.thumbhash }); }); - it('not loads original image when shared link download permission is false', () => { - const asset = assetFactory.build({ originalPath: 'image.gif', originalMimeType: 'image/gif' }); + it('not loads original animated image when shared link download permission is false', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + duration: '2.0', + }); const sharedLink = sharedLinkFactory.build({ allowDownload: false, assets: [asset] }); render(PhotoViewer, { asset, sharedLink }); @@ -107,8 +189,13 @@ describe('PhotoViewer component', () => { expect(getAssetOriginalUrlSpy).not.toBeCalled(); }); - it('not loads original image when shared link showMetadata permission is false', () => { - const asset = assetFactory.build({ originalPath: 'image.gif', originalMimeType: 'image/gif' }); + it('not loads original animated image when shared link showMetadata permission is false', () => { + const asset = assetFactory.build({ + originalPath: 'image.gif', + originalMimeType: 'image/gif', + type: AssetTypeEnum.Image, + duration: '2.0', + }); const sharedLink = sharedLinkFactory.build({ showMetadata: false, assets: [asset] }); render(PhotoViewer, { asset, sharedLink }); diff --git a/web/src/lib/components/asset-viewer/photo-viewer.svelte b/web/src/lib/components/asset-viewer/photo-viewer.svelte index d88609f7bb..2607f6de79 100644 --- a/web/src/lib/components/asset-viewer/photo-viewer.svelte +++ b/web/src/lib/components/asset-viewer/photo-viewer.svelte @@ -2,12 +2,14 @@ import { shortcuts } from '$lib/actions/shortcut'; import { zoomImageAction } from '$lib/actions/zoom-image'; import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; + import OcrBoundingBox from '$lib/components/asset-viewer/ocr-bounding-box.svelte'; import BrokenAsset from '$lib/components/assets/broken-asset.svelte'; import { assetViewerFadeDuration } from '$lib/constants'; import { castManager } from '$lib/managers/cast-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; + import { ocrManager } from '$lib/stores/ocr.svelte'; import { boundingBoxesArray } from '$lib/stores/people.store'; import { alwaysLoadOriginalFile } from '$lib/stores/preferences.store'; import { SlideshowLook, SlideshowState, slideshowLookCssMapping, slideshowStore } from '$lib/stores/slideshow.store'; @@ -15,11 +17,12 @@ import { getAssetOriginalUrl, getAssetThumbnailUrl, handlePromiseError } from '$lib/utils'; import { canCopyImageToClipboard, copyImageToClipboard, isWebCompatibleImage } from '$lib/utils/asset-utils'; import { handleError } from '$lib/utils/handle-error'; + import { getOcrBoundingBoxes } from '$lib/utils/ocr-utils'; import { getBoundingBox } from '$lib/utils/people-utils'; import { cancelImageUrl } from '$lib/utils/sw-messaging'; import { getAltText } from '$lib/utils/thumbnail-util'; import { toTimelineAsset } from '$lib/utils/timeline-util'; - import { AssetMediaSize, type AssetResponseDto, type SharedLinkResponseDto } from '@immich/sdk'; + import { AssetMediaSize, AssetTypeEnum, type AssetResponseDto, type SharedLinkResponseDto } from '@immich/sdk'; import { LoadingSpinner, toastManager } from '@immich/ui'; import { onDestroy, onMount } from 'svelte'; import { useSwipe, type SwipeCustomEvent } from 'svelte-gestures'; @@ -71,6 +74,14 @@ $boundingBoxesArray = []; }); + let ocrBoxes = $derived( + ocrManager.showOverlay && $photoViewerImgElement + ? getOcrBoundingBoxes(ocrManager.data, $photoZoomState, $photoViewerImgElement) + : [], + ); + + let isOcrActive = $derived(ocrManager.showOverlay); + const preload = (targetSize: AssetMediaSize | 'original', preloadAssets?: TimelineAsset[]) => { for (const preloadAsset of preloadAssets || []) { if (preloadAsset.isImage) { @@ -130,16 +141,25 @@ if ($photoZoomState.currentZoom > 1) { return; } + + if (ocrManager.showOverlay) { + return; + } + if (onNextAsset && event.detail.direction === 'left') { onNextAsset(); } + if (onPreviousAsset && event.detail.direction === 'right') { onPreviousAsset(); } }; // when true, will force loading of the original image - let forceUseOriginal: boolean = $derived(asset.originalMimeType === 'image/gif' || $photoZoomState.currentZoom > 1); + let forceUseOriginal: boolean = $derived( + (asset.type === AssetTypeEnum.Image && asset.duration && !asset.duration.includes('0:00:00.000')) || + $photoZoomState.currentZoom > 1, + ); const targetImageSize = $derived.by(() => { if ($alwaysLoadOriginalFile || forceUseOriginal || originalImageLoaded) { @@ -151,7 +171,6 @@ $effect(() => { if (assetFileUrl) { - // this can't be in an async context with $effect void cast(assetFileUrl); } }); @@ -232,7 +251,7 @@ {:else if !imageError}
{/each} + + {#each ocrBoxes as ocrBox (ocrBox.id)} + + {/each} {#if isFaceEditMode.value} diff --git a/web/src/lib/components/asset-viewer/video-native-viewer.svelte b/web/src/lib/components/asset-viewer/video-native-viewer.svelte index 92c467bc1e..a25789a76c 100644 --- a/web/src/lib/components/asset-viewer/video-native-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-native-viewer.svelte @@ -43,7 +43,9 @@ let videoPlayer: HTMLVideoElement | undefined = $state(); let isLoading = $state(true); - let assetFileUrl = $state(''); + let assetFileUrl = $derived( + playOriginalVideo ? getAssetOriginalUrl({ id: assetId, cacheKey }) : getAssetPlaybackUrl({ id: assetId, cacheKey }), + ); let isScrubbing = $state(false); let showVideo = $state(false); @@ -53,11 +55,9 @@ }); $effect(() => { - assetFileUrl = playOriginalVideo - ? getAssetOriginalUrl({ id: assetId, cacheKey }) - : getAssetPlaybackUrl({ id: assetId, cacheKey }); - if (videoPlayer) { - videoPlayer.load(); + // reactive on `assetFileUrl` changes + if (assetFileUrl) { + videoPlayer?.load(); } }); diff --git a/web/src/lib/components/asset-viewer/video-remote-viewer.svelte b/web/src/lib/components/asset-viewer/video-remote-viewer.svelte index 392028c49f..94a7e748c5 100644 --- a/web/src/lib/components/asset-viewer/video-remote-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-remote-viewer.svelte @@ -35,7 +35,6 @@ $effect(() => { if (assetFileUrl) { - // this can't be in an async context with $effect void cast(assetFileUrl); } }); diff --git a/web/src/lib/components/assets/thumbnail/thumbnail.svelte b/web/src/lib/components/assets/thumbnail/thumbnail.svelte index dd13d613b2..38d734fc22 100644 --- a/web/src/lib/components/assets/thumbnail/thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/thumbnail.svelte @@ -4,7 +4,7 @@ import { getAssetOriginalUrl, getAssetPlaybackUrl, getAssetThumbnailUrl } from '$lib/utils'; import { timeToSeconds } from '$lib/utils/date-time'; import { getAltText } from '$lib/utils/thumbnail-util'; - import { AssetMediaSize, AssetVisibility } from '@immich/sdk'; + import { AssetMediaSize, AssetVisibility, type UserResponseDto } from '@immich/sdk'; import { mdiArchiveArrowDownOutline, mdiCameraBurst, @@ -46,6 +46,7 @@ imageClass?: ClassValue; brokenAssetClass?: ClassValue; dimmed?: boolean; + albumUsers?: UserResponseDto[]; onClick?: (asset: TimelineAsset) => void; onSelect?: (asset: TimelineAsset) => void; onMouseEvent?: (event: { isMouseOver: boolean; selectedGroupIndex: number }) => void; @@ -64,6 +65,7 @@ readonly = false, showArchiveIcon = false, showStackedIcon = true, + albumUsers = [], onClick = undefined, onSelect = undefined, onMouseEvent = undefined, @@ -85,6 +87,8 @@ let width = $derived(thumbnailSize || thumbnailWidth || 235); let height = $derived(thumbnailSize || thumbnailHeight || 235); + let assetOwner = $derived(albumUsers?.find((user) => user.id === asset.ownerId) ?? null); + const onIconClickedHandler = (e?: MouseEvent) => { e?.stopPropagation(); e?.preventDefault(); @@ -264,28 +268,36 @@ {#if !authManager.isSharedLink && asset.isFavorite}
- + +
+ {/if} + + {#if !!assetOwner} +
+

+ {assetOwner.name} +

{/if} {#if !authManager.isSharedLink && showArchiveIcon && asset.visibility === AssetVisibility.Archive}
- +
{/if} {#if asset.isImage && asset.projectionType === ProjectionType.EQUIRECTANGULAR}
- +
{/if} - {#if asset.isImage && asset.duration} + {#if asset.isImage && asset.duration && !asset.duration.includes('0:00:00.000')}
- +
{/if} @@ -300,7 +312,7 @@ >

{asset.stack.assetCount.toLocaleString($locale)}

- +
{/if} @@ -351,7 +363,7 @@ playbackOnIconHover={!$playVideoThumbnailOnHover} /> - {:else if asset.isImage && asset.duration && mouseOver} + {:else if asset.isImage && asset.duration && !asset.duration.includes('0:00:00.000') && mouseOver}
@@ -366,7 +378,7 @@ />
- +
@@ -406,13 +418,13 @@ {disabled} > {#if disabled} - + {:else if selected}
- +
{:else} - + {/if} {/if} diff --git a/web/src/lib/components/forms/library-import-paths-form.svelte b/web/src/lib/components/forms/library-import-paths-form.svelte deleted file mode 100644 index 02f82504a7..0000000000 --- a/web/src/lib/components/forms/library-import-paths-form.svelte +++ /dev/null @@ -1,207 +0,0 @@ - - -
- - - {#each validatedPaths as validatedPath, listIndex (validatedPath.importPath)} - - - - - - - {/each} - - - - - -
- {#if validatedPath.isValid} - - {:else} - - {/if} - {validatedPath.importPath} - onEditImportPath(listIndex)} - size="small" - /> -
- {#if importPaths.length === 0} - {$t('admin.no_paths_added')} - {/if} - -
-
-
- -
-
- - -
-
-
diff --git a/web/src/lib/components/forms/library-scan-settings-form.svelte b/web/src/lib/components/forms/library-scan-settings-form.svelte deleted file mode 100644 index fde3849599..0000000000 --- a/web/src/lib/components/forms/library-scan-settings-form.svelte +++ /dev/null @@ -1,151 +0,0 @@ - - -
- - - {#each exclusionPatterns as exclusionPattern, listIndex (exclusionPattern)} - - - - - {/each} - - - - - -
{exclusionPattern} - onEditExclusionPattern(listIndex)} - aria-label={$t('edit_exclusion_pattern')} - size="small" - /> -
- {#if exclusionPatterns.length === 0} - {$t('admin.no_pattern_added')} - {/if} - - -
- -
- - -
-
diff --git a/web/src/lib/components/jobs/JobsPanel.svelte b/web/src/lib/components/jobs/JobsPanel.svelte deleted file mode 100644 index 99dfef3b59..0000000000 --- a/web/src/lib/components/jobs/JobsPanel.svelte +++ /dev/null @@ -1,197 +0,0 @@ - - -
- {#each jobList as [jobName, { title, subtitle, description, disabled, allText, refreshText, missingText, icon, handleCommand: handleCommandOverride }] (jobName)} - {@const { jobCounts: statistics, queueStatus } = jobs[jobName]} - (handleCommandOverride || handleCommand)(jobName, command)} - /> - {/each} -
diff --git a/web/src/lib/components/layouts/AdminPageLayout.svelte b/web/src/lib/components/layouts/AdminPageLayout.svelte index a74a6aee35..45d21c9139 100644 --- a/web/src/lib/components/layouts/AdminPageLayout.svelte +++ b/web/src/lib/components/layouts/AdminPageLayout.svelte @@ -4,16 +4,16 @@ import NavigationBar from '$lib/components/shared-components/navigation-bar/navigation-bar.svelte'; import AdminSidebar from '$lib/sidebars/AdminSidebar.svelte'; import { sidebarStore } from '$lib/stores/sidebar.svelte'; - import { AppShell, AppShellHeader, AppShellSidebar, Scrollable } from '@immich/ui'; + import { AppShell, AppShellHeader, AppShellSidebar, Scrollable, type BreadcrumbItem } from '@immich/ui'; import type { Snippet } from 'svelte'; type Props = { - title: string; + breadcrumbs: BreadcrumbItem[]; buttons?: Snippet; children?: Snippet; }; - let { title, buttons, children }: Props = $props(); + let { breadcrumbs, buttons, children }: Props = $props(); @@ -24,7 +24,7 @@ - + {@render children?.()} diff --git a/web/src/lib/components/layouts/TitleLayout.svelte b/web/src/lib/components/layouts/TitleLayout.svelte index 1beab45586..2d867bab2f 100644 --- a/web/src/lib/components/layouts/TitleLayout.svelte +++ b/web/src/lib/components/layouts/TitleLayout.svelte @@ -1,26 +1,20 @@
-
-
{title}
- {#if description} - {description} - {/if} -
+ {@render buttons?.()}
{@render children?.()} diff --git a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte index 108714348f..32622a1547 100644 --- a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte +++ b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte @@ -2,13 +2,14 @@ import StorageTemplateSettings from '$lib/components/admin-settings/StorageTemplateSettings.svelte'; import FormatMessage from '$lib/elements/FormatMessage.svelte'; import { user } from '$lib/stores/user.store'; + import { Link } from '@immich/ui';

{#snippet children({ message })} - {message} + {message} {/snippet}

diff --git a/web/src/lib/components/places-page/places-list.svelte b/web/src/lib/components/places-page/places-list.svelte index 3da4772e0c..bcb90cb18e 100644 --- a/web/src/lib/components/places-page/places-list.svelte +++ b/web/src/lib/components/places-page/places-list.svelte @@ -9,7 +9,6 @@ import { type PlacesGroup, getSelectedPlacesGroupOption } from '$lib/utils/places-utils'; import { Icon } from '@immich/ui'; import { t } from 'svelte-i18n'; - import { run } from 'svelte/legacy'; interface Props { places?: AssetResponseDto[]; @@ -70,39 +69,27 @@ }, }; - let filteredPlaces: AssetResponseDto[] = $state([]); - let groupedPlaces: PlacesGroup[] = $state([]); + const filteredPlaces = $derived.by(() => { + const searchQueryNormalized = normalizeSearchString(searchQuery); + return searchQueryNormalized + ? places.filter((place) => normalizeSearchString(place.exifInfo?.city ?? '').includes(searchQueryNormalized)) + : places; + }); - let placesGroupOption: string = $state(PlacesGroupBy.None); - - let hasPlaces = $derived(places.length > 0); - - // Step 1: Filter using the given search query. - run(() => { - if (searchQuery) { - const searchQueryNormalized = normalizeSearchString(searchQuery); - - filteredPlaces = places.filter((place) => { - return normalizeSearchString(place.exifInfo?.city ?? '').includes(searchQueryNormalized); - }); - } else { - filteredPlaces = places; - } + const placesGroupOption: string = $derived(getSelectedPlacesGroupOption(userSettings)); + const groupingFunction = $derived(groupOptions[placesGroupOption] ?? groupOptions[PlacesGroupBy.None]); + const groupedPlaces: PlacesGroup[] = $derived(groupingFunction(filteredPlaces)); + $effect(() => { searchResultCount = filteredPlaces.length; }); - // Step 2: Group places. - run(() => { - placesGroupOption = getSelectedPlacesGroupOption(userSettings); - const groupFunc = groupOptions[placesGroupOption] ?? groupOptions[PlacesGroupBy.None]; - groupedPlaces = groupFunc(filteredPlaces); - + $effect(() => { placesGroupIds = groupedPlaces.map(({ id }) => id); }); -{#if hasPlaces} +{#if places.length > 0} {#if placesGroupOption === PlacesGroupBy.None} diff --git a/web/src/lib/components/server-statistics/ServerStatisticsPanel.svelte b/web/src/lib/components/server-statistics/ServerStatisticsPanel.svelte index d8de773943..1fc01faf9c 100644 --- a/web/src/lib/components/server-statistics/ServerStatisticsPanel.svelte +++ b/web/src/lib/components/server-statistics/ServerStatisticsPanel.svelte @@ -7,20 +7,11 @@ import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js'; import { t } from 'svelte-i18n'; - interface Props { - stats?: ServerStatsResponseDto; - } + type Props = { + stats: ServerStatsResponseDto; + }; - let { - stats = { - photos: 0, - videos: 0, - usage: 0, - usagePhotos: 0, - usageVideos: 0, - usageByUser: [], - }, - }: Props = $props(); + const { stats }: Props = $props(); const zeros = (value: number) => { const maxLength = 13; diff --git a/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts b/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts index f016916f7f..e65d42b183 100644 --- a/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts +++ b/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts @@ -46,8 +46,7 @@ export class AlbumModalRowConverter { ): AlbumModalRow[] { // only show recent albums if no search was entered, or we're in the normal albums (non-shared) modal. const recentAlbumsToShow = !this.shared && search.length === 0 ? recentAlbums : []; - const rows: AlbumModalRow[] = []; - rows.push({ type: AlbumModalRowType.NEW_ALBUM, selected: selectedRowIndex === 0 }); + const rows: AlbumModalRow[] = [{ type: AlbumModalRowType.NEW_ALBUM, selected: selectedRowIndex === 0 }]; const filteredAlbums = sortAlbums( search.length > 0 && albums.length > 0 diff --git a/web/src/lib/components/shared-components/change-location.svelte b/web/src/lib/components/shared-components/change-location.svelte index 23fd00190e..0102e34977 100644 --- a/web/src/lib/components/shared-components/change-location.svelte +++ b/web/src/lib/components/shared-components/change-location.svelte @@ -27,7 +27,7 @@ let { asset = undefined, point: initialPoint, onClose }: Props = $props(); let places: PlacesResponseDto[] = $state([]); - let suggestedPlaces: PlacesResponseDto[] = $state([]); + let suggestedPlaces: PlacesResponseDto[] = $derived(places.slice(0, 5)); let searchWord: string = $state(''); let latestSearchTimeout: number; let showLoadingSpinner = $state(false); @@ -52,9 +52,6 @@ }); $effect(() => { - if (places) { - suggestedPlaces = places.slice(0, 5); - } if (searchWord === '') { suggestedPlaces = []; } diff --git a/web/src/lib/components/shared-components/context-menu/context-menu.svelte b/web/src/lib/components/shared-components/context-menu/context-menu.svelte index f63cbd0621..7bf9ba58b3 100644 --- a/web/src/lib/components/shared-components/context-menu/context-menu.svelte +++ b/web/src/lib/components/shared-components/context-menu/context-menu.svelte @@ -33,37 +33,36 @@ children, }: Props = $props(); - let left: number = $state(0); - let top: number = $state(0); + const swap = (direction: string) => (direction === 'left' ? 'right' : 'left'); + + const layoutDirection = $derived(languageManager.rtl ? swap(direction) : direction); + const position = $derived.by(() => { + if (!menuElement) { + return { left: 0, top: 0 }; + } + + const rect = menuElement.getBoundingClientRect(); + const directionWidth = layoutDirection === 'left' ? rect.width : 0; + const menuHeight = Math.min(menuElement.clientHeight, height) || 0; + + const left = Math.max(8, Math.min(window.innerWidth - rect.width, x - directionWidth)); + const top = Math.max(8, Math.min(window.innerHeight - menuHeight, y)); + + return { left, top }; + }); // We need to bind clientHeight since the bounding box may return a height // of zero when starting the 'slide' animation. let height: number = $state(0); let isTransitioned = $state(false); - - $effect(() => { - if (menuElement) { - let layoutDirection = direction; - if (languageManager.rtl) { - layoutDirection = direction === 'left' ? 'right' : 'left'; - } - - const rect = menuElement.getBoundingClientRect(); - const directionWidth = layoutDirection === 'left' ? rect.width : 0; - const menuHeight = Math.min(menuElement.clientHeight, height) || 0; - - left = Math.max(8, Math.min(window.innerWidth - rect.width, x - directionWidth)); - top = Math.max(8, Math.min(window.innerHeight - menuHeight, y)); - } - });
{ diff --git a/web/src/lib/components/shared-components/empty-placeholder.svelte b/web/src/lib/components/shared-components/empty-placeholder.svelte index ae7f9aab6a..78c675c93b 100644 --- a/web/src/lib/components/shared-components/empty-placeholder.svelte +++ b/web/src/lib/components/shared-components/empty-placeholder.svelte @@ -7,9 +7,10 @@ fullWidth?: boolean; src?: string; title?: string; + class?: string; } - let { onClick = undefined, text, fullWidth = false, src = empty1Url, title }: Props = $props(); + let { onClick = undefined, text, fullWidth = false, src = empty1Url, title, class: className }: Props = $props(); let width = $derived(fullWidth ? 'w-full' : 'w-1/2'); @@ -22,7 +23,7 @@ diff --git a/web/src/lib/components/shared-components/map/map.svelte b/web/src/lib/components/shared-components/map/map.svelte index 063d747750..e3a926f9b6 100644 --- a/web/src/lib/components/shared-components/map/map.svelte +++ b/web/src/lib/components/shared-components/map/map.svelte @@ -376,7 +376,7 @@ } }} > - {#snippet children({ feature }: { feature: Feature })} + {#snippet children({ feature }: { feature: Feature })} {#if useLocationPin} {:else} diff --git a/web/src/lib/components/shared-components/search-bar/search-bar.svelte b/web/src/lib/components/shared-components/search-bar/search-bar.svelte index ea1147fe06..a88da2cebf 100644 --- a/web/src/lib/components/shared-components/search-bar/search-bar.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-bar.svelte @@ -9,9 +9,9 @@ import { generateId } from '$lib/utils/generate-id'; import { getMetadataSearchQuery } from '$lib/utils/metadata-search'; import type { MetadataSearchDto, SmartSearchDto } from '@immich/sdk'; - import { IconButton, modalManager } from '@immich/ui'; + import { Button, IconButton, modalManager } from '@immich/ui'; import { mdiClose, mdiMagnify, mdiTune } from '@mdi/js'; - import { onDestroy, tick } from 'svelte'; + import { onDestroy, onMount, tick } from 'svelte'; import { t } from 'svelte-i18n'; import SearchHistoryBox from './search-history-box.svelte'; @@ -31,6 +31,8 @@ let isSearchSuggestions = $state(false); let selectedId: string | undefined = $state(); let close: (() => Promise) | undefined; + let showSearchTypeDropdown = $state(false); + let currentSearchType = $state('smart'); const listboxId = generateId(); const searchTypeId = generateId(); @@ -70,6 +72,7 @@ const onFocusIn = () => { searchStore.isSearchEnabled = true; + getSearchType(); }; const onFocusOut = () => { @@ -98,6 +101,9 @@ const searchResult = await result.onClose; close = undefined; + // Refresh search type after modal closes + getSearchType(); + if (!searchResult) { return; } @@ -139,6 +145,7 @@ const onEscape = () => { closeDropdown(); + closeSearchTypeDropdown(); }; const onArrow = async (direction: 1 | -1) => { @@ -168,6 +175,20 @@ searchHistoryBox?.clearSelection(); }; + const toggleSearchTypeDropdown = () => { + showSearchTypeDropdown = !showSearchTypeDropdown; + }; + + const closeSearchTypeDropdown = () => { + showSearchTypeDropdown = false; + }; + + const selectSearchType = (type: string) => { + localStorage.setItem('searchQueryType', type); + currentSearchType = type; + showSearchTypeDropdown = false; + }; + const onsubmit = (event: Event) => { event.preventDefault(); onSubmit(); @@ -180,17 +201,18 @@ case 'metadata': case 'description': case 'ocr': { + currentSearchType = searchType; return searchType; } default: { + currentSearchType = 'smart'; return 'smart'; } } } function getSearchTypeText(): string { - const searchType = getSearchType(); - switch (searchType) { + switch (currentSearchType) { case 'smart': { return $t('context'); } @@ -203,8 +225,22 @@ case 'ocr': { return $t('ocr'); } + default: { + return $t('context'); + } } } + + onMount(() => { + getSearchType(); + }); + + const searchTypes = [ + { value: 'smart', label: () => $t('context') }, + { value: 'metadata', label: () => $t('filename') }, + { value: 'description', label: () => $t('description') }, + { value: 'ocr', label: () => $t('ocr') }, + ] as const; 0} > -

- {getSearchTypeText()} -

+
+ + + {#if showSearchTypeDropdown} +
+ {#each searchTypes as searchType (searchType.value)} + + {/each} +
+ {/if} +
{/if} diff --git a/web/src/lib/components/shared-components/search-bar/search-camera-section.svelte b/web/src/lib/components/shared-components/search-bar/search-camera-section.svelte index 1d451eacc4..ac158aa8a3 100644 --- a/web/src/lib/components/shared-components/search-bar/search-camera-section.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-camera-section.svelte @@ -64,10 +64,11 @@ } } - let makeFilter = $derived(filters.make); - let modelFilter = $derived(filters.model); - let lensModelFilter = $derived(filters.lensModel); + const makeFilter = $derived(filters.make); + const modelFilter = $derived(filters.model); + const lensModelFilter = $derived(filters.lensModel); + // TODO replace by async $derived, at the latest when it's in stable https://svelte.dev/docs/svelte/await-expressions $effect(() => { handlePromiseError(updateMakes()); }); diff --git a/web/src/lib/components/shared-components/search-bar/search-location-section.svelte b/web/src/lib/components/shared-components/search-bar/search-location-section.svelte index cba5e105af..37a4a3ca9b 100644 --- a/web/src/lib/components/shared-components/search-bar/search-location-section.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-location-section.svelte @@ -7,11 +7,10 @@
diff --git a/web/src/lib/components/shared-components/side-bar/purchase-info.svelte b/web/src/lib/components/shared-components/side-bar/purchase-info.svelte index 8c16e3ba38..629326c41b 100644 --- a/web/src/lib/components/shared-components/side-bar/purchase-info.svelte +++ b/web/src/lib/components/shared-components/side-bar/purchase-info.svelte @@ -74,10 +74,10 @@ {#if $isPurchased && $preferences.purchase.showSupportBadge} {:else if !$isPurchased && showBuyButton && getAccountAge() > 14} + + + + diff --git a/web/src/lib/modals/LibraryExclusionPatternEditModal.svelte b/web/src/lib/modals/LibraryExclusionPatternEditModal.svelte new file mode 100644 index 0000000000..56207c8cf4 --- /dev/null +++ b/web/src/lib/modals/LibraryExclusionPatternEditModal.svelte @@ -0,0 +1,45 @@ + + + + +
+ {$t('admin.exclusion_pattern_description')} + + + + +
+
+ + + + + + + +
diff --git a/web/src/lib/modals/LibraryExclusionPatternModal.svelte b/web/src/lib/modals/LibraryExclusionPatternModal.svelte deleted file mode 100644 index fe5da01c45..0000000000 --- a/web/src/lib/modals/LibraryExclusionPatternModal.svelte +++ /dev/null @@ -1,78 +0,0 @@ - - - - -
-

- {$t('admin.exclusion_pattern_description')} -

- {$t('admin.add_exclusion_pattern_description')} -

-
- - -
-
- {#if isDuplicate} -

{$t('errors.exclusion_pattern_already_exists')}

- {/if} -
-
-
- - - - {#if isEditing} - - {/if} - - - -
diff --git a/web/src/lib/modals/LibraryFolderAddModal.svelte b/web/src/lib/modals/LibraryFolderAddModal.svelte new file mode 100644 index 0000000000..67ae5bf773 --- /dev/null +++ b/web/src/lib/modals/LibraryFolderAddModal.svelte @@ -0,0 +1,44 @@ + + + + +
+ {$t('admin.library_folder_description')} + + + + +
+
+ + + + + + + +
diff --git a/web/src/lib/modals/LibraryFolderEditModal.svelte b/web/src/lib/modals/LibraryFolderEditModal.svelte new file mode 100644 index 0000000000..c1ab657275 --- /dev/null +++ b/web/src/lib/modals/LibraryFolderEditModal.svelte @@ -0,0 +1,45 @@ + + + + +
+ {$t('admin.library_folder_description')} + + + + +
+
+ + + + + + + +
diff --git a/web/src/lib/modals/LibraryImportPathModal.svelte b/web/src/lib/modals/LibraryImportPathModal.svelte deleted file mode 100644 index 5c1454fdd9..0000000000 --- a/web/src/lib/modals/LibraryImportPathModal.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - - - -
-

{$t('admin.library_import_path_description')}

- -
- - -
- -
- {#if isDuplicate} -

{$t('errors.import_path_already_exists')}

- {/if} -
-
-
- - - - - {#if isEditing} - - {/if} - - - -
diff --git a/web/src/lib/modals/LibraryRenameModal.svelte b/web/src/lib/modals/LibraryRenameModal.svelte index af204cdf0e..0a7d675b11 100644 --- a/web/src/lib/modals/LibraryRenameModal.svelte +++ b/web/src/lib/modals/LibraryRenameModal.svelte @@ -1,21 +1,25 @@ diff --git a/web/src/lib/modals/NavigateToDateModal.svelte b/web/src/lib/modals/NavigateToDateModal.svelte index 4b83c66bc6..365cbdb21c 100644 --- a/web/src/lib/modals/NavigateToDateModal.svelte +++ b/web/src/lib/modals/NavigateToDateModal.svelte @@ -1,6 +1,6 @@ + + + +
{$t('server_restarting_description')}
+
+
diff --git a/web/src/lib/modals/SharedLinkCreateModal.svelte b/web/src/lib/modals/SharedLinkCreateModal.svelte index f2fcacd17e..40fc21ccc2 100644 --- a/web/src/lib/modals/SharedLinkCreateModal.svelte +++ b/web/src/lib/modals/SharedLinkCreateModal.svelte @@ -68,7 +68,7 @@ {#if slug} - /s/{encodeURIComponent(slug)} + /s/{encodeURIComponent(slug)} {/if}
diff --git a/web/src/lib/modals/TagCreateModal.svelte b/web/src/lib/modals/TagCreateModal.svelte index 360681d7b9..5c48e83b08 100644 --- a/web/src/lib/modals/TagCreateModal.svelte +++ b/web/src/lib/modals/TagCreateModal.svelte @@ -14,7 +14,7 @@ const { onClose, baseTag }: Props = $props(); - let tagValue = $state(baseTag?.value ? `${baseTag.value}/` : ''); + let tagValue = $state(baseTag?.path ? `${baseTag.path}/` : ''); const createTag = async () => { const [tag] = await upsertTags({ tagUpsertDto: { tags: [tagValue] } }); diff --git a/web/src/lib/modals/UserEditModal.svelte b/web/src/lib/modals/UserEditModal.svelte index 84e4edc32a..4b4878e46d 100644 --- a/web/src/lib/modals/UserEditModal.svelte +++ b/web/src/lib/modals/UserEditModal.svelte @@ -89,7 +89,7 @@ {$t('admin.note_apply_storage_label_previous_assets')} - + {$t('admin.storage_template_migration_job')} diff --git a/web/src/lib/services/asset.service.ts b/web/src/lib/services/asset.service.ts new file mode 100644 index 0000000000..245b4888ca --- /dev/null +++ b/web/src/lib/services/asset.service.ts @@ -0,0 +1,11 @@ +import { eventManager } from '$lib/managers/event-manager.svelte'; +import { openFileUploadDialog } from '$lib/utils/file-uploader'; +import { copyAsset, deleteAssets } from '@immich/sdk'; + +export const handleReplaceAsset = async (oldAssetId: string) => { + const [newAssetId] = await openFileUploadDialog({ multiple: false }); + await copyAsset({ assetCopyDto: { sourceId: oldAssetId, targetId: newAssetId } }); + await deleteAssets({ assetBulkDeleteDto: { ids: [oldAssetId], force: true } }); + + eventManager.emit('AssetReplace', { oldAssetId, newAssetId }); +}; diff --git a/web/src/lib/services/library.service.ts b/web/src/lib/services/library.service.ts new file mode 100644 index 0000000000..8b4d35a5f6 --- /dev/null +++ b/web/src/lib/services/library.service.ts @@ -0,0 +1,368 @@ +import { goto } from '$app/navigation'; +import { AppRoute } from '$lib/constants'; +import { eventManager } from '$lib/managers/event-manager.svelte'; +import LibraryExclusionPatternAddModal from '$lib/modals/LibraryExclusionPatternAddModal.svelte'; +import LibraryExclusionPatternEditModal from '$lib/modals/LibraryExclusionPatternEditModal.svelte'; +import LibraryFolderAddModal from '$lib/modals/LibraryFolderAddModal.svelte'; +import LibraryFolderEditModal from '$lib/modals/LibraryFolderEditModal.svelte'; +import LibraryRenameModal from '$lib/modals/LibraryRenameModal.svelte'; +import LibraryUserPickerModal from '$lib/modals/LibraryUserPickerModal.svelte'; +import { handleError } from '$lib/utils/handle-error'; +import { getFormatter } from '$lib/utils/i18n'; +import { + createLibrary, + deleteLibrary, + QueueCommand, + QueueName, + runQueueCommandLegacy, + scanLibrary, + updateLibrary, + type LibraryResponseDto, +} from '@immich/sdk'; +import { modalManager, toastManager, type ActionItem } from '@immich/ui'; +import { mdiPencilOutline, mdiPlusBoxOutline, mdiSync, mdiTrashCanOutline } from '@mdi/js'; +import type { MessageFormatter } from 'svelte-i18n'; + +export const getLibrariesActions = ($t: MessageFormatter, libraries: LibraryResponseDto[]) => { + const ScanAll: ActionItem = { + title: $t('scan_all_libraries'), + type: $t('command'), + icon: mdiSync, + onAction: () => void handleScanAllLibraries(), + shortcuts: { shift: true, key: 'r' }, + $if: () => libraries.length > 0, + }; + + const Create: ActionItem = { + title: $t('create_library'), + type: $t('command'), + icon: mdiPlusBoxOutline, + onAction: () => void handleCreateLibrary(), + shortcuts: { shift: true, key: 'n' }, + }; + + return { ScanAll, Create }; +}; + +export const getLibraryActions = ($t: MessageFormatter, library: LibraryResponseDto) => { + const Rename: ActionItem = { + icon: mdiPencilOutline, + type: $t('command'), + title: $t('rename'), + onAction: () => void modalManager.show(LibraryRenameModal, { library }), + shortcuts: { key: 'r' }, + }; + + const Delete: ActionItem = { + icon: mdiTrashCanOutline, + type: $t('command'), + title: $t('delete'), + color: 'danger', + onAction: () => void handleDeleteLibrary(library), + shortcuts: { key: 'Backspace' }, + }; + + const AddFolder: ActionItem = { + icon: mdiPlusBoxOutline, + type: $t('command'), + title: $t('add'), + onAction: () => void modalManager.show(LibraryFolderAddModal, { library }), + }; + + const AddExclusionPattern: ActionItem = { + icon: mdiPlusBoxOutline, + type: $t('command'), + title: $t('add'), + onAction: () => void modalManager.show(LibraryExclusionPatternAddModal, { library }), + }; + + const Scan: ActionItem = { + icon: mdiSync, + type: $t('command'), + title: $t('scan_library'), + onAction: () => void handleScanLibrary(library), + shortcuts: { shift: true, key: 'r' }, + }; + + return { Rename, Delete, AddFolder, AddExclusionPattern, Scan }; +}; + +export const getLibraryFolderActions = ($t: MessageFormatter, library: LibraryResponseDto, folder: string) => { + const Edit: ActionItem = { + icon: mdiPencilOutline, + type: $t('command'), + title: $t('edit'), + onAction: () => void modalManager.show(LibraryFolderEditModal, { folder, library }), + }; + + const Delete: ActionItem = { + icon: mdiTrashCanOutline, + type: $t('command'), + title: $t('delete'), + onAction: () => void handleDeleteLibraryFolder(library, folder), + }; + + return { Edit, Delete }; +}; + +export const getLibraryExclusionPatternActions = ( + $t: MessageFormatter, + library: LibraryResponseDto, + exclusionPattern: string, +) => { + const Edit: ActionItem = { + icon: mdiPencilOutline, + type: $t('command'), + title: $t('edit'), + onAction: () => void modalManager.show(LibraryExclusionPatternEditModal, { exclusionPattern, library }), + }; + + const Delete: ActionItem = { + icon: mdiTrashCanOutline, + type: $t('command'), + title: $t('delete'), + onAction: () => void handleDeleteExclusionPattern(library, exclusionPattern), + }; + + return { Edit, Delete }; +}; + +const handleScanAllLibraries = async () => { + const $t = await getFormatter(); + + try { + await runQueueCommandLegacy({ name: QueueName.Library, queueCommandDto: { command: QueueCommand.Start } }); + toastManager.info($t('admin.refreshing_all_libraries')); + } catch (error) { + handleError(error, $t('errors.unable_to_scan_libraries')); + } +}; + +const handleScanLibrary = async (library: LibraryResponseDto) => { + const $t = await getFormatter(); + try { + await scanLibrary({ id: library.id }); + toastManager.info($t('admin.scanning_library')); + } catch (error) { + handleError(error, $t('errors.unable_to_scan_library')); + } +}; + +export const handleViewLibrary = async (library: LibraryResponseDto) => { + await goto(`${AppRoute.ADMIN_LIBRARY_MANAGEMENT}/${library.id}`); +}; + +export const handleCreateLibrary = async () => { + const $t = await getFormatter(); + + const ownerId = await modalManager.show(LibraryUserPickerModal, {}); + if (!ownerId) { + return; + } + + try { + const createdLibrary = await createLibrary({ createLibraryDto: { ownerId } }); + eventManager.emit('LibraryCreate', createdLibrary); + toastManager.success($t('admin.library_created', { values: { library: createdLibrary.name } })); + } catch (error) { + handleError(error, $t('errors.unable_to_create_library')); + } +}; + +export const handleRenameLibrary = async (library: { id: string }, name?: string) => { + const $t = await getFormatter(); + + if (!name) { + return false; + } + + try { + const updatedLibrary = await updateLibrary({ + id: library.id, + updateLibraryDto: { name }, + }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +const handleDeleteLibrary = async (library: LibraryResponseDto) => { + const $t = await getFormatter(); + + const confirmed = await modalManager.showDialog({ + prompt: $t('admin.confirm_delete_library', { values: { library: library.name } }), + }); + + if (!confirmed) { + return; + } + + if (library.assetCount > 0) { + const isConfirmed = await modalManager.showDialog({ + prompt: $t('admin.confirm_delete_library_assets', { values: { count: library.assetCount } }), + }); + if (!isConfirmed) { + return; + } + } + + try { + await deleteLibrary({ id: library.id }); + eventManager.emit('LibraryDelete', { id: library.id }); + toastManager.success($t('admin.library_deleted')); + } catch (error) { + handleError(error, $t('errors.unable_to_remove_library')); + } +}; + +export const handleAddLibraryFolder = async (library: LibraryResponseDto, folder: string) => { + const $t = await getFormatter(); + + if (library.importPaths.includes(folder)) { + toastManager.danger($t('errors.library_folder_already_exists')); + return false; + } + + try { + const updatedLibrary = await updateLibrary({ + id: library.id, + updateLibraryDto: { importPaths: [...library.importPaths, folder] }, + }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +export const handleEditLibraryFolder = async (library: LibraryResponseDto, oldFolder: string, newFolder: string) => { + const $t = await getFormatter(); + + if (oldFolder === newFolder) { + return true; + } + + const importPaths = library.importPaths.map((path) => (path === oldFolder ? newFolder : path)); + + try { + const updatedLibrary = await updateLibrary({ id: library.id, updateLibraryDto: { importPaths } }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +const handleDeleteLibraryFolder = async (library: LibraryResponseDto, folder: string) => { + const $t = await getFormatter(); + + const confirmed = await modalManager.showDialog({ + prompt: $t('admin.library_remove_folder_prompt'), + confirmText: $t('remove'), + }); + + if (!confirmed) { + return false; + } + + try { + const updatedLibrary = await updateLibrary({ + id: library.id, + updateLibraryDto: { importPaths: library.importPaths.filter((path) => path !== folder) }, + }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +export const handleAddLibraryExclusionPattern = async (library: LibraryResponseDto, exclusionPattern: string) => { + const $t = await getFormatter(); + + if (library.exclusionPatterns.includes(exclusionPattern)) { + toastManager.danger($t('errors.exclusion_pattern_already_exists')); + return false; + } + + try { + const updatedLibrary = await updateLibrary({ + id: library.id, + updateLibraryDto: { exclusionPatterns: [...library.exclusionPatterns, exclusionPattern] }, + }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +export const handleEditExclusionPattern = async ( + library: LibraryResponseDto, + oldExclusionPattern: string, + newExclusionPattern: string, +) => { + const $t = await getFormatter(); + + if (oldExclusionPattern === newExclusionPattern) { + return true; + } + + const exclusionPatterns = library.exclusionPatterns.map((pattern) => + pattern === oldExclusionPattern ? newExclusionPattern : pattern, + ); + + try { + const updatedLibrary = await updateLibrary({ id: library.id, updateLibraryDto: { exclusionPatterns } }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; + +const handleDeleteExclusionPattern = async (library: LibraryResponseDto, exclusionPattern: string) => { + const $t = await getFormatter(); + + const confirmed = await modalManager.showDialog({ prompt: $t('admin.library_remove_exclusion_pattern_prompt') }); + + if (!confirmed) { + return false; + } + + try { + const updatedLibrary = await updateLibrary({ + id: library.id, + updateLibraryDto: { + exclusionPatterns: library.exclusionPatterns.filter((pattern) => pattern !== exclusionPattern), + }, + }); + eventManager.emit('LibraryUpdate', updatedLibrary); + toastManager.success($t('admin.library_updated')); + } catch (error) { + handleError(error, $t('errors.unable_to_update_library')); + return false; + } + + return true; +}; diff --git a/web/src/lib/services/queue.service.ts b/web/src/lib/services/queue.service.ts new file mode 100644 index 0000000000..2372461d1a --- /dev/null +++ b/web/src/lib/services/queue.service.ts @@ -0,0 +1,246 @@ +import { goto } from '$app/navigation'; +import { AppRoute } from '$lib/constants'; +import { eventManager } from '$lib/managers/event-manager.svelte'; +import JobCreateModal from '$lib/modals/JobCreateModal.svelte'; +import { user } from '$lib/stores/user.store'; +import { handleError } from '$lib/utils/handle-error'; +import { getFormatter } from '$lib/utils/i18n'; +import { emptyQueue, getQueue, QueueName, updateQueue, type QueueResponseDto } from '@immich/sdk'; +import { modalManager, toastManager, type ActionItem, type IconLike } from '@immich/ui'; +import { + mdiClose, + mdiCog, + mdiContentDuplicate, + mdiDatabaseOutline, + mdiFaceRecognition, + mdiFileJpgBox, + mdiFileXmlBox, + mdiFolderMove, + mdiImageSearch, + mdiLibraryShelves, + mdiOcr, + mdiPause, + mdiPlay, + mdiPlus, + mdiStateMachine, + mdiSync, + mdiTable, + mdiTagFaces, + mdiTrashCanOutline, + mdiTrayFull, + mdiVideo, +} from '@mdi/js'; +import type { MessageFormatter } from 'svelte-i18n'; +import { get } from 'svelte/store'; + +type QueueItem = { + icon: IconLike; + title: string; + subtitle?: string; +}; + +export const getQueuesActions = ($t: MessageFormatter) => { + const ViewQueues: ActionItem = { + title: $t('admin.queues'), + description: $t('admin.queues_page_description'), + icon: mdiSync, + type: $t('page'), + isGlobal: true, + $if: () => get(user)?.isAdmin, + onAction: () => goto(AppRoute.ADMIN_QUEUES), + }; + + const CreateJob: ActionItem = { + icon: mdiPlus, + title: $t('admin.create_job'), + type: $t('command'), + shortcuts: { shift: true, key: 'n' }, + onAction: async () => { + await modalManager.show(JobCreateModal, {}); + }, + }; + + const ManageConcurrency: ActionItem = { + icon: mdiCog, + title: $t('admin.manage_concurrency'), + description: $t('admin.manage_concurrency_description'), + type: $t('page'), + onAction: () => goto(`${AppRoute.ADMIN_SETTINGS}?isOpen=job`), + }; + + return { ViewQueues, ManageConcurrency, CreateJob }; +}; + +export const getQueueActions = ($t: MessageFormatter, queue: QueueResponseDto) => { + const Pause: ActionItem = { + icon: mdiPause, + title: $t('pause'), + $if: () => !queue.isPaused, + onAction: () => handlePauseQueue(queue), + }; + + const Resume: ActionItem = { + icon: mdiPlay, + title: $t('resume'), + $if: () => queue.isPaused, + onAction: () => handleResumeQueue(queue), + }; + + const Empty: ActionItem = { + icon: mdiClose, + title: $t('clear'), + onAction: () => handleEmptyQueue(queue), + }; + + const RemoveFailedJobs: ActionItem = { + icon: mdiTrashCanOutline, + color: 'danger', + title: $t('admin.remove_failed_jobs'), + onAction: () => handleRemoveFailedJobs(queue), + }; + + return { Pause, Resume, Empty, RemoveFailedJobs }; +}; + +export const handlePauseQueue = async (queue: QueueResponseDto) => { + const response = await updateQueue({ name: queue.name, queueUpdateDto: { isPaused: true } }); + eventManager.emit('QueueUpdate', response); +}; + +export const handleResumeQueue = async (queue: QueueResponseDto) => { + const response = await updateQueue({ name: queue.name, queueUpdateDto: { isPaused: false } }); + eventManager.emit('QueueUpdate', response); +}; + +export const handleEmptyQueue = async (queue: QueueResponseDto) => { + const $t = await getFormatter(); + const item = asQueueItem($t, queue); + + try { + await emptyQueue({ name: queue.name, queueDeleteDto: { failed: false } }); + const response = await getQueue({ name: queue.name }); + eventManager.emit('QueueUpdate', response); + toastManager.success($t('admin.cleared_jobs', { values: { job: item.title } })); + } catch (error) { + handleError(error, $t('errors.something_went_wrong')); + } +}; + +const handleRemoveFailedJobs = async (queue: QueueResponseDto) => { + const $t = await getFormatter(); + + try { + await emptyQueue({ name: queue.name, queueDeleteDto: { failed: true } }); + const response = await getQueue({ name: queue.name }); + eventManager.emit('QueueUpdate', response); + toastManager.success(); + } catch (error) { + handleError(error, $t('errors.something_went_wrong')); + } +}; + +export const asQueueItem = ($t: MessageFormatter, queue: { name: QueueName }): QueueItem => { + // TODO merge this mapping with data from QueuePanel.svelte + const items: Record = { + [QueueName.ThumbnailGeneration]: { + icon: mdiFileJpgBox, + title: $t('admin.thumbnail_generation_job'), + subtitle: $t('admin.thumbnail_generation_job_description'), + }, + [QueueName.MetadataExtraction]: { + icon: mdiTable, + title: $t('admin.metadata_extraction_job'), + subtitle: $t('admin.metadata_extraction_job_description'), + }, + [QueueName.Library]: { + icon: mdiLibraryShelves, + title: $t('external_libraries'), + subtitle: $t('admin.library_tasks_description'), + }, + [QueueName.Sidecar]: { + title: $t('admin.sidecar_job'), + icon: mdiFileXmlBox, + subtitle: $t('admin.sidecar_job_description'), + }, + [QueueName.SmartSearch]: { + icon: mdiImageSearch, + title: $t('admin.machine_learning_smart_search'), + subtitle: $t('admin.smart_search_job_description'), + }, + [QueueName.DuplicateDetection]: { + icon: mdiContentDuplicate, + title: $t('admin.machine_learning_duplicate_detection'), + subtitle: $t('admin.duplicate_detection_job_description'), + }, + [QueueName.FaceDetection]: { + icon: mdiFaceRecognition, + title: $t('admin.face_detection'), + subtitle: $t('admin.face_detection_description'), + }, + [QueueName.FacialRecognition]: { + icon: mdiTagFaces, + title: $t('admin.machine_learning_facial_recognition'), + subtitle: $t('admin.facial_recognition_job_description'), + }, + [QueueName.Ocr]: { + icon: mdiOcr, + title: $t('admin.machine_learning_ocr'), + subtitle: $t('admin.ocr_job_description'), + }, + [QueueName.VideoConversion]: { + icon: mdiVideo, + title: $t('admin.video_conversion_job'), + subtitle: $t('admin.video_conversion_job_description'), + }, + [QueueName.StorageTemplateMigration]: { + icon: mdiFolderMove, + title: $t('admin.storage_template_migration'), + }, + [QueueName.Migration]: { + icon: mdiFolderMove, + title: $t('admin.migration_job'), + subtitle: $t('admin.migration_job_description'), + }, + [QueueName.BackgroundTask]: { + icon: mdiTrayFull, + title: $t('admin.background_task_job'), + }, + [QueueName.Search]: { + icon: '', + title: $t('search'), + }, + [QueueName.Notifications]: { + icon: '', + title: $t('notifications'), + }, + [QueueName.BackupDatabase]: { + icon: mdiDatabaseOutline, + title: $t('admin.backup_database'), + }, + [QueueName.Workflow]: { + icon: mdiStateMachine, + title: $t('workflow'), + }, + }; + + return items[queue.name]; +}; + +export const asQueueSlug = (name: QueueName) => { + return name.replaceAll(/[A-Z]/g, (m) => '-' + m.toLowerCase()); +}; + +export const fromQueueSlug = (slug: string): QueueName | undefined => { + const name = slug.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase()); + if (Object.values(QueueName).includes(name as QueueName)) { + return name as QueueName; + } +}; + +export const getQueueDetailUrl = (queue: QueueResponseDto) => { + return `${AppRoute.ADMIN_QUEUES}/${asQueueSlug(queue.name)}`; +}; + +export const handleViewQueue = (queue: QueueResponseDto) => { + return goto(getQueueDetailUrl(queue)); +}; diff --git a/web/src/lib/services/shared-link.service.ts b/web/src/lib/services/shared-link.service.ts index 3ce6f4222d..4e6a942682 100644 --- a/web/src/lib/services/shared-link.service.ts +++ b/web/src/lib/services/shared-link.service.ts @@ -16,48 +16,37 @@ import { type SharedLinkEditDto, type SharedLinkResponseDto, } from '@immich/sdk'; -import { MenuItemType, menuManager, modalManager, toastManager, type MenuItem } from '@immich/ui'; -import { mdiCircleEditOutline, mdiContentCopy, mdiDelete, mdiDotsVertical, mdiQrcode } from '@mdi/js'; +import { modalManager, toastManager, type ActionItem } from '@immich/ui'; +import { mdiContentCopy, mdiPencilOutline, mdiQrcode, mdiTrashCanOutline } from '@mdi/js'; import type { MessageFormatter } from 'svelte-i18n'; export const getSharedLinkActions = ($t: MessageFormatter, sharedLink: SharedLinkResponseDto) => { - const Edit: MenuItem = { + const Edit: ActionItem = { title: $t('edit_link'), - icon: mdiCircleEditOutline, - onSelect: () => void goto(`${AppRoute.SHARED_LINKS}/${sharedLink.id}`), + icon: mdiPencilOutline, + onAction: () => void goto(`${AppRoute.SHARED_LINKS}/${sharedLink.id}`), }; - const Delete: MenuItem = { + const Delete: ActionItem = { title: $t('delete_link'), - icon: mdiDelete, + icon: mdiTrashCanOutline, color: 'danger', - onSelect: () => void handleDeleteSharedLink(sharedLink), + onAction: () => void handleDeleteSharedLink(sharedLink), }; - const Copy: MenuItem = { + const Copy: ActionItem = { title: $t('copy_link'), icon: mdiContentCopy, - onSelect: () => void copyToClipboard(asUrl(sharedLink)), + onAction: () => void copyToClipboard(asUrl(sharedLink)), }; - const ViewQrCode: MenuItem = { + const ViewQrCode: ActionItem = { title: $t('view_qr_code'), icon: mdiQrcode, - onSelect: () => void handleShowSharedLinkQrCode(sharedLink), + onAction: () => void handleShowSharedLinkQrCode(sharedLink), }; - const ContextMenu: MenuItem = { - title: $t('shared_link_options'), - icon: mdiDotsVertical, - onSelect: ({ event }) => - void menuManager.show({ - target: event.currentTarget as HTMLElement, - position: 'top-right', - items: [Edit, Copy, MenuItemType.Divider, Delete], - }), - }; - - return { Edit, Delete, Copy, ViewQrCode, ContextMenu }; + return { Edit, Delete, Copy, ViewQrCode }; }; const asUrl = (sharedLink: SharedLinkResponseDto) => { diff --git a/web/src/lib/services/system-config.service.ts b/web/src/lib/services/system-config.service.ts index b555c425ef..ffd0094c72 100644 --- a/web/src/lib/services/system-config.service.ts +++ b/web/src/lib/services/system-config.service.ts @@ -1,12 +1,11 @@ import { downloadManager } from '$lib/managers/download-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; -import type { ActionItem } from '$lib/types'; import { copyToClipboard } from '$lib/utils'; import { downloadBlob } from '$lib/utils/asset-utils'; import { handleError } from '$lib/utils/handle-error'; import { getFormatter } from '$lib/utils/i18n'; import { getConfig, updateConfig, type ServerFeaturesDto, type SystemConfigDto } from '@immich/sdk'; -import { toastManager } from '@immich/ui'; +import { toastManager, type ActionItem } from '@immich/ui'; import { mdiContentCopy, mdiDownload, mdiUpload } from '@mdi/js'; import { isEqual } from 'lodash-es'; import type { MessageFormatter } from 'svelte-i18n'; @@ -18,21 +17,33 @@ export const getSystemConfigActions = ( ) => { const CopyToClipboard: ActionItem = { title: $t('copy_to_clipboard'), + description: $t('admin.copy_config_to_clipboard_description'), + type: $t('command'), icon: mdiContentCopy, - onSelect: () => void handleCopyToClipboard(config), + onAction: () => void handleCopyToClipboard(config), + shortcuts: { shift: true, key: 'c' }, }; const Download: ActionItem = { title: $t('export_as_json'), + description: $t('admin.export_config_as_json_description'), + type: $t('command'), icon: mdiDownload, - onSelect: () => handleDownloadConfig(config), + onAction: () => handleDownloadConfig(config), + shortcuts: [ + { shift: true, key: 's' }, + { shift: true, key: 'd' }, + ], }; const Upload: ActionItem = { title: $t('import_from_json'), + description: $t('admin.import_config_from_json_description'), + type: $t('command'), icon: mdiUpload, $if: () => !featureFlags.configFile, - onSelect: () => handleUploadConfig(), + onAction: () => handleUploadConfig(), + shortcuts: { shift: true, key: 'u' }, }; return { CopyToClipboard, Download, Upload }; diff --git a/web/src/lib/services/user-admin.service.ts b/web/src/lib/services/user-admin.service.ts index 93b8800b11..7a49f2fbe3 100644 --- a/web/src/lib/services/user-admin.service.ts +++ b/web/src/lib/services/user-admin.service.ts @@ -1,13 +1,11 @@ import { goto } from '$app/navigation'; import { eventManager } from '$lib/managers/event-manager.svelte'; -import { serverConfigManager } from '$lib/managers/server-config-manager.svelte'; import PasswordResetSuccessModal from '$lib/modals/PasswordResetSuccessModal.svelte'; import UserCreateModal from '$lib/modals/UserCreateModal.svelte'; import UserDeleteConfirmModal from '$lib/modals/UserDeleteConfirmModal.svelte'; import UserEditModal from '$lib/modals/UserEditModal.svelte'; import UserRestoreConfirmModal from '$lib/modals/UserRestoreConfirmModal.svelte'; import { user as authUser } from '$lib/stores/user.store'; -import type { ActionItem } from '$lib/types'; import { handleError } from '$lib/utils/handle-error'; import { getFormatter } from '$lib/utils/i18n'; import { @@ -21,101 +19,72 @@ import { type UserAdminResponseDto, type UserAdminUpdateDto, } from '@immich/sdk'; -import { MenuItemType, menuManager, modalManager, toastManager } from '@immich/ui'; +import { modalManager, toastManager, type ActionItem } from '@immich/ui'; import { mdiDeleteRestore, - mdiDotsVertical, - mdiEyeOutline, mdiLockReset, mdiLockSmart, mdiPencilOutline, mdiPlusBoxOutline, mdiTrashCanOutline, } from '@mdi/js'; -import { DateTime } from 'luxon'; import type { MessageFormatter } from 'svelte-i18n'; import { get } from 'svelte/store'; -const getDeleteDate = (deletedAt: string): Date => - DateTime.fromISO(deletedAt).plus({ days: serverConfigManager.value.userDeleteDelay }).toJSDate(); - export const getUserAdminsActions = ($t: MessageFormatter) => { const Create: ActionItem = { title: $t('create_user'), + type: $t('command'), icon: mdiPlusBoxOutline, - onSelect: () => void modalManager.show(UserCreateModal, {}), + onAction: () => void modalManager.show(UserCreateModal, {}), + shortcuts: { shift: true, key: 'n' }, }; return { Create }; }; export const getUserAdminActions = ($t: MessageFormatter, user: UserAdminResponseDto) => { - const View: ActionItem = { - icon: mdiEyeOutline, - title: $t('view'), - onSelect: () => void goto(`/admin/users/${user.id}`), - }; - const Update: ActionItem = { icon: mdiPencilOutline, title: $t('edit'), - onSelect: () => void modalManager.show(UserEditModal, { user }), + onAction: () => modalManager.show(UserEditModal, { user }), }; const Delete: ActionItem = { icon: mdiTrashCanOutline, title: $t('delete'), + type: $t('command'), color: 'danger', $if: () => get(authUser).id !== user.id && !user.deletedAt, - onSelect: () => void modalManager.show(UserDeleteConfirmModal, { user }), + onAction: () => modalManager.show(UserDeleteConfirmModal, { user }), + shortcuts: { key: 'Backspace' }, }; const Restore: ActionItem = { icon: mdiDeleteRestore, title: $t('restore'), + type: $t('command'), color: 'primary', $if: () => !!user.deletedAt && user.status === UserStatus.Deleted, - onSelect: () => void modalManager.show(UserRestoreConfirmModal, { user }), - props: { - title: $t('admin.user_restore_scheduled_removal', { - values: { date: getDeleteDate(user.deletedAt!) }, - }), - }, + onAction: () => modalManager.show(UserRestoreConfirmModal, { user }), }; const ResetPassword: ActionItem = { icon: mdiLockReset, title: $t('reset_password'), + type: $t('command'), $if: () => get(authUser).id !== user.id, - onSelect: () => void handleResetPasswordUserAdmin(user), + onAction: () => void handleResetPasswordUserAdmin(user), }; const ResetPinCode: ActionItem = { icon: mdiLockSmart, + type: $t('command'), title: $t('reset_pin_code'), - onSelect: () => void handleResetPinCodeUserAdmin(user), + onAction: () => void handleResetPinCodeUserAdmin(user), }; - const ContextMenu: ActionItem = { - icon: mdiDotsVertical, - title: $t('actions'), - onSelect: ({ event }) => - void menuManager.show({ - target: event.currentTarget as HTMLElement, - position: 'top-right', - items: [ - View, - Update, - ResetPassword, - ResetPinCode, - get(authUser).id === user.id ? undefined : MenuItemType.Divider, - Restore, - Delete, - ].filter(Boolean), - }), - }; - - return { View, Update, Delete, Restore, ResetPassword, ResetPinCode, ContextMenu }; + return { Update, Delete, Restore, ResetPassword, ResetPinCode }; }; export const handleCreateUserAdmin = async (dto: UserAdminCreateDto) => { @@ -172,6 +141,10 @@ export const handleRestoreUserAdmin = async (user: UserAdminResponseDto) => { } }; +export const handleNavigateUserAdmin = async (user: UserAdminResponseDto) => { + await goto(`/admin/users/${user.id}`); +}; + // TODO move password reset server-side const generatePassword = (length: number = 16) => { let generatedPassword = ''; diff --git a/web/src/lib/sidebars/AdminSidebar.svelte b/web/src/lib/sidebars/AdminSidebar.svelte index 2fecaebf49..919c072527 100644 --- a/web/src/lib/sidebars/AdminSidebar.svelte +++ b/web/src/lib/sidebars/AdminSidebar.svelte @@ -2,16 +2,16 @@ import BottomInfo from '$lib/components/shared-components/side-bar/bottom-info.svelte'; import { AppRoute } from '$lib/constants'; import { NavbarItem } from '@immich/ui'; - import { mdiAccountMultipleOutline, mdiBookshelf, mdiCog, mdiServer, mdiSync } from '@mdi/js'; + import { mdiAccountMultipleOutline, mdiBookshelf, mdiCog, mdiServer, mdiTrayFull } from '@mdi/js'; import { t } from 'svelte-i18n';
- - + +
diff --git a/web/src/lib/stores/maintenance.store.ts b/web/src/lib/stores/maintenance.store.ts new file mode 100644 index 0000000000..9680a06366 --- /dev/null +++ b/web/src/lib/stores/maintenance.store.ts @@ -0,0 +1,4 @@ +import { type MaintenanceAuthDto } from '@immich/sdk'; +import { writable } from 'svelte/store'; + +export const maintenanceAuth = writable(); diff --git a/web/src/lib/stores/ocr.svelte.ts b/web/src/lib/stores/ocr.svelte.ts new file mode 100644 index 0000000000..f9862b1edc --- /dev/null +++ b/web/src/lib/stores/ocr.svelte.ts @@ -0,0 +1,46 @@ +import { getAssetOcr } from '@immich/sdk'; + +export type OcrBoundingBox = { + id: string; + assetId: string; + x1: number; + y1: number; + x2: number; + y2: number; + x3: number; + y3: number; + x4: number; + y4: number; + boxScore: number; + textScore: number; + text: string; +}; + +class OcrManager { + #data = $state([]); + showOverlay = $state(false); + #hasOcrData = $derived(this.#data.length > 0); + + get data() { + return this.#data; + } + + get hasOcrData() { + return this.#hasOcrData; + } + + async getAssetOcr(id: string) { + this.#data = await getAssetOcr({ id }); + } + + clear() { + this.#data = []; + this.showOverlay = false; + } + + toggleOcrBoundingBox() { + this.showOverlay = !this.showOverlay; + } +} + +export const ocrManager = new OcrManager(); diff --git a/web/src/lib/stores/websocket.ts b/web/src/lib/stores/websocket.ts index c543fdb4ff..534fcd6a48 100644 --- a/web/src/lib/stores/websocket.ts +++ b/web/src/lib/stores/websocket.ts @@ -1,18 +1,19 @@ +import { page } from '$app/state'; +import { AppRoute } from '$lib/constants'; import { authManager } from '$lib/managers/auth-manager.svelte'; +import { eventManager } from '$lib/managers/event-manager.svelte'; import { notificationManager } from '$lib/stores/notification-manager.svelte'; +import type { ReleaseEvent } from '$lib/types'; import { createEventEmitter } from '$lib/utils/eventemitter'; import { type AssetResponseDto, type NotificationDto, type ServerVersionResponseDto } from '@immich/sdk'; import { io, type Socket } from 'socket.io-client'; import { get, writable } from 'svelte/store'; import { user } from './user.store'; -export interface ReleaseEvent { - isAvailable: boolean; - /** ISO8601 */ - checkedAt: string; - serverVersion: ServerVersionResponseDto; - releaseVersion: ServerVersionResponseDto; +interface AppRestartEvent { + isMaintenanceMode: boolean; } + export interface Events { on_upload_success: (asset: AssetResponseDto) => void; on_user_delete: (id: string) => void; @@ -25,9 +26,11 @@ export interface Events { on_person_thumbnail: (personId: string) => void; on_server_version: (serverVersion: ServerVersionResponseDto) => void; on_config_update: () => void; - on_new_release: (newRelease: ReleaseEvent) => void; + on_new_release: (event: ReleaseEvent) => void; on_session_delete: (sessionId: string) => void; on_notification: (notification: NotificationDto) => void; + + AppRestartV1: (event: AppRestartEvent) => void; } const websocket: Socket = io({ @@ -41,7 +44,7 @@ const websocket: Socket = io({ export const websocketStore = { connected: writable(false), serverVersion: writable(), - release: writable(), + serverRestarting: writable(), }; export const websocketEvents = createEventEmitter(websocket); @@ -50,18 +53,18 @@ websocket .on('connect', () => websocketStore.connected.set(true)) .on('disconnect', () => websocketStore.connected.set(false)) .on('on_server_version', (serverVersion) => websocketStore.serverVersion.set(serverVersion)) - .on('on_new_release', (releaseVersion) => websocketStore.release.set(releaseVersion)) + .on('AppRestartV1', (mode) => websocketStore.serverRestarting.set(mode)) + .on('on_new_release', (event) => eventManager.emit('ReleaseEvent', event)) .on('on_session_delete', () => authManager.logout()) + .on('on_user_delete', (id) => eventManager.emit('UserAdminDeleted', { id })) .on('on_notification', () => notificationManager.refresh()) .on('connect_error', (e) => console.log('Websocket Connect Error', e)); export const openWebsocketConnection = () => { try { - if (!get(user)) { - return; + if (get(user) || page.url.pathname.startsWith(AppRoute.MAINTENANCE)) { + websocket.connect(); } - - websocket.connect(); } catch (error) { console.log('Cannot connect to websocket', error); } diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index 960158a0f7..e7d38b1a25 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -1,4 +1,11 @@ -import type { MenuItem } from '@immich/ui'; -import type { HTMLAttributes } from 'svelte/elements'; +import type { QueueResponseDto, ServerVersionResponseDto } from '@immich/sdk'; -export type ActionItem = MenuItem & { props?: Omit, 'color'> }; +export interface ReleaseEvent { + isAvailable: boolean; + /** ISO8601 */ + checkedAt: string; + serverVersion: ServerVersionResponseDto; + releaseVersion: ServerVersionResponseDto; +} + +export type QueueSnapshot = { timestamp: number; snapshot?: QueueResponseDto[] }; diff --git a/web/src/lib/utils/actions.ts b/web/src/lib/utils/actions.ts index af79527841..05de75d3bc 100644 --- a/web/src/lib/utils/actions.ts +++ b/web/src/lib/utils/actions.ts @@ -79,14 +79,15 @@ const undoDeleteAssets = async (onUndoDelete: OnUndoDelete, assets: TimelineAsse */ export function updateStackedAssetInTimeline(timelineManager: TimelineManager, { stack, toDeleteIds }: StackResponse) { if (stack != undefined) { - timelineManager.updateAssetOperation([stack.primaryAssetId], (asset) => { - asset.stack = { - id: stack.id, - primaryAssetId: stack.primaryAssetId, - assetCount: stack.assets.length, - }; - return { remove: false }; - }); + timelineManager.update( + [stack.primaryAssetId], + (asset) => + (asset.stack = { + id: stack.id, + primaryAssetId: stack.primaryAssetId, + assetCount: stack.assets.length, + }), + ); timelineManager.removeAssets(toDeleteIds); } @@ -101,7 +102,7 @@ export function updateStackedAssetInTimeline(timelineManager: TimelineManager, { * @param assets - The array of asset response DTOs to update in the timeline manager. */ export function updateUnstackedAssetInTimeline(timelineManager: TimelineManager, assets: TimelineAsset[]) { - timelineManager.updateAssetOperation( + timelineManager.update( assets.map((asset) => asset.id), (asset) => { asset.stack = null; @@ -109,5 +110,5 @@ export function updateUnstackedAssetInTimeline(timelineManager: TimelineManager, }, ); - timelineManager.addAssets(assets); + timelineManager.upsertAssets(assets); } diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts index dc572b541a..bc853c53e4 100644 --- a/web/src/lib/utils/asset-utils.ts +++ b/web/src/lib/utils/asset-utils.ts @@ -3,7 +3,7 @@ import ToastAction from '$lib/components/ToastAction.svelte'; import { AppRoute } from '$lib/constants'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { downloadManager } from '$lib/managers/download-manager.svelte'; -import type { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; +import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte'; import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts index 3f602bdb29..516d682625 100644 --- a/web/src/lib/utils/file-uploader.ts +++ b/web/src/lib/utils/file-uploader.ts @@ -12,7 +12,6 @@ import { AssetMediaStatus, AssetVisibility, checkBulkUpload, - getAssetOriginalPath, getBaseUrl, type AssetMediaResponseDto, } from '@immich/sdk'; @@ -44,12 +43,10 @@ export const addDummyItems = () => { export const uploadExecutionQueue = new ExecutorQueue({ concurrency: 2 }); -type FileUploadParam = { multiple?: boolean } & ( - | { albumId?: string; assetId?: never } - | { albumId?: never; assetId?: string } -); +type FileUploadParam = { multiple?: boolean; albumId?: string }; + export const openFileUploadDialog = async (options: FileUploadParam = {}) => { - const { albumId, multiple = true, assetId } = options; + const { albumId, multiple = true } = options; const extensions = uploadManager.getExtensions(); return new Promise((resolve, reject) => { @@ -68,7 +65,7 @@ export const openFileUploadDialog = async (options: FileUploadParam = {}) => { } const files = Array.from(target.files); - resolve(fileUploadHandler({ files, albumId, replaceAssetId: assetId })); + resolve(fileUploadHandler({ files, albumId })); }, { passive: true }, ); @@ -88,7 +85,6 @@ type FileUploadHandlerParams = Omit => { const extensions = uploadManager.getExtensions(); @@ -99,9 +95,7 @@ export const fileUploadHandler = async ({ const deviceAssetId = getDeviceAssetId(file); uploadAssetsStore.addItem({ id: deviceAssetId, file, albumId }); promises.push( - uploadExecutionQueue.addTask(() => - fileUploader({ assetFile: file, deviceAssetId, albumId, replaceAssetId, isLockedAssets }), - ), + uploadExecutionQueue.addTask(() => fileUploader({ assetFile: file, deviceAssetId, albumId, isLockedAssets })), ); } } @@ -127,7 +121,6 @@ async function fileUploader({ assetFile, deviceAssetId, albumId, - replaceAssetId, isLockedAssets = false, }: FileUploaderParams): Promise { const fileCreatedAt = new Date(assetFile.lastModified).toISOString(); @@ -183,27 +176,17 @@ async function fileUploader({ const queryParams = asQueryString(authManager.params); uploadAssetsStore.updateItem(deviceAssetId, { message: $t('asset_uploading') }); - if (replaceAssetId) { - const response = await uploadRequest({ - url: getBaseUrl() + getAssetOriginalPath(replaceAssetId) + (queryParams ? `?${queryParams}` : ''), - method: 'PUT', - data: formData, - onUploadProgress: (event) => uploadAssetsStore.updateProgress(deviceAssetId, event.loaded, event.total), - }); - responseData = response.data; - } else { - const response = await uploadRequest({ - url: getBaseUrl() + '/assets' + (queryParams ? `?${queryParams}` : ''), - data: formData, - onUploadProgress: (event) => uploadAssetsStore.updateProgress(deviceAssetId, event.loaded, event.total), - }); + const response = await uploadRequest({ + url: getBaseUrl() + '/assets' + (queryParams ? `?${queryParams}` : ''), + data: formData, + onUploadProgress: (event) => uploadAssetsStore.updateProgress(deviceAssetId, event.loaded, event.total), + }); - if (![200, 201].includes(response.status)) { - throw new Error($t('errors.unable_to_upload_file')); - } - - responseData = response.data; + if (![200, 201].includes(response.status)) { + throw new Error($t('errors.unable_to_upload_file')); } + + responseData = response.data; } if (responseData.status === AssetMediaStatus.Duplicate) { diff --git a/web/src/lib/utils/maintenance.ts b/web/src/lib/utils/maintenance.ts new file mode 100644 index 0000000000..f3d8bd1cbb --- /dev/null +++ b/web/src/lib/utils/maintenance.ts @@ -0,0 +1,33 @@ +import { AppRoute } from '$lib/constants'; +import { maintenanceAuth as maintenanceAuth$ } from '$lib/stores/maintenance.store'; +import { maintenanceLogin } from '@immich/sdk'; + +export function maintenanceCreateUrl(url: URL) { + const target = new URL(AppRoute.MAINTENANCE, url.origin); + target.searchParams.set('continue', url.pathname + url.search); + return target.href; +} + +export function maintenanceReturnUrl(searchParams: URLSearchParams) { + return searchParams.get('continue') ?? '/'; +} + +export function maintenanceShouldRedirect(maintenanceMode: boolean, currentUrl: URL | Location) { + return maintenanceMode !== currentUrl.pathname.startsWith(AppRoute.MAINTENANCE); +} + +export const loadMaintenanceAuth = async () => { + const query = new URLSearchParams(location.search); + + try { + const auth = await maintenanceLogin({ + maintenanceLoginDto: { + token: query.get('token') ?? undefined, + }, + }); + + maintenanceAuth$.set(auth); + } catch { + // silently fail + } +}; diff --git a/web/src/lib/utils/ocr-utils.ts b/web/src/lib/utils/ocr-utils.ts new file mode 100644 index 0000000000..97364d06f5 --- /dev/null +++ b/web/src/lib/utils/ocr-utils.ts @@ -0,0 +1,131 @@ +import type { OcrBoundingBox } from '$lib/stores/ocr.svelte'; +import type { ZoomImageWheelState } from '@zoom-image/core'; + +const getContainedSize = (img: HTMLImageElement): { width: number; height: number } => { + const ratio = img.naturalWidth / img.naturalHeight; + let width = img.height * ratio; + let height = img.height; + if (width > img.width) { + width = img.width; + height = img.width / ratio; + } + return { width, height }; +}; + +export interface OcrBox { + id: string; + points: { x: number; y: number }[]; + text: string; + confidence: number; +} + +export interface BoundingBoxDimensions { + minX: number; + maxX: number; + minY: number; + maxY: number; + width: number; + height: number; + centerX: number; + centerY: number; + rotation: number; + skewX: number; + skewY: number; +} + +/** + * Calculate bounding box dimensions and properties from OCR points + * @param points - Array of 4 corner points of the bounding box + * @returns Dimensions, rotation, and skew values for the bounding box + */ +export const calculateBoundingBoxDimensions = (points: { x: number; y: number }[]): BoundingBoxDimensions => { + const [topLeft, topRight, bottomRight, bottomLeft] = points; + const minX = Math.min(...points.map(({ x }) => x)); + const maxX = Math.max(...points.map(({ x }) => x)); + const minY = Math.min(...points.map(({ y }) => y)); + const maxY = Math.max(...points.map(({ y }) => y)); + const width = maxX - minX; + const height = maxY - minY; + const centerX = (minX + maxX) / 2; + const centerY = (minY + maxY) / 2; + + // Calculate rotation angle from the bottom edge (bottomLeft to bottomRight) + const rotation = Math.atan2(bottomRight.y - bottomLeft.y, bottomRight.x - bottomLeft.x) * (180 / Math.PI); + + // Calculate skew angles to handle perspective distortion + // SkewX: compare left and right edges + const leftEdgeAngle = Math.atan2(bottomLeft.y - topLeft.y, bottomLeft.x - topLeft.x); + const rightEdgeAngle = Math.atan2(bottomRight.y - topRight.y, bottomRight.x - topRight.x); + const skewX = (rightEdgeAngle - leftEdgeAngle) * (180 / Math.PI); + + // SkewY: compare top and bottom edges + const topEdgeAngle = Math.atan2(topRight.y - topLeft.y, topRight.x - topLeft.x); + const bottomEdgeAngle = Math.atan2(bottomRight.y - bottomLeft.y, bottomRight.x - bottomLeft.x); + const skewY = (bottomEdgeAngle - topEdgeAngle) * (180 / Math.PI); + + return { + minX, + maxX, + minY, + maxY, + width, + height, + centerX, + centerY, + rotation, + skewX, + skewY, + }; +}; + +/** + * Convert normalized OCR coordinates to screen coordinates + * OCR coordinates are normalized (0-1) and represent the 4 corners of a rotated rectangle + */ +export const getOcrBoundingBoxes = ( + ocrData: OcrBoundingBox[], + zoom: ZoomImageWheelState, + photoViewer: HTMLImageElement | null, +): OcrBox[] => { + const boxes: OcrBox[] = []; + + if (photoViewer === null || !photoViewer.naturalWidth || !photoViewer.naturalHeight) { + return boxes; + } + + const clientHeight = photoViewer.clientHeight; + const clientWidth = photoViewer.clientWidth; + const { width, height } = getContainedSize(photoViewer); + + const imageWidth = photoViewer.naturalWidth; + const imageHeight = photoViewer.naturalHeight; + + for (const ocr of ocrData) { + // Convert normalized coordinates (0-1) to actual pixel positions + // OCR provides 4 corners of a potentially rotated rectangle + const points = [ + { x: ocr.x1, y: ocr.y1 }, + { x: ocr.x2, y: ocr.y2 }, + { x: ocr.x3, y: ocr.y3 }, + { x: ocr.x4, y: ocr.y4 }, + ].map((point) => ({ + x: + (width / imageWidth) * zoom.currentZoom * point.x * imageWidth + + ((clientWidth - width) / 2) * zoom.currentZoom + + zoom.currentPositionX, + y: + (height / imageHeight) * zoom.currentZoom * point.y * imageHeight + + ((clientHeight - height) / 2) * zoom.currentZoom + + zoom.currentPositionY, + })); + + boxes.push({ + id: ocr.id, + points, + text: ocr.text, + confidence: ocr.textScore, + }); + } + + return boxes; +}; diff --git a/web/src/lib/utils/server.ts b/web/src/lib/utils/server.ts index 046ee496a8..50fe4d72fe 100644 --- a/web/src/lib/utils/server.ts +++ b/web/src/lib/utils/server.ts @@ -12,8 +12,11 @@ async function _init(fetch: Fetch) { // https://github.com/oazapfts/oazapfts/blob/main/README.md#fetch-options defaults.fetch = fetch; await initLanguage(); - await featureFlagsManager.init(); await serverConfigManager.init(); + + if (!serverConfigManager.value.maintenanceMode) { + await featureFlagsManager.init(); + } } export const init = memoize(_init, () => 'singlevalue'); diff --git a/web/src/lib/utils/tree-utils.ts b/web/src/lib/utils/tree-utils.ts index 267bb2eec7..64b51158c4 100644 --- a/web/src/lib/utils/tree-utils.ts +++ b/web/src/lib/utils/tree-utils.ts @@ -62,8 +62,16 @@ export class TreeNode extends Map { const child = this.values().next().value!; child.value = joinPaths(this.value, child.value); child.parent = this.parent; - this.parent.delete(this.value); - this.parent.set(child.value, child); + + const entries = Array.from(this.parent.entries()); + this.parent.clear(); + for (const [key, value] of entries) { + if (key === this.value) { + this.parent.set(child.value, child); + } else { + this.parent.set(key, value); + } + } } for (const child of this.values()) { diff --git a/web/src/routes/(user)/+layout.svelte b/web/src/routes/(user)/+layout.svelte index ea10c45444..e6e349fe91 100644 --- a/web/src/routes/(user)/+layout.svelte +++ b/web/src/routes/(user)/+layout.svelte @@ -1,8 +1,6 @@ diff --git a/web/src/routes/(user)/albums/+page.svelte b/web/src/routes/(user)/albums/+page.svelte index cdd13ba938..88bf67ca19 100644 --- a/web/src/routes/(user)/albums/+page.svelte +++ b/web/src/routes/(user)/albums/+page.svelte @@ -52,7 +52,7 @@ bind:albumGroupIds={albumGroups} > {#snippet empty()} - createAlbumAndRedirect()} /> + createAlbumAndRedirect()} class="mt-10 mx-auto" /> {/snippet} diff --git a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte index f3c48b99a4..3f4d3dd39f 100644 --- a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -66,6 +66,8 @@ } from '@immich/sdk'; import { Button, Icon, IconButton, modalManager, toastManager } from '@immich/ui'; import { + mdiAccountEye, + mdiAccountEyeOutline, mdiArrowLeft, mdiCogOutline, mdiDeleteOutline, @@ -101,6 +103,9 @@ let isShowActivity = $state(false); let albumOrder: AssetOrder | undefined = $state(data.album.order); + let timelineManager = $state() as TimelineManager; + let showAlbumUsers = $derived(timelineManager?.showAssetOwners ?? false); + const assetInteraction = new AssetInteraction(); const timelineInteraction = new AssetInteraction(); @@ -244,7 +249,7 @@ }; const handleUndoRemoveAssets = async (assets: TimelineAsset[]) => { - timelineManager.addAssets(assets); + timelineManager.upsertAssets(assets); await refreshAlbum(); }; @@ -290,13 +295,17 @@ let album = $derived(data.album); let albumId = $derived(album.id); + const containsEditors = $derived(album?.shared && album.albumUsers.some(({ role }) => role === AlbumUserRole.Editor)); + const albumUsers = $derived( + showAlbumUsers && containsEditors ? [album.owner, ...album.albumUsers.map(({ user }) => user)] : [], + ); + $effect(() => { if (!album.isActivityEnabled && activityManager.commentCount === 0) { isShowActivity = false; } }); - let timelineManager = $state() as TimelineManager; const options = $derived.by(() => { if (viewMode === AlbumPageViewMode.SELECT_ASSETS) { return { @@ -418,6 +427,7 @@ - timelineManager.updateAssetOperation(ids, (asset) => { - asset.isFavorite = isFavorite; - return { remove: false }; - })} + onFavorite={(ids, isFavorite) => timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} > {/if} @@ -567,7 +573,11 @@ onClick={() => updateThumbnailUsingCurrentSelection()} /> {/if} - + timelineManager.update(ids, (asset) => (asset.visibility = visibility))} + /> {/if} @@ -649,6 +659,13 @@ color="secondary" offset={{ x: 175, y: 25 }} > + {#if containsEditors} + timelineManager.toggleShowAssetOwners()} + /> + {/if} {#if album.assetCount > 0} {#snippet empty()} - + {/snippet} @@ -66,11 +66,7 @@ > - timelineManager.updateAssetOperation(ids, (asset) => { - asset.visibility = visibility; - return { remove: false }; - })} + onArchive={(ids, visibility) => timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> @@ -80,11 +76,7 @@ - timelineManager.updateAssetOperation(ids, (asset) => { - asset.isFavorite = isFavorite; - return { remove: false }; - })} + onFavorite={(ids, isFavorite) => timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} /> diff --git a/web/src/routes/(user)/explore/+page.svelte b/web/src/routes/(user)/explore/+page.svelte index 86fb0850af..89505249b4 100644 --- a/web/src/routes/(user)/explore/+page.svelte +++ b/web/src/routes/(user)/explore/+page.svelte @@ -114,6 +114,6 @@ {/if} {#if !hasPeople && places.length === 0} - + {/if} diff --git a/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte index 676a68e673..781dc80ec8 100644 --- a/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -59,7 +59,7 @@ onEscape={handleEscape} > {#snippet empty()} - + {/snippet} @@ -85,7 +85,7 @@ timelineManager.removeAssets(assetIds)} + onArchive={(ids, visibility) => timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> {#if $preferences.tags.enabled} @@ -94,7 +94,7 @@ timelineManager.removeAssets(assetIds)} - onUndoDelete={(assets) => timelineManager.addAssets(assets)} + onUndoDelete={(assets) => timelineManager.upsertAssets(assets)} /> diff --git a/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte index 510b609784..b16018bbf4 100644 --- a/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -65,7 +65,7 @@ removeAction={AssetAction.SET_VISIBILITY_TIMELINE} > {#snippet empty()} - + {/snippet} diff --git a/web/src/routes/(user)/map/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/map/[[photos=photos]]/[[assetId=id]]/+page.svelte index dd5cbe8b8f..fd443a6470 100644 --- a/web/src/routes/(user)/map/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/map/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -1,6 +1,7 @@ + + + {page.data.meta?.title || 'Web'} - Immich diff --git a/web/src/routes/+layout.ts b/web/src/routes/+layout.ts index b5edece09e..ab4b91f9cc 100644 --- a/web/src/routes/+layout.ts +++ b/web/src/routes/+layout.ts @@ -1,17 +1,29 @@ +import { goto } from '$app/navigation'; +import { serverConfigManager } from '$lib/managers/server-config-manager.svelte'; +import { maintenanceCreateUrl, maintenanceReturnUrl, maintenanceShouldRedirect } from '$lib/utils/maintenance'; import { init } from '$lib/utils/server'; +import { commandPaletteManager } from '@immich/ui'; import type { LayoutLoad } from './$types'; export const ssr = false; export const csr = true; -export const load = (async ({ fetch }) => { +export const load = (async ({ fetch, url }) => { let error; try { await init(fetch); + + if (maintenanceShouldRedirect(serverConfigManager.value.maintenanceMode, url)) { + await goto( + serverConfigManager.value.maintenanceMode ? maintenanceCreateUrl(url) : maintenanceReturnUrl(url.searchParams), + ); + } } catch (initError) { error = initError; } + commandPaletteManager.enable(); + return { error, meta: { diff --git a/web/src/routes/+page.ts b/web/src/routes/+page.ts index bd6d1a62da..5ff4f58bf6 100644 --- a/web/src/routes/+page.ts +++ b/web/src/routes/+page.ts @@ -12,6 +12,11 @@ export const csr = true; export const load = (async ({ fetch }) => { try { await init(fetch); + + if (serverConfigManager.value.maintenanceMode) { + redirect(302, AppRoute.MAINTENANCE); + } + const authenticated = await loadUser(); if (authenticated) { redirect(302, AppRoute.PHOTOS); diff --git a/web/src/routes/admin/jobs-status/+page.svelte b/web/src/routes/admin/jobs-status/+page.svelte deleted file mode 100644 index 84586a8af0..0000000000 --- a/web/src/routes/admin/jobs-status/+page.svelte +++ /dev/null @@ -1,98 +0,0 @@ - - - - {#snippet buttons()} - - {#if pausedJobs.length > 0} - - {/if} - - - - {/snippet} -
-
- {#if jobs} - - {/if} -
-
-
diff --git a/web/src/routes/admin/jobs-status/+page.ts b/web/src/routes/admin/jobs-status/+page.ts index 90057ff969..92971ccd9a 100644 --- a/web/src/routes/admin/jobs-status/+page.ts +++ b/web/src/routes/admin/jobs-status/+page.ts @@ -1,18 +1,5 @@ -import { authenticate } from '$lib/utils/auth'; -import { getFormatter } from '$lib/utils/i18n'; -import { getQueuesLegacy } from '@immich/sdk'; +import { AppRoute } from '$lib/constants'; +import { redirect } from '@sveltejs/kit'; import type { PageLoad } from './$types'; -export const load = (async ({ url }) => { - await authenticate(url, { admin: true }); - - const jobs = await getQueuesLegacy(); - const $t = await getFormatter(); - - return { - jobs, - meta: { - title: $t('admin.job_status'), - }, - }; -}) satisfies PageLoad; +export const load = (() => redirect(307, AppRoute.ADMIN_QUEUES)) satisfies PageLoad; diff --git a/web/src/routes/admin/library-management/+page.svelte b/web/src/routes/admin/library-management/+page.svelte index 600b6ff048..aef8447d00 100644 --- a/web/src/routes/admin/library-management/+page.svelte +++ b/web/src/routes/admin/library-management/+page.svelte @@ -1,36 +1,17 @@ - + + + + + {#snippet buttons()}
- {#if libraries.length > 0} - - {/if} - + +
{/snippet}
-
+
{#if libraries.length > 0} - +
@@ -276,91 +84,36 @@ - {#each libraries as library, index (library.id)} + {#each libraries as library (library.id + library.name)} + {@const { photos, usage, videos } = statistics[library.id]} + {@const [diskUsage, diskUsageUnit] = getBytesWithUnit(usage, 0)} - - {#if editImportPaths === index} - -
- handleUpdate(lib, index)} - onCancel={() => (editImportPaths = undefined)} - /> -
- {/if} - {#if editScanSettings === index} - -
- handleUpdate(lib, index)} - onCancel={() => (editScanSettings = undefined)} - /> -
- {/if} {/each}
{library.name} - {#if owner[index] == undefined} - - {:else}{owner[index].name}{/if} + {owners[library.id].name} - {#if photos[index] == undefined} - - {:else} - {photos[index].toLocaleString($locale)} - {/if} + {photos.toLocaleString($locale)} - {#if videos[index] == undefined} - - {:else} - {videos[index].toLocaleString($locale)} - {/if} + {videos.toLocaleString($locale)} - {#if diskUsage[index] == undefined} - - {:else} - {diskUsage[index]} - {diskUsageUnit[index]} - {/if} + {diskUsage} + {diskUsageUnit} - - onScanClicked(library)} text={$t('scan_library')} /> -
- onRenameClicked(index)} text={$t('rename')} /> - onEditImportPathClicked(index)} text={$t('edit_import_paths')} /> - onScanSettingClicked(index)} text={$t('scan_settings')} /> -
- handleDelete(library, index)} - activeColor="bg-red-200" - textColor="text-red-600" - text={$t('delete_library')} - /> -
+
+
- - {:else} - + {/if}
diff --git a/web/src/routes/admin/library-management/+page.ts b/web/src/routes/admin/library-management/+page.ts index 735c7fac92..cb7190b0e4 100644 --- a/web/src/routes/admin/library-management/+page.ts +++ b/web/src/routes/admin/library-management/+page.ts @@ -1,6 +1,6 @@ import { authenticate, requestServerInfo } from '$lib/utils/auth'; import { getFormatter } from '$lib/utils/i18n'; -import { searchUsersAdmin } from '@immich/sdk'; +import { getAllLibraries, getLibraryStatistics, getUserAdmin, searchUsersAdmin } from '@immich/sdk'; import type { PageLoad } from './$types'; export const load = (async ({ url }) => { @@ -9,8 +9,19 @@ export const load = (async ({ url }) => { const allUsers = await searchUsersAdmin({ withDeleted: false }); const $t = await getFormatter(); + const libraries = await getAllLibraries(); + const statistics = await Promise.all( + libraries.map(async ({ id }) => [id, await getLibraryStatistics({ id })] as const), + ); + const owners = await Promise.all( + libraries.map(async ({ id, ownerId }) => [id, await getUserAdmin({ id: ownerId })] as const), + ); + return { allUsers, + libraries, + statistics: Object.fromEntries(statistics), + owners: Object.fromEntries(owners), meta: { title: $t('admin.external_library_management'), }, diff --git a/web/src/routes/admin/library-management/[id]/+page.svelte b/web/src/routes/admin/library-management/[id]/+page.svelte new file mode 100644 index 0000000000..db73952b3c --- /dev/null +++ b/web/src/routes/admin/library-management/[id]/+page.svelte @@ -0,0 +1,149 @@ + + + (library = newLibrary)} + onLibraryDelete={({ id }) => id === library.id && goto(AppRoute.ADMIN_LIBRARY_MANAGEMENT)} +/> + + + + + {#snippet buttons()} +
+ + + +
+ {/snippet} + +
+ {library.name} +
+ + + +
+ + +
+
+ + {$t('folders')} +
+ +
+
+ +
+ {#if library.importPaths.length === 0} + modalManager.show(LibraryFolderAddModal, { library })} + /> + {:else} + + + {#each library.importPaths as folder (folder)} + {@const { Edit, Delete } = getLibraryFolderActions($t, library, folder)} + + + + + {/each} + +
+ {folder} + + + +
+ {/if} +
+
+
+ + +
+
+ + {$t('exclusion_pattern')} +
+ +
+
+ +
+ + + {#each library.exclusionPatterns as exclusionPattern (exclusionPattern)} + {@const { Edit, Delete } = getLibraryExclusionPatternActions($t, library, exclusionPattern)} + + + + + {/each} + +
+ {exclusionPattern} + + + +
+
+
+
+
+
+
diff --git a/web/src/routes/admin/library-management/[id]/+page.ts b/web/src/routes/admin/library-management/[id]/+page.ts new file mode 100644 index 0000000000..77ce1eb1c8 --- /dev/null +++ b/web/src/routes/admin/library-management/[id]/+page.ts @@ -0,0 +1,28 @@ +import { AppRoute } from '$lib/constants'; +import { authenticate } from '$lib/utils/auth'; +import { getFormatter } from '$lib/utils/i18n'; +import { getLibrary, getLibraryStatistics, type LibraryResponseDto } from '@immich/sdk'; +import { redirect } from '@sveltejs/kit'; +import type { PageLoad } from './$types'; + +export const load = (async ({ params: { id }, url }) => { + await authenticate(url, { admin: true }); + let library: LibraryResponseDto; + + try { + library = await getLibrary({ id }); + } catch { + redirect(302, AppRoute.ADMIN_LIBRARY_MANAGEMENT); + } + + const statistics = await getLibraryStatistics({ id }); + const $t = await getFormatter(); + + return { + library, + statistics, + meta: { + title: $t('admin.library_details'), + }, + }; +}) satisfies PageLoad; diff --git a/web/src/routes/admin/queues/+page.svelte b/web/src/routes/admin/queues/+page.svelte new file mode 100644 index 0000000000..ae75fa760c --- /dev/null +++ b/web/src/routes/admin/queues/+page.svelte @@ -0,0 +1,83 @@ + + + + + + + + {#snippet buttons()} + + {#if pausedQueues.length > 0} + + {/if} + + + + {/snippet} + +
+
+ {#if queues} + + {/if} +
+
+
diff --git a/web/src/routes/admin/queues/+page.ts b/web/src/routes/admin/queues/+page.ts new file mode 100644 index 0000000000..59aded520a --- /dev/null +++ b/web/src/routes/admin/queues/+page.ts @@ -0,0 +1,18 @@ +import { authenticate } from '$lib/utils/auth'; +import { getFormatter } from '$lib/utils/i18n'; +import { getQueues } from '@immich/sdk'; +import type { PageLoad } from './$types'; + +export const load = (async ({ url }) => { + await authenticate(url, { admin: true }); + + const queues = await getQueues(); + const $t = await getFormatter(); + + return { + queues, + meta: { + title: $t('admin.queues'), + }, + }; +}) satisfies PageLoad; diff --git a/web/src/routes/admin/queues/[name]/+page.svelte b/web/src/routes/admin/queues/[name]/+page.svelte new file mode 100644 index 0000000000..354a5a7057 --- /dev/null +++ b/web/src/routes/admin/queues/[name]/+page.svelte @@ -0,0 +1,82 @@ + + + + + + {#snippet buttons()} + + + + + + + {/snippet} +
+ +
+ {item.title} + {#if queue.isPaused} + + {$t('paused')} + + {/if} +
+ {item.subtitle} + +
+ {$t('active_count', { values: { count: queue.statistics.active } })} + {$t('waiting_count', { values: { count: queue.statistics.waiting } })} + {#if queue.statistics.failed > 0} + {$t('failed_count', { values: { count: queue.statistics.failed } })} + {/if} +
+ +
+ + +
+ + {$t('admin.jobs_over_time')} +
+
+ + + +
+
+
+
+
diff --git a/web/src/routes/admin/queues/[name]/+page.ts b/web/src/routes/admin/queues/[name]/+page.ts new file mode 100644 index 0000000000..3c111abf7c --- /dev/null +++ b/web/src/routes/admin/queues/[name]/+page.ts @@ -0,0 +1,31 @@ +import { AppRoute } from '$lib/constants'; +import { fromQueueSlug } from '$lib/services/queue.service'; +import { authenticate, requestServerInfo } from '$lib/utils/auth'; +import { getFormatter } from '$lib/utils/i18n'; +import { getQueue, getQueueJobs, QueueJobStatus } from '@immich/sdk'; +import { redirect } from '@sveltejs/kit'; +import type { PageLoad } from './$types'; + +export const load = (async ({ params, url }) => { + await authenticate(url, { admin: true }); + await requestServerInfo(); + + const name = fromQueueSlug(params.name); + if (!name) { + redirect(302, AppRoute.ADMIN_QUEUES); + } + + const [queue, failedJobs] = await Promise.all([ + getQueue({ name }), + getQueueJobs({ name, status: [QueueJobStatus.Failed, QueueJobStatus.Paused] }), + ]); + const $t = await getFormatter(); + + return { + queue, + failedJobs, + meta: { + title: $t('admin.queue_details'), + }, + }; +}) satisfies PageLoad; diff --git a/web/src/routes/admin/server-status/+page.svelte b/web/src/routes/admin/server-status/+page.svelte index 433703ae0e..31b193d952 100644 --- a/web/src/routes/admin/server-status/+page.svelte +++ b/web/src/routes/admin/server-status/+page.svelte @@ -1,35 +1,33 @@ - +
- +
diff --git a/web/src/routes/admin/system-settings/+page.svelte b/web/src/routes/admin/system-settings/+page.svelte index 3f3d9a4f83..87faf461c6 100644 --- a/web/src/routes/admin/system-settings/+page.svelte +++ b/web/src/routes/admin/system-settings/+page.svelte @@ -7,6 +7,7 @@ import LibrarySettings from '$lib/components/admin-settings/LibrarySettings.svelte'; import LoggingSettings from '$lib/components/admin-settings/LoggingSettings.svelte'; import MachineLearningSettings from '$lib/components/admin-settings/MachineLearningSettings.svelte'; + import MaintenanceSettings from '$lib/components/admin-settings/MaintenanceSettings.svelte'; import MapSettings from '$lib/components/admin-settings/MapSettings.svelte'; import MetadataSettings from '$lib/components/admin-settings/MetadataSettings.svelte'; import NewVersionCheckSettings from '$lib/components/admin-settings/NewVersionCheckSettings.svelte'; @@ -26,7 +27,7 @@ import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { systemConfigManager } from '$lib/managers/system-config-manager.svelte'; import { getSystemConfigActions } from '$lib/services/system-config.service'; - import { Alert, HStack } from '@immich/ui'; + import { Alert, CommandPaletteContext, HStack } from '@immich/ui'; import { mdiAccountOutline, mdiBackupRestore, @@ -40,6 +41,7 @@ mdiLockOutline, mdiMapMarkerOutline, mdiPaletteOutline, + mdiRestore, mdiRobotOutline, mdiServerOutline, mdiSync, @@ -113,6 +115,13 @@ key: 'machine-learning', icon: mdiRobotOutline, }, + { + component: MaintenanceSettings, + title: $t('admin.maintenance_settings'), + subtitle: $t('admin.maintenance_settings_description'), + key: 'maintenance', + icon: mdiRestore, + }, { component: MapSettings, title: $t('admin.map_gps_settings'), @@ -206,7 +215,9 @@ ); - + + + {#snippet buttons()}