diff --git a/.github/.nvmrc b/.github/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/.github/.nvmrc +++ b/.github/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/.github/workflows/auto-close.yml b/.github/workflows/auto-close.yml index 559cb20e66..dbbb404e9e 100644 --- a/.github/workflows/auto-close.yml +++ b/.github/workflows/auto-close.yml @@ -30,12 +30,17 @@ jobs: while IFS= read -r header; do printf '%s\n' "$BODY" | grep -qF "$header" || OK=false done < <(sed '//d' .github/pull_request_template.md | grep "^## ") - echo "uses_template=$OK" >> "$GITHUB_OUTPUT" + echo "uses_template=$OK" | tee --append "$GITHUB_OUTPUT" close_template: runs-on: ubuntu-latest needs: parse_template - if: ${{ needs.parse_template.outputs.uses_template == 'false' && github.event.pull_request.state != 'closed' }} + if: >- + ${{ + needs.parse_template.outputs.uses_template == 'false' + && github.event.pull_request.state != 'closed' + && !contains(github.event.pull_request.labels.*.name, 'auto-closed:template') + }} permissions: pull-requests: write steps: @@ -66,7 +71,7 @@ jobs: env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} - run: gh pr edit "$PR_NUMBER" --add-label "auto-closed:template" + run: gh pr edit "$PR_NUMBER" --repo "${{ github.repository }}" --add-label "auto-closed:template" close_llm: runs-on: ubuntu-latest @@ -113,7 +118,7 @@ jobs: env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} - run: gh pr edit "$PR_NUMBER" --remove-label "auto-closed:template" || true + run: gh pr edit "$PR_NUMBER" --repo "${{ github.repository }}" --remove-label "auto-closed:template" || true - name: Check for remaining auto-closed labels id: check_labels @@ -121,9 +126,9 @@ jobs: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} run: | - REMAINING=$(gh pr view "$PR_NUMBER" --json labels \ + REMAINING=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json labels \ --jq '[.labels[].name | select(startswith("auto-closed:"))] | length') - echo "remaining=$REMAINING" >> "$GITHUB_OUTPUT" + echo "remaining=$REMAINING" | tee --append "$GITHUB_OUTPUT" - name: Reopen PR if: ${{ steps.check_labels.outputs.remaining == '0' }} diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml index 44645c1e1b..0b10c681a1 100644 --- a/.github/workflows/build-mobile.yml +++ b/.github/workflows/build-mobile.yml @@ -51,14 +51,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -79,7 +79,7 @@ jobs: steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -103,7 +103,7 @@ jobs: - name: Restore Gradle Cache id: cache-gradle-restore - uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: | ~/.gradle/caches @@ -114,7 +114,7 @@ jobs: key: build-mobile-gradle-${{ runner.os }}-main - name: Setup Flutter SDK - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0 + uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: 'stable' flutter-version-file: ./mobile/pubspec.yaml @@ -153,14 +153,14 @@ jobs: fi - name: Publish Android Artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: release-apk-signed path: mobile/build/app/outputs/flutter-apk/*.apk - name: Save Gradle Cache id: cache-gradle-save - uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 if: github.ref == 'refs/heads/main' with: path: | @@ -185,13 +185,13 @@ jobs: run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ inputs.ref || github.sha }} persist-credentials: false - name: Setup Flutter SDK - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2 + uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: 'stable' flutter-version-file: ./mobile/pubspec.yaml @@ -210,7 +210,7 @@ jobs: working-directory: ./mobile - name: Setup Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@3ff19f5e2baf30647122352b96108b1fbe250c64 # v1.299.0 with: ruby-version: '3.3' bundler-cache: true @@ -291,7 +291,7 @@ jobs: security delete-keychain build.keychain || true - name: Upload IPA artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ios-release-ipa path: mobile/ios/Runner.ipa diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml index 3de4676622..e093cf9bf0 100644 --- a/.github/workflows/cache-cleanup.yml +++ b/.github/workflows/cache-cleanup.yml @@ -19,7 +19,7 @@ jobs: actions: write steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} diff --git a/.github/workflows/check-openapi.yml b/.github/workflows/check-openapi.yml index b725b45f6c..cd05f320c6 100644 --- a/.github/workflows/check-openapi.yml +++ b/.github/workflows/check-openapi.yml @@ -24,7 +24,7 @@ jobs: persist-credentials: false - name: Check for breaking API changes - uses: oasdiff/oasdiff-action/breaking@748daafaf3aac877a36307f842a48d55db938ac8 # v0.0.31 + uses: oasdiff/oasdiff-action/breaking@1f38ea5ea0b4a2e4e49901c3bcdf4386a05e9ea1 # v0.0.37 with: base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json revision: open-api/immich-openapi-specs.json diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index d3eb66810e..13e71491a6 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -31,7 +31,7 @@ jobs: working-directory: ./cli steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -42,7 +42,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 @@ -71,7 +71,7 @@ jobs: steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -83,13 +83,13 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Set up QEMU - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Login to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 if: ${{ !github.event.pull_request.head.repo.fork }} with: registry: ghcr.io @@ -104,7 +104,7 @@ jobs: - name: Generate docker image tags id: metadata - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: flavor: | latest=false @@ -115,7 +115,7 @@ jobs: type=raw,value=latest,enable=${{ github.event_name == 'release' }} - name: Build and push image - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: file: cli/Dockerfile platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/close-duplicates.yml b/.github/workflows/close-duplicates.yml index 1b18c0c5e1..839e5b3ceb 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:4f9860d04c88f7f87861f8ee84bfeedaec15ed7ca5ca87bc7db44b036f81645f + image: ghcr.io/immich-app/mdq:main@sha256:557cca601891b8b7d78b940071d35aaf7aaeb9b327d19b22cf282118edbc5272 outputs: checked: ${{ steps.get_checkbox.outputs.checked }} steps: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3450fe96bb..2378b032b6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,7 +44,7 @@ jobs: steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 + uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 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@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 + uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 # â„šī¸ 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@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 + uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2573ba8123..84509103be 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,14 +23,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -60,7 +60,7 @@ jobs: suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn'] steps: - name: Login to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -90,7 +90,7 @@ jobs: suffix: [''] steps: - name: Login to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -132,7 +132,7 @@ jobs: suffixes: '-rocm' platforms: linux/amd64 runner-mapping: '{"linux/amd64": "pokedex-large"}' - uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@bd49ed7a5a6022149f79b6564df48177476a822b # multi-runner-build-workflow-v2.2.1 + uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.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@bd49ed7a5a6022149f79b6564df48177476a822b # multi-runner-build-workflow-v2.2.1 + uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.0 permissions: contents: read actions: read @@ -178,7 +178,7 @@ jobs: runs-on: ubuntu-latest if: always() steps: - - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4 + - uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5 with: needs: ${{ toJSON(needs) }} @@ -189,6 +189,6 @@ jobs: runs-on: ubuntu-latest if: always() steps: - - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4 + - uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5 with: needs: ${{ toJSON(needs) }} diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index 02d7b3456a..2055bfce65 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -21,14 +21,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -54,7 +54,7 @@ jobs: steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -67,7 +67,7 @@ jobs: fetch-depth: 0 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 @@ -86,7 +86,7 @@ jobs: run: pnpm build - name: Upload build output - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: docs-build-output path: docs/build/ diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index babda72c33..05c845ccd1 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -20,7 +20,7 @@ jobs: artifact: ${{ steps.get-artifact.outputs.result }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -119,7 +119,7 @@ jobs: if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -131,7 +131,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup Mise - uses: immich-app/devtools/actions/use-mise@dab18118da6476e8237ac94080fd937983fecd42 # use-mise-action-v1.1.2 + uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3 - name: Load parameters id: parameters diff --git a/.github/workflows/docs-destroy.yml b/.github/workflows/docs-destroy.yml index 05842889cc..bb24a017fe 100644 --- a/.github/workflows/docs-destroy.yml +++ b/.github/workflows/docs-destroy.yml @@ -17,7 +17,7 @@ jobs: pull-requests: write steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -29,7 +29,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup Mise - uses: immich-app/devtools/actions/use-mise@dab18118da6476e8237ac94080fd937983fecd42 # use-mise-action-v1.1.2 + uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3 - name: Destroy Docs Subdomain env: diff --git a/.github/workflows/fix-format.yml b/.github/workflows/fix-format.yml index 0091bcef89..ae8e0b29ca 100644 --- a/.github/workflows/fix-format.yml +++ b/.github/workflows/fix-format.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -29,7 +29,7 @@ jobs: persist-credentials: true - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 diff --git a/.github/workflows/merge-translations.yml b/.github/workflows/merge-translations.yml index 392dec5e37..fcda857eda 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@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} diff --git a/.github/workflows/pr-label-validation.yml b/.github/workflows/pr-label-validation.yml index e04b32d74f..416e40df0d 100644 --- a/.github/workflows/pr-label-validation.yml +++ b/.github/workflows/pr-label-validation.yml @@ -14,13 +14,13 @@ jobs: pull-requests: write steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Require PR to have a changelog label - uses: mheap/github-action-required-labels@8afbe8ae6ab7647d0c9f0cfa7c2f939650d22509 # v5.5.1 + uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5.2 with: token: ${{ steps.token.outputs.token }} mode: exactly diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 24f3f8faf1..75ee750e9f 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 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 e3e6659140..dec9b06d67 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -50,7 +50,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -63,10 +63,10 @@ jobs: ref: main - name: Install uv - uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a # v7.4.0 + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 @@ -124,7 +124,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -136,13 +136,13 @@ jobs: persist-credentials: false - name: Download APK - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: release-apk-signed github-token: ${{ steps.generate-token.outputs.token }} - name: Create draft release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 with: draft: true tag_name: ${{ needs.bump_version.outputs.version }} diff --git a/.github/workflows/preview-label.yaml b/.github/workflows/preview-label.yaml index dc6f0eff0a..c63ef17f20 100644 --- a/.github/workflows/preview-label.yaml +++ b/.github/workflows/preview-label.yaml @@ -14,12 +14,12 @@ jobs: pull-requests: write steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2 + - uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0 with: github-token: ${{ steps.token.outputs.token }} message-id: 'preview-status' @@ -32,7 +32,7 @@ jobs: pull-requests: write steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -48,14 +48,14 @@ jobs: name: 'preview' }) - - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2 + - uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0 if: ${{ github.event.pull_request.head.repo.fork }} with: github-token: ${{ steps.token.outputs.token }} message-id: 'preview-status' message: 'PRs from forks cannot have preview environments.' - - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2 + - uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0 if: ${{ !github.event.pull_request.head.repo.fork }} with: github-token: ${{ steps.token.outputs.token }} diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index 2da7d79b26..d9b6ffb7f5 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -19,7 +19,7 @@ jobs: working-directory: ./open-api/typescript-sdk steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -30,7 +30,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 # Setup .npmrc file to publish to npm - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index d100dd281f..21e5e25bc6 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -20,14 +20,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -49,7 +49,7 @@ jobs: working-directory: ./mobile steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -61,7 +61,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup Flutter SDK - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0 + uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: 'stable' flutter-version-file: ./mobile/pubspec.yaml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a2ebe2389..a606aba124 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,14 +17,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -63,7 +63,7 @@ jobs: working-directory: ./server steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -75,7 +75,7 @@ jobs: token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -108,7 +108,7 @@ jobs: working-directory: ./cli steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -119,7 +119,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -155,7 +155,7 @@ jobs: working-directory: ./cli steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -166,7 +166,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -197,7 +197,7 @@ jobs: working-directory: ./web steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -208,7 +208,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -241,7 +241,7 @@ jobs: working-directory: ./web steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -252,7 +252,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -279,7 +279,7 @@ jobs: contents: read steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -290,7 +290,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -327,7 +327,7 @@ jobs: working-directory: ./e2e steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -338,7 +338,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -373,7 +373,7 @@ jobs: working-directory: ./server steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -385,7 +385,7 @@ jobs: submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -412,7 +412,7 @@ jobs: runner: [ubuntu-latest, ubuntu-24.04-arm] steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -424,7 +424,7 @@ jobs: submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -464,7 +464,7 @@ jobs: run: docker compose logs --no-color > docker-compose-logs.txt working-directory: ./e2e - name: Archive Docker logs - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: name: e2e-server-docker-logs-${{ matrix.runner }} @@ -484,7 +484,7 @@ jobs: runner: [ubuntu-latest, ubuntu-24.04-arm] steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -496,7 +496,7 @@ jobs: submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -522,7 +522,7 @@ jobs: run: pnpm test:web if: ${{ !cancelled() }} - name: Archive e2e test (web) results - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: success() || failure() with: name: e2e-web-test-results-${{ matrix.runner }} @@ -533,7 +533,7 @@ jobs: run: pnpm test:web:ui if: ${{ !cancelled() }} - name: Archive ui test (web) results - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: success() || failure() with: name: e2e-ui-test-results-${{ matrix.runner }} @@ -544,7 +544,7 @@ jobs: run: pnpm test:web:maintenance if: ${{ !cancelled() }} - name: Archive maintenance tests (web) results - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: success() || failure() with: name: e2e-maintenance-isolated-test-results-${{ matrix.runner }} @@ -554,7 +554,7 @@ jobs: run: docker compose logs --no-color > docker-compose-logs.txt working-directory: ./e2e - name: Archive Docker logs - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: name: e2e-web-docker-logs-${{ matrix.runner }} @@ -566,7 +566,7 @@ jobs: runs-on: ubuntu-latest if: always() steps: - - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4 + - uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5 with: needs: ${{ toJSON(needs) }} mobile-unit-tests: @@ -578,7 +578,7 @@ jobs: contents: read steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -588,7 +588,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Flutter SDK - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0 + uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: 'stable' flutter-version-file: ./mobile/pubspec.yaml @@ -610,7 +610,7 @@ jobs: working-directory: ./machine-learning steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -620,7 +620,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Install uv - uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a # v7.4.0 + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: 3.11 - name: Install dependencies @@ -650,7 +650,7 @@ jobs: working-directory: ./.github steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -661,7 +661,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -680,7 +680,7 @@ jobs: contents: read steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -701,7 +701,7 @@ jobs: contents: read steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -712,7 +712,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: @@ -763,7 +763,7 @@ jobs: working-directory: ./server steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -774,7 +774,7 @@ jobs: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: diff --git a/.github/workflows/weblate-lock.yml b/.github/workflows/weblate-lock.yml index 6e997ad76a..09024063c0 100644 --- a/.github/workflows/weblate-lock.yml +++ b/.github/workflows/weblate-lock.yml @@ -24,14 +24,14 @@ jobs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2 + uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3 with: github-token: ${{ steps.token.outputs.token }} filters: | @@ -47,7 +47,7 @@ jobs: if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }} steps: - id: token - uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -68,6 +68,6 @@ jobs: permissions: {} if: always() steps: - - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4 + - uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5 with: needs: ${{ toJSON(needs) }} diff --git a/.gitignore b/.gitignore index 3220701cc6..e8fdfa266c 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ vite.config.js.timestamp-* .pnpm-store .devcontainer/library .devcontainer/.env* +*.tsbuildinfo +*.tsbuildInfo diff --git a/cli/.nvmrc b/cli/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/cli/.nvmrc +++ b/cli/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/cli/package.json b/cli/package.json index c22b2c17b7..0b4954cb6a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@immich/cli", - "version": "2.6.2", + "version": "2.7.5", "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": "^24.11.0", + "@types/node": "^24.12.0", "@vitest/coverage-v8": "^4.0.0", "byte-size": "^9.0.0", "cli-progress": "^3.12.0", @@ -28,13 +28,13 @@ "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^63.0.0", + "eslint-plugin-unicorn": "^64.0.0", "globals": "^17.0.0", "mock-fs": "^5.2.0", "prettier": "^3.7.4", "prettier-plugin-organize-imports": "^4.0.0", - "typescript": "^5.3.3", - "typescript-eslint": "^8.28.0", + "typescript": "^6.0.0", + "typescript-eslint": "^8.58.0", "vite": "^8.0.0", "vitest": "^4.0.0", "vitest-fetch-mock": "^0.4.0", @@ -68,6 +68,6 @@ "micromatch": "^4.0.8" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" } } diff --git a/cli/tsconfig.json b/cli/tsconfig.json index d3a02a8257..f2d8d61a5f 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -15,8 +15,12 @@ "incremental": true, "skipLibCheck": true, "esModuleInterop": true, - "baseUrl": "./", + "rootDir": "./src", + "paths": { + "src/*": ["./src/*"], + }, + "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo", "types": ["vitest/globals"] }, - "exclude": ["dist", "node_modules"] + "exclude": ["dist", "node_modules", "vite.config.ts"] } diff --git a/deployment/mise.toml b/deployment/mise.toml index 4f03e27ff7..bda19c4c84 100644 --- a/deployment/mise.toml +++ b/deployment/mise.toml @@ -1,5 +1,5 @@ [tools] -terragrunt = "0.99.4" +terragrunt = "0.99.5" opentofu = "1.11.5" [tasks."tg:fmt"] diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 6e435b3c6b..bcfb86a2aa 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -90,6 +90,7 @@ services: IMMICH_THIRD_PARTY_BUG_FEATURE_URL: https://github.com/immich-app/immich/issues IMMICH_THIRD_PARTY_DOCUMENTATION_URL: https://docs.immich.app IMMICH_THIRD_PARTY_SUPPORT_URL: https://docs.immich.app/community-guides + IMMICH_HELMET_FILE: 'true' ports: - 9230:9230 - 9231:9231 @@ -155,7 +156,7 @@ services: redis: container_name: immich_redis - image: docker.io/valkey/valkey:9@sha256:3eeb09785cd61ec8e3be35f8804c8892080f3ca21934d628abc24ee4ed1698f6 + image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 healthcheck: test: redis-cli ping || exit 1 diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index 4d07794fea..700f68ff19 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:9@sha256:3eeb09785cd61ec8e3be35f8804c8892080f3ca21934d628abc24ee4ed1698f6 + image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 healthcheck: test: redis-cli ping || exit 1 restart: always @@ -85,7 +85,7 @@ services: container_name: immich_prometheus ports: - 9090:9090 - image: prom/prometheus@sha256:4a61322ac1103a0e3aea2a61ef1718422a48fa046441f299d71e660a3bc71ae9 + image: prom/prometheus@sha256:dda13e28bf95a5e5ca5b8ed56852006094c1c8e8871d9c9dbeed30aa6e55271f volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus @@ -97,7 +97,7 @@ services: command: ['./run.sh', '-disable-reporting'] ports: - 3000:3000 - image: grafana/grafana:12.3.2-ubuntu@sha256:6cca4b429a1dc0d37d401dee54825c12d40056c3c6f3f56e3f0d6318ce77749b + image: grafana/grafana:12.4.2-ubuntu@sha256:78839fe49e1425c02416fa8072591533a72bd9598e563b54a07d78f9e27fb5d3 volumes: - grafana-data:/var/lib/grafana diff --git a/docker/docker-compose.rootless.yml b/docker/docker-compose.rootless.yml index eb41bf9bca..c16a623807 100644 --- a/docker/docker-compose.rootless.yml +++ b/docker/docker-compose.rootless.yml @@ -61,7 +61,7 @@ services: redis: container_name: immich_redis - image: docker.io/valkey/valkey:9@sha256:3eeb09785cd61ec8e3be35f8804c8892080f3ca21934d628abc24ee4ed1698f6 + image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 user: '1000:1000' security_opt: - no-new-privileges:true diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 4437087d24..610b375011 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:9@sha256:3eeb09785cd61ec8e3be35f8804c8892080f3ca21934d628abc24ee4ed1698f6 + image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 healthcheck: test: redis-cli ping || exit 1 restart: always diff --git a/docs/.nvmrc b/docs/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/docs/.nvmrc +++ b/docs/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/docs/docs/administration/img/keycloak-access-settings.webp b/docs/docs/administration/img/keycloak-access-settings.webp new file mode 100644 index 0000000000..1ba55042cc Binary files /dev/null and b/docs/docs/administration/img/keycloak-access-settings.webp differ diff --git a/docs/docs/administration/img/keycloak-capability-config.webp b/docs/docs/administration/img/keycloak-capability-config.webp new file mode 100644 index 0000000000..5c96a94ed3 Binary files /dev/null and b/docs/docs/administration/img/keycloak-capability-config.webp differ diff --git a/docs/docs/administration/img/keycloak-general-settings.webp b/docs/docs/administration/img/keycloak-general-settings.webp new file mode 100644 index 0000000000..27976b5939 Binary files /dev/null and b/docs/docs/administration/img/keycloak-general-settings.webp differ diff --git a/docs/docs/administration/oauth.md b/docs/docs/administration/oauth.md index d0a9ce733e..3b1e8c729d 100644 --- a/docs/docs/administration/oauth.md +++ b/docs/docs/administration/oauth.md @@ -14,6 +14,7 @@ Immich supports 3rd party authentication via [OpenID Connect][oidc] (OIDC), an i - [Authelia](https://www.authelia.com/integration/openid-connect/immich/) - [Okta](https://www.okta.com/openid-connect/) - [Google](https://developers.google.com/identity/openid-connect/openid-connect) +- [Keycloak](https://www.keycloak.org) ## Prerequisites @@ -253,4 +254,40 @@ Configuration of OAuth in Immich System Settings +
+Keycloak Example + +### Keycloak Example + +Here's an example of OAuth configured for Keycloak: + +Create your immich client on your Keycloak Realm. + + + + + +Configuration of OAuth in Immich System Settings + +| Setting | Value | +| ---------------------------- | ----------------------------------------------------- | +| Issuer URL | `https:///realms/` | +| Client ID | immich | +| Client Secret | can be optained from Clients -> immich -> Credentials | +| Scope | openid email profile | +| Signing Algorithm | RS256 | +| Storage Label Claim | preferred_username | +| Role Claim | immich_role | +| Storage Quota Claim | immich_quota | +| Default Storage Quota (GiB) | 0 (empty for unlimited quota) | +| Button Text | Sign in with Keycloak (recommended) | +| Auto Register | Enabled (optional) | +| Auto Launch | Enabled (optional) | +| Mobile Redirect URI Override | Disabled | +| Mobile Redirect URI | | + +Role Claim can be managed via Client Role. Remember to create a mapper with claim name `immich_role`. + +
+ [oidc]: https://openid.net/connect/ diff --git a/docs/docs/features/duplicates-utility.md b/docs/docs/features/duplicates-utility.md new file mode 100644 index 0000000000..f790c42708 --- /dev/null +++ b/docs/docs/features/duplicates-utility.md @@ -0,0 +1,28 @@ +# Duplicates Utility + +Immich comes with a duplicates utility to help you detect assets that look visually similar. The duplicate detection feature relies on machine learning and is enabled by default. For more information about when the duplicate detection job runs, see [Jobs and Workers](/administration/jobs-workers). Once an asset has been processed and added to a duplicate group, it becomes available to review in the "Review duplicates" utility, which can be found [here](https://my.immich.app/utilities/duplicates). + +## Reviewing duplicates + +The review duplicates page allows the user to individually select which assets should be kept and which ones should be trashed. When more than one asset is kept, there is an option to automatically put the kept assets into a stack. + +### Automatic preselection + +When using "Deduplicate All" or viewing suggestions, Immich automatically preselects which assets to keep based on: + +1. **Image size in bytes** — larger files are preferred as they typically have higher quality. +2. **Count of EXIF data** — assets with more metadata are preferred. + +### Synchronizing metadata + +When resolving duplicates, metadata from trashed assets is automatically synchronized to the kept assets. The following metadata is synchronized: + +| Name | Description | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------- | +| Album | The kept assets will be added to _every_ album that the other assets in the group belong to. | +| Favorite | If any of the assets in the group have been added to favorites, every kept asset will also be added to favorites. | +| Rating | If one or more assets in the duplicate group have a rating, the highest rating is selected and synchronized to the kept assets. | +| Description | Descriptions from each asset are combined together and synchronized to all the kept assets. | +| Visibility | The most restrictive visibility is applied to the kept assets. | +| Location | Latitude and longitude are copied if all assets with geolocation data in the group share the same coordinates. | +| Tag | Tags from all assets in the group are merged and applied to every kept asset. | diff --git a/docs/docs/features/searching.md b/docs/docs/features/searching.md index 7360787127..92eb01c39d 100644 --- a/docs/docs/features/searching.md +++ b/docs/docs/features/searching.md @@ -26,7 +26,7 @@ You can search the following types of content: | Time frame | Start and end date of a specific time bucket | | Media type | Image or video or both | | Display options | In Archive, in Favorites or Not in any album | -| Start rating | User-assigned start rating | +| Star rating | User-assigned star rating | diff --git a/docs/docs/features/supported-formats.md b/docs/docs/features/supported-formats.md index 4c4ac6039a..86ac264cc3 100644 --- a/docs/docs/features/supported-formats.md +++ b/docs/docs/features/supported-formats.md @@ -28,17 +28,17 @@ For the full list, refer to the [Immich source code](https://github.com/immich-a ## Video formats -| Format | Extension(s) | Supported? | Notes | -| :---------- | :-------------------- | :----------------: | :---- | -| `3GPP` | `.3gp` `.3gpp` | :white_check_mark: | | -| `AVI` | `.avi` | :white_check_mark: | | -| `FLV` | `.flv` | :white_check_mark: | | -| `M4V` | `.m4v` | :white_check_mark: | | -| `MATROSKA` | `.mkv` | :white_check_mark: | | -| `MP2T` | `.mts` `.m2ts` `.m2t` | :white_check_mark: | | -| `MP4` | `.mp4` `.insv` | :white_check_mark: | | -| `MPEG` | `.mpg` `.mpe` `.mpeg` | :white_check_mark: | | -| `MXF` | `.mxf` | :white_check_mark: | | -| `QUICKTIME` | `.mov` | :white_check_mark: | | -| `WEBM` | `.webm` | :white_check_mark: | | -| `WMV` | `.wmv` | :white_check_mark: | | +| Format | Extension(s) | Supported? | Notes | +| :---------- | :-------------------------- | :----------------: | :---- | +| `3GPP` | `.3gp` `.3gpp` | :white_check_mark: | | +| `AVI` | `.avi` | :white_check_mark: | | +| `FLV` | `.flv` | :white_check_mark: | | +| `M4V` | `.m4v` | :white_check_mark: | | +| `MATROSKA` | `.mkv` | :white_check_mark: | | +| `MP2T` | `.mts` `.m2ts` `.m2t` `.ts` | :white_check_mark: | | +| `MP4` | `.mp4` `.insv` | :white_check_mark: | | +| `MPEG` | `.mpg` `.mpe` `.mpeg` | :white_check_mark: | | +| `MXF` | `.mxf` | :white_check_mark: | | +| `QUICKTIME` | `.mov` | :white_check_mark: | | +| `WEBM` | `.webm` | :white_check_mark: | | +| `WMV` | `.wmv` | :white_check_mark: | | diff --git a/docs/docs/guides/custom-map-styles.md b/docs/docs/guides/custom-map-styles.md index 1a61afc324..ac693c16ba 100644 --- a/docs/docs/guides/custom-map-styles.md +++ b/docs/docs/guides/custom-map-styles.md @@ -3,8 +3,8 @@ You may decide that you'd like to modify the style document which is used to draw the maps in Immich. In addition to visual customization, this also allows you to pick your own map tile provider instead of the default one. The default -`style.json` for [light theme](https://github.com/immich-app/immich/tree/main/server/resources/style-light.json) -and [dark theme](https://github.com/immich-app/immich/blob/main/server/resources/style-dark.json) +`style.json` for [light theme](https://tiles.immich.cloud/v1/style/light.json) +and [dark theme](https://tiles.immich.cloud/v1/style/dark.json) can be used as a basis for creating your own style. There are several sources for already-made `style.json` map themes, as well as diff --git a/docs/docs/install/environment-variables.md b/docs/docs/install/environment-variables.md index e9e3bb032c..41068dee97 100644 --- a/docs/docs/install/environment-variables.md +++ b/docs/docs/install/environment-variables.md @@ -29,22 +29,23 @@ These environment variables are used by the `docker-compose.yml` file and do **N ## General -| Variable | Description | Default | Containers | Workers | -| :---------------------------------- | :---------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- | -| `TZ` | Timezone | \*1 | server | microservices | -| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices | -| `IMMICH_LOG_LEVEL` | Log level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices | -| `IMMICH_LOG_FORMAT` | Log output format (`console`, `json`) | `console` | server | api, microservices | -| `IMMICH_MEDIA_LOCATION` | Media location inside the container âš ī¸**You probably shouldn't set this**\*2âš ī¸ | `/data` | server | api, microservices | -| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices | -| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | | -| `CPU_CORES` | Number of cores available to the Immich server | auto-detected CPU core count | server | | -| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api | -| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices | -| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices | -| `IMMICH_TRUSTED_PROXIES` | List of comma-separated IPs set as trusted proxies | | server | api | -| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/administration/system-integrity) | | server | api, microservices | -| `IMMICH_ALLOW_SETUP` | When `false` disables the `/auth/admin-sign-up` endpoint | `true` | server | api | +| Variable | Description | Default | Containers | Workers | +| :---------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- | +| `TZ` | Timezone | \*1 | server | microservices | +| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices | +| `IMMICH_LOG_LEVEL` | Log level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices | +| `IMMICH_LOG_FORMAT` | Log output format (`console`, `json`) | `console` | server | api, microservices | +| `IMMICH_MEDIA_LOCATION` | Media location inside the container âš ī¸**You probably shouldn't set this**\*2âš ī¸ | `/data` | server | api, microservices | +| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices | +| `IMMICH_HELMET_FILE` | Path to a json file with [helmet](https://www.npmjs.com/package/helmet) options. Set to `false` to disable. Set to `true` to use `server/helmet.json`. | `false` | server | api, microservices | +| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | | +| `CPU_CORES` | Number of cores available to the Immich server | auto-detected CPU core count | server | | +| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api | +| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices | +| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices | +| `IMMICH_TRUSTED_PROXIES` | List of comma-separated IPs set as trusted proxies | | server | api | +| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/administration/system-integrity) | | server | api, microservices | +| `IMMICH_ALLOW_SETUP` | When `false` disables the `/auth/admin-sign-up` endpoint | `true` | server | api | \*1: `TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`. `TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution. diff --git a/docs/docs/install/requirements.md b/docs/docs/install/requirements.md index 178cf45388..66f3033a43 100644 --- a/docs/docs/install/requirements.md +++ b/docs/docs/install/requirements.md @@ -49,7 +49,7 @@ Immich requires [**Docker**](https://docs.docker.com/get-started/get-docker/) wi The Compose plugin will be installed by both Docker Engine and Desktop by following the linked installation guides; it can also be [separately installed](https://docs.docker.com/compose/install/). :::note -Immich requires the command `docker compose`; the similarly named `docker-compose` is [deprecated](https://docs.docker.com/compose/migrate/) and is no longer supported by Immich. +Immich requires the command `docker compose`; the similarly named `docker-compose` is [deprecated](https://docs.docker.com/retired/#docker-compose-v1-replaced-by-compose-v2) and is no longer supported by Immich. ::: ### Special requirements for Windows users diff --git a/docs/package.json b/docs/package.json index 60a6dccf87..f976791279 100644 --- a/docs/package.json +++ b/docs/package.json @@ -30,17 +30,17 @@ "postcss": "^8.4.25", "prism-react-renderer": "^2.3.1", "raw-loader": "^4.0.2", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", "tailwindcss": "^3.2.4", "url": "^0.11.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "~3.9.0", - "@docusaurus/tsconfig": "^3.7.0", + "@docusaurus/tsconfig": "^3.10.0", "@docusaurus/types": "^3.7.0", "prettier": "^3.7.4", - "typescript": "^5.1.6" + "typescript": "^6.0.0" }, "browserslist": { "production": [ @@ -58,6 +58,6 @@ "node": ">=20" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" } } diff --git a/docs/static/archived-versions.json b/docs/static/archived-versions.json index 09cd1b1548..964291ad08 100644 --- a/docs/static/archived-versions.json +++ b/docs/static/archived-versions.json @@ -1,7 +1,11 @@ [ { - "label": "v2.6.2", - "url": "https://docs.v2.6.2.archive.immich.app" + "label": "v2.7.5", + "url": "https://docs.v2.7.5.archive.immich.app" + }, + { + "label": "v2.6.3", + "url": "https://docs.v2.6.3.archive.immich.app" }, { "label": "v2.5.6", diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 674c46e46d..a6ba1bd9dd 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,8 +1,4 @@ { // This file is not used in compilation. It is here just for a nice editor experience. - "extends": "@docusaurus/tsconfig", - - "compilerOptions": { - "baseUrl": "." - } + "extends": "@docusaurus/tsconfig" } diff --git a/e2e/.nvmrc b/e2e/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/e2e/.nvmrc +++ b/e2e/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml index 957de4698e..c8a3b975d4 100644 --- a/e2e/docker-compose.yml +++ b/e2e/docker-compose.yml @@ -44,7 +44,7 @@ services: redis: container_name: immich-e2e-redis - image: docker.io/valkey/valkey:9@sha256:3eeb09785cd61ec8e3be35f8804c8892080f3ca21934d628abc24ee4ed1698f6 + image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 healthcheck: test: redis-cli ping || exit 1 diff --git a/e2e/package.json b/e2e/package.json index 58304f3433..24b9d849ee 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -1,6 +1,6 @@ { "name": "immich-e2e", - "version": "2.6.2", + "version": "2.7.5", "description": "", "main": "index.js", "type": "module", @@ -32,15 +32,15 @@ "@playwright/test": "^1.44.1", "@socket.io/component-emitter": "^3.1.2", "@types/luxon": "^3.4.2", - "@types/node": "^24.11.0", + "@types/node": "^24.12.0", "@types/pg": "^8.15.1", "@types/pngjs": "^6.0.4", - "@types/supertest": "^6.0.2", + "@types/supertest": "^7.0.0", "dotenv": "^17.2.3", "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^63.0.0", + "eslint-plugin-unicorn": "^64.0.0", "exiftool-vendored": "^35.0.0", "globals": "^17.0.0", "luxon": "^3.4.4", @@ -51,13 +51,13 @@ "sharp": "^0.34.5", "socket.io-client": "^4.7.4", "supertest": "^7.0.0", - "typescript": "^5.3.3", + "typescript": "^6.0.0", "typescript-eslint": "^8.28.0", "utimes": "^5.2.1", "vite-tsconfig-paths": "^6.1.1", "vitest": "^4.0.0" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" } } diff --git a/e2e/src/api/specs/duplicate.e2e-spec.ts b/e2e/src/api/specs/duplicate.e2e-spec.ts new file mode 100644 index 0000000000..d6d0ec1394 --- /dev/null +++ b/e2e/src/api/specs/duplicate.e2e-spec.ts @@ -0,0 +1,651 @@ +import { LoginResponseDto } from '@immich/sdk'; +import { createUserDto, uuidDto } from 'src/fixtures'; +import { errorDto } from 'src/responses'; +import { app, utils } from 'src/utils'; +import request from 'supertest'; +import { beforeAll, beforeEach, describe, expect, it } from 'vitest'; + +describe('/duplicates', () => { + let admin: LoginResponseDto; + let user1: LoginResponseDto; + let user2: LoginResponseDto; + + beforeAll(async () => { + await utils.resetDatabase(); + + admin = await utils.adminSetup(); + + [user1, user2] = await Promise.all([ + utils.userSetup(admin.accessToken, createUserDto.user1), + utils.userSetup(admin.accessToken, createUserDto.user2), + ]); + }); + + beforeEach(async () => { + // Reset assets, albums, tags, and stacks between tests to ensure clean state for repeated test runs + // Note: We don't reset users since they're set up once in beforeAll + // Stack must be reset before asset due to foreign key constraint + await utils.resetDatabase(['stack', 'asset', 'album', 'tag']); + }); + + describe('GET /duplicates', () => { + it('should return empty array when no duplicates', async () => { + const { status, body } = await request(app) + .get('/duplicates') + .set('Authorization', `Bearer ${user1.accessToken}`); + + expect(status).toBe(200); + expect(body).toEqual([]); + }); + + it('should return duplicate groups with suggestedKeepAssetIds', async () => { + // Create assets with different file sizes for duplicate detection + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Manually set duplicateId on both assets to create a duplicate group + const duplicateId = '00000000-0000-4000-8000-000000000001'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .get('/duplicates') + .set('Authorization', `Bearer ${user1.accessToken}`); + + expect(status).toBe(200); + expect(body).toEqual([ + { + duplicateId, + assets: expect.arrayContaining([ + expect.objectContaining({ id: asset1.id }), + expect.objectContaining({ id: asset2.id }), + ]), + suggestedKeepAssetIds: expect.any(Array), + }, + ]); + expect(body[0].suggestedKeepAssetIds.length).toBe(1); + }); + }); + + describe('POST /duplicates/resolve', () => { + it('should require authentication', async () => { + const { status, body } = await request(app) + .post('/duplicates/resolve') + .send({ + groups: [{ duplicateId: uuidDto.dummy, keepAssetIds: [], trashAssetIds: [] }], + }); + + expect(status).toBe(401); + expect(body).toEqual(errorDto.unauthorized); + }); + + it('should return failure for non-existent duplicate group', async () => { + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId: uuidDto.dummy, keepAssetIds: [], trashAssetIds: [] }], + }); + + expect(status).toBe(200); + expect(body).toEqual({ + status: 'COMPLETED', + results: [ + { + duplicateId: uuidDto.dummy, + status: 'FAILED', + reason: expect.stringContaining('not found or access denied'), + }, + ], + }); + }); + + it('should resolve duplicate group with keepers', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000002'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body).toEqual({ + status: 'COMPLETED', + results: [ + { + duplicateId, + status: 'SUCCESS', + }, + ], + }); + + // Verify side effects: duplicateId cleared on kept asset + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.duplicateId).toBeNull(); + + // Verify side effects: trashed asset is trashed and duplicateId cleared + const trashedAsset = await utils.getAssetInfo(user1.accessToken, asset2.id); + expect(trashedAsset.isTrashed).toBe(true); + expect(trashedAsset.duplicateId).toBeNull(); + }); + + it('should reject when keepAssetIds and trashAssetIds overlap', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000003'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset1.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('FAILED'); + expect(body.results[0].reason).toContain('disjoint'); + }); + + it('should require keepAssetIds when partially trashing', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000004'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [], trashAssetIds: [asset1.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('FAILED'); + expect(body.results[0].reason).toContain('must cover all assets'); + }); + + it('should reject partial resolution (not all assets covered)', async () => { + const [asset1, asset2, asset3] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000010'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset3.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('FAILED'); + expect(body.results[0].reason).toContain('must cover all assets'); + }); + + it('should reject asset not in duplicate group', async () => { + const [asset1, asset2, outsideAsset] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000011'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [outsideAsset.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('FAILED'); + expect(body.results[0].reason).toContain('not a member of duplicate group'); + }); + + it('should allow trash-all without keepers', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000012'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [], trashAssetIds: [asset1.id, asset2.id] }], + }); + + expect(status).toBe(200); + expect(body).toEqual({ + status: 'COMPLETED', + results: [ + { + duplicateId, + status: 'SUCCESS', + }, + ], + }); + + // Verify both assets are trashed + const [asset1Info, asset2Info] = await Promise.all([ + utils.getAssetInfo(user1.accessToken, asset1.id), + utils.getAssetInfo(user1.accessToken, asset2.id), + ]); + + expect(asset1Info.isTrashed).toBe(true); + expect(asset1Info.duplicateId).toBeNull(); + expect(asset2Info.isTrashed).toBe(true); + expect(asset2Info.duplicateId).toBeNull(); + }); + + it('should reject cross-user duplicate group access', async () => { + const asset1 = await utils.createAsset(user1.accessToken); + const asset2 = await utils.createAsset(user2.accessToken); + + const duplicateId = '00000000-0000-4000-8000-000000000013'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user2.accessToken, asset2.id, duplicateId); + + // User1 tries to resolve a group containing user2's asset + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('FAILED'); + expect(body.results[0].reason).toContain('not a member of duplicate group'); + }); + + it('should synchronize favorites when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Mark one asset as favorite + await request(app) + .put('/assets') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ ids: [asset2.id], isFavorite: true }); + + const duplicateId = '00000000-0000-4000-8000-000000000020'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify favorite was synchronized to keeper + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.isFavorite).toBe(true); + expect(keptAsset.duplicateId).toBeNull(); + }); + + it('should synchronize visibility when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Archive one asset + await utils.archiveAssets(user1.accessToken, [asset2.id]); + + const duplicateId = '00000000-0000-4000-8000-000000000021'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify visibility was synchronized to keeper + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.visibility).toBe('archive'); + expect(keptAsset.duplicateId).toBeNull(); + }); + + it('should synchronize rating when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Set rating on one asset + await request(app) + .put('/assets') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ ids: [asset2.id], rating: 5 }); + + const duplicateId = '00000000-0000-4000-8000-000000000022'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify rating was synchronized to keeper + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.exifInfo?.rating).toBe(5); + expect(keptAsset.duplicateId).toBeNull(); + }); + + it('should synchronize description when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Set description on one asset + await request(app) + .put('/assets') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ ids: [asset2.id], description: 'Test description for duplicate' }); + + const duplicateId = '00000000-0000-4000-8000-000000000023'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify description was synchronized to keeper + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.exifInfo?.description).toBe('Test description for duplicate'); + expect(keptAsset.duplicateId).toBeNull(); + }); + + it('should synchronize location when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Set location on one asset + await request(app) + .put('/assets') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ ids: [asset2.id], latitude: 40.7128, longitude: -74.006 }); + + const duplicateId = '00000000-0000-4000-8000-000000000024'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify location was synchronized to keeper + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.exifInfo?.latitude).toBe(40.7128); + expect(keptAsset.exifInfo?.longitude).toBe(-74.006); + expect(keptAsset.duplicateId).toBeNull(); + }); + + it('should synchronize albums when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Create albums and add assets to different albums + const album1 = await utils.createAlbum(user1.accessToken, { + albumName: 'Album 1', + assetIds: [asset1.id], + }); + const album2 = await utils.createAlbum(user1.accessToken, { + albumName: 'Album 2', + assetIds: [asset2.id], + }); + + const duplicateId = '00000000-0000-4000-8000-000000000025'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify keeper is now in both albums + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.duplicateId).toBeNull(); + + // Check albums directly + const { status: album1Status, body: album1Body } = await request(app) + .get(`/albums/${album1.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`); + const { status: album2Status, body: album2Body } = await request(app) + .get(`/albums/${album2.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`); + + expect(album1Status).toBe(200); + expect(album2Status).toBe(200); + expect(album1Body.assets.map((a: any) => a.id)).toContain(asset1.id); + expect(album2Body.assets.map((a: any) => a.id)).toContain(asset1.id); + }); + + it('should synchronize tags when enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + // Wait for metadata extraction to complete before adding tags + // Otherwise, metadata jobs will race and overwrite our tags + await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction'); + + // Create tags and tag assets differently + const tags = await utils.upsertTags(user1.accessToken, ['tag1', 'tag2']); + await utils.tagAssets(user1.accessToken, tags[0].id, [asset1.id]); + await utils.tagAssets(user1.accessToken, tags[1].id, [asset2.id]); + + const duplicateId = '00000000-0000-4000-8000-000000000026'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify keeper has both tags + const keptAsset = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(keptAsset.duplicateId).toBeNull(); + expect(keptAsset.tags).toBeDefined(); + const tagIds = keptAsset.tags?.map((t) => t.id) || []; + expect(tagIds).toContain(tags[0].id); + expect(tagIds).toContain(tags[1].id); + }); + + it('should handle batch resolve with mixed success and failure', async () => { + // Create first group that will succeed + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + const duplicateId1 = '00000000-0000-4000-8000-000000000027'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId1); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId1); + + // Create second group with non-existent duplicate ID (will fail) + const fakeId = '00000000-0000-4000-8000-000000000099'; + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [ + { duplicateId: duplicateId1, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }, + { duplicateId: fakeId, keepAssetIds: [], trashAssetIds: [] }, + ], + }); + + expect(status).toBe(200); + expect(body.status).toBe('COMPLETED'); + expect(body.results).toHaveLength(2); + + // First group should succeed + expect(body.results[0].duplicateId).toBe(duplicateId1); + expect(body.results[0].status).toBe('SUCCESS'); + + // Second group should fail + expect(body.results[1].duplicateId).toBe(fakeId); + expect(body.results[1].status).toBe('FAILED'); + expect(body.results[1].reason).toContain('not found or access denied'); + + // Verify first group was actually resolved despite second failure + const asset1Info = await utils.getAssetInfo(user1.accessToken, asset1.id); + expect(asset1Info.duplicateId).toBeNull(); + const asset2Info = await utils.getAssetInfo(user1.accessToken, asset2.id); + expect(asset2Info.isTrashed).toBe(true); + }); + + it('should trash assets when trash is enabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000028'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + // Ensure trash is enabled (default) + const config = await utils.getSystemConfig(admin.accessToken); + expect(config.trash.enabled).toBe(true); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Verify asset is trashed (not deleted) + const trashedAsset = await utils.getAssetInfo(user1.accessToken, asset2.id); + expect(trashedAsset.isTrashed).toBe(true); + }); + + it('should delete assets when trash is disabled', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const duplicateId = '00000000-0000-4000-8000-000000000029'; + await utils.setAssetDuplicateId(user1.accessToken, asset1.id, duplicateId); + await utils.setAssetDuplicateId(user1.accessToken, asset2.id, duplicateId); + + // Disable trash + await request(app) + .put('/system-config') + .set('Authorization', `Bearer ${admin.accessToken}`) + .send({ + trash: { enabled: false, days: 30 }, + }); + + const { status, body } = await request(app) + .post('/duplicates/resolve') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ + groups: [{ duplicateId, keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(status).toBe(200); + expect(body.results[0].status).toBe('SUCCESS'); + + // Asset should be marked as deleted (force delete) + const { status: getStatus } = await request(app) + .get(`/assets/${asset2.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`); + + // Asset should still be accessible (soft deleted) but marked as deleted + expect(getStatus).toBe(200); + + // Re-enable trash for other tests + await utils.resetAdminConfig(admin.accessToken); + }); + }); +}); diff --git a/e2e/src/fixtures.ts b/e2e/src/fixtures.ts index 9e311c896d..1e03ad6d24 100644 --- a/e2e/src/fixtures.ts +++ b/e2e/src/fixtures.ts @@ -2,6 +2,8 @@ export const uuidDto = { invalid: 'invalid-uuid', // valid uuid v4 notFound: '00000000-0000-4000-a000-000000000000', + dummy: '00000000-0000-4000-a000-000000000001', + dummy2: '00000000-0000-4000-a000-000000000002', }; const adminLoginDto = { diff --git a/e2e/src/specs/maintenance/server/database-backups.e2e-spec.ts b/e2e/src/specs/maintenance/server/database-backups.e2e-spec.ts index 2b0f6ae61a..b69bd099ed 100644 --- a/e2e/src/specs/maintenance/server/database-backups.e2e-spec.ts +++ b/e2e/src/specs/maintenance/server/database-backups.e2e-spec.ts @@ -10,7 +10,9 @@ describe('/admin/database-backups', () => { beforeAll(async () => { await utils.resetDatabase(); - admin = await utils.adminSetup(); + admin = await utils.adminSetup({ + onboarding: false, + }); await utils.resetBackups(admin.accessToken); }); @@ -94,7 +96,9 @@ describe('/admin/database-backups', () => { ({ status, body }) => status === 200 && !body.maintenanceMode, ); - admin = await utils.adminSetup(); + admin = await utils.adminSetup({ + onboarding: false, + }); }); it.sequential('should not work when the server is configured', async () => { diff --git a/e2e/src/specs/web/album.e2e-spec.ts b/e2e/src/specs/web/album.e2e-spec.ts index 953c7d00ae..cd8bb87582 100644 --- a/e2e/src/specs/web/album.e2e-spec.ts +++ b/e2e/src/specs/web/album.e2e-spec.ts @@ -1,6 +1,7 @@ import { LoginResponseDto } from '@immich/sdk'; -import { test } from '@playwright/test'; -import { utils } from 'src/utils'; +import { expect, test } from '@playwright/test'; +import { readFileSync } from 'node:fs'; +import { testAssetDir, utils } from 'src/utils'; test.describe('Album', () => { let admin: LoginResponseDto; @@ -22,4 +23,41 @@ test.describe('Album', () => { await page.reload(); await page.getByRole('button', { name: 'Select photos' }).waitFor(); }); + + test('should keep map view open after viewing an asset from the map and going back', async ({ context, page }) => { + await utils.setAuthCookies(context, admin.accessToken); + + const imagePath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`; + const mapAsset = await utils.createAsset(admin.accessToken, { + assetData: { + bytes: readFileSync(imagePath), + filename: 'thompson-springs.jpg', + }, + }); + + await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction'); + + const mapAlbum = await utils.createAlbum(admin.accessToken, { + albumName: 'Map Test Album', + assetIds: [mapAsset.id], + }); + + await page.goto(`/albums/${mapAlbum.id}`); + const mapButton = page.getByRole('button', { name: 'Map' }); + await expect(mapButton).toBeVisible(); + await mapButton.click(); + + const mapModal = page.getByRole('dialog'); + await expect(mapModal).toBeVisible(); + + const mapMarker = mapModal.getByRole('img', { name: /Map marker/i }).first(); + await expect(mapMarker).toBeVisible(); + await mapMarker.click(); + + await page.waitForSelector('#immich-asset-viewer'); + await page.getByRole('button', { name: 'Go back' }).click(); + + await expect(page.locator('#immich-asset-viewer')).not.toBeVisible(); + await expect(mapModal).toBeVisible(); + }); }); diff --git a/e2e/src/ui/mock-network/base-network.ts b/e2e/src/ui/mock-network/base-network.ts index f23202ca77..7c4aee59e3 100644 --- a/e2e/src/ui/mock-network/base-network.ts +++ b/e2e/src/ui/mock-network/base-network.ts @@ -1,5 +1,5 @@ import { BrowserContext } from '@playwright/test'; -import { playwrightHost } from 'playwright.config'; +import { playwrightHost } from 'src/../playwright.config'; export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserId: string) => { await context.addCookies([ @@ -173,6 +173,7 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI '.mpeg', '.mpg', '.mts', + '.ts', '.vob', '.webm', '.wmv', diff --git a/e2e/src/ui/mock-network/ocr-network.ts b/e2e/src/ui/mock-network/ocr-network.ts new file mode 100644 index 0000000000..3b1a2fe62e --- /dev/null +++ b/e2e/src/ui/mock-network/ocr-network.ts @@ -0,0 +1,55 @@ +import { faker } from '@faker-js/faker'; +import type { AssetOcrResponseDto } from '@immich/sdk'; +import { BrowserContext } from '@playwright/test'; + +export type MockOcrBox = { + text: string; + x1: number; + y1: number; + x2: number; + y2: number; + x3: number; + y3: number; + x4: number; + y4: number; +}; + +export const createMockOcrData = (assetId: string, boxes: MockOcrBox[]): AssetOcrResponseDto[] => { + return boxes.map((box) => ({ + id: faker.string.uuid(), + assetId, + x1: box.x1, + y1: box.y1, + x2: box.x2, + y2: box.y2, + x3: box.x3, + y3: box.y3, + x4: box.x4, + y4: box.y4, + boxScore: 0.95, + textScore: 0.9, + text: box.text, + })); +}; + +export const setupOcrMockApiRoutes = async ( + context: BrowserContext, + ocrDataByAssetId: Map, +) => { + await context.route('**/assets/*/ocr', async (route, request) => { + if (request.method() !== 'GET') { + return route.fallback(); + } + const url = new URL(request.url()); + const segments = url.pathname.split('/'); + const assetIdIndex = segments.indexOf('assets') + 1; + const assetId = segments[assetIdIndex]; + + const ocrData = ocrDataByAssetId.get(assetId) ?? []; + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: ocrData, + }); + }); +}; diff --git a/e2e/src/ui/specs/asset-viewer/ocr.e2e-spec.ts b/e2e/src/ui/specs/asset-viewer/ocr.e2e-spec.ts new file mode 100644 index 0000000000..5a442a6081 --- /dev/null +++ b/e2e/src/ui/specs/asset-viewer/ocr.e2e-spec.ts @@ -0,0 +1,300 @@ +import type { AssetOcrResponseDto, AssetResponseDto } from '@immich/sdk'; +import { expect, test } from '@playwright/test'; +import { toAssetResponseDto } from 'src/ui/generators/timeline'; +import { + createMockStack, + createMockStackAsset, + MockStack, + setupBrokenAssetMockApiRoutes, +} from 'src/ui/mock-network/broken-asset-network'; +import { createMockOcrData, setupOcrMockApiRoutes } from 'src/ui/mock-network/ocr-network'; +import { assetViewerUtils } from '../timeline/utils'; +import { setupAssetViewerFixture } from './utils'; + +test.describe.configure({ mode: 'parallel' }); + +const PRIMARY_OCR_BOXES = [ + { text: 'Hello World', x1: 0.1, y1: 0.1, x2: 0.4, y2: 0.1, x3: 0.4, y3: 0.15, x4: 0.1, y4: 0.15 }, + { text: 'Immich Photo', x1: 0.2, y1: 0.3, x2: 0.6, y2: 0.3, x3: 0.6, y3: 0.36, x4: 0.2, y4: 0.36 }, +]; + +const SECONDARY_OCR_BOXES = [ + { text: 'Second Asset Text', x1: 0.15, y1: 0.2, x2: 0.55, y2: 0.2, x3: 0.55, y3: 0.26, x4: 0.15, y4: 0.26 }, +]; + +test.describe('OCR bounding boxes', () => { + const fixture = setupAssetViewerFixture(920); + + test.beforeEach(async ({ context }) => { + const primaryAssetDto = toAssetResponseDto(fixture.primaryAsset); + const ocrDataByAssetId = new Map([ + [primaryAssetDto.id, createMockOcrData(primaryAssetDto.id, PRIMARY_OCR_BOXES)], + ]); + + await setupOcrMockApiRoutes(context, ocrDataByAssetId); + }); + + test('OCR bounding boxes appear when clicking OCR button', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + const ocrButton = page.getByLabel('Text recognition'); + await expect(ocrButton).toBeVisible(); + await ocrButton.click(); + + const ocrBoxes = page.locator('[data-viewer-content] [data-testid="ocr-box"]'); + await expect(ocrBoxes).toHaveCount(2); + + await expect(ocrBoxes.nth(0)).toContainText('Hello World'); + await expect(ocrBoxes.nth(1)).toContainText('Immich Photo'); + }); + + test('OCR bounding boxes toggle off on second click', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + const ocrButton = page.getByLabel('Text recognition'); + await ocrButton.click(); + await expect(page.locator('[data-viewer-content] [data-testid="ocr-box"]').first()).toBeVisible(); + + await ocrButton.click(); + await expect(page.locator('[data-viewer-content] [data-testid="ocr-box"]')).toHaveCount(0); + }); +}); + +test.describe('OCR with stacked assets', () => { + const fixture = setupAssetViewerFixture(921); + let mockStack: MockStack; + let primaryAssetDto: AssetResponseDto; + let secondAssetDto: AssetResponseDto; + + test.beforeAll(async () => { + primaryAssetDto = toAssetResponseDto(fixture.primaryAsset); + secondAssetDto = createMockStackAsset(fixture.adminUserId); + secondAssetDto.originalFileName = 'second-ocr-asset.jpg'; + mockStack = createMockStack(primaryAssetDto, [secondAssetDto], new Set()); + }); + + test.beforeEach(async ({ context }) => { + await setupBrokenAssetMockApiRoutes(context, mockStack); + + const ocrDataByAssetId = new Map([ + [primaryAssetDto.id, createMockOcrData(primaryAssetDto.id, PRIMARY_OCR_BOXES)], + [secondAssetDto.id, createMockOcrData(secondAssetDto.id, SECONDARY_OCR_BOXES)], + ]); + + await setupOcrMockApiRoutes(context, ocrDataByAssetId); + }); + + test('different OCR boxes shown for different stacked assets', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + const ocrButton = page.getByLabel('Text recognition'); + await expect(ocrButton).toBeVisible(); + await ocrButton.click(); + + const ocrBoxes = page.locator('[data-viewer-content] [data-testid="ocr-box"]'); + await expect(ocrBoxes).toHaveCount(2); + await expect(ocrBoxes.nth(0)).toContainText('Hello World'); + + const stackThumbnails = page.locator('#stack-slideshow [data-asset]'); + await expect(stackThumbnails).toHaveCount(2); + await stackThumbnails.nth(1).click(); + + // refreshOcr() clears showOverlay when switching assets, so re-enable it + await expect(ocrBoxes).toHaveCount(0); + await expect(ocrButton).toBeVisible(); + await ocrButton.click(); + + await expect(ocrBoxes).toHaveCount(1); + await expect(ocrBoxes.first()).toContainText('Second Asset Text'); + }); +}); + +test.describe('OCR boxes and zoom', () => { + const fixture = setupAssetViewerFixture(922); + + test.beforeEach(async ({ context }) => { + const primaryAssetDto = toAssetResponseDto(fixture.primaryAsset); + const ocrDataByAssetId = new Map([ + [primaryAssetDto.id, createMockOcrData(primaryAssetDto.id, PRIMARY_OCR_BOXES)], + ]); + + await setupOcrMockApiRoutes(context, ocrDataByAssetId); + }); + + test('OCR boxes scale with zoom', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + const ocrButton = page.getByLabel('Text recognition'); + await expect(ocrButton).toBeVisible(); + await ocrButton.click(); + + const ocrBox = page.locator('[data-viewer-content] [data-testid="ocr-box"]').first(); + await expect(ocrBox).toBeVisible(); + + const initialBox = await ocrBox.boundingBox(); + expect(initialBox).toBeTruthy(); + + const { width, height } = page.viewportSize()!; + await page.mouse.move(width / 2, height / 2); + await page.mouse.wheel(0, -3); + + await expect(async () => { + const zoomedBox = await ocrBox.boundingBox(); + expect(zoomedBox).toBeTruthy(); + expect(zoomedBox!.width).toBeGreaterThan(initialBox!.width); + expect(zoomedBox!.height).toBeGreaterThan(initialBox!.height); + }).toPass({ timeout: 2000 }); + }); +}); + +test.describe('OCR text interaction', () => { + const fixture = setupAssetViewerFixture(923); + + test.beforeEach(async ({ context }) => { + const primaryAssetDto = toAssetResponseDto(fixture.primaryAsset); + const ocrDataByAssetId = new Map([ + [primaryAssetDto.id, createMockOcrData(primaryAssetDto.id, PRIMARY_OCR_BOXES)], + ]); + + await setupOcrMockApiRoutes(context, ocrDataByAssetId); + }); + + test('OCR text box has data-overlay-interactive attribute', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + await page.getByLabel('Text recognition').click(); + + const ocrBox = page.locator('[data-viewer-content] [data-testid="ocr-box"]').first(); + await expect(ocrBox).toBeVisible(); + await expect(ocrBox).toHaveAttribute('data-overlay-interactive'); + }); + + test('OCR text box receives focus on click', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + await page.getByLabel('Text recognition').click(); + + const ocrBox = page.locator('[data-viewer-content] [data-testid="ocr-box"]').first(); + await expect(ocrBox).toBeVisible(); + + await ocrBox.click(); + await expect(ocrBox).toBeFocused(); + }); + + test('dragging on OCR text box does not trigger image pan', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + await page.getByLabel('Text recognition').click(); + + const ocrBox = page.locator('[data-viewer-content] [data-testid="ocr-box"]').first(); + await expect(ocrBox).toBeVisible(); + + const imgLocator = page.locator('[data-viewer-content] img[draggable="false"]'); + const initialTransform = await imgLocator.evaluate((element) => { + return getComputedStyle(element.closest('[style*="transform"]') ?? element).transform; + }); + + const box = await ocrBox.boundingBox(); + expect(box).toBeTruthy(); + const centerX = box!.x + box!.width / 2; + const centerY = box!.y + box!.height / 2; + + await page.mouse.move(centerX, centerY); + await page.mouse.down(); + await page.mouse.move(centerX + 50, centerY + 30, { steps: 5 }); + await page.mouse.up(); + + const afterTransform = await imgLocator.evaluate((element) => { + return getComputedStyle(element.closest('[style*="transform"]') ?? element).transform; + }); + expect(afterTransform).toBe(initialTransform); + }); + + test('split touch gesture across zoom container does not trigger zoom', async ({ page }) => { + await page.goto(`/photos/${fixture.primaryAsset.id}`); + await assetViewerUtils.waitForViewerLoad(page, fixture.primaryAsset); + + await page.getByLabel('Text recognition').click(); + const ocrBox = page.locator('[data-viewer-content] [data-testid="ocr-box"]').first(); + await expect(ocrBox).toBeVisible(); + + const imgLocator = page.locator('[data-viewer-content] img[draggable="false"]'); + const initialTransform = await imgLocator.evaluate((element) => { + return getComputedStyle(element.closest('[style*="transform"]') ?? element).transform; + }); + + const viewerContent = page.locator('[data-viewer-content]'); + const viewerBox = await viewerContent.boundingBox(); + expect(viewerBox).toBeTruthy(); + + // Dispatch a synthetic split gesture: one touch inside the viewer, one outside + await page.evaluate( + ({ viewerCenterX, viewerCenterY, outsideY }) => { + const viewer = document.querySelector('[data-viewer-content]'); + if (!viewer) { + return; + } + + const createTouch = (id: number, x: number, y: number) => { + return new Touch({ + identifier: id, + target: viewer, + clientX: x, + clientY: y, + }); + }; + + const insideTouch = createTouch(0, viewerCenterX, viewerCenterY); + const outsideTouch = createTouch(1, viewerCenterX, outsideY); + + const touchStartEvent = new TouchEvent('touchstart', { + touches: [insideTouch, outsideTouch], + targetTouches: [insideTouch], + changedTouches: [insideTouch, outsideTouch], + bubbles: true, + cancelable: true, + }); + + const touchMoveEvent = new TouchEvent('touchmove', { + touches: [createTouch(0, viewerCenterX, viewerCenterY - 30), createTouch(1, viewerCenterX, outsideY + 30)], + targetTouches: [createTouch(0, viewerCenterX, viewerCenterY - 30)], + changedTouches: [ + createTouch(0, viewerCenterX, viewerCenterY - 30), + createTouch(1, viewerCenterX, outsideY + 30), + ], + bubbles: true, + cancelable: true, + }); + + const touchEndEvent = new TouchEvent('touchend', { + touches: [], + targetTouches: [], + changedTouches: [insideTouch, outsideTouch], + bubbles: true, + cancelable: true, + }); + + viewer.dispatchEvent(touchStartEvent); + viewer.dispatchEvent(touchMoveEvent); + viewer.dispatchEvent(touchEndEvent); + }, + { + viewerCenterX: viewerBox!.x + viewerBox!.width / 2, + viewerCenterY: viewerBox!.y + viewerBox!.height / 2, + outsideY: 10, // near the top of the page, outside the viewer + }, + ); + + const afterTransform = await imgLocator.evaluate((element) => { + return getComputedStyle(element.closest('[style*="transform"]') ?? element).transform; + }); + expect(afterTransform).toBe(initialTransform); + }); +}); diff --git a/e2e/src/ui/specs/search/search-gallery.e2e-spec.ts b/e2e/src/ui/specs/search/search-gallery.e2e-spec.ts index c3721b1c54..87f809de75 100644 --- a/e2e/src/ui/specs/search/search-gallery.e2e-spec.ts +++ b/e2e/src/ui/specs/search/search-gallery.e2e-spec.ts @@ -6,6 +6,7 @@ import { generateTimelineData, TimelineAssetConfig, TimelineData, + toAssetResponseDto, } from 'src/ui/generators/timeline'; import { setupBaseMockApiRoutes } from 'src/ui/mock-network/base-network'; import { setupTimelineMockApiRoutes, TimelineTestContext } from 'src/ui/mock-network/timeline-network'; @@ -30,6 +31,10 @@ test.describe('search gallery-viewer', () => { }; 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', + ); adminUserId = faker.string.uuid(); testContext.adminId = adminUserId; timelineRestData = generateTimelineData({ ...createDefaultTimelineConfig(), ownerId: adminUserId }); @@ -44,7 +49,10 @@ test.describe('search gallery-viewer', () => { await context.route('**/api/search/metadata', async (route, request) => { if (request.method() === 'POST') { - const searchAssets = assets.slice(0, 5).filter((asset) => !changes.assetDeletions.includes(asset.id)); + const searchAssets = assets + .slice(0, 5) + .filter((asset) => !changes.assetDeletions.includes(asset.id)) + .map((asset) => toAssetResponseDto(asset)); return route.fulfill({ status: 200, contentType: 'application/json', diff --git a/e2e/src/ui/specs/timeline/utils.ts b/e2e/src/ui/specs/timeline/utils.ts index b7003295cf..e67229d3c9 100644 --- a/e2e/src/ui/specs/timeline/utils.ts +++ b/e2e/src/ui/specs/timeline/utils.ts @@ -62,7 +62,7 @@ export const thumbnailUtils = { 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`); + return page.locator(`[data-thumbnail-focus-container][data-asset="${assetId}"] button[role="checkbox"]`); }, selectedAsset(page: Page) { return page.locator('[data-thumbnail-focus-container][data-selected]'); diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index a5567f0778..4d44d99e2f 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -510,6 +510,9 @@ export const utils = { createStack: (accessToken: string, assetIds: string[]) => createStack({ stackCreateDto: { assetIds } }, { headers: asBearerAuth(accessToken) }), + setAssetDuplicateId: (accessToken: string, assetId: string, duplicateId: string | null) => + updateAssets({ assetBulkUpdateDto: { ids: [assetId], duplicateId } }, { headers: asBearerAuth(accessToken) }), + upsertTags: (accessToken: string, tags: string[]) => upsertTags({ tagUpsertDto: { tags } }, { headers: asBearerAuth(accessToken) }), diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index f6efbf41e9..61eefdac07 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -14,8 +14,10 @@ "outDir": "./dist", "incremental": true, "skipLibCheck": true, + "paths": { + "src/*": ["./src/*"] + }, "esModuleInterop": true, - "baseUrl": "./" }, "include": ["src/**/*.ts", "vitest*.config.ts"], "exclude": ["dist", "node_modules"] diff --git a/i18n/af.json b/i18n/af.json index e641c07b21..95919bb1dc 100644 --- a/i18n/af.json +++ b/i18n/af.json @@ -178,6 +178,17 @@ "stop_motion_photo": "Stop bewegingsfoto", "stop_photo_sharing": "Staak die deel van u foto’s?", "stop_photo_sharing_description": "{partner} sal nie meer toegang tot u foto’s hÃĒ nie.", + "unnamed_share": "Naamlose deelskakel", + "unsaved_change": "Onbewaarde verandering", + "unselect_all": "Ontkies alles", + "unselect_all_duplicates": "Ontkies alle duplikate", + "unselect_all_in": "Ontkies alles in {group}", + "unstack": "Ontstapel", + "unstack_action_prompt": "{count} ongestapel", + "unstacked_assets_count": "{count, plural, one {# item} other {# items}} ontstapel", + "unsupported_field_type": "Onondersteunde veldtipe", + "unsupported_file_type": "LÃĒer {file} kan nie opgelaai word nie omdat die lÃĒertipe {type} nie ondersteun word nie.", + "untagged": "Sonder etiket", "untitled_workflow": "Naamlose werkvloei", "up_next": "Volgende", "update_location_action_prompt": "Werk die ligging van {count} gekose items by met:", @@ -187,6 +198,7 @@ "upload_concurrency": "Aantal gelyktydige oplaaie", "upload_details": "Oplaaidetails", "upload_dialog_info": "Wil u ’n rugsteun maak van die gekose item(s) op die bediener?", + "upload_dialog_title": "Laai item op", "upload_error_with_count": "Oplaaifout vir {count, plural, one {# item} other {# items}}", "upload_errors": "Oplaai voltooi met {count, plural, one {# fout} other {# foute}}, verfris die blad om die nuwe items te sien.", "upload_finished": "Klaar opgelaai", @@ -257,6 +269,7 @@ "viewer_remove_from_stack": "Verwyder van stapel", "viewer_stack_use_as_main_asset": "Gebruik as hoofitem", "viewer_unstack": "Ontstapel", + "visibility": "Sigbaarheid", "visibility_changed": "Sigbaarheid verander vir {count, plural, one {# mens} other {# mense}}", "visual": "Visueel", "visual_builder": "Visuele bouer", diff --git a/i18n/ar.json b/i18n/ar.json index 3834d76a5f..fe0b9d072c 100644 --- a/i18n/ar.json +++ b/i18n/ar.json @@ -3,7 +3,7 @@ "account": "Ø­ØŗØ§Ø¨", "account_settings": "ØĨؚداداØĒ Ø§Ų„Ø­ØŗØ§Ø¨", "acknowledge": "ØŖŲØ¯ØąŲƒ Ø°Ų„Ųƒ", - "action": "ØšŲ…Ų„ŲŠØŠ", + "action": "ØĨØŦØąØ§ØĄ", "action_common_update": "ØĒØ­Ø¯ŲŠØĢ", "action_description": "Ų…ØŦŲ…ŲˆØšØŠ Ų…Ų† Ø§Ų„ŲØšØ§Ų„ŲŠØ§ØĒ Ø§Ų„ØĒ؊ ØŗØĒŲ†ŲØ° ØšŲ„Ų‰ Ø§Ų„ØŖØĩŲˆŲ„ Ø§Ų„ØĒ؊ ØĒŲ… ØĒØĩ؁؊ØĒŲ‡Ø§", "actions": "ØšŲ…Ų„ŲŠØ§ØĒ", @@ -61,8 +61,8 @@ "backup_onboarding_1_description": "Ų†ØŗØŽØŠ ØŽØ§ØąØŦ Ø§Ų„Ų…ŲˆŲ‚Øš ؁؊ Ų…ŲˆŲ‚Øš ØĸØŽØą.", "backup_onboarding_2_description": "Ų†ØŗØŽ Ų…Ø­Ų„ŲŠØŠ ØšŲ„Ų‰ ØŖØŦŲ‡Ø˛ØŠ Ų…ØŽØĒŲ„ŲØŠ. ŲŠØ´Ų…Ų„ Ø°Ų„Ųƒ Ø§Ų„Ų…Ų„ŲØ§ØĒ Ø§Ų„ØąØĻŲŠØŗŲŠØŠ ŲˆŲ†ØŗØŽØŠ احØĒŲŠØ§ØˇŲŠØŠ Ų…Ø­Ų„ŲŠØŠ Ų…Ų†Ų‡Ø§.", "backup_onboarding_3_description": "ØĨØŦŲ…Ø§Ų„ŲŠ Ų†ŲØŗØŽ Ø¨ŲŠØ§Ų†Ø§ØĒŲƒØŒ Ø¨Ų…Ø§ ؁؊ Ø°Ų„Ųƒ Ø§Ų„Ų…Ų„ŲØ§ØĒ Ø§Ų„ØŖØĩŲ„ŲŠØŠ. ŲŠØ´Ų…Ų„ Ø°Ų„Ųƒ Ų†ØŗØŽØŠŲ‹ ŲˆØ§Ø­Ø¯ØŠŲ‹ ØŽØ§ØąØŦ Ø§Ų„Ų…ŲˆŲ‚Øš ŲˆŲ†ØŗØŽØĒŲŠŲ† Ų…Ø­Ų„ŲŠØĒŲŠŲ†.", - "backup_onboarding_description": "ŲŠŲŲ†ØĩØ­ باØĒباؚ Ø§ØŗØĒØąØ§ØĒ؊ØŦŲŠØŠ Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠ 3-2-1 Ų„Ø­Ų…Ø§ŲŠØŠ Ø¨ŲŠØ§Ų†Ø§ØĒ؃. احØĒŲØ¸ Ø¨Ų†ØŗØŽ احØĒŲŠØ§ØˇŲŠØŠ Ų…Ų† ØĩŲˆØąŲƒ/ŲŲŠØ¯ŲŠŲˆŲ‡Ø§ØĒ؃ Ø§Ų„Ų…Ø­Ų…Ų‘Ų„ØŠØŒ Ø¨Ø§Ų„ØĨØļØ§ŲØŠ ØĨŲ„Ų‰ Ų‚Ø§ØšØ¯ØŠ Ø¨ŲŠØ§Ų†Ø§ØĒ Immich، Ų„ØļŲ…Ø§Ų† Ø­Ų„ Ų†ØŗØŽ احØĒŲŠØ§ØˇŲŠ Ø´Ø§Ų…Ų„.", - "backup_onboarding_footer": "Ų„Ų…Ø˛ŲŠØ¯ Ų…Ų† Ø§Ų„Ų…ØšŲ„ŲˆŲ…Ø§ØĒ Ø­ŲˆŲ„ Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠ Ų„Ų€ Immich، ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ Ø§Ų„ØĒØšŲ„ŲŠŲ…Ø§ØĒ .", + "backup_onboarding_description": "ŲŠŲŲ†ØĩØ­ باØĒباؚ Ø§ØŗØĒØąØ§ØĒ؊ØŦŲŠØŠ Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠ 3-2- 1 Ų„Ø­Ų…Ø§ŲŠØŠ Ø¨ŲŠØ§Ų†Ø§ØĒ؃. احØĒŲØ¸ Ø¨Ų†ØŗØŽ احØĒŲŠØ§ØˇŲŠØŠ Ų…Ų† ØĩŲˆØąŲƒ/ŲŲŠØ¯ŲŠŲˆŲ‡Ø§ØĒ؃ Ø§Ų„Ų…Ø­Ų…Ų‘Ų„ØŠØŒ Ø¨Ø§Ų„ØĨØļØ§ŲØŠ ØĨŲ„Ų‰ Ų‚Ø§ØšØ¯ØŠ Ø¨ŲŠØ§Ų†Ø§ØĒ Immich، Ų„ØļŲ…Ø§Ų† Ø­Ų„ Ų†ØŗØŽ احØĒŲŠØ§ØˇŲŠ Ø´Ø§Ų…Ų„.", + "backup_onboarding_footer": "Ų„Ų…Ø˛ŲŠØ¯ Ų…Ų† Ø§Ų„Ų…ØšŲ„ŲˆŲ…Ø§ØĒ Ø­ŲˆŲ„ Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠ Ų„Ų€ Immich، ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ Ø§Ų„ŲˆØĢاØĻŲ‚.", "backup_onboarding_parts_title": "؊ØĒØļŲ…Ų† Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠ 3-2-1 Ų…Ø§ ŲŠŲ„ŲŠ:", "backup_onboarding_title": "Ø§Ų„Ų†ØŗØŽ Ø§Ų„Ø§Ø­ØĒŲŠØ§ØˇŲŠØŠ", "backup_settings": "ØĨؚداداØĒ ØĒŲØąŲŠØē Ų‚Ø§ØšØ¯ØŠ Ø§Ų„Ø¨ŲŠØ§Ų†Ø§ØĒ", @@ -333,7 +333,7 @@ "storage_template_migration_description": "Ų‚Ų… بØĒØˇØ¨ŲŠŲ‚ Ø§Ų„Ų‚Ø§Ų„Ø¨ Ø§Ų„Ø­Ø§Ų„ŲŠ {template} ØšŲ„Ų‰ Ø§Ų„Ų…Ø­ØĒŲˆŲŠØ§ØĒ Ø§Ų„ØĒ؊ ØĒŲ… ØąŲØšŲ‡Ø§ ØŗØ§Ø¨Ų‚Ų‹Ø§", "storage_template_migration_info": "ØĒØēŲŠŲŠØąØ§ØĒ Ø§Ų„Ų†Ų…ŲˆØ°ØŦ Ø§Ų„ØŽØ˛Ų†ŲŠ ØŗØĒØēŲŠØą ØŦŲ…ŲŠØš Ø§Ų„Øĩ؊Øē Ø§Ų„Ų‰ Ø§Ø­ØąŲ ØĩØēŲŠØąØŠ. ØĒØēŲŠŲŠØąØ§ØĒ Ø§Ų„Ų†Ų…ŲˆØ°ØŦ ØŗØĒŲ†ØˇØ¨Ų‚ ŲŲ‚Øˇ ØšŲ„Ų‰ Ø§Ų„Ų…Ø­ØĒŲˆŲŠØ§ØĒ Ø§Ų„ØŦØ¯ŲŠØ¯ØŠ. Ų„ØĒØˇØ¨ŲŠŲ‚ Ø§Ų„Ų†Ų…ŲˆØ°ØŦ ØšŲ„Ų‰ Ø§Ų„Ų…Ø­ØĒŲˆŲŠØ§ØĒ Ø§Ų„ØĒ؊ ØĒŲ… ØąŲØšŲ‡Ø§ ØŗØ§Ø¨Ų‚Ų‹Ø§ØŒ Ų‚Ų… بØĒØ´ØēŲŠŲ„ {job}.", "storage_template_migration_job": "ŲˆØ¸ŲŠŲØŠ ØĒŲ‡ØŦŲŠØą Ų‚Ø§Ų„Ø¨ Ø§Ų„ØĒØŽØ˛ŲŠŲ†", - "storage_template_more_details": "Ų„Ų…Ø˛ŲŠØ¯ Ų…Ų† Ø§Ų„ØĒŲØ§ØĩŲŠŲ„ Ø­ŲˆŲ„ Ų‡Ø°Ų‡ Ø§Ų„Ų…ŲŠØ˛ØŠØŒ ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ Storage Template ؈implications", + "storage_template_more_details": "Ų„Ų…Ø˛ŲŠØ¯ Ų…Ų† Ø§Ų„ØĒŲØ§ØĩŲŠŲ„ Ø­ŲˆŲ„ Ų‡Ø°Ų‡ Ø§Ų„Ų…ŲŠØ˛ØŠØŒ ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ Storage Template ؈ implications.", "storage_template_onboarding_description_v2": "ØšŲ†Ø¯ Ø§Ų„ØĒŲØšŲŠŲ„. Ų‡Ø°Ų‡ Ø§Ų„ØŽØ§ØĩŲŠØŠ ØŗØĒŲ‚ŲˆŲ… Ø¨Ø§Ų„ØĒØąØĒŲŠØ¨ Ø§Ų„ØĒŲ„Ų‚Ø§ØĻ؊ Ų„Ų„Ų…Ų„ŲØ§ØĒ Ø¨Ų†Ø§ØĄ ØšŲ„Ų‰ Ų†Ų…ŲˆØ°ØŦ Ų…ØšØąŲ Ų…Ų† Ų‚Ø¨Ų„ Ø§Ų„Ų…ØŗØĒØŽØ¯Ų…. ØąØŦØ§ØĄ Ø§ØˇŲ„Øš ØšŲ„Ų‰ Ø§Ų„ØĒ؈ØĢŲŠŲ‚.", "storage_template_path_length": "Ø§Ų„Ø­Ø¯ Ø§Ų„ØĒŲ‚ØąŲŠØ¨ŲŠ Ų„ØˇŲˆŲ„ Ø§Ų„Ų…ØŗØ§Øą: {length, number}/{limit, number}", "storage_template_settings": "Ų‚Ø§Ų„Ø¨ Ø§Ų„ØĒØŽØ˛ŲŠŲ†", @@ -372,7 +372,7 @@ "transcoding_audio_codec": "ŲƒŲˆØ¯ Ø§Ų„Øĩ؈ØĒ", "transcoding_audio_codec_description": "Opus Ų‡Ųˆ Ø§Ų„ØŽŲŠØ§Øą Ø°Ųˆ ØŖØšŲ„Ų‰ ØŦŲˆØ¯ØŠØŒ ŲˆŲ„ŲƒŲ†Ų‡ ؊ØĒŲ…ØĒØš بØĒŲˆØ§ŲŲ‚ ØŖŲ‚Ų„ Ų…Øš Ø§Ų„ØŖØŦŲ‡Ø˛ØŠ ØŖŲˆ Ø§Ų„Ø¨ØąŲ…ØŦŲŠØ§ØĒ Ø§Ų„Ų‚Ø¯ŲŠŲ…ØŠ.", "transcoding_bitrate_description": "Ų…Ų‚Ø§ØˇØš Ø§Ų„ŲŲŠØ¯ŲŠŲˆ Ø§Ų„ØĒ؊ ؊ØĒØŦØ§ŲˆØ˛ Ų…ØšØ¯Ų„ Ø§Ų„Ø¨ØĒ ØŖŲ‚ØĩŲ‰ Ų‚ŲŠŲ…ØŠ ØŖŲˆ Ø§Ų„ØĒ؊ Ų„Ø§ ØĒŲƒŲˆŲ† ؁؊ ØĒŲ†ØŗŲŠŲ‚ Ų…Ų‚Ø¨ŲˆŲ„", - "transcoding_codecs_learn_more": "Ų„Ų…ØšØąŲØŠ Ø§Ų„Ų…Ø˛ŲŠØ¯ Ø­ŲˆŲ„ Ø§Ų„Ų…ØĩØˇŲ„Ø­Ø§ØĒ Ø§Ų„Ų…ØŗØĒØŽØ¯Ų…ØŠ Ų‡Ų†Ø§ØŒ ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ ؈ØĢاØĻŲ‚ FFmpeg Ų„Ų„H.264 codec, HEVC codec and VP9 codec.", + "transcoding_codecs_learn_more": "Ų„Ų…ØšØąŲØŠ Ø§Ų„Ų…Ø˛ŲŠØ¯ Ø­ŲˆŲ„ Ø§Ų„Ų…ØĩØˇŲ„Ø­Ø§ØĒ Ø§Ų„Ų…ØŗØĒØŽØ¯Ų…ØŠ Ų‡Ų†Ø§ØŒ ŲŠØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ ؈ØĢاØĻŲ‚ FFmpeg Ų„Ų€ H.264 codec، ؈ HEVC codec ؈ VP9 codec.", "transcoding_constant_quality_mode": "؈ØļØš Ø§Ų„ØŦŲˆØ¯ØŠ Ø§Ų„ØĢابØĒØŠ", "transcoding_constant_quality_mode_description": "ICQ ØŖŲØļŲ„ Ų…Ų† CQP، ŲˆŲ„ŲƒŲ† بؚØļ ØŖØŦŲ‡Ø˛ØŠ ØšØĒاد Ø§Ų„ØĒØŗØąŲŠØš Ų„Ø§ ØĒØ¯ØšŲ… Ų‡Ø°Ø§ Ø§Ų„ŲˆØļØš. ØĒØšŲŠŲŠŲ† Ų‡Ø°Ø§ Ø§Ų„ØŽŲŠØ§Øą ŲŠØŗØŦØšŲ„ Ø§Ų„ØŖŲØļŲ„ŲŠØŠ Ų„Ų„ŲˆØļØš Ø§Ų„Ų…Ø­Ø¯Ø¯ ØšŲ†Ø¯ Ø§ØŗØĒØŽØ¯Ø§Ų… Ø§Ų„ØĒØąŲ…ŲŠØ˛ Ø¨Ų†Ø§ØĄŲ‹ ØšŲ„Ų‰ Ø§Ų„ØŦŲˆØ¯ØŠ. ؊ØĒŲ… ØĒØŦØ§Ų‡Ų„Ų‡ Ø¨ŲˆØ§ØŗØˇØŠ NVENC Ų„ØŖŲ†Ų‡ Ų„Ø§ ŲŠØ¯ØšŲ… ICQ.", "transcoding_constant_rate_factor": "ØšØ§Ų…Ų„ Ų…ØšØ¯Ų„ Ø§Ų„ØŦŲˆØ¯ØŠ Ø§Ų„ØĢابØĒ (-crf)", @@ -441,7 +441,7 @@ "user_successfully_removed": "Ø§Ų„Ų…ØŗØĒØŽØ¯Ų… {email} ØĒŲ…ØĒ Ø§Ø˛Ø§Ų„ØĒŲ‡ Ø¨Ų†ØŦاح.", "users_page_description": "ØĩŲØ­ØŠ Ø§Ø¯Ø§ØąØŠ Ø§Ų„Ų…ØŗØĒØŽØ¯Ų…ŲŠŲ†", "version_check_enabled_description": "ØĒŲØšŲŠŲ„ Ø§Ų„ØĒØ­Ų‚Ų‚ Ų…Ų† Ø§Ų„ØĨØĩØ¯Ø§ØąØ§ØĒ Ø§Ų„ØŦØ¯ŲŠØ¯ØŠ", - "version_check_implications": "ØĒØšØĒŲ…Ø¯ Ų…ŲŠØ˛ØŠ Ø§Ų„ØĒØ­Ų‚Ų‚ Ų…Ų† Ø§Ų„ØĨØĩØ¯Ø§Øą ØšŲ„Ų‰ Ø§Ų„ØĒŲˆØ§ØĩŲ„ Ø§Ų„Ø¯ŲˆØąŲŠ Ų…Øš github.com", + "version_check_implications": "ØĒØšØĒŲ…Ø¯ Ų…ŲŠØ˛ØŠ Ø§Ų„ØĒØ­Ų‚Ų‚ Ų…Ų† Ø§Ų„ØĨØĩØ¯Ø§Øą ØšŲ„Ų‰ Ø§Ų„ØĒŲˆØ§ØĩŲ„ Ø§Ų„Ø¯ŲˆØąŲŠ Ų…Øš {server}", "version_check_settings": "Ø§Ų„ØĒØ­Ų‚Ų‚ Ų…Ų† Ø§Ų„ØĨØĩØ¯Ø§Øą", "version_check_settings_description": "ØĒŲØšŲŠŲ„/ØĒØšØˇŲŠŲ„ Ø§Ų„ØĨØ´ØšØ§Øą Ų„ØĨØĩØ¯Ø§Øą ØŦØ¯ŲŠØ¯", "video_conversion_job": "ØĒØ­ŲˆŲŠŲ„ ØŖØ´ØąØˇØŠ Ø§Ų„ŲŲŠØ¯ŲŠŲˆ", @@ -849,9 +849,12 @@ "create_link_to_share": "ØĨŲ†Ø´Ø§ØĄ ØąØ§Ø¨Øˇ Ų„Ų„Ų…Ø´Ø§ØąŲƒØŠ", "create_link_to_share_description": "Ø§Ų„ØŗŲ…Ø§Ø­ Ų„ØŖŲŠ Ø´ØŽØĩ Ų„Ø¯ŲŠŲ‡ Ø§Ų„ØąØ§Ø¨Øˇ Ø¨Ų…Ø´Ø§Ų‡Ø¯ØŠ Ø§Ų„ØĩŲˆØąØŠ (Ø§Ų„ØĩŲˆØą) Ø§Ų„Ų…Ø­Ø¯Ø¯ØŠ", "create_new": "Ø§Ų†Ø´Ø§ØĄ ØŦØ¯ŲŠØ¯", + "create_new_face": "ØĨŲ†Ø´Ø§ØĄ ؈ØŦŲ‡ ØŦØ¯ŲŠØ¯", "create_new_person": "ØĨŲ†Ø´Ø§ØĄ Ø´ØŽØĩ ØŦØ¯ŲŠØ¯", "create_new_person_hint": "ØĒØšŲŠŲŠŲ† Ø§Ų„Ų…Ø­ØĒŲˆŲŠØ§ØĒ Ø§Ų„Ų…Ø­Ø¯Ø¯ØŠ Ų„Ø´ØŽØĩ ØŦØ¯ŲŠØ¯", "create_new_user": "ØĨŲ†Ø´Ø§ØĄ Ų…ØŗØĒØŽØ¯Ų… ØŦØ¯ŲŠØ¯", + "create_person": "ØĨŲ†Ø´Ø§ØĄ Ø´ØŽØĩ", + "create_person_subtitle": "ØŖØļ؁ Ø§ØŗŲ…Ø§Ų‹ Ų„Ų„ŲˆØŦŲ‡ Ø§Ų„Ų…Ø­Ø¯Ø¯ Ų„ØĨŲ†Ø´Ø§ØĄ Ø§Ų„Ø´ØŽØĩ Ø§Ų„ØŦØ¯ŲŠØ¯ ŲˆØ§Ų„ØĨØ´Ø§ØąØŠ ØĨŲ„ŲŠŲ‡", "create_shared_album_page_share_add_assets": "ØĨØļØ§ŲØŠ Ø§Ų„ØŖØĩŲˆŲ„", "create_shared_album_page_share_select_photos": "حدد Ø§Ų„ØĩŲˆØą", "create_shared_link": "Ø§Ų†Ø´Ø§ØĄ ØąØ§Ø¨Øˇ Ų…Ø´ØĒØąŲƒ", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "ØĒŲ… Ø§Ų„Ø§ØĩŲ„Ø§Ø­", "crop_aspect_ratio_free": "Ø­Øą", "crop_aspect_ratio_original": "اØĩŲ„ŲŠ", + "crop_aspect_ratio_square": "Ų…ØąØ¨Øš", "curated_object_page_title": "ØŖØ´ŲŠØ§ØĄ", "current_device": "Ø§Ų„ØŦŲ‡Ø§Ø˛ Ø§Ų„Ø­Ø§Ų„ŲŠ", "current_pin_code": "ØąŲ…Ø˛ PIN Ø§Ų„Ø­Ø§Ų„ŲŠ", @@ -880,7 +884,7 @@ "daily_title_text_date": "E ، MMM DD", "daily_title_text_date_year": "E ، MMM DD ، yyyy", "dark": "Ų…ØšØĒŲ…", - "dark_theme": "ØĒØ¨Ø¯ŲŠŲ„ Ø§Ų„Ų…Ø¸Ų‡Øą Ø§Ų„Ø¯Ø§ŲƒŲ†", + "dark_theme": "ØĒØ¨Ø¯ŲŠŲ„ Ø§Ų„Ų…Ø¸Ų‡Øą ØĨŲ„Ų‰ Ø§Ų„Ø¯Ø§ŲƒŲ†", "date": "ØĒØ§ØąŲŠØŽ", "date_after": "Ø§Ų„ØĒØ§ØąØŽ بؚد", "date_and_time": "Ø§Ų„ØĒØ§ØąŲŠØŽ ؈ Ø§Ų„ŲˆŲ‚ØĒ", @@ -891,10 +895,8 @@ "day": "ŲŠŲˆŲ…", "days": "Ø§ŲŠØ§Ų…", "deduplicate_all": "ØĨŲ„ØēØ§ØĄ ØĒŲƒØąØ§Øą Ø§Ų„ŲƒŲ„", - "deduplication_criteria_1": "Ø­ØŦŲ… Ø§Ų„ØĩŲˆØąØŠ Ø¨ŲˆØ­Ø¯Ø§ØĒ Ø§Ų„Ø¨Ø§ŲŠØĒ", - "deduplication_criteria_2": "ؚدد Ø¨ŲŠØ§Ų†Ø§ØĒ EXIF", - "deduplication_info": "Ų…ØšŲ„ŲˆŲ…Ø§ØĒ ØĨŲ„ØēØ§ØĄ Ø§Ų„Ø¨ŲŠØ§Ų†Ø§ØĒ Ø§Ų„Ų…ŲƒØąØąØŠ", - "deduplication_info_description": "Ų„ØĒØ­Ø¯ŲŠØ¯ Ø§Ų„ØŖØĩŲˆŲ„ Ų…ØŗØ¨Ų‚Ø§ ØĒŲ„Ų‚Ø§ØĻŲŠØ§ ؈ØĨØ˛Ø§Ų„ØŠ Ø§Ų„ØĒŲƒØąØ§ØąØ§ØĒ Ø¨ŲƒŲ…ŲŠØ§ØĒ ŲƒØ¨ŲŠØąØŠØŒ Ų†Ų†Ø¸Øą ØĨŲ„Ų‰:", + "default_locale": "Ø§Ų„ØĨؚداداØĒ Ø§Ų„Ų…Ø­Ų„ŲŠØŠ Ø§Ų„Ø§ŲØĒØąØ§ØļŲŠØŠ", + "default_locale_description": "ØĒŲ†ØŗŲŠŲ‚ Ø§Ų„ØĒŲˆØ§ØąŲŠØŽ ŲˆØ§Ų„ØŖØąŲ‚Ø§Ų… Ø¨Ų†Ø§ØĄŲ‹ ØšŲ„Ų‰ Ø§Ų„ØĨؚداداØĒ Ø§Ų„Ų…Ø­Ų„ŲŠØŠ Ų„Ų„Ų…ØĒØĩŲØ­", "delete": "Ø­Ø°Ų", "delete_action_confirmation_message": "Ų‡Ų„ Ø§Ų†ØĒ Ų…ØĒØŖŲƒØ¯ Ų…Ų† Ø­Ø°Ų Ų‡Ø°Ø§ Ø§Ų„Ų…Ų„ŲØŸ Ų‡Ø°Ø§ ØŗØ¤Ø¯ŲŠ Ø§Ų„Ų‰ Ų†Ų‚Ų„ Ø§Ų„Ų…Ų„Ų Ø§Ų„Ų‰ ØŗŲ„ØŠ Ų…Ų‡Ų…Ų„Ø§ØĒ Ø§Ų„ØŽØ§Ø¯Ų… ŲˆØŗŲŠØĒŲ… Ø§Ø´ØšØ§ØąŲƒ Ø§Ų† ŲƒŲ†ØĒ ØĒØąŲŠØ¯ Ø­Ø°ŲŲ‡ ØšŲ„Ų‰ Ø§Ų„ØŦŲ‡Ø§Ø˛", "delete_action_prompt": "ØĒŲ… Ø­Ø°Ų {count}", @@ -970,7 +972,7 @@ "downloading_media": "ØĒŲ†Ø˛ŲŠŲ„ Ø§Ų„ŲˆØŗØ§ØĻØˇ", "drop_files_to_upload": "Ų‚Ų… بØĨØŗŲ‚Ø§Øˇ Ø§Ų„Ų…Ų„ŲØ§ØĒ ؁؊ ØŖŲŠ Ų…ŲƒØ§Ų† Ų„ØąŲØšŲ‡Ø§", "duplicates": "Ø§Ų„ØĒŲƒØąØ§ØąØ§ØĒ", - "duplicates_description": "Ų‚Ų… Ø¨Ø­Ų„ ŲƒŲ„ Ų…ØŦŲ…ŲˆØšØŠ Ų…Ų† ØŽŲ„Ø§Ų„ Ø§Ų„ØĨØ´Ø§ØąØŠ ØĨŲ„Ų‰ Ø§Ų„ØĒŲƒØąØ§ØąØ§ØĒ، ØĨŲ† ؈ØŦدØĒ", + "duplicates_description": "Ų‚Ų… Ø¨Ø­Ų„ ŲƒŲ„ Ų…ØŦŲ…ŲˆØšØŠ Ų…Ų† ØŽŲ„Ø§Ų„ Ø§Ų„ØĨØ´Ø§ØąØŠ ØĨŲ„Ų‰ Ø§Ų„ØĒŲƒØąØ§ØąØ§ØĒ، ØĨŲ† ؈ØŦدØĒ.", "duration": "Ø§Ų„Ų…Ø¯ØŠ", "edit": "ØĒØšØ¯ŲŠŲ„", "edit_album": "ØĒØšØ¯ŲŠŲ„ Ø§Ų„ØŖŲ„Ø¨ŲˆŲ…", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "ØšŲ†ŲˆØ§Ų† Ø§Ų„ØŖŲ„Ø¨ŲˆŲ…", "licenses": "ØąŲØŽŲŽØĩ", "light": "Ø§Ų„Ų…Øļ؊ØĻ", + "light_theme": "Ø§Ų„ØĒØ¨Ø¯ŲŠŲ„ ØĨŲ„Ų‰ Ø§Ų„Ų…Ø¸Ų‡Øą Ø§Ų„ŲØ§ØĒØ­", "like": "اؚØŦاب", "like_deleted": "ØĒŲ… Ø­Ø°Ų Ø§Ų„ØĨØšØŦاب", "link_motion_video": "ØąØ§Ø¨Øˇ ŲŲŠØ¯ŲŠŲˆ Ø§Ų„Ø­ØąŲƒØŠ", + "link_to_docs": "Ų„Ų…Ø˛ŲŠØ¯ Ų…Ų† Ø§Ų„Ų…ØšŲ„ŲˆŲ…Ø§ØĒ، ŲŠŲØąØŦŲ‰ Ø§Ų„ØąØŦŲˆØš ØĨŲ„Ų‰ Ø§Ų„ŲˆØĢاØĻŲ‚.", "link_to_oauth": "Ø§Ų„ØąØ¨Øˇ Ų…Øš OAuth", "linked_oauth_account": "Ø­ØŗØ§Ø¨ Ų…ØąØĒØ¨Øˇ Ø¨Ų€ OAuth", "list": "Ų‚Ø§ØĻŲ…ØŠ", @@ -1651,6 +1655,7 @@ "only_favorites": "Ø§Ų„Ų…ŲØļŲ„ØŠ ŲŲ‚Øˇ", "open": "؁ØĒØ­", "open_calendar": "Ø§ŲØĒØ­ Ø§Ų„ØąØ˛Ų†Ø§Ų…ØŠ", + "open_in_browser": "؁ØĒØ­ ؁؊ Ų…ØĒØĩŲØ­", "open_in_map_view": "؁ØĒØ­ ؁؊ ØšØąØļ Ø§Ų„ØŽØąŲŠØˇØŠ", "open_in_openstreetmap": "؁ØĒØ­ ؁؊ OpenStreetMap", "open_the_search_filters": "Ø§ŲØĒØ­ Ų…ØąØ´Ø­Ø§ØĒ Ø§Ų„Ø¨Ø­ØĢ", @@ -2212,6 +2217,7 @@ "tag": "Ø§Ų„ØšŲ„Ø§Ų…ØŠ", "tag_assets": "ØŖØĩŲˆŲ„ Ø§Ų„ØšŲ„Ø§Ų…ØŠ", "tag_created": "ØĒŲ… ØĨŲ†Ø´Ø§ØĄ Ø§Ų„ØšŲ„Ø§Ų…ØŠ: {tag}", + "tag_face": "ØšŲ„Ų‘ŲŲ… Ø§Ų„ŲˆØŦŲ‡", "tag_feature_description": "ØĒØĩŲØ­ Ø§Ų„ØĩŲˆØą ŲˆŲ…Ų‚Ø§ØˇØš Ø§Ų„ŲŲŠØ¯ŲŠŲˆ Ø§Ų„Ų…ØŦŲ…ØšØŠ Ø­ØŗØ¨ Ų…ŲˆØ§ØļŲŠØš Ø§Ų„ØšŲ„Ø§Ų…Ø§ØĒ Ø§Ų„Ų…Ų†ØˇŲ‚ŲŠØŠ", "tag_not_found_question": "Ų„Ø§ ŲŠŲ…ŲƒŲ† Ø§Ų„ØšØĢŲˆØą ØšŲ„Ų‰ ØšŲ„Ø§Ų…ØŠØŸ Ų‚Ų… بØĨŲ†Ø´Ø§ØĄ ØšŲ„Ø§Ų…ØŠ ØŦØ¯ŲŠØ¯ØŠ.", "tag_people": "ØšŲ„ŲŲ‘Ų… Ø§Ų„ØŖØ´ØŽØ§Øĩ", @@ -2386,13 +2392,14 @@ "view_name": "ØšØąØļ", "view_next_asset": "ØšØąØļ Ø§Ų„Ų…Ø­ØĒŲˆŲ‰ Ø§Ų„ØĒØ§Ų„ŲŠ", "view_previous_asset": "ØšØąØļ Ø§Ų„Ų…Ø­ØĒŲˆŲ‰ Ø§Ų„ØŗØ§Ø¨Ų‚", - "view_qr_code": "Â­ØšØąØļ ØąŲ…Ø˛ Ø§Ų„Ø§ØŗØĒØŦاب؊ Ø§Ų„ØŗØąŲŠØšØŠ", + "view_qr_code": "ØšØąØļ ØąŲ…Ø˛ Ø§Ų„Ø§ØŗØĒØŦاب؊ Ø§Ų„ØŗØąŲŠØšØŠ", "view_similar_photos": "ØšØąØļ ØĩŲˆØą Ų…Ø´Ø§Ø¨Ų‡ØŠ", "view_stack": "ØšØąØļ Ø§Ų„ØĒŲƒØ¯ŲŠØŗ", "view_user": "ØšØąØļ Ø§Ų„Ų…ØŗØĒØŽØ¯Ų…", "viewer_remove_from_stack": "Ø­Ø°Ų Ų…Ų† Ø§Ų„ŲƒŲˆŲ…Ų‡ ØŖŲˆ Ø§Ų„Ų…ØŦŲ…ŲˆØšØŠ", "viewer_stack_use_as_main_asset": "Ø§ØŗØĒØŽØ¯Ų… ŲƒØŖØĩŲ„ ØąØĻŲŠØŗŲŠ", "viewer_unstack": "؁؃ Ø§Ų„ŲƒŲˆŲ…Ų‡", + "visibility": "ØĨŲ…ŲƒØ§Ų†ŲŠØŠ Ø§Ų„ØąØ¤ŲŠØŠ", "visibility_changed": "Ø§Ų„ØąØ¤ŲŠØŠ ØĒØēŲŠØąØĒ Ų„Ų€ {count, plural, one {Ø´ØŽØĩ ŲˆØ§Ø­Ø¯} other {# ؚد؊ ØŖØ´ØŽØ§Øĩ}}", "visual": "Ų…ØąØĻ؊", "visual_builder": "ادا؊ Ų†Ø´Ø§ØĄ Ų…ØąØĻŲŠØŠ", @@ -2404,14 +2411,14 @@ "welcome_to_immich": "Ų…ØąØ­Ø¨Ø§Ų‹ Ø¨Ųƒ ؁؊ Immich", "width": "ØšŲØąØļ", "wifi_name": "Ø§ØŗŲ… Ø´Ø¨ŲƒØŠ Wi-Fi", - "workflow_delete_prompt": "Ų‡Ų„ ØŖŲ†ØĒ Ų…ØĒØŖŲƒØ¯ Ų…Ų† Ø­Ø°Ų ØŗŲŠØą Ø§Ų„ØšŲ…Ų„ Ų‡Ø°Ø§ØŸ", + "workflow_delete_prompt": "Ų…ØĒØŖŲƒØ¯ Ų…Ų† Ø­Ø°Ų ØŗŲŠØą Ø§Ų„ØšŲ…Ų„ Ų‡Ø°Ø§ØŸ", "workflow_deleted": "ØĒŲ… Ø­Ø°Ų ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", "workflow_description": "؈Øĩ؁ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", "workflow_info": "Ų…ØšŲ„ŲˆŲ…Ø§ØĒ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", "workflow_json": "؅؄؁ JSON Ų„ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", "workflow_json_help": "Ų‚Ų… بØĒØšØ¯ŲŠŲ„ ØĨؚداداØĒ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„ بØĩ؊ØēØŠ JSON. ØŗØĒØĒŲ… Ų…Ø˛Ø§Ų…Ų†ØŠ Ø§Ų„ØĒØēŲŠŲŠØąØ§ØĒ Ų…Øš ØŖØ¯Ø§ØŠ Ø§Ų„ØĨŲ†Ø´Ø§ØĄ Ø§Ų„Ų…ØąØĻŲŠØŠ.", "workflow_name": "Ø§ØŗŲ… ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", - "workflow_navigation_prompt": "Ų‡Ų„ Ø§Ų†ØĒ Ų…ØĒØ§ŲƒØ¯ Ų…Ų† Ø§Ų„Ų…ØēØ§Ø¯ØąØŠ Ø¨Ø¯ŲˆŲ† Ø­ŲØ¸ Ø§Ų„ØĒØēŲŠŲŠØąØ§ØĒ؟", + "workflow_navigation_prompt": "Ų…ØĒØ§ŲƒØ¯ Ų…Ų† Ø§Ų„Ų…ØēØ§Ø¯ØąØŠ Ø¨Ø¯ŲˆŲ† Ø­ŲØ¸ Ø§Ų„ØĒØēŲŠŲŠØąØ§ØĒ؟", "workflow_summary": "Ų…Ų„ØŽØĩ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", "workflow_update_success": "ØĒŲ… ØĒØ­Ø¯ŲŠØĢ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„ Ø¨Ų†ØŦاح", "workflow_updated": "ØĒŲ… ØĒØ­Ø¯ŲŠØĢ ØŗŲŠØą Ø§Ų„ØšŲ…Ų„", diff --git a/i18n/be.json b/i18n/be.json index 2605a382b1..ed66c4e1b3 100644 --- a/i18n/be.json +++ b/i18n/be.json @@ -239,7 +239,7 @@ "user_settings": "НаĐģĐ°Đ´Ņ‹ ĐēĐ°Ņ€Ņ‹ŅŅ‚Đ°ĐģҌĐŊŅ–Đēа", "user_settings_description": "ĐšŅ–Ņ€Đ°Đ˛Đ°ĐŊĐŊĐĩ ĐŊаĐģадаĐŧŅ– ĐēĐ°Ņ€Ņ‹ŅŅ‚Đ°ĐģҌĐŊŅ–Đēа", "version_check_enabled_description": "ĐŖĐēĐģŅŽŅ‡Ņ‹Ņ†ŅŒ ĐŋŅ€Đ°Đ˛ĐĩŅ€Đē҃ вĐĩҀҁҖҖ", - "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ‹Ņ ĐŋŅ€Đ°Đ˛ĐĩŅ€ĐēŅ– вĐĩҀҁҖҖ ĐŋĐĩŅ€Ņ‹ŅĐ´Ņ‹Ņ‡ĐŊа ĐˇĐ˛ŅŅ€Ņ‚Đ°ĐĩŅ†Ņ†Đ° да github.com", + "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ‹Ņ ĐŋŅ€Đ°Đ˛ĐĩŅ€ĐēŅ– вĐĩҀҁҖҖ ĐŋĐĩŅ€Ņ‹ŅĐ´Ņ‹Ņ‡ĐŊа ĐˇĐ˛ŅŅ€Ņ‚Đ°ĐĩŅ†Ņ†Đ° да {server}", "version_check_settings": "ĐŸŅ€Đ°Đ˛ĐĩŅ€Đēа вĐĩҀҁҖҖ", "version_check_settings_description": "ĐŖĐēĐģŅŽŅ‡Ņ‹Ņ†ŅŒ/адĐēĐģŅŽŅ‡Ņ‹Ņ†ŅŒ аĐŋĐ°Đ˛ŅŅˆŅ‡ŅĐŊĐŊŅ– ай ĐŊОваК вĐĩҀҁҖҖ" }, diff --git a/i18n/bg.json b/i18n/bg.json index 4e64363267..024ba3502e 100644 --- a/i18n/bg.json +++ b/i18n/bg.json @@ -333,7 +333,7 @@ "storage_template_migration_description": "ĐŸŅ€Đ¸ĐģĐ°ĐŗĐ°ĐŊĐĩ ĐŊа Ņ‚ĐĩĐēŅƒŅ‰Đ¸Ņ {template} ĐēҊĐŧ ĐŋŅ€ĐĩĐ´Đ¸ŅˆĐŊĐž ĐēĐ°Ņ‡ĐĩĐŊĐ¸Ņ‚Đĩ Ņ„Đ°ĐšĐģОвĐĩ", "storage_template_migration_info": "ШайĐģĐžĐŊа ҉Đĩ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐ˛Đ° Đ˛ŅĐ¸Ņ‡Đēи Ņ€Đ°ĐˇŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ ĐŊа иĐŧĐĩĐŊĐ°Ņ‚Đ° ĐŊа Ņ„Đ°ĐšĐģОвĐĩŅ‚Đĩ в Đ´ĐžĐģĐĩĐŊ Ņ€ĐĩĐŗĐ¸ŅŅ‚ŅŠŅ€. ĐŸŅ€ĐžĐŧĐĩĐŊĐ¸Ņ‚Đĩ в ŅˆĐ°ĐąĐģĐžĐŊĐ¸Ņ‚Đĩ ҉Đĩ ҁĐĩ ĐŋŅ€Đ¸ĐģĐ°ĐŗĐ°Ņ‚ ŅĐ°ĐŧĐž Са ĐŊОви ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸. За да ĐŋŅ€Đ¸ĐģĐžĐļĐ¸Ņ‚Đĩ ĐŋŅ€Đ¸ĐŊŅƒĐ´Đ¸Ņ‚ĐĩĐģĐŊĐž ŅˆĐ°ĐąĐģĐžĐŊа ĐēҊĐŧ вĐĩ҇Đĩ ĐēĐ°Ņ‡ĐĩĐŊи ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, иСĐŋҊĐģĐŊĐĩŅ‚Đĩ {job}.", "storage_template_migration_job": "Đ—Đ°Đ´Đ°Ņ‡Đ° Са ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Ņ ĐŊа ŅˆĐ°ĐąĐģĐžĐŊа Са ŅŅŠŅ…Ņ€Đ°ĐŊĐĩĐŊиĐĩ", - "storage_template_more_details": "За ĐŋОвĐĩ҇Đĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ ĐžŅ‚ĐŊĐžŅĐŊĐž Ņ‚Đ°ĐˇĐ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ҁĐĩ ĐžĐąŅŠŅ€ĐŊĐĩŅ‚Đĩ ĐēҊĐŧ ŅˆĐ°ĐąĐģĐžĐŊа Storage Template и ĐŊĐĩĐŗĐžĐ˛Đ¸Ņ‚Đĩ ĐŋĐžŅĐģĐĩĐ´ŅŅ‚Đ˛Đ¸Ņ ", + "storage_template_more_details": "За ĐŋОвĐĩ҇Đĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ ĐžŅ‚ĐŊĐžŅĐŊĐž Ņ‚Đ°ĐˇĐ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ҁĐĩ ĐžĐąŅŠŅ€ĐŊĐĩŅ‚Đĩ ĐēҊĐŧ ŅˆĐ°ĐąĐģĐžĐŊа Storage Template и ĐŊĐĩĐŗĐžĐ˛Đ¸Ņ‚Đĩ ĐŋĐžŅĐģĐĩĐ´ŅŅ‚Đ˛Đ¸Ņ", "storage_template_onboarding_description_v2": "ĐšĐžĐŗĐ°Ņ‚Đž Đĩ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊа, Ņ‚Đ°ĐˇĐ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ҉Đĩ ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐ¸Ņ€Đ° Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Ņ„Đ°ĐšĐģОвĐĩŅ‚Đĩ, ҁĐŋĐžŅ€ĐĩĐ´ ŅˆĐ°ĐąĐģĐžĐŊ, Đ´ĐĩŅ„Đ¸ĐŊĐ¸Ņ€Đ°ĐŊ ĐžŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐ¸Ņ‚ĐĩĐģŅ. За Đ´ĐžĐŋҊĐģĐŊĐ¸Ņ‚ĐĩĐģĐŊа иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ, ĐŧĐžĐģŅ виĐļŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŅ‚Đ°.", "storage_template_path_length": "ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩ ĐŊа Đ´ŅŠĐģĐļиĐŊĐ°Ņ‚Đ° ĐŊа ĐŋŅŠŅ‚Ņ: {length, number}/{limit, number}", "storage_template_settings": "ШайĐģĐžĐŊ Са ŅŅŠŅ…Ņ€Đ°ĐŊĐĩĐŊиĐĩ", @@ -441,7 +441,7 @@ "user_successfully_removed": "ĐŸĐžŅ‚Ņ€ĐĩĐąĐ¸Ņ‚ĐĩĐģ {email} Đĩ ҃ҁĐŋĐĩ҈ĐŊĐž ĐŋŅ€ĐĩĐŧĐ°Ņ…ĐŊĐ°Ņ‚.", "users_page_description": "ĐĄŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đ° Са адĐŧиĐŊĐ¸ŅŅ‚Ņ€Đ¸Ņ€Đ°ĐŊĐĩ ĐŊа ĐŋĐžŅ‚Ņ€ĐĩĐąĐ¸Ņ‚ĐĩĐģи", "version_check_enabled_description": "АĐēŅ‚Đ¸Đ˛Đ¸Ņ€Đ°Đš ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ĐŊа вĐĩŅ€ŅĐ¸ŅŅ‚Đ°", - "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸ŅŅ‚Đ° Са ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ĐŊа вĐĩŅ€ŅĐ¸ŅŅ‚Đ° Ņ€Đ°ĐˇŅ‡Đ¸Ņ‚Đ° ĐŊа ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐŊа ĐēĐžĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Ņ ҁ github.com", + "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸ŅŅ‚Đ° Са ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ĐŊа вĐĩŅ€ŅĐ¸ŅŅ‚Đ° Ņ€Đ°ĐˇŅ‡Đ¸Ņ‚Đ° ĐŊа ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐŊа ĐēĐžĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Ņ ҁ {server}", "version_check_settings": "ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа ĐŊа вĐĩŅ€ŅĐ¸ŅŅ‚Đ°", "version_check_settings_description": "АĐēŅ‚Đ¸Đ˛Đ¸Ņ€Đ°ĐšŅ‚Đĩ/Đ´ĐĩаĐēŅ‚Đ¸Đ˛Đ¸Ņ€Đ°ĐšŅ‚Đĩ иСвĐĩŅŅ‚Đ¸ĐĩŅ‚Đž Са ĐŊОва вĐĩŅ€ŅĐ¸Ņ", "video_conversion_job": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´Đ¸Ņ€Đ°ĐŊĐĩ ĐŊа видĐĩĐžĐēĐģиĐŋОвĐĩŅ‚Đĩ", @@ -849,9 +849,12 @@ "create_link_to_share": "ĐĄŅŠĐˇĐ´Đ°Đ˛Đ°ĐŊĐĩ ĐŊа ĐģиĐŊĐē Са ҁĐŋОдĐĩĐģŅĐŊĐĩ", "create_link_to_share_description": "ПозвоĐģĐĩŅ‚Đĩ ĐŊа Đ˛ŅĐĩĐēи, ĐēĐžĐšŅ‚Đž иĐŧа ĐģиĐŊĐē, да види Đ¸ĐˇĐąŅ€Đ°ĐŊĐ°Ņ‚Đ°(Đ¸Ņ‚Đĩ) ҁĐŊиĐŧĐēа(и)", "create_new": "ĐĄĐĒЗДАЙ НОВ", + "create_new_face": "ĐĄŅŠĐˇĐ´Đ°Đš ĐŊОвО ĐģĐ¸Ņ†Đĩ", "create_new_person": "ĐĄŅŠĐˇĐ´Đ°Đ˛Đ°ĐŊĐĩ ĐŊа ĐŊОвО ĐģĐ¸Ņ†Đĩ", "create_new_person_hint": "ĐŸŅ€Đ¸ŅĐ˛ĐžĐšŅ‚Đĩ Đ¸ĐˇĐąŅ€Đ°ĐŊĐ¸Ņ‚Đĩ Ņ„Đ°ĐšĐģОвĐĩ ĐŊа ĐŊОв Ņ‡ĐžĐ˛ĐĩĐē", "create_new_user": "ĐĄŅŠĐˇĐ´Đ°Đ˛Đ°ĐŊĐĩ ĐŊа ĐŊОв ĐŋĐžŅ‚Ņ€ĐĩĐąĐ¸Ņ‚ĐĩĐģ", + "create_person": "ĐĄŅŠĐˇĐ´Đ°Đš Ņ‡ĐžĐ˛ĐĩĐē", + "create_person_subtitle": "Добави иĐŧĐĩ ĐēҊĐŧ Đ¸ĐˇĐąŅ€Đ°ĐŊĐžŅ‚Đž ĐģĐ¸Ņ†Đĩ Са да ŅŅŠĐˇĐ´Đ°Đ´Đĩ҈ и да ҁĐģĐžĐļĐ¸Ņˆ ĐĩŅ‚Đ¸ĐēĐĩŅ‚ ĐŊа ĐŊĐžĐ˛Đ¸Ņ Ņ‡ĐžĐ˛ĐĩĐē", "create_shared_album_page_share_add_assets": "ДОБАВИ ОБЕКĐĸИ", "create_shared_album_page_share_select_photos": "ИСйĐĩŅ€Đ¸ ҁĐŊиĐŧĐēи", "create_shared_link": "ĐĄŅŠĐˇĐ´Đ°Đš ĐģиĐŊĐē Са ҁĐŋОдĐĩĐģŅĐŊĐĩ", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "ФиĐēŅĐ¸Ņ€Đ°ĐŊ", "crop_aspect_ratio_free": "ХвОйОдĐĩĐŊ", "crop_aspect_ratio_original": "ĐžŅ€Đ¸ĐŗĐ¸ĐŊаĐģĐĩĐŊ", + "crop_aspect_ratio_square": "ĐšĐ˛Đ°Đ´Ņ€Đ°Ņ‚", "curated_object_page_title": "НĐĩŅ‰Đ°", "current_device": "ĐĸĐĩĐēŅƒŅ‰Đž ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đž", "current_pin_code": "ĐĄĐĩĐŗĐ°ŅˆĐĩĐŊ PIN ĐēОд", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM yyyy", "dark": "ĐĸҊĐŧĐĩĐŊ", - "dark_theme": "ĐĸҊĐŧĐŊа Ņ‚ĐĩĐŧа", + "dark_theme": "ĐŸŅ€ĐĩĐŧиĐŊи ĐēҊĐŧ Ņ‚ŅŠĐŧĐŊа Ņ‚ĐĩĐŧа", "date": "Đ”Đ°Ņ‚Đ°", "date_after": "Đ”Đ°Ņ‚Đ° ҁĐģĐĩĐ´", "date_and_time": "Đ”Đ°Ņ‚Đ° и Ņ‡Đ°Ņ", @@ -891,10 +895,8 @@ "day": "ДĐĩĐŊ", "days": "ДĐŊи", "deduplicate_all": "ДĐĩĐ´ŅƒĐŋĐģиĐēĐ¸Ņ€Đ°ĐŊĐĩ ĐŊа Đ˛ŅĐ¸Ņ‡Đēи", - "deduplication_criteria_1": "РаСĐŧĐĩŅ€ ĐŊа ҁĐŊиĐŧĐēĐ°Ņ‚Đ° в ĐąĐ°ĐšŅ‚ĐžĐ˛Đĩ", - "deduplication_criteria_2": "Đ‘Ņ€ĐžĐš EXIF даĐŊĐŊи", - "deduplication_info": "ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Са Đ´ĐĩĐ´ŅƒĐŋĐģиĐēĐ°Ņ†Đ¸ŅŅ‚Đ°", - "deduplication_info_description": "За Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģĐŊĐž Đ¸ĐˇĐąĐ¸Ņ€Đ°ĐŊĐĩ ĐŊа Ņ€ĐĩŅŅƒŅ€ŅĐ¸ и ĐŋŅ€ĐĩĐŧĐ°Ņ…Đ˛Đ°ĐŊĐĩ ĐŊа Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Đ¸ ĐŊа ĐĩĐ´Ņ€Đž, Ņ€Đ°ĐˇĐŗĐģĐĩĐļдаĐŧĐĩ:", + "default_locale": "ЕзиĐē ĐŋĐž ĐŋĐžĐ´Ņ€Đ°ĐˇĐąĐ¸Ņ€Đ°ĐŊĐĩ", + "default_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ ĐŊа Đ´Đ°Ņ‚Đ° и Ņ‡Đ¸ŅĐģа ҁĐŋĐžŅ€ĐĩĐ´ ĐĩСиĐēĐžĐ˛Đ°Ņ‚Đ° ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēа ĐŊа ĐąŅ€Đ°ŅƒĐˇŅŠŅ€Đ°", "delete": "Đ˜ĐˇŅ‚Ņ€Đ¸Đš", "delete_action_confirmation_message": "ĐĄĐ¸ĐŗŅƒŅ€ĐŊи Đģи ҁ҂Đĩ, ҇Đĩ Đ¸ŅĐēĐ°Ņ‚Đĩ да Đ¸ĐˇŅ‚Ņ€Đ¸ĐĩŅ‚Đĩ Ņ‚ĐžĐˇĐ¸ ОйĐĩĐēŅ‚? ĐĄĐģĐĩдва ĐŋŅ€ĐĩĐŧĐĩŅŅ‚Đ˛Đ°ĐŊĐĩ ĐŊа ОйĐĩĐēŅ‚Đ° в ĐēĐžŅˆĐ° Са ĐžŅ‚ĐŋĐ°Đ´ŅŠŅ†Đ¸ ĐŊа ŅŅŠŅ€Đ˛ŅŠŅ€Đ° и ҉Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐĩĐŊиĐĩ ОйĐĩĐēŅ‚Đ° да ĐąŅŠĐ´Đĩ Đ¸ĐˇŅ‚Ņ€Đ¸Ņ‚ ĐģĐžĐēаĐģĐŊĐž", "delete_action_prompt": "{count} ŅĐ° Đ¸ĐˇŅ‚Ņ€Đ¸Ņ‚Đ¸", @@ -970,7 +972,7 @@ "downloading_media": "Đ˜ĐˇŅ‚ĐĩĐŗĐģŅĐŊĐĩ ĐŊа ĐŧĐĩĐ´Đ¸Ņ", "drop_files_to_upload": "ĐŸŅƒŅĐŊĐĩŅ‚Đĩ Ņ„Đ°ĐšĐģОвĐĩŅ‚Đĩ, Са да ĐŗĐ¸ ĐēĐ°Ņ‡Đ¸Ņ‚Đĩ", "duplicates": "Đ”ŅƒĐąĐģиĐēĐ°Ņ‚Đ¸", - "duplicates_description": "ИСйĐĩŅ€ĐĩŅ‚Đĩ Đ˛ŅŅĐēа ĐŗŅ€ŅƒĐŋа, ĐēĐ°Ņ‚Đž ĐŋĐžŅĐžŅ‡Đ¸Ņ‚Đĩ ĐēОи, аĐēĐž иĐŧа Ņ‚Đ°Đēива, ŅĐ° Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Đ¸", + "duplicates_description": "ИСйĐĩŅ€ĐĩŅ‚Đĩ Đ˛ŅŅĐēа ĐŗŅ€ŅƒĐŋа, ĐēĐ°Ņ‚Đž ĐŋĐžŅĐžŅ‡Đ¸Ņ‚Đĩ ĐēОи, аĐēĐž иĐŧа Ņ‚Đ°Đēива, ŅĐ° Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Đ¸.", "duration": "ĐŸŅ€ĐžĐ´ŅŠĐģĐļĐ¸Ņ‚ĐĩĐģĐŊĐžŅŅ‚", "edit": "Đ ĐĩдаĐēŅ‚Đ¸Ņ€Đ°ĐŊĐĩ", "edit_album": "Đ ĐĩдаĐēŅ‚Đ¸Ņ€Đ°ĐŊĐĩ ĐŊа аĐģĐąŅƒĐŧ", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Đ—Đ°ĐŗĐģавиĐĩ ĐŊа аĐģĐąŅƒĐŧа", "licenses": "Đ›Đ¸Ņ†ĐĩĐŊСи", "light": "ХвĐĩŅ‚ĐģĐž", + "light_theme": "ĐŸŅ€ĐĩĐŧиĐŊи ĐēҊĐŧ ŅĐ˛ĐĩŅ‚Đģа Ņ‚ĐĩĐŧа", "like": "ĐĨĐ°Ņ€ĐĩŅĐ°ĐšŅ‚Đĩ", "like_deleted": "ĐšĐ°Ņ‚Đž Đ¸ĐˇŅ‚Ņ€Đ¸Ņ‚", "link_motion_video": "ЛиĐŊĐē ĐēҊĐŧ видĐĩĐž", + "link_to_docs": "За ĐŋОвĐĩ҇Đĩ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ виĐļŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŅ‚Đ°.", "link_to_oauth": "ЛиĐŊĐē ĐēҊĐŧ OAuth", "linked_oauth_account": "ĐĄĐ˛ŅŠŅ€ĐˇĐ°ĐŊ OAuth аĐēĐ°ŅƒĐŊŅ‚", "list": "Đ›Đ¸ŅŅ‚", @@ -1651,13 +1655,14 @@ "only_favorites": "ХаĐŧĐž ĐģŅŽĐąĐ¸Đŧи", "open": "ĐžŅ‚Đ˛ĐžŅ€Đ¸", "open_calendar": "ĐžŅ‚Đ˛ĐžŅ€Đ¸ ĐēаĐģĐĩĐŊĐ´Đ°Ņ€", + "open_in_browser": "ĐžŅ‚Đ˛ĐžŅ€Đ¸ в ĐąŅ€Đ°ŅƒĐˇŅŠŅ€", "open_in_map_view": "ĐžŅ‚Đ˛ĐžŅ€Đ¸ Đ¸ĐˇĐŗĐģĐĩĐ´ ĐŊа ĐēĐ°Ņ€Ņ‚Đ°", "open_in_openstreetmap": "ĐžŅ‚Đ˛ĐžŅ€Đ¸ в OpenStreetMap", "open_the_search_filters": "ĐžŅ‚Đ˛Đ°Ņ€Đ¸ Ņ„Đ¸ĐģŅ‚Ņ€Đ¸Ņ‚Đĩ Са Ņ‚ŅŠŅ€ŅĐĩĐŊĐĩ", "options": "ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи", "or": "иĐģи", - "organize_into_albums": "Organitzar per àlbums", - "organize_into_albums_description": "Posar les fotos existents dins dels àlbums fent servir la configuraciÃŗ de sincronitzaciÃŗ", + "organize_into_albums": "ĐŸĐžĐ´Ņ€ĐĩĐ´ĐĩŅ‚Đĩ в аĐģĐąŅƒĐŧи", + "organize_into_albums_description": "ДобавĐĩŅ‚Đĩ ĐŊаĐģĐ¸Ņ‡ĐŊĐ¸Ņ‚Đĩ ҁĐŊиĐŧĐēи в аĐģĐąŅƒĐŧи, ĐēĐ°Ņ‚Đž иСĐŋĐžĐģĐˇĐ˛Đ°Ņ‚Đĩ Ņ‚ĐĩĐēŅƒŅ‰Đ¸Ņ‚Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи Са ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€Đ°ĐŊĐĩ", "organize_your_library": "ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐ¸Ņ€Đ°ĐŊĐĩ ĐŊа Đ˛Đ°ŅˆĐ°Ņ‚Đ° йийĐģĐ¸ĐžŅ‚ĐĩĐēа", "original": "ĐžŅ€Đ¸ĐŗĐ¸ĐŊаĐģ", "other": "Đ”Ņ€ŅƒĐŗĐ¸", @@ -1805,7 +1810,7 @@ "purchase_server_description_2": "ĐĄŅ‚Đ°Ņ‚ŅƒŅ ĐŊа ĐŋĐžĐ´Đ´Ņ€ŅŠĐļĐŊиĐē", "purchase_server_title": "ĐĄŅŠŅ€Đ˛ŅŠŅ€", "purchase_settings_server_activated": "ĐŸŅ€ĐžĐ´ŅƒĐēŅ‚ĐžĐ˛Đ¸ŅŅ‚ ĐēĐģŅŽŅ‡ ĐŊа ŅŅŠŅ€Đ˛ŅŠŅ€Đ° ҁĐĩ ҃ĐŋŅ€Đ°Đ˛ĐģŅĐ˛Đ° ĐžŅ‚ адĐŧиĐŊĐ¸ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", - "query_asset_id": "Buscar item per ID", + "query_asset_id": "ĐĸŅŠŅ€ŅĐĩĐŊĐĩ ĐŊа ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŋĐž ID", "queue_status": "В ĐžĐŋĐ°ŅˆĐēа {count} ĐžŅ‚ {total}", "rate_asset": "ЗадаваĐŊĐĩ ĐŊа Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", "rating": "ĐžŅ†ĐĩĐŊĐēа ҁҊҁ СвĐĩСди", @@ -2212,6 +2217,7 @@ "tag": "ĐĸĐ°Đŗ", "tag_assets": "ĐĸĐ°ĐŗĐŊи ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "tag_created": "ĐĄŅŠĐˇĐ´Đ°Đ´ĐĩĐŊ ĐĩŅ‚Đ¸ĐēĐĩŅ‚: {tag}", + "tag_face": "ĐžŅ‚ĐąĐĩĐģĐĩĐļи ĐģĐ¸Ņ†Đĩ", "tag_feature_description": "Đ Đ°ĐˇĐŗĐģĐĩĐļдаĐŊĐĩ ĐŊа ҁĐŊиĐŧĐēи и видĐĩĐžĐēĐģиĐŋОвĐĩ, ĐŗŅ€ŅƒĐŋĐ¸Ņ€Đ°ĐŊи ĐŋĐž Ņ‚ĐĩĐŧи ҁ ĐģĐžĐŗĐ¸Ņ‡ĐĩҁĐēи Ņ‚Đ°ĐŗĐžĐ˛Đĩ", "tag_not_found_question": "НĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ да ĐŊаĐŧĐĩŅ€Đ¸Ņ‚Đĩ ĐĩŅ‚Đ¸ĐēĐĩŅ‚? ĐĄŅŠĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŊОв ĐĩŅ‚Đ¸ĐēĐĩŅ‚.", "tag_people": "ĐžŅ‚ĐąĐĩĐģĐĩĐļи ĐĨĐžŅ€Đ°", @@ -2393,6 +2399,7 @@ "viewer_remove_from_stack": "ĐŸŅ€ĐĩĐŧĐ°Ņ…Đ˛Đ°ĐŊĐĩ ĐžŅ‚ ĐžĐŋĐ°ŅˆĐēĐ°Ņ‚Đ°", "viewer_stack_use_as_main_asset": "ИСĐŋĐžĐģСваК ĐēĐ°Ņ‚Đž ĐžŅĐŊОвĐĩĐŊ", "viewer_unstack": "ĐŸŅ€ĐĩĐŧĐ°Ņ…ĐŊи ĐžŅ‚ ĐžĐŋĐ°ŅˆĐēĐ°Ņ‚Đ°", + "visibility": "ВидиĐŧĐžŅŅ‚", "visibility_changed": "ВидиĐŧĐžŅŅ‚Ņ‚Đ° Đĩ ĐŋŅ€ĐžĐŧĐĩĐŊĐĩĐŊа Са {count, plural, one {# Ņ‡ĐžĐ˛ĐĩĐē} other {# Ņ‡ĐžĐ˛ĐĩĐēа}}", "visual": "Đ’Đ¸ĐˇŅƒĐ°ĐģĐĩĐŊ", "visual_builder": "Đ’Đ¸ĐˇŅƒĐ°ĐģĐĩĐŊ ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ‚ĐžŅ€", diff --git a/i18n/bn.json b/i18n/bn.json index 4580ca5551..dcc6834323 100644 --- a/i18n/bn.json +++ b/i18n/bn.json @@ -231,6 +231,8 @@ "metadata_settings_description": "āĻŽā§‡āϟāĻžāĻĄā§‡āϟāĻž āϏ⧇āϟāĻŋāĻ‚āϏ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧁āύ (Manage metadata settings)", "migration_job": "āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ (Migration)", "migration_job_description": "āĻ…ā§āϝāĻžāϏ⧇āϟ āĻāĻŦāĻ‚ āĻĢ⧇āϏ āĻĨāĻžāĻŽā§āĻŦāύ⧇āχāϞāϗ⧁āϞ⧋āϕ⧇ āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ⧇ āĻŽāĻžāχāĻ—ā§āϰ⧇āϟ āĻ•āϰ⧁āύāĨ¤ (Migrate thumbnails for assets and faces to the latest folder structure)", + "nightly_tasks_cluster_faces_setting_description": "āύāϤ⧁āύ āĻļāύāĻžāĻ•ā§āϤ āĻšāĻ“āϝāĻŧāĻž āĻŽā§āĻ–āϗ⧁āϞāĻŋāϤ⧇ āĻĢ⧇āϏāĻŋāϝāĻŧāĻžāϞ āϰāĻŋāĻ•āĻ—āύāĻŋāĻļāύ āϚāĻžāϞāĻžāύ", + "nightly_tasks_cluster_new_faces_setting": "āύāϤ⧁āύ āĻŽā§āĻ–āϗ⧁āϞ⧋āϰ āϗ⧁āĻšā§āĻ›", "nightly_tasks_database_cleanup_setting": "āĻĄā§‡āϟāĻžāĻŦ⧇āϏ āĻ•ā§āϞāĻŋāύāφāĻĒ āϟāĻžāĻ¸ā§āĻ•āϏāĻŽā§‚āĻš (Database cleanup tasks)", "nightly_tasks_database_cleanup_setting_description": "āĻĄā§‡āϟāĻžāĻŦ⧇āϏ āĻĨ⧇āϕ⧇ āĻĒ⧁āϰ⧋āύ⧋ āĻāĻŦāĻ‚ āĻŽā§‡ā§ŸāĻžāĻĻā§‹āĻ¤ā§āϤ⧀āĻ°ā§āĻŖ āĻĄā§‡āϟāĻž āĻŽā§āϛ⧇ āĻĢ⧇āϞ⧁āύ", "nightly_tasks_generate_memories_setting": "āĻŽā§‡āĻŽā§‹āϰāĻŋāϜ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ (Generate memories)", @@ -257,6 +259,20 @@ "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": "āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• āχāĻŽā§‡āχāϞ āĻĒāĻžāĻ āĻžāύ", + "notification_email_test_email_failed": "āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• āχāĻŽā§‡āϞ āĻĒāĻžāĻ āĻžāύ⧋ āϏāĻŽā§āĻ­āĻŦ āĻšāϝāĻŧāύāĻŋ, āφāĻĒāύāĻžāϰ āϏ⧇āϟāĻŋāĻ‚āϏ āϝāĻžāϚāĻžāχ āĻ•āϰ⧁āύ", + "notification_email_test_email_sent": "{email}-āĻ āĻāĻ•āϟāĻŋ āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• āχāĻŽā§‡āϞ āĻĒāĻžāĻ āĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇āĨ¤ āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āφāĻĒāύāĻžāϰ āχāύāĻŦāĻ•ā§āϏ āĻĻ⧇āϖ⧁āύāĨ¤", + "notification_email_username_description": "āχāĻŽā§‡āϞ āϏāĻžāĻ°ā§āĻ­āĻžāϰ⧇ āϭ⧇āϰāĻŋāĻĢāĻŋāϕ⧇āϏāύ⧇āϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āχāωāϜāĻžāϰāύ⧇āĻŽ", + "notification_enable_email_notifications": "āχāĻŽā§‡āϞ āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āϏāύ āϏāĻ•ā§āϰāĻŋāϝāĻŧ āĻ•āϰ⧁āύ", + "notification_settings": "āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āϏāύ āϏ⧇āϟāĻŋāĻ‚āϏ", + "notification_settings_description": "āχāĻŽā§‡āχāϞ āϏāĻš āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ āϏ⧇āϟāĻŋāĻ‚āϏ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧁āύ", + "oauth_auto_launch": "āĻ…āĻŸā§‹ āϞāĻžā§āϚ", + "oauth_auto_launch_description": "āϞāĻ—āχāύ āĻĒ⧇āĻœā§‡ āĻĒā§āϰāĻŦ⧇āĻļ āĻ•āϰāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ OAuth āϞāĻ—āχāύ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϟāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āĻļ⧁āϰ⧁ āĻ•āϰ⧁āύ", + "oauth_auto_register": "āϏ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇ āϰ⧇āϜāĻŋāĻ¸ā§āϟāĻžāϰ āĻ•āϰ⧁āύ", + "oauth_auto_register_description": "OAuth āĻĻāĻŋāϝāĻŧ⧇ āϏāĻžāχāύ āχāύ āĻ•āϰāĻžāϰ āĻĒāϰ āύāϤ⧁āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āĻĻ⧇āϰ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āύāĻŋāĻŦāĻ¨ā§āϧāύ āĻ•āϰ⧁āύ", + "oauth_button_text": "āĻŦāĻžāϟāύ āĻŸā§‡āĻ•ā§āϏāϟ", + "oauth_client_secret_description": "āĻ—ā§‹āĻĒāύ⧀āϝāĻŧ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡āϰ āϜāĻ¨ā§āϝ āĻĒā§āϰāϝāĻŧā§‹āϜāύ, āĻ…āĻĨāĻŦāĻž āϝāĻĻāĻŋ āĻĒāĻžāĻŦāϞāĻŋāĻ• āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡āϰ āϜāĻ¨ā§āϝ PKCE (Proof Key for Code Exchange) āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āύāĻž āĻšāϝāĻŧāĨ¤", "oauth_enable_description": "OAuth-āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϞāĻ—āχāύ āĻ•āϰ⧁āύ", "oauth_mobile_redirect_uri": "āĻŽā§‹āĻŦāĻžāχāϞ āϰāĻŋāĻĄāĻžāχāϰ⧇āĻ•ā§āϟ āχāωāφāϰāφāχ (URI)", "oauth_mobile_redirect_uri_override": "āĻŽā§‹āĻŦāĻžāχāϞ āϰāĻŋāĻĄāĻžāχāϰ⧇āĻ•ā§āϟ āχāωāφāϰāφāχ (URI) āĻ“āĻ­āĻžāϰāϰāĻžāχāĻĄ", @@ -323,6 +339,20 @@ "storage_template_settings": "āĻ¸ā§āĻŸā§‹āϰ⧇āϜ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ (Storage Template)", "storage_template_settings_description": "āφāĻĒāϞ⧋āĻĄ āĻ•āϰāĻž āĻ…ā§āϝāĻžāϏ⧇āĻŸā§‡āϰ āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻāĻŦāĻ‚ āĻĢāĻžāχāϞ āύ⧇āĻŽ āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰ⧁āύ", "storage_template_user_label": "{label} āĻšāϞ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ¸ā§āĻŸā§‹āϰ⧇āϜ āϞ⧇āĻŦ⧇āϞ (Storage Label)", + "system_settings": "āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āϏ⧇āϟāĻŋāĻ‚āϏ", + "tag_cleanup_job": "āĻŸā§āϝāĻžāĻ— āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž", + "template_email_available_tags": "āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āĻŸā§‡ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ: {tags}", + "template_email_if_empty": "āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟāϟāĻŋ āĻ–āĻžāϞāĻŋ āĻĨāĻžāĻ•āϞ⧇ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āχāĻŽā§‡āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤", + "template_email_invite_album": "āχāύāĻ­āĻžāχāϟ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ", + "template_email_preview": "āĻĒā§āϰāĻŋāĻ­āĻŋāω", + "template_email_settings": "āχāĻŽā§‡āχāϞ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ", + "template_email_update_album": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧁āύ", + "template_email_welcome": "āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ āχāĻŽā§‡āχāϞ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ", + "template_settings": "āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ", + "template_settings_description": "āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ⧇āϰ āϜāĻ¨ā§āϝ āĻ•āĻžāĻ¸ā§āϟāĻŽ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧁āύ", + "theme_custom_css_settings": "āĻ•āĻžāĻ¸ā§āϟāĻŽ CSS", + "theme_custom_css_settings_description": "āĻ•ā§āϝāĻžāϏāϕ⧇āĻĄāĻŋāĻ‚ āĻ¸ā§āϟāĻžāχāϞ āĻļā§€āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ Immich āĻāϰ āĻĄāĻŋāϜāĻžāχāύ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜ āĻ•āϰāĻž āϝāĻžāϝāĻŧāĨ¤", + "theme_settings": "āĻĨā§€āĻŽ āϏ⧇āϟāĻŋāĻ‚āϏ", "theme_settings_description": "āχāĻŽāĻŋāϚ (Immich) āĻ“āϝāĻŧ⧇āĻŦ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ⧇āϰ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāĻœā§‡āĻļāύ āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰ⧁āύ", "thumbnail_generation_job": "āĻĨāĻžāĻŽā§āĻŦāύ⧇āχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ (Generate Thumbnails)", "thumbnail_generation_job_description": "āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ…ā§āϝāĻžāϏ⧇āĻŸā§‡āϰ āϜāĻ¨ā§āϝ āĻŦ⧜, āϛ⧋āϟ āĻāĻŦāĻ‚ āĻŦā§āϞāĻžāϰ (āĻ…āĻ¸ā§āĻĒāĻˇā§āϟ) āĻĨāĻžāĻŽā§āĻŦāύ⧇āχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ, āϏ⧇āχ āϏāĻžāĻĨ⧇ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āϜāĻ¨ā§āϝāĻ“ āĻĨāĻžāĻŽā§āĻŦāύ⧇āχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύāĨ¤", @@ -334,8 +364,281 @@ "transcoding_acceleration_vaapi": "VA-API (āĻ­āĻŋāĻĄāĻŋāĻ“ āĻ…ā§āϝāĻžāĻ•ā§āϏāĻŋāϞāĻžāϰ⧇āĻļāύ āĻāĻĒāĻŋāφāχ)", "transcoding_accepted_audio_codecs": "āĻ—ā§āϰāĻšāĻŖāϝ⧋āĻ—ā§āϝ āĻ…āĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•āϏāĻŽā§‚āĻš (Accepted audio codecs)", "transcoding_accepted_audio_codecs_description": "āϕ⧋āύ āĻ…āĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•āϗ⧁āϞ⧋ āĻŸā§āϰāĻžāύāϏāϕ⧋āĻĄ āĻ•āϰāĻžāϰ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āύ⧇āχ āϤāĻž āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύāĨ¤ āĻāϟāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŸā§āϰāĻžāύāϏāϕ⧋āĻĄ āĻĒāϞāĻŋāϏāĻŋāϰ (transcode policies) āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšā§ŸāĨ¤", - "transcoding_accepted_containers": "āĻ—ā§āϰāĻšāĻŖāϝ⧋āĻ—ā§āϝ āĻ•āĻ¨ā§āĻŸā§‡āχāύāĻžāϰāϏāĻŽā§‚āĻš (Accepted containers)" + "transcoding_accepted_containers": "āĻ—ā§āϰāĻšāĻŖāϝ⧋āĻ—ā§āϝ āĻ•āĻ¨ā§āĻŸā§‡āχāύāĻžāϰāϏāĻŽā§‚āĻš (Accepted containers)", + "transcoding_accepted_containers_description": "āϕ⧋āύ āĻ•āĻ¨ā§āĻŸā§‡āχāύāĻžāϰ āĻĢāϰāĻŽā§āϝāĻžāϟāϗ⧁āϞ⧋āϕ⧇ MP4-āĻ āϰāĻŋāĻŽā§āĻ•ā§āϏ āĻ•āϰāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āύ⧇āχ āϤāĻž āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύāĨ¤ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻĒāϞāĻŋāϏāĻŋāϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤", + "transcoding_accepted_video_codecs": "āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āĻ­āĻŋāĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•āϗ⧁āϞ⧋", + "transcoding_accepted_video_codecs_description": "āϕ⧋āύ āĻ­āĻŋāĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•āϗ⧁āϞ⧋ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āύ⧇āχ āϤāĻž āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύāĨ¤ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āύ⧀āϤāĻŋāϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤", + "transcoding_advanced_options_description": "āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āύ⧇āχ āĻāĻŽāύ āĻ…āĻĒāĻļāύāϏāĻŽā§‚āĻš", + "transcoding_audio_codec": "āĻ…āĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•", + "transcoding_audio_codec_description": "Opus āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŽāĻžāύ⧇āϰ āĻ…āĻĒāĻļāύ, āϤāĻŦ⧇ āĻĒ⧁āϰ⧋āύ⧋ āĻĄāĻŋāĻ­āĻžāχāϏ āĻŦāĻž āϏāĻĢāϟāĻ“ā§Ÿā§āϝāĻžāϰ⧇āϰ āϏāĻžāĻĨ⧇ āĻāϰ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻ•āĻŽāĨ¤", + "transcoding_bitrate_description": "āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āĻŸā§‡āϰ āĻšā§‡ā§Ÿā§‡ āĻŦ⧇āĻļāĻŋ āĻŦāĻž āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āĻĢāϰāĻŽā§āϝāĻžāĻŸā§‡ āύ⧟ āĻāĻŽāύ āĻ­āĻŋāĻĄāĻŋāĻ“", + "transcoding_codecs_learn_more": "āĻāĻ–āĻžāύ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻĒāϰāĻŋāĻ­āĻžāώāĻž āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āϜāĻžāύāϤ⧇ FFmpeg āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻĻ⧇āϖ⧁āύ, H.264 āϕ⧋āĻĄā§‡āĻ•, HEVC āϕ⧋āĻĄā§‡āĻ• āĻāĻŦāĻ‚ VP9 āϕ⧋āĻĄā§‡āĻ•āĨ¤", + "transcoding_constant_quality_mode": "āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŽāĻžāύ āĻŽā§‹āĻĄ", + "transcoding_constant_quality_mode_description": "ICQ, CQP-āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻ­āĻžāϞ⧋ āĻŽāĻžāύ āĻĻā§‡ā§Ÿ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻŦ āĻšāĻžāĻ°ā§āĻĄāĻ“ā§Ÿā§āϝāĻžāϰ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϞāĻžāϰ⧇āĻļāύ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇ āύāĻžāĨ¤ āĻāχ āĻ…āĻĒāĻļāύ āϚāĻžāϞ⧁ āĻĨāĻžāĻ•āϞ⧇ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ-āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āĻāύāϕ⧋āĻĄāĻŋāĻ‚ā§Ÿā§‡ āĻāϟāĻŋ āĻĒā§āϰāĻžāϧāĻžāĻ¨ā§āϝ āĻĒāĻžāĻŦ⧇āĨ¤ NVENC āĻāϟāĻŋ āϏāĻŽāĻ°ā§āĻĨāύ āĻ•āϰ⧇ āύāĻž, āϤāĻžāχ āĻāϟāĻŋ āωāĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤", + "transcoding_constant_rate_factor": "āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϰ⧇āϟ āĻĢā§āϝāĻžāĻ•ā§āϟāϰ (-crf)", + "transcoding_constant_rate_factor_description": "āĻ­āĻŋāĻĄāĻŋāĻ“āϰ āϗ⧁āĻŖāĻŽāĻžāύ⧇āϰ āĻ¸ā§āϤāϰāĨ¤ āϏāĻžāϧāĻžāϰāĻŖ āĻŽāĻžāύāϗ⧁āϞ⧋ āĻšāϞ⧋ H.264-āĻāϰ āϜāĻ¨ā§āϝ ā§¨ā§Š, HEVC-āĻāϰ āϜāĻ¨ā§āϝ ā§¨ā§Ž, VP9-āĻāϰ āϜāĻ¨ā§āϝ ā§Šā§§ āĻāĻŦāĻ‚ AV1-āĻāϰ āϜāĻ¨ā§āϝ ā§Šā§ĢāĨ¤ āĻŽāĻžāύ āϝāϤ āĻ•āĻŽ āĻšāĻŦ⧇, āĻ­āĻŋāĻĄāĻŋāĻ“āϰ āϗ⧁āĻŖāĻŽāĻžāύ āϤāϤ āωāĻ¨ā§āύāϤ āĻšāĻŦ⧇, āϤāĻŦ⧇ āĻĢāĻžāχāϞ⧇āϰ āφāĻ•āĻžāϰ āϤāϤ āĻŦ⧜ āĻšāĻŦ⧇āĨ¤", + "transcoding_disabled_description": "āϕ⧋āύ⧋ āĻ­āĻŋāĻĄāĻŋāĻ“ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻŦ⧇āύ āύāĻž, āĻāϤ⧇ āĻ•āĻŋāϛ⧁ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡ āĻĒā§āϞ⧇āĻŦā§āϝāĻžāĻ• āύāĻˇā§āϟ āĻšāϤ⧇ āĻĒāĻžāϰ⧇", + "transcoding_encoding_options": "āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āĻāϰ āĻ…āĻĒāĻļāύāϗ⧁āϞāĻŋ", + "transcoding_encoding_options_description": "āĻāύāϕ⧋āĻĄ āĻ•āϰāĻž āĻ­āĻŋāĻĄāĻŋāĻ“āϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āϕ⧋āĻĄā§‡āĻ•, āϰ⧇āĻœā§‹āϞāĻŋāωāĻļāύ, āϕ⧋āϝāĻŧāĻžāϞāĻŋāϟāĻŋ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ…āĻĒāĻļāύ āϏ⧇āϟ āĻ•āϰ⧁āύ", + "transcoding_hardware_acceleration": "āĻšāĻžāĻ°ā§āĻĄāĻ“ā§Ÿā§āϝāĻžāϰ āĻāĻ•ā§āϏāĻŋāϞāĻžāϰ⧇āϏāύ (Acceleration)", + "transcoding_hardware_acceleration_description": "āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ•: āĻĻā§āϰ⧁āϤāϤāϰ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄāĻŋāĻ‚, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ•āχ āĻŦāĻŋāϟāϰ⧇āĻŸā§‡ āϗ⧁āĻŖāĻŽāĻžāύ āĻšā§āϰāĻžāϏ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇", + "transcoding_hardware_decoding": "āĻšāĻžāĻ°ā§āĻĄāĻ“ā§Ÿā§āϝāĻžāϰ āĻĄāĻŋāϕ⧋āĻĄāĻŋāĻ‚", + "transcoding_hardware_decoding_setting_description": "āĻļ⧁āϧ⧁ āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āĻ…ā§āϝāĻžāĻ•ā§āϏāĻŋāϞāĻžāϰ⧇āĻļāύ āĻ•āϰāĻžāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ āĻāϟāĻŋ āĻāĻ¨ā§āĻĄ-āϟ⧁-āĻāĻ¨ā§āĻĄ āĻ…ā§āϝāĻžāĻ•ā§āϏāĻŋāϞāĻžāϰ⧇āĻļāύ āϏāĻ•ā§āώāĻŽ āĻ•āϰ⧇āĨ¤ āϏāĻŦ āĻ­āĻŋāĻĄāĻŋāĻ“āϤ⧇ āĻ•āĻžāϜ āύāĻžāĻ“ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤", + "transcoding_max_b_frames": "āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋ-āĻĢā§āϰ⧇āĻŽ (B-frames)", + "transcoding_max_b_frames_description": "āĻŽāĻžāύ āϝāϤ āĻŦ⧇āĻļāĻŋ āĻšāĻŦ⧇, āĻ•āĻŽāĻĒā§āϰ⧇āĻļāύ āϤāϤ āĻ­āĻžāϞ⧋ āĻšāĻŦ⧇ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āϧ⧀āϰ⧇ āϚāϞāĻŦ⧇āĨ¤ āĻĒ⧁āϰ⧋āύ⧋ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āĻšāĻžāĻ°ā§āĻĄāĻ“ā§Ÿā§āϝāĻžāϰ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϞāĻžāϰ⧇āĻļāύ āĻ•āĻžāϜ āύāĻžāĻ“ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ ā§Ļ āĻĻāĻŋāϞ⧇ B-frames āĻŦāĻ¨ā§āϧ āĻĨāĻžāĻ•āĻŦ⧇, -ā§§ āĻĻāĻŋāϞ⧇ āĻāϟāĻŋ āύāĻŋāĻœā§‡ āĻĨ⧇āϕ⧇āχ āĻ āĻŋāĻ• āĻšāĻŦ⧇āĨ¤", + "transcoding_max_bitrate": "āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āϟ", + "transcoding_max_bitrate_description": "āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āϟ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰāϞ⧇ āĻĢāĻžāχāϞ⧇āϰ āφāĻ•āĻžāϰ āφāϰāĻ“ āĻ…āύ⧁āĻŽāĻžāύāϝ⧋āĻ—ā§āϝ āĻšāϤ⧇ āĻĒāĻžāϰ⧇, āϤāĻŦ⧇ āĻāϰ āĻĢāϞ⧇ āϕ⧋āϝāĻŧāĻžāϞāĻŋāϟāĻŋāϰ āĻ•āĻŋāϛ⧁āϟāĻž āĻ…āĻŦāύāϤāĻŋ āϘāĻŸā§‡āĨ¤ 720p-āϤ⧇, VP9 āĻŦāĻž HEVC-āĻāϰ āϜāĻ¨ā§āϝ āϏāĻžāϧāĻžāϰāĻŖ āĻŽāĻžāύ āĻšāϞ⧋ 2600 kbit/s, āĻ…āĻĨāĻŦāĻž H.264-āĻāϰ āϜāĻ¨ā§āϝ 4500 kbit/sāĨ¤āĻāϰ āĻŽāĻžāύ 0 āϏ⧇āϟ āĻ•āϰāĻž āĻšāϞ⧇ āĻāϟāĻŋ āĻŦāĻ¨ā§āϧ āĻĨāĻžāϕ⧇āĨ¤ āϝāĻ–āύ āϕ⧋āύ⧋ āĻāĻ•āĻ• āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻ•āϰāĻž āĻĨāĻžāϕ⧇ āύāĻž, āϤāĻ–āύ k (kbit/s-āĻāϰ āϜāĻ¨ā§āϝ) āϧāϰ⧇ āύ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ; āϤāĻžāχ 5000, 5000k, āĻāĻŦāĻ‚ 5M (Mbit/s-āĻāϰ āϜāĻ¨ā§āϝ) āϏāĻŽāϤ⧁āĻ˛ā§āϝāĨ¤", + "transcoding_max_keyframe_interval": "āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āϕ⧀āĻĢā§āϰ⧇āĻŽ āĻŦā§āϝāĻŦāϧāĻžāύ", + "transcoding_max_keyframe_interval_description": "āϕ⧀āĻĢā§āϰ⧇āĻŽā§‡āϰ āĻŽāĻ§ā§āϝ⧇ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻĢā§āϰ⧇āĻŽ āĻĻā§‚āϰāĻ¤ā§āĻŦ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧇āĨ¤ āĻŽāĻžāύ āĻ•āĻŽ āĻšāϞ⧇ āĻ•āĻŽāĻĒā§āϰ⧇āĻļāύ āĻĻāĻ•ā§āώāϤāĻž āĻ•āĻŽā§‡, āϤāĻŦ⧇ āĻ­āĻŋāĻĄāĻŋāĻ“āϤ⧇ āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰāĻž āĻĻā§āϰ⧁āϤ āĻšā§Ÿ āĻāĻŦāĻ‚ āĻĻā§āϰ⧁āϤ āϚāϞāĻŽāĻžāύ āĻĻ⧃āĻļā§āϝ⧇ āĻŽāĻžāύāĻ“ āĻ•āĻŋāϛ⧁āϟāĻž āĻ­āĻžāϞ⧋ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ ā§Ļ āĻĻāĻŋāϞ⧇ āĻāχ āĻŽāĻžāύ āĻ¸ā§āĻŦ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻšā§ŸāĨ¤", + "transcoding_optimal_description": "āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϰ⧇āĻœā§‹āϞāĻŋāωāĻļāύ⧇āϰ āĻšā§‡ā§Ÿā§‡ āĻŦ⧜ āĻŦāĻž āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āĻĢāϰāĻŽā§āϝāĻžāĻŸā§‡ āύ⧟ āĻāĻŽāύ āĻ­āĻŋāĻĄāĻŋāĻ“", + "transcoding_policy": "āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āύ⧀āϤāĻŋ", + "transcoding_policy_description": "āĻ­āĻŋāĻĄāĻŋāĻ“ āĻ•āĻ–āύ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻž āĻšāĻŦ⧇ āϤāĻž āϏ⧇āϟ āĻ•āϰ⧁āύ", + "transcoding_preferred_hardware_device": "āĻĒāĻ›āĻ¨ā§āĻĻ⧇āϰ āĻšāĻžāĻ°ā§āĻĄāĻ“āϝāĻŧā§āϝāĻžāϰ āĻĄāĻŋāĻ­āĻžāχāϏ", + "transcoding_preferred_hardware_device_description": "āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ VAAPI āĻāĻŦāĻ‚ QSV-āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻĒā§āϰāϝ⧋āĻœā§āϝāĨ¤ āĻšāĻžāĻ°ā§āĻĄāĻ“āϝāĻŧā§āϝāĻžāϰ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄāĻŋāĻ‚āϝāĻŧ⧇āϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ dri āύ⧋āĻĄ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧇āĨ¤", + "transcoding_preset_preset": "āĻĒā§āϰāĻŋāϏ⧇āϟ (-preset)", + "transcoding_preset_preset_description": "āĻ•āĻŽā§āĻĒā§āϰ⧇āĻļāύ āĻ¸ā§āĻĒāĻŋāĻĄāĨ¤ āϧ⧀āϰāĻ—āϤāĻŋāϰ āĻĒā§āϰāĻŋāϏ⧇āϟāϗ⧁āϞ⧋ āϛ⧋āϟ āĻĢāĻžāχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŦāĻŋāϟāϰ⧇āϟ āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϗ⧁āĻŖāĻŽāĻžāύ āĻŦ⧃āĻĻā§āϧāĻŋ āĻ•āϰ⧇āĨ¤ VP9 'faster'-āĻāϰ āĻšā§‡āϝāĻŧ⧇ āĻŦ⧇āĻļāĻŋ āĻ—āϤāĻŋ āωāĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰ⧇āĨ¤", + "transcoding_reference_frames": "āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ āĻĢā§āϰ⧇āĻŽ", + "transcoding_reference_frames_description": "āĻāĻ•āϟāĻŋ āĻĢā§āϰ⧇āĻŽ āĻ•āĻŽā§āĻĒā§āϰ⧇āϏ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ āĻ•āϤāϟāĻŋ āĻĢā§āϰ⧇āĻŽāϕ⧇ āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ āĻšāĻŋāϏ⧇āĻŦ⧇ āύ⧇āĻ“ā§ŸāĻž āĻšāĻŦ⧇āĨ¤ āĻŽāĻžāύ āϝāϤ āĻŦ⧇āĻļāĻŋ āĻšāĻŦ⧇, āĻ•āĻŽāĻĒā§āϰ⧇āĻļāύ āĻĻāĻ•ā§āώāϤāĻž āϤāϤ āĻ­āĻžāϞ⧋ āĻšāĻŦ⧇, āϤāĻŦ⧇ āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āϧ⧀āϰ āĻšāĻŦ⧇āĨ¤ ā§Ļ āĻĻāĻŋāϞ⧇ āĻāχ āĻŽāĻžāύ āĻ¸ā§āĻŦ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻšāĻŦ⧇āĨ¤", + "transcoding_required_description": "āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ…āύ⧁āĻŽā§‹āĻĻāĻŋāϤ āĻĢāϰāĻŽā§āϝāĻžāĻŸā§‡ āύ⧇āχ āĻāĻŽāύ āĻ­āĻŋāĻĄāĻŋāĻ“", + "transcoding_settings": "āĻ­āĻŋāĻĄāĻŋāĻ“ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄāĻŋāĻ‚ āϏ⧇āϟāĻŋāĻ‚āϏ", + "transcoding_settings_description": "āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧁āύ āϕ⧋āύ āĻ­āĻŋāĻĄāĻŋāĻ“āϗ⧁āϞ⧋āϕ⧇ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āĻāĻŦāĻ‚ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻĒā§āϰāĻ•ā§āϰāĻŋ⧟āĻž āĻ•āϰāϤ⧇ āĻšāĻŦ⧇", + "transcoding_target_resolution": "āϟāĻžāĻ°ā§āϗ⧇āϟ āϰ⧇āĻœā§‹āϞāĻŋāωāĻļāύ", + "transcoding_target_resolution_description": "āωāĻšā§āϚ āϰ⧇āĻœā§‹āϞāĻŋāωāĻļāύ āĻŦ⧇āĻļāĻŋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϰāĻžāϖ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āϧ⧀āϰ⧇ āĻšā§Ÿ, āĻĢāĻžāχāϞ āĻŦ⧜ āĻšā§Ÿ, āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒ āϧ⧀āϰ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋ⧟āĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤", + "transcoding_temporal_aq": "āĻŸā§‡āĻŽā§āĻĒā§‹āϰāĻžāϞ AQ", + "transcoding_temporal_aq_description": "āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ NVENC-āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻĒā§āϰāϝ⧋āĻœā§āϝāĨ¤ āĻŸā§‡āĻŽā§āĻĒā§‹āϰāĻžāϞ āĻ…ā§āϝāĻžāĻĄāĻžāĻĒāϟāĻŋāĻ­ āϕ⧋āϝāĻŧāĻžāĻ¨ā§āϟāĻžāχāĻœā§‡āĻļāύ (Adaptive Quantization) āωāĻšā§āϚ-āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āĻ“ āĻ¸ā§āĻŦāĻ˛ā§āĻĒ-āĻ—āϤāĻŋāϰ āĻĻ⧃āĻļā§āϝ⧇āϰ āĻŽāĻžāύ āĻŦ⧃āĻĻā§āϧāĻŋ āĻ•āϰ⧇āĨ¤ āĻĒ⧁āϰ⧋āύ⧋ āĻĄāĻŋāĻ­āĻžāχāϏāϗ⧁āϞ⧋āϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āύāĻžāĻ“ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤", + "transcoding_threads": "āĻĨā§āϰ⧇āĻĄ", + "transcoding_threads_description": "āωāĻšā§āϚ āĻŽāĻžāύ⧇ āĻāύāϕ⧋āĻĄāĻŋāĻ‚ āĻĻā§āϰ⧁āϤ āĻšā§Ÿ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻ•āĻŽ āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ CPU āϕ⧋āϰ⧇āϰ āĻŦ⧇āĻļāĻŋ āĻŽāĻžāύ āĻĻ⧇āĻ“ā§ŸāĻž āωāϚāĻŋāϤ āύ⧟āĨ¤ ā§Ļ āĻĻāĻŋāϞ⧇ āϏāĻ°ā§āĻŦāĻžāϧāĻŋāĻ• āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦ⧇āĨ¤", + "transcoding_tone_mapping": "āĻŸā§‹āύ-āĻŽā§āϝāĻžāĻĒāĻŋāĻ‚", + "transcoding_tone_mapping_description": "āĻāχāϚāĻĄāĻŋāφāϰ (HDR) āĻ­āĻŋāĻĄāĻŋāĻ“āϕ⧇ āĻāϏāĻĄāĻŋāφāϰ (SDR)-āĻ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāϰ āĻŦāĻžāĻšā§āϝāĻŋāĻ• āϰ⧂āĻĒ āĻ…āĻ•ā§āώ⧁āĻŖā§āĻŖ āϰāĻžāĻ–āĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻž āĻšāϝāĻŧāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ āϰāĻ™, āĻĄāĻŋāĻŸā§‡āχāϞ āĻāĻŦāĻ‚ āωāĻœā§āĻœā§āĻŦāϞāϤāĻžāϰ āϜāĻ¨ā§āϝ āĻ­āĻŋāĻ¨ā§āύ āĻ­āĻŋāĻ¨ā§āύ āϏāĻŽāĻ¨ā§āĻŦāϝāĻŧ āĻ•āϰ⧇āĨ¤ āĻšā§‡āĻŦāϞ āĻĄāĻŋāĻŸā§‡āχāϞ, āĻŽā§‹āĻŦāĻŋāϝāĻŧāĻžāϏ āϰāĻ™ āĻāĻŦāĻ‚ āϰāĻžāχāύāĻšāĻžāĻ°ā§āĻĄ āωāĻœā§āĻœā§āĻŦāϞāϤāĻž āĻ…āĻ•ā§āώ⧁āĻŖā§āĻŖ āϰāĻžāϖ⧇āĨ¤", + "transcoding_transcode_policy": "āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āύ⧀āϤāĻŋ", + "transcoding_transcode_policy_description": "āĻ•āĻ–āύ āĻāĻ•āϟāĻŋ āĻ­āĻŋāĻĄāĻŋāĻ“ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻž āĻšāĻŦ⧇ āϤāĻžāϰ āύ⧀āϤāĻŋāĻŽāĻžāϞāĻžāĨ¤ HDR āĻ­āĻŋāĻĄāĻŋāĻ“ āĻāĻŦāĻ‚ YUV 4:2:0 āĻŦā§āϝāϤ⧀āϤ āĻ…āĻ¨ā§āϝ āĻĒāĻŋāĻ•ā§āϏ⧇āϞ āĻĢāϰāĻŽā§āϝāĻžāĻŸā§‡āϰ āĻ­āĻŋāĻĄāĻŋāĻ“ āϏāĻ°ā§āĻŦāĻĻāĻž āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻž āĻšāĻŦ⧇ (āϝāĻĻāĻŋ āύāĻž āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄāĻŋāĻ‚ āĻŦāĻ¨ā§āϧ āĻ•āϰāĻž āĻĨāĻžāϕ⧇)āĨ¤", + "transcoding_two_pass_encoding": "āϟ⧁-āĻĒāĻžāϏ āĻāύāϕ⧋āĻĄāĻŋāĻ‚", + "transcoding_two_pass_encoding_setting_description": "āφāϰāĻ“ āωāĻ¨ā§āύāϤ āĻŽāĻžāύ⧇āϰ āĻāύāϕ⧋āĻĄā§‡āĻĄ āĻ­āĻŋāĻĄāĻŋāĻ“ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĻ⧁āχ āϧāĻžāĻĒ⧇ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰ⧁āύāĨ¤ āϝāĻ–āύ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āϟ āϏāĻ•ā§āϰāĻŋāϝāĻŧ āĻ•āϰāĻž āĻšāϝāĻŧ (āϝāĻž H.264 āĻāĻŦāĻ‚ HEVC-āĻāϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻŦāĻļā§āϝāĻ•), āϤāĻ–āύ āĻāχ āĻŽā§‹āĻĄāϟāĻŋ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āĻŸā§‡āϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇ āĻāĻ•āϟāĻŋ āĻŦāĻŋāϟāϰ⧇āϟ āϰ⧇āĻžā§āϜ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāĻŦāĻ‚ CRF āωāĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰ⧇āĨ¤ VP9-āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻŦāĻŋāϟāϰ⧇āϟ āύāĻŋāĻˇā§āĻ•ā§āϰāĻŋāϝāĻŧ āĻĨāĻžāĻ•āϞ⧇āĻ“ CRF āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤", + "transcoding_video_codec": "āĻ­āĻŋāĻĄāĻŋāĻ“ āϕ⧋āĻĄā§‡āĻ•", + "transcoding_video_codec_description": "VP9 āωāĻšā§āϚ āĻ•āĻ°ā§āĻŽāĻĻāĻ•ā§āώāϤāĻž āϏāĻŽā§āĻĒāĻ¨ā§āύ āĻāĻŦāĻ‚ āĻ“āϝāĻŧ⧇āĻŦ⧇āϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāϤ⧇ āĻŦ⧇āĻļāĻŋ āϏāĻŽāϝāĻŧ āϞāĻžāϗ⧇āĨ¤ HEVC-āĻāϰ āĻ•āĻ°ā§āĻŽāĻ•ā§āώāĻŽāϤāĻžāĻ“ āĻĒā§āϰāĻžāϝāĻŧ āĻāĻ•āχ āϰāĻ•āĻŽ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāϰ āĻ“āϝāĻŧ⧇āĻŦ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāϤāĻž āĻ•āĻŽāĨ¤ H.264 āĻŦā§āϝāĻžāĻĒāĻ•āĻ­āĻžāĻŦ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻāĻŦāĻ‚ āĻĻā§āϰ⧁āϤ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰāĻž āϝāĻžāϝāĻŧ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāϟāĻŋ āĻ…āύ⧇āĻ• āĻŦāĻĄāĻŧ āĻĢāĻžāχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤ AV1 āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻ•āĻ°ā§āĻŽāĻĻāĻ•ā§āώ āϕ⧋āĻĄā§‡āĻ•, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĒ⧁āϰ⧋āύ⧋ āĻĄāĻŋāĻ­āĻžāχāϏāϗ⧁āϞ⧋āϤ⧇ āĻāϰ āϏāĻŽāĻ°ā§āĻĨāύ āύ⧇āχāĨ¤", + "trash_enabled_description": "āĻŸā§āĻ°ā§āϝāĻžāĻļ āĻĢāĻŋāϚāĻžāϰ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ", + "trash_number_of_days": "āĻĻāĻŋāύ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž", + "trash_number_of_days_description": "āĻŸā§āĻ°ā§āϝāĻžāĻļ⧇ āĻĨāĻžāĻ•āĻž āĻ…ā§āϝāĻžāϏ⧇āϟāϗ⧁āϞ⧋ āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āφāϗ⧇ āϰāĻžāĻ–āĻžāϰ āĻĻāĻŋāύ āϏāĻ‚āĻ–ā§āϝāĻž", + "trash_settings": "āĻŸā§āĻ°ā§āϝāĻžāĻļ āϏ⧇āϟāĻŋāĻ‚āϏ", + "trash_settings_description": "āĻŸā§āĻ°ā§āϝāĻžāĻļ āϏ⧇āϟāĻŋāĻ‚āϏ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧁āύ", + "unlink_all_oauth_accounts": "āϏāĻ•āϞ OAuth āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āφāύāϞāĻŋāĻ™ā§āĻ• āĻ•āϰ⧁āύ", + "unlink_all_oauth_accounts_description": "āύāϤ⧁āύ āĻĒā§āϰ⧋āĻ­āĻžāχāĻĄāĻžāϰ⧇ āĻŽāĻžāχāĻ—ā§āϰ⧇āϟ āĻ•āϰāĻžāϰ āφāϗ⧇ āϏāĻŦ OAuth āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āφāύāϞāĻŋāĻ™ā§āĻ• āĻ•āϰ⧁āύāĨ¤", + "unlink_all_oauth_accounts_prompt": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻŦ OAuth āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āφāύāϞāĻŋāĻ™ā§āĻ• āĻ•āϰāϤ⧇ āύāĻŋāĻļā§āϚāĻŋāϤ? āĻāϟāĻŋ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ OAuth āφāχāĻĄāĻŋ āϰāĻŋāϏ⧇āϟ āĻ•āϰ⧇ āĻĻ⧇āĻŦ⧇ āĻāĻŦāĻ‚ āĻāϟāĻŋ āφāϰ āĻĒā§‚āĻ°ā§āĻŦāĻžāĻŦāĻ¸ā§āĻĨāĻžāϝāĻŧ āĻĢ⧇āϰāĻžāύ⧋ āϝāĻžāĻŦ⧇ āύāĻžāĨ¤", + "user_cleanup_job": "āχāωāϜāĻžāϰ āĻ•ā§āϞāĻŋāύāφāĻĒ", + "user_delete_delay": "{user}-āĻāϰ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϏ⧇āϟ {delay, plural, one {# day} other {# days}} āĻĒāϰ āĻ¸ā§āĻĨāĻžāϝāĻŧā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻšāĻŦ⧇āĨ¤", + "user_delete_delay_settings": "āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϏāĻŽā§Ÿ āĻŦāĻŋāϞāĻŽā§āĻŦ", + "user_delete_delay_settings_description": "āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āĻĒāϰ āĻ•āϤ āĻĻāĻŋāύ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž āĻšāĻŦ⧇āĨ¤ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āĻ•āĻžāϜ āĻŽāĻ§ā§āϝāϰāĻžāϤ⧇ āϚāĻžāϞāĻžāύ⧋ āĻšā§Ÿ āĻāĻŦāĻ‚ āĻĻ⧇āĻ–āĻž āĻšā§Ÿ āϕ⧋āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϜāĻ¨ā§āϝ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤāĨ¤ āĻāχ āϏ⧇āϟāĻŋāĻ‚ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϞ⧇ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻāĻ•ā§āϏāĻŋāĻ•āĻŋāωāĻļāύ⧇āϰ āϏāĻŽā§Ÿ āϤāĻž āĻĒā§āϰāϝ⧋āĻœā§āϝ āĻšāĻŦ⧇āĨ¤", + "user_delete_immediately": "{user}-āĻāϰ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻ¸ā§āĻĨāĻžāϝāĻŧā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϜāĻ¨ā§āϝ immediately āĻ•āĻŋāωāϤ⧇ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤", + "user_delete_immediately_checkbox": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻ“ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻ¤ā§ŽāĻ•ā§āώāĻŖāĻžā§Ž āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϜāĻ¨ā§āϝ āĻ•āĻŋāω", + "user_details": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϤāĻĨā§āϝ", + "user_management": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻŽā§āϝāĻžāύ⧇āϜāĻŽā§‡āĻ¨ā§āϟ", + "user_password_has_been_reset": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āϰāĻŋāϏ⧇āϟ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇:", + "user_password_reset_description": "āĻĻāϝāĻŧāĻž āĻ•āϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āϜāĻ¨ā§āϝ āϏāĻžāĻŽāϝāĻŧāĻŋāĻ• āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĻāĻŋāύ āĻāĻŦāĻ‚ āϜāĻžāύāĻŋā§Ÿā§‡ āĻĻāĻŋāύ āϝ⧇ āϤāĻžāϰāĻž āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āϞāĻ—āχāύ⧇ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŦ⧇āύāĨ¤", + "user_restore_description": "{user} āĻāϰ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻĒ⧁āύāϰ⧁āĻĻā§āϧāĻžāϰ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤", + "user_restore_scheduled_removal": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻĒ⧁āύāϰ⧁āĻĻā§āϧāĻžāϰ āĻ•āϰ⧁āύ - āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āϤāĻžāϰāĻŋāĻ–:{date, date, long}", + "user_settings": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϏ⧇āϟāĻŋāĻ‚āϏ", + "user_settings_description": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϏ⧇āϟāĻŋāĻ‚āϏ āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰ⧁āύ", + "user_successfully_removed": "āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āχāωāϜāĻžāϰ {email}-āϕ⧇ āϏāϰāĻŋā§Ÿā§‡ āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤", + "version_check_enabled_description": "āĻ­āĻžāĻ°ā§āϏāύ āϝāĻžāϚāĻžāχ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ", + "version_check_implications": "āĻ­āĻžāĻ°ā§āϏāύ āĻšā§‡āĻ• āĻĢāĻŋāϚāĻžāϰāϟāĻŋ github.com-āĻāϰ āϏāĻ™ā§āϗ⧇ āύāĻŋ⧟āĻŽāĻŋāϤ āϏāĻ‚āϝ⧋āϗ⧇āϰ āĻ“āĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰāĻļā§€āϞ", + "version_check_settings": "āĻ­āĻžāĻ°ā§āϏāύ āϝāĻžāϚāĻžāχ", + "version_check_settings_description": "āύāϤ⧁āύ āĻ­āĻžāĻ°ā§āϏāύ⧇āϰ āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ āϚāĻžāϞ⧁/āĻŦāĻ¨ā§āϧ āĻ•āϰ⧁āύ", + "video_conversion_job": "āĻ­āĻŋāĻĄāĻŋāĻ“ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰ⧁āύ", + "video_conversion_job_description": "āĻŦā§āϰāĻžāωāϜāĻžāϰ āĻāĻŦāĻ‚ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āφāϰāĻ“ āĻ­āĻžāϞ⧋āĻ­āĻžāĻŦ⧇ āϚāϞāĻžāϰ āϜāĻ¨ā§āϝ āĻ­āĻŋāĻĄāĻŋāĻ“ āĻŸā§āϰāĻžāĻ¨ā§āϏāϕ⧋āĻĄ āĻ•āϰ⧁āύ" }, + "admin_email": "āĻ…ā§āϝāĻžāĻĄāĻŽāĻŋāύ⧇āϰ āχāĻŽā§‡āχāϞ", + "admin_password": "āĻ…ā§āϝāĻžāĻĄāĻŽāĻŋāύ⧇āϰ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ", + "administration": "āĻ…ā§āϝāĻžāĻĄāĻŽāĻŋāύ", + "advanced": "āĻ…ā§āϝāĻžāĻĄāĻ­āĻžāĻ¨ā§āϏāĻĄ", + "age_months": "āĻŦ⧟āϏ {months, plural, one {# month} other {# months}}", + "age_year_months": "āĻŦ⧟āϏ ā§§ āĻŦāĻ›āϰ, {months, plural, one {# month} other {# months}}", + "album_added": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āϝ⧁āĻ•ā§āϤ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "album_added_notification_setting_description": "āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāĻž āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡ āϝ⧁āĻ•ā§āϤ āĻšāϞ⧇ āχāĻŽā§‡āχāϞ āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ āĻĒāĻžāύ", + "album_cover_updated": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āĻ•āĻ­āĻžāϰ āφāĻĒāĻĄā§‡āϟ āĻšāϝāĻŧ⧇āϛ⧇", + "album_delete_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ {album} āĻŽā§āϛ⧇ āĻĢ⧇āϞāϤ⧇ āϚāĻžāύ?", + "album_delete_confirmation_description": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽāϟāĻŋ āĻļā§‡ā§ŸāĻžāϰ āĻ•āϰāĻž āĻĨāĻžāĻ•āϞ⧇āĻ“ āĻ…āĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰāĻž āφāϰ āĻāϟāĻŋ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ āύāĻžāĨ¤", + "album_info_updated": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āϤāĻĨā§āϝ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "album_leave": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āĻĨ⧇āϕ⧇ āĻŦ⧇āϰāĻŋā§Ÿā§‡ āϝ⧇āϤ⧇ āϚāĻžāύ ?", + "album_leave_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻŋ {album} āϛ⧇āĻĄāĻŧ⧇ āϝ⧇āϤ⧇ āϚāĻžāύ?", + "album_name": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āύāĻžāĻŽ", + "album_options": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āĻ…āĻĒāĻļāύāϏāĻŽā§‚āĻš", + "album_remove_user": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϏāϰāĻžāϤ⧇ āϚāĻžāύ?", + "album_remove_user_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻŋ {user}-āϕ⧇ āϏāϰāĻžāϤ⧇ āϚāĻžāύ?", + "album_share_no_users": "āĻāχ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽāϟāĻŋ āϏāĻŦ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āϏāĻ™ā§āϗ⧇ āĻļā§‡ā§ŸāĻžāϰ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇, āĻŦāĻž āĻļā§‡ā§ŸāĻžāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϕ⧋āύ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āύ⧇āχāĨ¤", + "album_updated": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "album_updated_setting_description": "āύāϤ⧁āύ āĻ…ā§āϝāĻžāϏ⧇āϟ āϝ⧁āĻ•ā§āϤ āĻšāϞ⧇ āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāĻž āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āϜāĻ¨ā§āϝ āχāĻŽā§‡āχāϞ āύ⧋āϟāĻŋāĻĢāĻŋāϕ⧇āĻļāύ āĻĒāĻžāύ", + "album_user_left": "āĻŦāĻžāĻŽ {album}", + "album_user_removed": "{user} āϕ⧇ āϏāϰāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇", + "album_with_link_access": "āϞāĻŋāĻ™ā§āĻ• āĻĨāĻžāĻ•āĻž āϝ⧇ āϕ⧇āω āĻāχ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡āϰ āĻ›āĻŦāĻŋ āĻ“ āĻŽāĻžāύ⧁āώāϜāύāϕ⧇ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāϰāĻŦ⧇āĨ¤", + "albums": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽāϏāĻŽā§‚āĻš", + "all": "āϏāĻŦ", + "all_albums": "āϏāĻ•āϞ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽāϏāĻŽā§‚āĻš", + "all_people": "āϏāĻŦ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀", + "all_videos": "āϏāĻŦ āĻ­āĻŋāĻĄāĻŋāĻ“", + "allow_dark_mode": "āĻĄāĻžāĻ°ā§āĻ• āĻŽā§‹āĻĄ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ", + "allow_edits": "āĻāĻĄāĻŋāĻŸā§‡āϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻāĻŋāύ", + "allow_public_user_to_download": "āϏāĻžāϧāĻžāϰāĻŖ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇", + "allow_public_user_to_upload": "āϏāĻžāϧāĻžāϰāĻŖ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āφāĻĒāϞ⧋āĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇", + "anti_clockwise": "āĻŦāĻŋāĻĒāϰ⧀āϤ āĻĻāĻŋāĻ•", + "api_key": "API āϕ⧀", + "api_key_description": "āĻāχ āĻŽāĻžāύ āĻāĻ•āĻŦāĻžāϰāχ āĻĻ⧇āĻ–āĻžāύ⧋ āĻšāĻŦ⧇āĨ¤ āωāχāĻ¨ā§āĻĄā§‹ āĻŦāĻ¨ā§āϧ āĻ•āϰāĻžāϰ āφāϗ⧇ āĻ…āĻŦāĻļā§āϝāχ āĻāϟāĻŋ āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύāĨ¤", + "api_key_empty": "API āϕ⧀-āĻāϰ āύāĻžāĻŽ āĻ–āĻžāϞāĻŋ āϰāĻžāĻ–āĻž āϝāĻžāĻŦ⧇ āύāĻž", + "api_keys": "API āϕ⧀ āϏāĻŽā§‚āĻš", + "app_settings": "āĻ…ā§āϝāĻžāĻĒ āϏ⧇āϟāĻŋāĻ‚āϏ", + "appears_in": "v1.106.4 āĻĨ⧇āϕ⧇, āĻ…ā§āϝāĻžāϏ⧇āϟ āϏāĻžāχāĻĄāĻŦāĻžāϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšā§Ÿ ‘[albums]-āĻ āωāĻĒāĻ¸ā§āĻĨāĻŋāĻ¤â€™ āĻŦā§‹āĻāĻžāϤ⧇", + "archive": "āφāĻ°ā§āĻ•āĻžāχāĻ­", + "archive_or_unarchive_photo": "āĻĢāĻŸā§‹ āφāĻ°ā§āĻ•āĻžāχāĻ­ āĻ…āĻĨāĻŦāĻž āφāύāφāĻ°ā§āĻ•āĻžāχāĻ­ āĻ•āϰ⧁āύ", + "archive_size": "āφāĻ°ā§āĻ•āĻžāχāĻ­ āϏāĻžāχāϜ", + "archive_size_description": "āĻĄāĻžāωāύāϞ⧋āĻĄā§‡āϰ āφāĻ°ā§āĻ•āĻžāχāĻ­ āϏāĻžāχāϜ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧁āύ (GiB)", + "are_these_the_same_person": "āĻāϰāĻž āĻ•āĻŋ āĻāĻ•āχ āĻŦā§āϝāĻ•ā§āϤāĻŋ?", + "are_you_sure_to_do_this": "āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻŋ āĻāϟāĻŋ āĻ•āϰāϤ⧇ āϚāĻžāύ?", + "asset_added_to_album": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡ āϝ⧁āĻ•ā§āϤ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "asset_adding_to_album": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡ āϝ⧁āĻ•ā§āϤ āĻ•āϰāĻž āĻšāĻšā§āϛ⧇â€Ļ", + "asset_description_updated": "āĻ…ā§āϝāĻžāϏ⧇āĻŸā§‡āϰ āĻŦāĻŋāĻŦāϰāĻŖ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "asset_filename_is_offline": "{filename} āĻ…ā§āϝāĻžāϏ⧇āϟāϟāĻŋ āĻŦāĻ°ā§āϤāĻŽāĻžāύ⧇ āĻ…āĻĢāϞāĻžāχāύ", + "asset_has_unassigned_faces": "āĻ…ā§āϝāĻžāϏ⧇āϟāϟāĻŋāϰ āĻ•āĻŋāϛ⧁ āĻŽā§āĻ– āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻĢ⧇āϏ āϰāϝāĻŧ⧇āϛ⧇", + "asset_hashing": "āĻšā§āϝāĻžāĻļāĻŋāĻ‚ āϚāϞāϛ⧇â€Ļ", + "asset_offline": "āĻ…ā§āϝāĻžāϏ⧇āϟ āĻŦāĻ°ā§āϤāĻŽāĻžāύ⧇ āĻ…āĻĢāϞāĻžāχāύ", + "asset_offline_description": "āĻāχ āĻāĻ•ā§āϏāϟāĻžāĻ°ā§āύāĻžāϞ āĻ…ā§āϝāĻžāϏ⧇āϟāϟāĻŋ āĻāĻ–āύ āĻĄāĻŋāĻ¸ā§āϕ⧇ āύ⧇āχāĨ¤ āϏāĻšāĻžāϝāĻŧāϤāĻžāϰ āϜāĻ¨ā§āϝ Immich āĻ…ā§āϝāĻžāĻĄāĻŽāĻŋāύāĻŋāĻ¸ā§āĻŸā§āϰ⧇āϟāϰ⧇āϰ āϏāĻžāĻĨ⧇ āϝ⧋āĻ—āĻžāϝ⧋āĻ— āĻ•āϰ⧁āύāĨ¤", + "asset_skipped": "āĻāĻĄāĻŧāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇", + "asset_skipped_in_trash": "āĻŸā§āĻ°ā§āϝāĻžāĻļ⧇", + "asset_uploaded": "āφāĻĒāϞ⧋āĻĄ āϏāĻŽā§āĻĒāĻ¨ā§āύ", + "asset_uploading": "āφāĻĒāϞ⧋āĻĄ āϚāϞāϛ⧇â€Ļ", + "assets": "āĻ…ā§āϝāĻžāϏ⧇āϟāϏāĻŽā§‚āĻš", + "assets_added_to_album_count": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡ {count, plural, one {# asset} other {# assets}} āϝ⧁āĻ•ā§āϤ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "assets_moved_to_trash_count": "{count, plural, one {# asset} other {# assets}} āĻŸā§āĻ°ā§āϝāĻžāĻļ⧇ āϏāϰāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇", + "assets_permanently_deleted_count": "{count, plural, one {# asset} other {# assets}} āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "assets_removed_count": "{count, plural, one {# asset} other {# assets}} āϏāϰāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇", + "assets_restore_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ āφāĻĒāύāĻžāϰ āϏāĻŦ āĻŸā§āĻ°ā§āϝāĻžāĻļ āĻ•āϰāĻž āĻ…ā§āϝāĻžāϏ⧇āϟ āĻĒ⧁āύāϰ⧁āĻĻā§āϧāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāύ? āĻāϟāĻŋ āĻĒā§‚āĻ°ā§āĻŦāĻžāĻŦāĻ¸ā§āĻĨāĻžāϝāĻŧ āĻĢāĻŋāϰāĻžāύ⧋ āϝāĻžāĻŦ⧇ āύāĻžāĨ¤ āϤāĻŦ⧇ āĻ…āĻĢāϞāĻžāχāύ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻāχāĻ­āĻžāĻŦ⧇ āĻĒ⧁āύāϰ⧁āĻĻā§āϧāĻžāϰ āĻšāĻŦ⧇ āύāĻžāĨ¤", + "assets_restored_count": "{count, plural, one {# asset} other {# assets}} āĻĒ⧁āύāϰ⧁āĻĻā§āϧāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "assets_trashed_count": "{count, plural, one {# asset} other {# assets}} āĻŸā§āĻ°ā§āϝāĻžāĻļ⧇ āĻĒāĻžāĻ āĻžāύ⧋ āĻšā§Ÿā§‡āϛ⧇", + "assets_were_part_of_album_count": "{count, plural, one {Asset was} other {Assets were}} āφāϗ⧇āχ āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽā§‡ āϝ⧁āĻ•ā§āϤ āĻ›āĻŋāϞ", + "authorized_devices": "āĻ…āύ⧁āĻŽā§‹āĻĻāĻŋāϤ āĻĄāĻŋāĻ­āĻžāχāϏ", + "back": "āĻĢāĻŋāϰ⧇ āϝāĻžāύ", + "back_close_deselect": "āĻĢāĻŋāϰ⧇ āϝāĻžāύ, āĻŦāĻ¨ā§āϧ āĻ•āϰ⧁āύ āĻŦāĻž āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻŦāĻžāϤāĻŋāϞ āĻ•āϰ⧁āύ", + "backward": "āĻĒāĻŋāĻ›āύ⧇", + "birthdate_saved": "āϜāĻ¨ā§āĻŽ āϤāĻžāϰāĻŋāĻ– āϏāĻ‚āϰāĻ•ā§āώāĻŖ āϏāĻŽā§āĻĒāĻ¨ā§āύ", + "birthdate_set_description": "āĻāĻ•āϟāĻŋ āĻ›āĻŦāĻŋāϰ āϏāĻŽā§Ÿā§‡ āĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŦ⧟āϏ āĻ—āĻŖāύāĻžāϰ āϜāĻ¨ā§āϝ āϜāĻ¨ā§āĻŽ āϤāĻžāϰāĻŋāĻ– āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§ŸāĨ¤", + "blurred_background": "āĻŦā§āϞāĻžāϰāĻĄ āĻŦā§āϝāĻžāĻ•āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ", + "bugs_and_feature_requests": "āĻŦāĻžāĻ— āĻ“ āĻĢāĻŋāϚāĻžāϰ āϰāĻŋāĻ•ā§‹ā§Ÿā§‡āĻ¸ā§āϟ", + "build": "āĻŦāĻŋāĻ˛ā§āĻĄ", + "build_image": "āĻŦāĻŋāĻ˛ā§āĻĄ āχāĻŽā§‡āϜ", + "bulk_delete_duplicates_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ {count, plural, one {# duplicate asset} other {# duplicate assets}} āĻāĻ•āϏāĻžāĻĨ⧇ āĻŽā§āϛ⧇ āĻĢ⧇āϞāϤ⧇ āϚāĻžāύ? āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ—ā§āϰ⧁āĻĒ⧇āϰ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻŦ⧜ āĻ…ā§āϝāĻžāϏ⧇āϟ āϰāĻžāĻ–āĻž āĻšāĻŦ⧇, āĻŦāĻžāĻ•āĻŋāϗ⧁āϞ⧋ āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āϛ⧇ āϝāĻžāĻŦ⧇āĨ¤ āĻāϟāĻŋ āĻĒā§‚āĻ°ā§āĻŦāĻžāĻŦāĻ¸ā§āĻĨāĻžāϝāĻŧ āĻĢāĻŋāϰāĻžāύ⧋ āϝāĻžāĻŦ⧇ āύāĻž!", + "bulk_keep_duplicates_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ {count, plural, one {# duplicate asset} other {# duplicate assets}} āϰāĻžāĻ–āϤ⧇ āϚāĻžāύ? āϏāĻŦ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āĻ—ā§āϰ⧁āĻĒ āĻ āĻŋāĻ• āĻ•āϰāĻž āĻšāĻŦ⧇, āϕ⧋āύ⧋ āĻ•āĻŋāϛ⧁ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž āĻšāĻŦ⧇ āύāĻžāĨ¤", + "bulk_trash_duplicates_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ {count, plural, one {# duplicate asset} other {# duplicate assets}} āĻāĻ•āϏāĻžāĻĨ⧇ āĻŸā§āĻ°ā§āϝāĻžāĻļ āĻ•āϰāϤ⧇ āϚāĻžāύ? āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ—ā§āϰ⧁āĻĒ⧇āϰ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻŦ⧜ āĻ…ā§āϝāĻžāϏ⧇āϟ āϰāĻžāĻ–āĻž āĻšāĻŦ⧇, āĻŦāĻžāĻ•āĻŋāϗ⧁āϞ⧋ āĻŸā§āĻ°ā§āϝāĻžāĻļ⧇ āϝāĻžāĻŦ⧇āĨ¤", + "buy": "Immich āĻ•ā§āϰ⧟ āĻ•āϰ⧁āύ", + "camera": "āĻ•ā§āϝāĻžāĻŽā§‡āϰāĻž", + "camera_brand": "āĻ•ā§āϝāĻžāĻŽā§‡āϰāĻž āĻŦā§āĻ°ā§āϝāĻžāĻ¨ā§āĻĄ", + "camera_model": "āĻ•ā§āϝāĻžāĻŽā§‡āϰāĻž āĻŽāĻĄā§‡āϞ", + "cancel": "āĻŦāĻžāϤāĻŋāϞ", + "cancel_search": "āϏāĻžāĻ°ā§āϚ āĻŦāĻ¨ā§āϧ āĻ•āϰ⧁āύ", + "cannot_merge_people": "āĻŦā§āϝāĻ•ā§āϤāĻŋāĻĻ⧇āϰ āĻāĻ•āĻ¤ā§āϰ āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦ āύāϝāĻŧ", + "cannot_undo_this_action": "āĻāχ āĻ•āĻžāϜ āĻĒā§‚āĻ°ā§āĻŦāĻžāĻŦāĻ¸ā§āĻĨāĻžāϝāĻŧ āĻĢ⧇āϰāĻžāύ⧋ āϝāĻžāĻŦ⧇ āύāĻž!", + "cannot_update_the_description": "āĻŦāĻŋāĻŦāϰāĻŖ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āϏāĻŽā§āĻ­āĻŦ āύāϝāĻŧ", + "change_date": "āϤāĻžāϰāĻŋāĻ– āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ", + "change_expiration_time": "āĻŽā§‡āϝāĻŧāĻžāĻĻ āĻļ⧇āώ⧇āϰ āϏāĻŽāϝāĻŧ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ", + "change_location": "āϞ⧋āϕ⧇āĻļāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ", + "change_name": "āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧁āύ", + "change_name_successfully": "āύāĻžāĻŽ āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻšāϝāĻŧ⧇āϛ⧇", + "change_password": "āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧁āύ", + "change_password_description": "āφāĻĒāύāĻŋ āĻšāϝāĻŧāϤ⧋ āĻĒā§āϰāĻĨāĻŽāĻŦāĻžāϰ āϞāĻ—āχāύ āĻ•āϰāϛ⧇āύ āĻŦāĻž āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āĻ…āύ⧁āϰ⧋āϧ āĻ•āϰ⧇āϛ⧇āύāĨ¤ āύāĻŋāĻšā§‡ āύāϤ⧁āύ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĻāĻŋāύāĨ¤", + "change_your_password": "āφāĻĒāύāĻžāϰ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧁āύ", + "changed_visibility_successfully": "āĻ­āĻŋāϏāĻŋāĻŦāĻŋāϞāĻŋāϟāĻŋ āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻšāϝāĻŧ⧇āϛ⧇", + "check_logs": "āϞāĻ— āĻĻ⧇āϖ⧁āύ", + "choose_matching_people_to_merge": "āĻāĻ•āĻ¤ā§āϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻŽāĻŋāϞ āĻĨāĻžāĻ•āĻž āĻŦā§āϝāĻ•ā§āϤāĻŋāĻĻ⧇āϰ āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύ", + "city": "āĻļāĻšāϰ", + "clear": "āĻŽā§āϛ⧁āύ", + "clear_all": "āϏāĻŦ āĻŽā§āϛ⧁āύ", + "clear_all_recent_searches": "āϏāĻžāĻŽā§āĻĒā§āϰāϤāĻŋāĻ• āϏāĻŦ āĻ…āύ⧁āϏāĻ¨ā§āϧāĻžāύ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻ•āϰ⧁āύ", + "clear_message": "āĻŽā§‡āϏ⧇āϜ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻ•āϰ⧁āύ", + "clear_value": "āĻ­ā§āϝāĻžāϞ⧁ āĻŽā§āϛ⧁āύ", + "clockwise": "āϘ⧜āĻŋāϰ āĻ•āĻžāρāϟāĻžāϰ āĻĻāĻŋāϕ⧇", + "close": "āĻŦāĻ¨ā§āϧ", + "collapse": "āϏāĻ‚āϕ⧁āϚāĻŋāϤ āĻ•āϰ⧁āύ", + "collapse_all": "āϏāĻŦ āϏāĻ‚āϕ⧁āϚāĻŋāϤ", + "color": "āϰāĻ‚", + "color_theme": "āĻ•āĻžāϞāĻžāϰ āĻĨāĻŋāĻŽ", + "comment_deleted": "āĻŽāĻ¨ā§āϤāĻŦā§āϝ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "comment_options": "āĻŽāĻ¨ā§āϤāĻŦā§āϝ āĻ…āĻĒāĻļāύ", + "comments_and_likes": "āĻŽāĻ¨ā§āϤāĻŦā§āϝ āĻ“ āϞāĻžāχāĻ•", + "comments_are_disabled": "āĻŽāĻ¨ā§āϤāĻŦā§āϝ āĻŦāĻ¨ā§āϧ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "confirm": "āύāĻŋāĻļā§āϚāĻŋāϤ", + "confirm_admin_password": "āĻ…ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒ⧁āύāϰāĻžā§Ÿ āϞāĻŋāϖ⧁āύ", + "confirm_delete_shared_link": "āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻŋ āĻāχ āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāĻž āϞāĻŋāĻ™ā§āĻ•āϟāĻŋ āĻŽā§āϛ⧇ āĻĢ⧇āϞāϤ⧇ āϚāĻžāύ?", + "confirm_keep_this_delete_others": "āĻ¸ā§āĻŸā§āϝāĻžāϕ⧇āϰ āĻāχ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻ›āĻžā§œāĻž āϏāĻŦ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻŽā§āϛ⧇ āϝāĻžāĻŦ⧇āĨ¤ āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻŋ āϚāĻžāϞāĻŋāϝāĻŧ⧇ āϝ⧇āϤ⧇ āϚāĻžāύ?", + "confirm_password": "āĻĒāĻžāϏāĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻĒ⧁āύāϰāĻžā§Ÿ āϞāĻŋāϖ⧁āύ", + "contain": "āĻŽāĻžāĻĒāĻŽāϤ", + "context": "āĻĒā§āϰāϏāĻ™ā§āĻ—", + "continue": "āĻāĻ—āĻŋā§Ÿā§‡ āϝāĻžāύ", + "copied_image_to_clipboard": "āĻ›āĻŦāĻŋ āĻ•ā§āϞāĻŋāĻĒāĻŦā§‹āĻ°ā§āĻĄā§‡ āĻ•āĻĒāĻŋ āĻšāϝāĻŧ⧇āϛ⧇āĨ¤", + "copied_to_clipboard": "āĻ•ā§āϞāĻŋāĻĒāĻŦā§‹āĻ°ā§āĻĄā§‡ āĻ•āĻĒāĻŋ āĻšāϝāĻŧ⧇āϛ⧇!", + "copy_error": "Error-āϟāĻŋ āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύ", + "copy_file_path": "āĻĢāĻžāχāϞ āĻĒāĻžāĻĨ āĻ•āĻĒāĻŋ", + "copy_image": "āĻ›āĻŦāĻŋ āĻ•āĻĒāĻŋ", + "copy_link": "āϞāĻŋāĻ™ā§āĻ• āĻ•āĻĒāĻŋ", + "copy_link_to_clipboard": "āĻ•ā§āϞāĻŋāĻĒāĻŦā§‹āĻ°ā§āĻĄā§‡ āϞāĻŋāĻ™ā§āĻ• āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύ", + "copy_password": "āĻĒāĻžāϏāĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύ", + "copy_to_clipboard": "āĻ•ā§āϞāĻŋāĻĒāĻŦā§‹āĻ°ā§āĻĄā§‡ āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύ", + "country": "āĻĻ⧇āĻļ", + "cover": "āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖāĻ­āĻžāĻŦ⧇", + "covers": "āĻ•āĻ­āĻžāϰāϏ", + "create": "āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ", + "create_album": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āϤ⧈āϰāĻŋ", + "create_library": "āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āϤ⧈āϰāĻŋ", + "create_link": "āϞāĻŋāĻ™ā§āĻ• āϤ⧈āϰāĻŋ", + "create_link_to_share": "āĻļ⧇āϝāĻŧāĻžāϰ āϞāĻŋāĻ™ā§āĻ• āϤ⧈āϰāĻŋ", + "create_link_to_share_description": "āϞāĻŋāĻ™ā§āϕ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϏāĻŦāĻžāχ āύāĻŋāĻ°ā§āĻŦāĻžāϚāĻŋāϤ āĻ›āĻŦāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāϰāĻŦ⧇", + "create_new_person": "āύāϤ⧁āύ āĻŦā§āϝāĻ•ā§āϤāĻŋ āϝ⧋āĻ— āĻ•āϰ⧁āύ", + "create_new_person_hint": "āύāĻŋāĻ°ā§āĻŦāĻžāϚāĻŋāϤ āĻ…ā§āϝāĻžāϏ⧇āϟ āύāϤ⧁āύ āĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āϏāĻ™ā§āϗ⧇ āϝ⧁āĻ•ā§āϤ āĻ•āϰ⧁āύ", + "create_new_user": "āύāϤ⧁āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϝ⧋āĻ— āĻ•āϰ⧁āύ", + "create_tag": "āĻŸā§āϝāĻžāĻ— āϤ⧈āϰāĻŋ", + "create_tag_description": "āύāϤ⧁āύ āĻŸā§āϝāĻžāĻ— āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύāĨ¤ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āĻŸā§āϝāĻžāϗ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻĒāĻžāĻĨ - āĻĢāϰāĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āĻ¸ā§āĻ˛ā§āϝāĻžāĻļāϏāĻš āĻĻāĻŋāύāĨ¤", + "create_user": "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϝ⧋āĻ— āĻ•āϰ⧁āύ", + "created": "āϝ⧋āĻ— āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "current_device": "āϚāϞāϤāĻŋ āĻĄāĻŋāĻ­āĻžāχāϏ", + "custom_locale": "āĻ•āĻžāĻ¸ā§āϟāĻŽ āϞ⧋āϕ⧇āϞ", + "custom_locale_description": "āύāĻŋāĻ°ā§āĻŦāĻžāϚāĻŋāϤ āĻ­āĻžāώāĻž āĻāĻŦāĻ‚ āĻ…āĻžā§āϚāϞ⧇āϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋāϤ⧇ āϤāĻžāϰāĻŋāĻ–, āϏāĻŽā§Ÿ āĻāĻŦāĻ‚ āϏāĻ‚āĻ–ā§āϝāĻž āĻĢāϰāĻŽā§āϝāĻžāϟ āĻ•āϰ⧁āύ", + "dark": "āĻĄāĻžāĻ°ā§āĻ•", + "date_after": "āĻāϰ āĻĒāϰ⧇āϰ āϤāĻžāϰāĻŋāĻ–", + "date_and_time": "āϤāĻžāϰāĻŋāĻ– āĻāĻŦāĻ‚ āϏāĻŽā§Ÿ", + "date_before": "āĻāϰ āφāϗ⧇āϰ āϤāĻžāϰāĻŋāĻ–", + "date_of_birth_saved": "āϜāĻ¨ā§āĻŽ āϤāĻžāϰāĻŋāĻ– āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇", + "delete": "āĻŽā§āϛ⧁āύ", + "delete_album": "āĻ…ā§āϝāĻžāϞāĻŦāĻžāĻŽ āĻŽā§āϛ⧁āύ", + "delete_api_key_prompt": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ āĻāχ API key āĻŽā§āϛ⧇ āĻĢ⧇āϞāϤ⧇ āϚāĻžāύ?", + "delete_duplicates_confirmation": "āφāĻĒāύāĻŋ āĻ•āĻŋ āϏāĻ¤ā§āϝāĻŋāχ āĻāχ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟāϗ⧁āϞ⧋ āĻ¸ā§āĻĨāĻžā§Ÿā§€āĻ­āĻžāĻŦ⧇ āĻŽā§āĻ›āϤ⧇ āϚāĻžāύ?", + "delete_key": "key āĻŽā§āϛ⧁āύ", + "delete_library": "āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āĻŽā§āϛ⧁āύ", + "delete_link": "āϞāĻŋāĻ™ā§āĻ• āĻŽā§āϛ⧁āύ", + "delete_others": "āĻŦāĻžāĻ•āĻŋāϗ⧁āϞ⧋ āĻŽā§āϛ⧁āύ", + "delete_shared_link": "āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāĻž āϞāĻŋāĻ™ā§āĻ• āĻŽā§āϛ⧁āύ", + "delete_tag": "āĻŸā§āϝāĻžāĻ— āĻŽā§āϛ⧁āύ", + "delete_tag_confirmation_prompt": "āφāĻĒāύāĻŋ āĻ•āĻŋ āύāĻŋāĻļā§āϚāĻŋāϤāĻ­āĻžāĻŦ⧇ {tagName} āĻŸā§āϝāĻžāĻ—āϟāĻŋ āĻŽā§āĻ›āϤ⧇ āϚāĻžāύ?", + "delete_user": "āχāωāϜāĻžāϰ āĻŽā§āϛ⧁āύ", + "deleted_shared_link": "āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāĻž āϞāĻŋāĻ™ā§āĻ•āϟāĻŋ āĻŽā§āϛ⧁āύ", + "deletes_missing_assets": "āĻĄāĻŋāĻ¸ā§āĻ• āĻĨ⧇āϕ⧇ āĻšāĻžāϰāĻžāύ⧋ āĻ…ā§āϝāĻžāϏ⧇āϟāϗ⧁āϞ⧋ āĻŽā§āϛ⧇", + "description": "āĻŦāĻŋāĻŦāϰāύ", + "details": "āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ", + "direction": "āĻĻāĻŋāĻ•āύāĻŋāĻ°ā§āĻĻ⧇āĻļāύāĻž", + "disabled": "āύāĻŋāĻˇā§āĻ•ā§āϰāĻŋāϝāĻŧ", + "disallow_edits": "āϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āĻŦ⧇āύ āύāĻž", + "discord": "āĻĄāĻŋāϏāĻ•āĻ°ā§āĻĄ", + "discover": "āĻĄāĻŋāϏāĻ•āĻ­āĻžāϰ", + "dismiss_all_errors": "āϏāĻŦ āĻ¤ā§āϰ⧁āϟāĻŋ āĻŦāĻžāϤāĻŋāϞ āĻ•āϰ⧁āύ", + "dismiss_error": "āĻ¤ā§āϰ⧁āϟāĻŋ āĻŦāĻžāϤāĻŋāϞ āĻ•āϰ⧁āύ", + "display_options": "āĻĄāĻŋāϏāĻĒā§āϞ⧇ āĻ…āĻĒāĻļāύ", + "display_order": "āĻĄāĻŋāϏāĻĒā§āϞ⧇ āĻ…āĻ°ā§āĻĄāĻžāϰ", + "display_original_photos": "āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āĻ›āĻŦāĻŋ āĻĻ⧇āĻ–āĻžāύ", + "display_original_photos_setting_description": "āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āĻ…ā§āϝāĻžāϏ⧇āϟāϟāĻŋ āĻ“āϝāĻŧ⧇āĻŦ-āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ (web-compatible) āĻšāϞ⧇ āĻ…ā§āϝāĻžāϏ⧇āϟ āĻĻ⧇āĻ–āĻžāϰ āϏāĻŽāϝāĻŧ āĻĨāĻžāĻŽā§āĻŦāύ⧇āχāϞ⧇āϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ āĻŽā§‚āϞ āĻĢāĻŸā§‹āϟāĻŋ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻ•āϰāϤ⧇ āĻ…āĻ—ā§āϰāĻžāϧāĻŋāĻ•āĻžāϰ āĻĻāĻŋāύāĨ¤ āĻāϰ āĻĢāϞ⧇ āĻĢāĻŸā§‹ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ⧇āϰ āĻ—āϤāĻŋ āĻ•āĻŋāϛ⧁āϟāĻž āϧ⧀āϰ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤", + "do_not_show_again": "āĻāχ āĻŽā§‡āϏ⧇āϜāϟāĻŋ āφāϰ āĻĻ⧇āĻ–āĻžāĻŦ⧇āύ āύāĻž", + "documentation": "āϏāĻšāĻžā§ŸāĻ• āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž", + "done": "āϏāĻŽā§āĻĒāĻ¨ā§āύ", + "download": "āĻĄāĻžāωāύāϞ⧋āĻĄ", + "download_include_embedded_motion_videos": "āĻāĻŽāĻŦ⧇āĻĄā§‡āĻĄ āĻ­āĻŋāĻĄāĻŋāĻ“", + "download_include_embedded_motion_videos_description": "āĻŽā§‹āĻļāύ āĻĢāĻŸā§‹āϰ (motion photos) āĻŽāĻ§ā§āϝ⧇ āĻĨāĻžāĻ•āĻž āĻ­āĻŋāĻĄāĻŋāĻ“āϗ⧁āϞ⧋āϕ⧇ āφāϞāĻžāĻĻāĻž āĻĢāĻžāχāϞ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āĻ•āϰ⧁āύ", + "download_settings": "āĻĄāĻžāωāύāϞ⧋āĻĄ", + "download_settings_description": "āĻ…ā§āϝāĻžāϏ⧇āϟ āĻĄāĻžāωāύāϞ⧋āĻĄā§‡āϰ āϏ⧇āϟāĻŋāĻ‚āϏ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧁āύ", + "open_in_browser": "āĻŦā§āϰāĻžāωāϜāĻžāϰ⧇ āĻ“āĻĒ⧇āύ āĻ•āϰ⧁āύ", "user_usage_stats": "āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āĻĒāϰāĻŋāϏāĻ‚āĻ–ā§āϝāĻžāύ", "user_usage_stats_description": "āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āĻĒāϰāĻŋāϏāĻ‚āĻ–ā§āϝāĻžāύ āĻĻ⧇āϖ⧁āύ", "yes": "āĻšā§āϝāĻžāρ", diff --git a/i18n/ca.json b/i18n/ca.json index fbd6c5840f..88c6b8a323 100644 --- a/i18n/ca.json +++ b/i18n/ca.json @@ -372,7 +372,7 @@ "transcoding_audio_codec": "CÃ˛dec d'àudio", "transcoding_audio_codec_description": "Opus Ês l'opciÃŗ de màxima qualitat, perÃ˛ tÊ menor compatibilitat amb dispositius o programari antics.", "transcoding_bitrate_description": "Vídeos superiors a la taxa de bits màxima o que no tenen un format acceptat", - "transcoding_codecs_learn_more": "Per obtenir mÊs informaciÃŗ sobre la terminologia utilitzada, consulteu la documentaciÃŗ de FFmpeg per al cÃ˛dec H.264, cÃ˛dec HEVC i cÃ˛dec VP9.", + "transcoding_codecs_learn_more": "Per obtenir mÊs informaciÃŗ sobre la terminologia utilitzada, consulteu la documentaciÃŗ de FFmpeg per al cÃ˛dec H.264, cÃ˛dec HEVC i cÃ˛dec VP9.", "transcoding_constant_quality_mode": "Mode de qualitat constant", "transcoding_constant_quality_mode_description": "ICQ Ês millor que CQP, perÃ˛ alguns dispositius d'acceleraciÃŗ de maquinari no admeten aquest mode. Establir aquesta opciÃŗ preferirà el mode especificat quan utilitzeu la codificaciÃŗ basada en la qualitat. Ignorat per NVENC perquè no Ês compatible amb ICQ.", "transcoding_constant_rate_factor": "Factor de taxa constant (-crf)", @@ -441,7 +441,7 @@ "user_successfully_removed": "L'usuari {email} s'ha eliminat correctament.", "users_page_description": "Pàgina d'usuaris de l'administrador", "version_check_enabled_description": "Activa la comprovaciÃŗ de la versiÃŗ", - "version_check_implications": "La funciÃŗ de comprovaciÃŗ de versions depèn de comunicacions periÃ˛diques amb github.com", + "version_check_implications": "La funciÃŗ de comprovaciÃŗ de versions depèn de comunicacions periÃ˛diques amb {server}", "version_check_settings": "ComprovaciÃŗ de versiÃŗ", "version_check_settings_description": "Activa/desactiva la notificaciÃŗ de nova versiÃŗ", "video_conversion_job": "TranscodificaciÃŗ de vídeos", @@ -849,9 +849,12 @@ "create_link_to_share": "Crear enllaç per compartir", "create_link_to_share_description": "Deixa que qualsevol persona amb l'enllaç vegi les fotos seleccionades", "create_new": "CREAR NOU", + "create_new_face": "Crea una nova cara", "create_new_person": "Crea una nova persona", "create_new_person_hint": "Assigna els elements seleccionats a una persona nova", "create_new_user": "Crea un usuari nou", + "create_person": "Crea una persona", + "create_person_subtitle": "Afegeix un nom a la cara seleccionada per crear i etiquetar la nova persona", "create_shared_album_page_share_add_assets": "AFEGEIX ELEMENTS", "create_shared_album_page_share_select_photos": "Escull fotografies", "create_shared_link": "Crea un enllaç compartit", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixat", "crop_aspect_ratio_free": "Lliure", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Quadrat", "curated_object_page_title": "Coses", "current_device": "Dispositiu actual", "current_pin_code": "Codi PIN actual", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Fosc", - "dark_theme": "Canviar a tema fosc", + "dark_theme": "Canvia a tema fosc", "date": "Data", "date_after": "Data posterior a", "date_and_time": "Data i hora", @@ -891,10 +895,8 @@ "day": "Dia", "days": "Dies", "deduplicate_all": "Desduplica-ho tot", - "deduplication_criteria_1": "Mida d'imatge en bytes", - "deduplication_criteria_2": "Quantitat de dades EXIF", - "deduplication_info": "InformaciÃŗ de deduplicaciÃŗ", - "deduplication_info_description": "Per preseleccionar recursos automàticament i eliminar els duplicats de manera massiva, ens fixem en:", + "default_locale": "ConfiguraciÃŗ regional predeterminada", + "default_locale_description": "Format de dades i nÃēmeros en funciÃŗ de la configuraciÃŗ local", "delete": "Esborrar", "delete_action_confirmation_message": "Segur que vols eliminar aquest recurs? Aquesta acciÃŗ el mourà a la paperera del servidor, i et preguntarà si el vols eliminar localment", "delete_action_prompt": "{count} eliminats", @@ -970,7 +972,7 @@ "downloading_media": "Descàrrega multimèdia", "drop_files_to_upload": "Deixeu els fitxers a qualsevol lloc per pujar-los", "duplicates": "Duplicats", - "duplicates_description": "Resol cada grup indicant, si n'hi ha, quins sÃŗn duplicats", + "duplicates_description": "Resol cada grup indicant, si n'hi ha, quins sÃŗn duplicats.", "duration": "Durada", "edit": "Editar", "edit_album": "Edita l'àlbum", @@ -992,7 +994,7 @@ "edit_location_dialog_title": "UbicaciÃŗ", "edit_name": "Edita el nom", "edit_people": "Edita la gent", - "edit_tag": "Editar etiqueta", + "edit_tag": "Edita etiqueta", "edit_title": "Edita títol", "edit_user": "Edita l'usuari", "edit_workflow": "Edita el flux de treball", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Les modificacions s'han aplicat correctament", "editor_flip_horizontal": "Capgira horitzontalment", "editor_flip_vertical": "Capgira verticalment", + "editor_handle_corner": "{corner, select, top_left {Top-left} top_right {Top-right} bottom_left {Bottom-left} bottom_right {Bottom-right} other {A}} cantÃŗ per agafar", + "editor_handle_edge": "{edge, select, top {Top} bottom {Bottom} left {Left} right {Right} other {An}} cantÃŗ per agafar", "editor_orientation": "OrientaciÃŗ", "editor_reset_all_changes": "Reiniciar canvis", "editor_rotate_left": "Rota 90Âē al contrari de les agulles", @@ -1168,7 +1172,7 @@ "exif_bottom_sheet_description_error": "No s'ha pogut actualitzar la descripciÃŗ", "exif_bottom_sheet_details": "DETALLS", "exif_bottom_sheet_location": "UBICACIÓ", - "exif_bottom_sheet_no_description": "Sense descriociÃŗ", + "exif_bottom_sheet_no_description": "Sense descripciÃŗ", "exif_bottom_sheet_people": "PERSONES", "exif_bottom_sheet_person_add_person": "Afegir nom", "exit_slideshow": "Surt de la presentaciÃŗ de diapositives", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Títol de l'àlbum", "licenses": "Llicències", "light": "Llum", + "light_theme": "Canviar a tema clar", "like": "M'agrada", "like_deleted": "M'agrada suprimit", "link_motion_video": "Enllaçar vídeo en moviment", + "link_to_docs": "Per mÊs informaciÃŗ, mirar la documentation.", "link_to_oauth": "Enllaç a OAuth", "linked_oauth_account": "Compte OAuth enllaçat", "list": "Llista", @@ -1649,6 +1655,7 @@ "only_favorites": "NomÊs preferits", "open": "Obrir", "open_calendar": "Obrir el calendari", + "open_in_browser": "Obre al navegador", "open_in_map_view": "Obrir a la vista del mapa", "open_in_openstreetmap": "Obre a OpenStreetMap", "open_the_search_filters": "Obriu els filtres de cerca", @@ -2210,6 +2217,7 @@ "tag": "Etiqueta", "tag_assets": "Etiquetar actius", "tag_created": "Etiqueta creada: {tag}", + "tag_face": "Etiqueta una cara", "tag_feature_description": "Exploreu fotos i vídeos agrupats per temes d'etiquetes lÃ˛giques", "tag_not_found_question": "No trobeu una etiqueta? Crear una nova etiqueta.", "tag_people": "Etiquetar personas", @@ -2391,6 +2399,7 @@ "viewer_remove_from_stack": "Elimina de la pila", "viewer_stack_use_as_main_asset": "Fes servir com a element principal", "viewer_unstack": "Desapila", + "visibility": "Visibilitat", "visibility_changed": "La visibilitat ha canviat per {count, plural, one {# persona} other {# persones}}", "visual": "Visual", "visual_builder": "Constructor visual", diff --git a/i18n/cs.json b/i18n/cs.json index 363e568331..0c333532f3 100644 --- a/i18n/cs.json +++ b/i18n/cs.json @@ -441,7 +441,7 @@ "user_successfully_removed": "UÅživatel {email} byl ÃēspÄ›ÅĄně odstraněn.", "users_page_description": "StrÃĄnka sprÃĄvců", "version_check_enabled_description": "Povolit kontrolu verzí", - "version_check_implications": "Kontrola verze je zaloÅžena na pravidelnÊ komunikaci s github.com", + "version_check_implications": "Kontrola verze je zaloÅžena na pravidelnÊ komunikaci s {server}", "version_check_settings": "Kontrola verze", "version_check_settings_description": "Povolení/zakÃĄzÃĄní oznÃĄmení o novÊ verzi", "video_conversion_job": "PřekÃŗdovÃĄní videí", @@ -849,9 +849,12 @@ "create_link_to_share": "Vytvořit odkaz pro sdílení", "create_link_to_share_description": "UmoÅžnit kaÅždÊmu, kdo mÃĄ odkaz, zobrazit vybranÊ fotografie", "create_new": "VYTVOŘIT NOVÉ", + "create_new_face": "Vytvořit novÃŊ obličej", "create_new_person": "Vytvořit novou osobu", "create_new_person_hint": "Přiřadit vybranÊ poloÅžky novÊ osobě", "create_new_user": "Vytvořit novÊho uÅživatele", + "create_person": "Vytvořit osobu", + "create_person_subtitle": "Přidejte jmÊno ke zvolenÊmu obličeji pro vytvoření a označení novÊ osoby", "create_shared_album_page_share_add_assets": "PŘIDAT POLOÅŊKY", "create_shared_album_page_share_select_photos": "Vybrat fotografie", "create_shared_link": "Vytvořit sdílenÃŊ odkaz", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "PevnÃŊ", "crop_aspect_ratio_free": "VolnÃŊ", "crop_aspect_ratio_original": "Původní", + "crop_aspect_ratio_square": "Čtverec", "curated_object_page_title": "Věci", "current_device": "SoučasnÊ zařízení", "current_pin_code": "AktuÃĄlní PIN kÃŗd", @@ -880,7 +884,7 @@ "daily_title_text_date": "EEEE, d. MMMM", "daily_title_text_date_year": "EEEE, d. MMMM y", "dark": "TmavÃŊ", - "dark_theme": "Přepnout tmavÃŊ motiv", + "dark_theme": "Přepnout na tmavÃŊ motiv", "date": "Datum", "date_after": "Datum po", "date_and_time": "Datum a čas", @@ -891,10 +895,8 @@ "day": "Den", "days": "Dnů", "deduplicate_all": "Odstranit vÅĄechny duplicity", - "deduplication_criteria_1": "Velikost obrÃĄzku v bajtech", - "deduplication_criteria_2": "Počet EXIF dat", - "deduplication_info": "Informace o deduplikaci", - "deduplication_info_description": "Pro automatickÃŊ předvÃŊběr poloÅžek a hromadnÊ odstranění duplicit se zohledňuje:", + "default_locale": "VÃŊchozí nÃĄrodní prostředí", + "default_locale_description": "FormÃĄtovÃĄní datumu a čísel podle místního nastavení prohlíŞeče", "delete": "Smazat", "delete_action_confirmation_message": "Opravdu chcete odstranit tuto poloÅžku? Tato akce přesune poloÅžku do serverovÊho koÅĄe a zeptÃĄ se vÃĄs, zda ji chcete odstranit lokÃĄlně", "delete_action_prompt": "{count} smazÃĄno", @@ -970,7 +972,7 @@ "downloading_media": "StahovÃĄní mÊdia", "drop_files_to_upload": "Pro nahrÃĄní sem přetÃĄhněte soubory", "duplicates": "Duplicity", - "duplicates_description": "VyřeÅĄte kaÅždou skupinu tak, Åže uvedete, kterÊ skupiny jsou duplicitní", + "duplicates_description": "VyřeÅĄte kaÅždou skupinu tak, Åže uvedete, kterÊ skupiny jsou duplicitní.", "duration": "Doba trvÃĄní", "edit": "Upravit", "edit_album": "Upravit album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Podle nÃĄzvu alba", "licenses": "Licence", "light": "SvětlÃŊ", + "light_theme": "Přepnout na světlÃŊ motiv", "like": "Líbí se mi", "like_deleted": "Oblíbení smazÃĄno", "link_motion_video": "Připojit pohyblivÊ video", + "link_to_docs": "DalÅĄÃ­ informace najdete v dokumentaci.", "link_to_oauth": "Propojit s OAuth", "linked_oauth_account": "PropojenÃŊ OAuth Ãēčet", "list": "Seznam", @@ -2213,6 +2217,7 @@ "tag": "Značka", "tag_assets": "Přiřadit značku", "tag_created": "Vytvořena značka: {tag}", + "tag_face": "Označit obličej", "tag_feature_description": "ProchÃĄzení fotografií a videí seskupenÃŊch podle tÊmat logickÃŊch značek", "tag_not_found_question": "NemůŞete najít značku? Vytvořte novou.", "tag_people": "Označit lidi", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Odstranit ze seskupení", "viewer_stack_use_as_main_asset": "PouŞít jako hlavní poloÅžku", "viewer_unstack": "ZruÅĄit seskupení", + "visibility": "Viditelnost", "visibility_changed": "Viditelnost změněna u {count, plural, one {# osoby} few {# osob} other {# lidí}}", "visual": "VizuÃĄlní", "visual_builder": "VizuÃĄlní nÃĄvrhÃĄÅ™", diff --git a/i18n/da.json b/i18n/da.json index 1eafb3d827..7628be0f4c 100644 --- a/i18n/da.json +++ b/i18n/da.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Bruger {email} er blevet fjernet med succes.", "users_page_description": "Admin-brugere side", "version_check_enabled_description": "AktivÊr versionstjek", - "version_check_implications": "Funktionen til versionstjek er afhÃĻngig af periodisk kommunikation med github.com", + "version_check_implications": "Funktionen til versionstjek er afhÃĻngig af periodisk kommunikation med {server}", "version_check_settings": "Versionstjek", "version_check_settings_description": "Aktiver/deaktiverer notifikation for den nye version", "video_conversion_job": "Transkod videoer", @@ -849,9 +849,12 @@ "create_link_to_share": "Opret link for at dele", "create_link_to_share_description": "Tillad alle med linket at se de(t) valgte billede(r)", "create_new": "OPRET NY", + "create_new_face": "Opret nyt ansigt", "create_new_person": "Opret ny person", "create_new_person_hint": "Tildel valgte aktiver til en ny person", "create_new_user": "Opret ny bruger", + "create_person": "Opret person", + "create_person_subtitle": "Tilføj et navn til det valgte ansigt for at oprette og tagge den nye person", "create_shared_album_page_share_add_assets": "TILFØJ ELEMENT", "create_shared_album_page_share_select_photos": "VÃĻlg Billeder", "create_shared_link": "Opret delt link", @@ -863,9 +866,10 @@ "created_at": "Oprettet", "creating_linked_albums": "Opretter sammenkÃĻdede albums...", "crop": "BeskÃĻr", - "crop_aspect_ratio_fixed": "Fikset", - "crop_aspect_ratio_free": "Gratis", + "crop_aspect_ratio_fixed": "Fast", + "crop_aspect_ratio_free": "Fri", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Kvadrat", "curated_object_page_title": "Ting", "current_device": "NuvÃĻrende enhed", "current_pin_code": "NuvÃĻrende PIN kode", @@ -890,11 +894,9 @@ "date_range": "Datointerval", "day": "Dag", "days": "Dage", - "deduplicate_all": "Kopier alle", - "deduplication_criteria_1": "Billedstørrelse i bytes", - "deduplication_criteria_2": "Antal EXIF-data", - "deduplication_info": "Deduplikerings info", - "deduplication_info_description": "For automatisk at forudvÃĻlge emner og fjerne dubletter i bulk ser vi pÃĨ:", + "deduplicate_all": "Dedubliker alle", + "default_locale": "Standard sprog", + "default_locale_description": "FormatÊr datoer og tal baseret pÃĨ din browsers landestandard", "delete": "Slet", "delete_action_confirmation_message": "Er du sikker pÃĨ, at du vil slette dette objekt? Denne handling vil flytte objektet til serverens papirkurv, og vil spørge dig, om du vil slette den lokalt", "delete_action_prompt": "{count} slettet", @@ -970,7 +972,7 @@ "downloading_media": "Download medier", "drop_files_to_upload": "Slip filer hvor som helst for at uploade dem", "duplicates": "Duplikater", - "duplicates_description": "Løs hver gruppe ved at angive, hvilke, hvis nogen, er dubletter", + "duplicates_description": "Løs hver gruppe ved at angive hvilke, hvis nogen, er dubletter", "duration": "Varighed", "edit": "Rediger", "edit_album": "RedigÊr album", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Redigeringer gemt", "editor_flip_horizontal": "Vend horisontalt", "editor_flip_vertical": "Flip vertikal", + "editor_handle_corner": "{corner, select, top_left {Øverst venstre} top_right {Øverst højre} bottom_left {Nederst venstre} bottom_right {Nederst højre} other {A}} hjørnehÃĨndtag", + "editor_handle_edge": "{edge, select, top {Øverst} bottom {Nederst} left {Venstre} right {Højre} other {Et}} kanthÃĨndtag", "editor_orientation": "Orientering", "editor_reset_all_changes": "Nulstil ÃĻndringer", "editor_rotate_left": "RotÊr 90° mod uret", @@ -1017,7 +1021,7 @@ "empty_trash": "Tøm papirkurv", "empty_trash_confirmation": "Er du sikker pÃĨ, at du vil tømme papirkurven? Dette vil fjerne alle objekter i papirkurven permanent fra Immich.\nDu kan ikke fortryde denne handling!", "enable": "AktivÊr", - "enable_backup": "Aktiver backup", + "enable_backup": "AktivÊr backup", "enable_biometric_auth_description": "Indtast din PIN kode for at slÃĨ biometrisk adgangskontrol til", "enabled": "Aktiveret", "end_date": "Slutdato", @@ -1072,7 +1076,7 @@ "failed_to_update_notification_status": "Kunne ikke uploade notifikations status", "incorrect_email_or_password": "Forkert email eller kodeord", "library_folder_already_exists": "Denne import sti findes allerede.", - "page_not_found": "Siden blev ikke fundet :/", + "page_not_found": "Siden blev ikke fundet", "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.", "quota_higher_than_disk_size": "Du har sat en kvote der er større end disken", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Albumtitel", "licenses": "Licenser", "light": "Lys", + "light_theme": "Skift til lyst tema", "like": "Synes om", "like_deleted": "Ligesom slettet", "link_motion_video": "Link bevÃĻgelsesvideo", + "link_to_docs": "For yderligere information, se dokumentationen.", "link_to_oauth": "Link til OAuth", "linked_oauth_account": "Tilsluttet OAuth-konto", "list": "Liste", @@ -1649,6 +1655,7 @@ "only_favorites": "Kun favoritter", "open": "Åben", "open_calendar": "Åbn kalender", + "open_in_browser": "Åbn i browser", "open_in_map_view": "Åben i kortvisning", "open_in_openstreetmap": "Åben i OpenStreetMap", "open_the_search_filters": "Åbn søgefiltre", @@ -2210,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Tag mediefiler", "tag_created": "Oprettet tag: {tag}", + "tag_face": "Tag ansigt", "tag_feature_description": "Gennemse billeder og videoer grupperet efter logiske tag-emner", "tag_not_found_question": "Kan du ikke finde et tag? Opret et nyt tag.", "tag_people": "Tag personer", @@ -2391,6 +2399,7 @@ "viewer_remove_from_stack": "Fjern fra stak", "viewer_stack_use_as_main_asset": "Brug som hovedelement", "viewer_unstack": "Fjern fra stak", + "visibility": "Synlighed", "visibility_changed": "Synlighed ÃĻndret for {count, plural, one {# person} other {# personer}}", "visual": "Visuel", "visual_builder": "Visuel builder", diff --git a/i18n/de.json b/i18n/de.json index a6b2a844c4..9816055023 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -1,5 +1,5 @@ { - "about": "Über Immich", + "about": "Über", "account": "Konto", "account_settings": "Kontoeinstellungen", "acknowledge": "Verstanden", @@ -8,7 +8,7 @@ "action_description": "Eine Reihe von Aktionen, die an den gefilterten Assets ausgefÃŧhrt werden sollen", "actions": "Aktionen", "active": "Aktiv", - "active_count": "Aktive:{count}", + "active_count": "Aktive: {count}", "activity": "Aktivität", "activity_changed": "Aktivität ist {enabled, select, true {aktiviert} other {deaktiviert}}", "add": "HinzufÃŧgen", @@ -59,7 +59,7 @@ "backup_database_enable_description": "Datenbank regelmäßig sichern", "backup_keep_last_amount": "Anzahl der aufzubewahrenden frÃŧheren Sicherungen", "backup_onboarding_1_description": "Offsite-Kopie in der Cloud oder an einem anderen physischen Ort.", - "backup_onboarding_2_description": "lokale Kopien auf verschiedenen Geräten. Dazu gehÃļren die Hauptdateien und eine lokale Sicherung dieser Dateien.", + "backup_onboarding_2_description": "Lokale Kopien auf verschiedenen Geräten. Dazu gehÃļren die Hauptdateien und eine lokale Sicherung dieser Dateien.", "backup_onboarding_3_description": "Kopien deiner Daten inklusive Originaldateien. Dies umfasst 1 Kopie an einem anderen Ort und 2 lokale Kopien.", "backup_onboarding_description": "Eine 3-2-1 Sicherungsstrategie wird empfohlen, um deine Daten zu schÃŧtzen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende SicherungslÃļsung zu haben.", "backup_onboarding_footer": "Weitere Informationen zum Sichern von Immich findest du in der Dokumentation.", @@ -309,7 +309,7 @@ "reset_settings_to_recent_saved": "Einstellungen auf die zuletzt gespeicherten Einstellungen zurÃŧcksetzen", "scanning_library": "Bibliothek scannen", "search_jobs": "Suchaufgabenâ€Ļ", - "send_welcome_email": "BegrÃŧssungsmail senden", + "send_welcome_email": "BegrÃŧßungsmail senden", "server_external_domain_settings": "Externe Domain", "server_external_domain_settings_description": "FÃŧr externe Links verwendete Domäne", "server_public_users": "Öffentliche Benutzer", @@ -441,7 +441,7 @@ "user_successfully_removed": "Der Benutzer {email} wurde erfolgreich entfernt.", "users_page_description": "Administrator-Benutzerseite", "version_check_enabled_description": "VersionsprÃŧfung aktivieren", - "version_check_implications": "Die Funktion zur VersionsprÃŧfung basiert auf regelmäßiger Kommunikation mit GitHub.com", + "version_check_implications": "Die Funktion zur VersionsprÃŧfung basiert auf regelmäßiger Kommunikation mit {server}", "version_check_settings": "VersionsprÃŧfung", "version_check_settings_description": "Aktivieren/Deaktivieren der Benachrichtigung Ãŧber neue Versionen", "video_conversion_job": "Videos transkodieren", @@ -472,7 +472,7 @@ "advanced_settings_troubleshooting_title": "Fehlersuche", "age_months": "Alter {months, plural, one {# Monat} other {# Monate}}", "age_year_months": "Alter 1 Jahr, {months, plural, one {# Monat} other {# Monate}}", - "age_years": "Alter {years, plural, one {# Jahr} other {# Jahre}}", + "age_years": "{years, plural, other {Alter #}}", "album": "Album", "album_added": "Album hinzugefÃŧgt", "album_added_notification_setting_description": "Erhalte eine E-Mail-Benachrichtigung, wenn du zu einem freigegebenen Album hinzugefÃŧgt wurdest", @@ -541,7 +541,7 @@ "app_settings": "App-Einstellungen", "app_stores": "App Stores", "app_update_available": "App Update verfÃŧgbar", - "appears_in": "Erscheint in", + "appears_in": "Enthalten in", "apply_count": "Anwenden ({count, number})", "archive": "Archiv", "archive_action_prompt": "{count} zum Archiv hinzugefÃŧgt", @@ -580,7 +580,7 @@ "asset_restored_successfully": "Datei erfolgreich wiederhergestellt", "asset_skipped": "Übersprungen", "asset_skipped_in_trash": "Im Papierkorb", - "asset_trashed": "Datei GelÃļscht", + "asset_trashed": "Datei gelÃļscht", "asset_troubleshoot": "Datei Fehlerbehebung", "asset_uploaded": "Hochgeladen", "asset_uploading": "Hochladenâ€Ļ", @@ -610,14 +610,14 @@ "assets_were_part_of_album_count": "{count, plural, one {# Datei ist} other {# Dateien sind}} bereits im Album vorhanden", "assets_were_part_of_albums_count": "{count, plural, one {Datei war} other {Dateien waren}} bereits in den Alben", "authorized_devices": "Verwendete Geräte", - "automatic_endpoint_switching_subtitle": "Verbinden Sie sich lokal Ãŧber ein bestimmtes WiFi, wenn es verfÃŧgbar ist, und verwenden Sie andere VerbindungsmÃļglichkeiten", + "automatic_endpoint_switching_subtitle": "Verbinden Sie sich lokal Ãŧber ein bestimmtes WLAN-Netz, wenn es verfÃŧgbar ist, und verwenden Sie ansonsten andere VerbindungsmÃļglichkeiten", "automatic_endpoint_switching_title": "Automatische URL-Umschaltung", "autoplay_slideshow": "Automatische Diashow", "back": "ZurÃŧck", "back_close_deselect": "ZurÃŧck, Schließen oder Abwählen", "background_backup_running_error": "Sicherung läuft im Hintergrund. Manuelle Sicherung kann nicht gestartet werden", "background_location_permission": "Hintergrund Standortfreigabe", - "background_location_permission_content": "Um im Hintergrund zwischen den Netzwerken wechseln zu kÃļnnen, muss Immich *immer* Zugriff auf den genauen Standort haben, damit die App den Namen des WiFi-Netzwerks ermitteln kann", + "background_location_permission_content": "Um im Hintergrund zwischen den Netzwerken wechseln zu kÃļnnen, muss Immich *immer* Zugriff auf den genauen Standort haben, damit die App den Namen des WLAN-Netzwerks ermitteln kann", "background_options": "Hintergrund Optionen", "backup": "Sicherung", "backup_album_selection_page_albums_device": "Alben auf dem Gerät ({count})", @@ -652,7 +652,7 @@ "backup_controller_page_background_is_on": "Automatische Sicherung im Hintergrund ist aktiviert", "backup_controller_page_background_turn_off": "Hintergrundservice ausschalten", "backup_controller_page_background_turn_on": "Hintergrundservice einschalten", - "backup_controller_page_background_wifi": "Nur im WiFi", + "backup_controller_page_background_wifi": "Nur im WLAN", "backup_controller_page_backup": "Sicherung", "backup_controller_page_backup_selected": "Ausgewählt: ", "backup_controller_page_backup_sub": "Gesicherte Fotos und Videos", @@ -687,7 +687,7 @@ "backup_options_page_title": "Sicherungsoptionen", "backup_setting_subtitle": "Verwaltung der Upload-Einstellungen im Hintergrund und im Vordergrund", "backup_settings_subtitle": "Upload-Einstellungen verwalten", - "backup_upload_details_page_more_details": "Tippen fÃŧr weitere Details", + "backup_upload_details_page_more_details": "Tippe fÃŧr weitere Details", "backward": "RÃŧckwärts", "biometric_auth_enabled": "Biometrische Authentifizierung aktiviert", "biometric_locked_out": "Du bist von der biometrischen Authentifizierung ausgeschlossen", @@ -697,8 +697,8 @@ "birthdate_set_description": "Das Geburtsdatum wird verwendet, um das Alter dieser Person zum Zeitpunkt eines Fotos zu berechnen.", "blurred_background": "Unscharfer Hintergrund", "bugs_and_feature_requests": "Fehler & Verbesserungsvorschläge", - "build": "Erstelle", - "build_image": "Bild erstellen", + "build": "Build", + "build_image": "Abbildversion", "bulk_delete_duplicates_confirmation": "Bist du sicher, dass du {count, plural, one {# duplizierte Datei} other {# duplizierte Dateien gemeinsam}} lÃļschen mÃļchtest? Dabei wird die grÃļßte Datei jeder Gruppe behalten und alle anderen Duplikate endgÃŧltig gelÃļscht. Diese Aktion kann nicht rÃŧckgängig gemacht werden!", "bulk_keep_duplicates_confirmation": "Bist du sicher, dass du {count, plural, one {# duplizierte Datei} other {# duplizierte Dateien}} behalten mÃļchtest? Dies wird alle Duplikat-Gruppen auflÃļsen ohne etwas zu lÃļschen.", "bulk_trash_duplicates_confirmation": "Bist du sicher, dass du {count, plural, one {# duplizierte Datei} other {# duplizierte Dateien gemeinsam}} in den Papierkorb verschieben mÃļchtest? Dies wird die grÃļßte Datei jeder Gruppe behalten und alle anderen Duplikate in den Papierkorb verschieben.", @@ -728,7 +728,7 @@ "cannot_undo_this_action": "Diese Aktion kann nicht rÃŧckgängig gemacht werden!", "cannot_update_the_description": "Beschreibung kann nicht aktualisiert werden", "cast": "Übertragen", - "cast_description": "Konfiguration verfÃŧgbarer Ziele", + "cast_description": "VerfÃŧgbare Cast-Ziele konfigurieren", "change_date": "Datum ändern", "change_description": "Beschreibung anpassen", "change_display_order": "Anzeigereihenfolge ändern", @@ -739,7 +739,7 @@ "change_password": "Passwort ändern", "change_password_description": "Dies ist entweder das erste Mal, dass du dich im System anmeldest, oder es wurde eine Anfrage zur Änderung deines Passworts gestellt. Bitte gib unten dein neues Passwort ein.", "change_password_form_confirm_password": "Passwort bestätigen", - "change_password_form_description": "Hallo {name}\n\nDas ist entweder das erste Mal dass du dich einloggst oder es wurde eine Anfrage zur Änderung deines Passwortes gestellt. Bitte gib das neue Passwort ein.", + "change_password_form_description": "Hallo {name}\n\nDas ist entweder das erste Mal, dass du dich einloggst oder es wurde eine Anfrage zur Änderung deines Passwortes gestellt. Bitte gib das neue Passwort ein.", "change_password_form_log_out": "Von allen Geräte abmelden", "change_password_form_log_out_description": "Es wird empfohlen, alle anderen Geräte abzumelden", "change_password_form_new_password": "Neues Passwort", @@ -754,7 +754,7 @@ "charging_requirement_mobile_backup": "Backup im Hintergrund erfordert Aufladen des Geräts", "check_corrupt_asset_backup": "Auf beschädigte Asset-Backups ÃŧberprÃŧfen", "check_corrupt_asset_backup_button": "ÜberprÃŧfung durchfÃŧhren", - "check_corrupt_asset_backup_description": "FÃŧhre diese PrÃŧfung nur mit aktivierten WiFi durch, nachdem alle Dateien gesichert worden sind. Dieser Vorgang kann ein paar Minuten dauern.", + "check_corrupt_asset_backup_description": "FÃŧhre diese PrÃŧfung nur mit aktivierten WLAN durch, nachdem alle Dateien gesichert worden sind. Dieser Vorgang kann ein paar Minuten dauern.", "check_logs": "Logs prÃŧfen", "checksum": "PrÃŧfsumme", "choose_matching_people_to_merge": "Wähle passende Personen zum ZusammenfÃŧhren", @@ -807,13 +807,13 @@ "completed": "Abgeschlossen", "confirm": "Bestätigen", "confirm_admin_password": "Administrator Passwort bestätigen", - "confirm_delete_face": "Bist du sicher dass du das Gesicht von {name} aus der Datei entfernen willst?", + "confirm_delete_face": "Bist du sicher, dass du das Gesicht von {name} aus der Datei entfernen willst?", "confirm_delete_shared_link": "Bist du sicher, dass du diesen geteilten Link lÃļschen willst?", "confirm_keep_this_delete_others": "Alle anderen Dateien im Stapel bis auf diese werden gelÃļscht. Bist du sicher, dass du fortfahren mÃļchten?", "confirm_new_pin_code": "Neuen PIN-Code bestätigen", "confirm_password": "Passwort bestätigen", - "confirm_tag_face": "Wollen Sie dieses Gesicht mit {name} markieren?", - "confirm_tag_face_unnamed": "MÃļchten Sie dieses Gesicht markieren?", + "confirm_tag_face": "Wollen Sie dieses Gesicht mit {name} taggen?", + "confirm_tag_face_unnamed": "MÃļchten Sie dieses Gesicht taggen?", "connected_device": "Verbundenes Gerät", "connected_to": "Verbunden mit", "contain": "Vollständig", @@ -849,9 +849,12 @@ "create_link_to_share": "Link zum Teilen erstellen", "create_link_to_share_description": "Lass jeden mit dem Link die ausgewählten Fotos sehen", "create_new": "NEUES ERSTELLEN", + "create_new_face": "Neues Gesicht erstellen", "create_new_person": "Neue Person anlegen", "create_new_person_hint": "Ausgewählte Dateien einer neuen Person zuweisen", "create_new_user": "Neuen Nutzer erstellen", + "create_person": "Person anlegen", + "create_person_subtitle": "Gib dem gewählten Gesicht einen Namen um die neue Person zu erstellen und zu taggen", "create_shared_album_page_share_add_assets": "INHALTE HINZUFÜGEN", "create_shared_album_page_share_select_photos": "Fotos auswählen", "create_shared_link": "Geteilten Link erstellen", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixiert", "crop_aspect_ratio_free": "Frei", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Quadratisch", "curated_object_page_title": "Dinge", "current_device": "Aktuelles Gerät", "current_pin_code": "Aktueller PIN-Code", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Dunkel", - "dark_theme": "Dunkle Ansicht umschalten", + "dark_theme": "Auf dunkle Ansicht umschalten", "date": "Datum", "date_after": "Datum nach", "date_and_time": "Datum und Zeit", @@ -891,10 +895,8 @@ "day": "Tag", "days": "Tage", "deduplicate_all": "Alle Duplikate entfernen", - "deduplication_criteria_1": "BildgrÃļße in Bytes", - "deduplication_criteria_2": "Anzahl der EXIF-Daten", - "deduplication_info": "Deduplizierungsinformationen", - "deduplication_info_description": "FÃŧr die automatische Datei-Vorauswahl und das Deduplizieren aller Dateien berÃŧcksichtigen wir:", + "default_locale": "Standardgebietsschema", + "default_locale_description": "Datumsangaben und Zahlen werden entsprechend Ihrer Browsereinstellungen formatiert", "delete": "LÃļschen", "delete_action_confirmation_message": "Bist du sicher, dass du dieses Objekt lÃļschen willst? Diese Aktion wird das Objekt in den Papierkorb des Servers verschieben und fragen, ob du es lokal lÃļschen willst", "delete_action_prompt": "{count} gelÃļscht", @@ -970,7 +972,7 @@ "downloading_media": "Medien werden heruntergeladen", "drop_files_to_upload": "Lade Dateien hoch, indem du sie hierhin ziehst", "duplicates": "Duplikate", - "duplicates_description": "LÃļse jede Gruppe auf, indem du angibst, welche, wenn Ãŧberhaupt, Duplikate sind", + "duplicates_description": "LÃļse jede Gruppe auf, indem du angibst, welche, wenn Ãŧberhaupt, Duplikate sind.", "duration": "Dauer", "edit": "Bearbeiten", "edit_album": "Album bearbeiten", @@ -1024,7 +1026,7 @@ "enabled": "Aktiviert", "end_date": "Enddatum", "enqueued": "Eingereiht", - "enter_wifi_name": "WiFi-Name eingeben", + "enter_wifi_name": "WLAN-Name eingeben", "enter_your_pin_code": "PIN-Code eingeben", "enter_your_pin_code_subtitle": "Gib deinen PIN-Code ein, um auf den gesperrten Ordner zuzugreifen", "error": "Fehler", @@ -1036,7 +1038,7 @@ "error_loading_partners": "Fehler beim Laden der Partner: {error}", "error_retrieving_asset_information": "Fehler beim Abruf der Dateiinformationen", "error_saving_image": "Fehler: {error}", - "error_tag_face_bounding_box": "Fehler beim Markieren des Gesichts - Begrenzungen kÃļnnen nicht abgerufen werden", + "error_tag_face_bounding_box": "Fehler beim Taggen des Gesichts - Begrenzungen kÃļnnen nicht abgerufen werden", "error_title": "Fehler - Etwas ist schief gelaufen", "error_while_navigating": "Fehler beim Navigieren zur Datei", "errors": { @@ -1081,9 +1083,9 @@ "something_went_wrong": "Ein Fehler ist eingetreten", "unable_to_add_album_users": "Benutzer konnten nicht zum Album hinzugefÃŧgt werden", "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_comment": "Es kann kein Kommentar hinzugefÃŧgt werden", "unable_to_add_exclusion_pattern": "Ausschlussmuster konnte nicht hinzugefÃŧgt werden", - "unable_to_add_partners": "Es kÃļnnen keine Partner hinzufÃŧgt werden", + "unable_to_add_partners": "Es kÃļnnen keine Partner hinzugefÃŧ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", "unable_to_archive_unarchive": "Konnte nicht {archived, select, true {archivieren} other {entarchivieren}}", @@ -1240,7 +1242,7 @@ "geolocation_instruction_location": "Klicke auf eine Datei mit GPS Koordinaten um diesen Standort zu verwenden oder wähle einen Standort direkt auf der Karte", "get_help": "Hilfe erhalten", "get_people_error": "Fehler beim Laden der Personen", - "get_wifiname_error": "WiFi-Name konnte nicht ermittelt werden. Vergewissere dich, dass die erforderlichen Berechtigungen erteilt wurden und du mit einem WiFi-Netzwerk verbunden bist", + "get_wifiname_error": "Das WLAN-Netz konnte nicht ermittelt werden. Vergewissere dich, dass die erforderlichen Berechtigungen erteilt wurden und du mit einem WLAN-Netzwerk verbunden bist", "getting_started": "Erste Schritte", "go_back": "ZurÃŧck", "go_to_folder": "Gehe zu Ordner", @@ -1279,7 +1281,7 @@ "home_page_add_to_album_err_local": "Es kÃļnnen lokale Elemente noch nicht zu Alben hinzugefÃŧgt werden, Ãŧberspringen", "home_page_add_to_album_success": "{added} Elemente zu {album} hinzugefÃŧgt.", "home_page_album_err_partner": "Inhalte von Partnern kÃļnnen derzeit nicht zu Alben hinzugefÃŧgt werden", - "home_page_archive_err_local": "Kann lokale Elemente nicht archvieren, Ãŧberspringen", + "home_page_archive_err_local": "Kann lokale Elemente nicht archivieren, Ãŧberspringen", "home_page_archive_err_partner": "Inhalte von Partnern kÃļnnen nicht archiviert werden", "home_page_building_timeline": "Zeitachse wird erstellt", "home_page_delete_err_partner": "Inhalte von Partnern kÃļnnen nicht gelÃļscht werden, Ãŧberspringe", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Titel des Albums", "licenses": "Lizenzen", "light": "Hell", + "light_theme": "Auf helle Ansicht umschalten", "like": "Gefällt mir", "like_deleted": "Like gelÃļscht", "link_motion_video": "Bewegungsvideo verknÃŧpfen", + "link_to_docs": "Weitere Informationen finden Sie in der Dokumentation.", "link_to_oauth": "Mit OAuth verknÃŧpfen", "linked_oauth_account": "VerknÃŧpftes OAuth-Konto", "list": "Liste", @@ -1404,7 +1408,7 @@ "local_network_sheet_info": "Die App stellt Ãŧber diese URL eine Verbindung zum Server her, wenn sie das angegebene WLAN-Netzwerk verwendet", "location": "Standort", "location_permission": "Standort Genehmigung", - "location_permission_content": "Um die automatische Umschaltfunktion nutzen zu kÃļnnen, benÃļtigt Immich genaue Standortberechtigung, damit es den Namen des aktuellen WiFi-Netzwerks ermitteln kann", + "location_permission_content": "Um die automatische Umschaltfunktion nutzen zu kÃļnnen, benÃļtigt Immich genaue Standortberechtigung, damit es den Namen des aktuellen WLAN-Netzwerks ermitteln kann", "location_picker_choose_on_map": "Auf der Karte auswählen", "location_picker_latitude_error": "GÃŧltigen Breitengrad eingeben", "location_picker_latitude_hint": "Breitengrad eingeben", @@ -1562,7 +1566,7 @@ "name_or_nickname": "Name oder Nickname", "name_required": "Name ist erforderlich", "navigate": "Navigation", - "navigate_to_time": "Navigiere zu Zeit", + "navigate_to_time": "Zu Zeitpunkt navigieren", "network_requirement_photos_upload": "Mobile Daten verwenden, um Fotos zu sichern", "network_requirement_videos_upload": "Mobile Daten verwenden, um Videos zu sichern", "network_requirements": "Anforderungen ans Netzwerk", @@ -1665,7 +1669,7 @@ "other_devices": "Andere Geräte", "other_entities": "Andere Entitäten", "other_variables": "Sonstige Variablen", - "owned": "Eigenes", + "owned": "Eigene", "owner": "Besitzer", "page": "Seite", "partner": "Partner", @@ -1872,7 +1876,7 @@ "repair": "Reparatur", "repair_no_results_message": "Nicht auffindbare und fehlende Dateien werden hier angezeigt", "replace_with_upload": "Durch Upload ersetzen", - "repository": "Repositorium", + "repository": "Repository", "require_password": "Passwort erforderlich", "require_user_to_change_password_on_first_login": "Benutzer muss das Passwort beim ersten Login ändern", "rescan": "Erneut scannen", @@ -2011,7 +2015,7 @@ "selected_count": "{count, plural, other {# ausgewählt}}", "selected_gps_coordinates": "Ausgewählte GPS-Koordinaten", "send_message": "Nachricht senden", - "send_welcome_email": "BegrÃŧssungsmail senden", + "send_welcome_email": "BegrÃŧßungsmail senden", "server_endpoint": "Server-Endpunkt", "server_info_box_app_version": "App-Version", "server_info_box_server_url": "Server-URL", @@ -2171,7 +2175,7 @@ "sort_people_by_similarity": "Personen nach Ähnlichkeit sortieren", "sort_recent": "Neuestes Foto", "sort_title": "Titel", - "source": "Quellcode", + "source": "Quelle", "stack": "Stapel", "stack_action_prompt": "{count} gestapelt", "stack_duplicates": "Duplikate stapeln", @@ -2213,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Dateien taggen", "tag_created": "Tag erstellt: {tag}", + "tag_face": "Gesicht taggen", "tag_feature_description": "Durchsuchen von Fotos und Videos, gruppiert nach logischen Tag-Themen", "tag_not_found_question": "Kein Tag vorhanden? Erstelle einen neuen Tag.", "tag_people": "Personen taggen", @@ -2316,7 +2321,7 @@ "untagged": "Ohne Tag", "untitled_workflow": "Unbenannter Workflow", "up_next": "Weiter", - "update_location_action_prompt": "Aktualsiere den Ort von {count} ausgewählten Dateien mit:", + "update_location_action_prompt": "Aktualisiere den Ort von {count} ausgewählten Dateien mit:", "updated_at": "Aktualisiert", "updated_password": "Passwort aktualisiert", "upload": "Hochladen", @@ -2339,7 +2344,7 @@ "url": "URL", "usage": "Verwendung", "use_biometric": "Biometrie verwenden", - "use_browser_locale": "Benutze lokalen Browser", + "use_browser_locale": "Gebietsschema des Browsers verwenden", "use_browser_locale_description": "Datum, Uhrzeit und Zahlen werden entsprechend den Einstellungen Ihres Browsers formatiert", "use_current_connection": "Aktuelle Verbindung verwenden", "use_custom_date_range": "Stattdessen einen benutzerdefinierten Datumsbereich verwenden", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Aus Stapel entfernen", "viewer_stack_use_as_main_asset": "An Stapelanfang", "viewer_unstack": "Stapel aufheben", + "visibility": "Sichtbarkeit", "visibility_changed": "Sichtbarkeit fÃŧr {count, plural, one {# Person} other {# Personen}} geändert", "visual": "Visuell", "visual_builder": "Visueller Editor", @@ -2404,7 +2410,7 @@ "welcome": "Willkommen", "welcome_to_immich": "Willkommen bei Immich", "width": "Breite", - "wifi_name": "WiFi-Name", + "wifi_name": "WLAN-Netzwerk", "workflow_delete_prompt": "Bist du sicher, dass du diesen Workflow lÃļschen willst?", "workflow_deleted": "Workflow gelÃļscht", "workflow_description": "Workflow-Beschreibung", @@ -2423,7 +2429,7 @@ "years_ago": "Vor {years, plural, one {einem Jahr} other {# Jahren}}", "yes": "Ja", "you_dont_have_any_shared_links": "Du hast keine geteilten Links", - "your_wifi_name": "Dein WiFi-Name", + "your_wifi_name": "Dein WLAN-Netzwerk", "zero_to_clear_rating": "drÃŧcke 0 um die Dateibewertung zurÃŧckzusetzen", "zoom_image": "Bild vergrÃļßern", "zoom_to_bounds": "Auf Grenzen zoomen" diff --git a/i18n/de_CH.json b/i18n/de_CH.json index 5d25d2a142..f4fd0c59de 100644 --- a/i18n/de_CH.json +++ b/i18n/de_CH.json @@ -1,132 +1,132 @@ { "about": "Über", "account": "Konto", - "account_settings": "Konto Istelligä", - "acknowledge": "Bestätige", + "account_settings": "Konto Einstellungen", + "acknowledge": "Bestätigä", "action": "Aktion", "action_common_update": "Update", - "action_description": "Es paar Aktione, wo a de gfilterete Assets usgfÃŧhrt wärde sÃļlled", - "actions": "Aktione", + "action_description": "Aktionä, wo uf de gefilterti Mediä ausgfÃŧhrt werdä solled", + "actions": "Aktionen", "active": "Aktiv", - "active_count": "Aktivi: {count}", + "active_count": "Aktiv: {count}", "activity": "Aktivität", - "activity_changed": "Aktivität isch {enabled, select, true {aktiviert} other {deaktiviert}}", - "add": "HinzuefÃŧegä", - "add_a_description": "Beschriibig hinzuefÃŧege", - "add_a_location": "Standort hinzuefÃŧege", - "add_a_name": "Name hinzuefÃŧege", - "add_a_title": "Titel hinzuefÃŧege", - "add_action": "Aktion hinzuefÃŧege", - "add_action_description": "Aklicke um en Aktion dure zfÃŧehre", - "add_assets": "Assets hinzufÃŧege", - "add_birthday": "Geburtstag hinzuefÃŧege", + "activity_changed": "Aktivität ist {enabled, select, true {aktiviert} other {deaktiviert}}", + "add": "HinzuefÃŧge", + "add_a_description": "Beschreibung hinzufÃŧgen", + "add_a_location": "Standort hinzuefÃŧgä", + "add_a_name": "Namä hinzefÃŧgä", + "add_a_title": "Titel hinzufeÃŧgä", + "add_action": "Aktion hinzuefÃŧgä", + "add_action_description": "Klick do zum e Aktion hinzuefÃŧge", + "add_assets": "Mediä hinzuefÃŧge", + "add_birthday": "Geburtstag hinzuefÃŧge", "add_endpoint": "Endpunkt hinzuefÃŧge", - "add_exclusion_pattern": "Uuschlussmuster hinzuefÃŧege", - "add_filter": "Filter hinzuefÃŧge", - "add_filter_description": "Klicke, um e Filterbedingig hinzuezfÃŧege", - "add_location": "Standort hinzuefÃŧege", - "add_more_users": "Meh Benutzer hinzuefÃŧege", - "add_partner": "Partner hinzuefÃŧege", - "add_path": "Pfad hinzuefÃŧege", - "add_photos": "FÃļteli hinzuefÃŧege", - "add_tag": "Tag hinzuefÃŧege", - "add_to": "HinzuefÃŧege zu â€Ļ", - "add_to_album": "Zum Album hinzuefÃŧege", - "add_to_album_bottom_sheet_added": "Zu {album} hinzuegfÃŧegt", - "add_to_album_bottom_sheet_already_exists": "Scho in {album}", - "add_to_album_bottom_sheet_some_local_assets": "Es hend es paar lokali Dateie nÃļd chÃļne im Album hinzuegfÃŧegt werde", - "add_to_album_toggle": "Uuswahl umschalte fÃŧr {album}", - "add_to_albums": "Zu Albe hinzuefÃŧege", - "add_to_albums_count": "Zu Albe hinzuefÃŧege ({count})", - "add_to_bottom_bar": "HinzuefÃŧege zu", - "add_to_shared_album": "Zum teilte Album hinzuefÃŧege", - "add_upload_to_stack": "Upload zum Stack hinzuefÃŧege", - "add_url": "URL hinzuefÃŧege", - "add_workflow_step": "Workflow-Schritt hinzuefÃŧege", - "added_to_archive": "Is Archiv verschobe", - "added_to_favorites": "Zu dine Favoritä hinzuegfÃŧegt", - "added_to_favorites_count": "{count, number} zu Favorite hinzuegfÃŧegt", + "add_exclusion_pattern": "Ausschlussmuster hinzufÃŧgen", + "add_filter": "Filter hinzufÃŧgen", + "add_filter_description": "Klicke hier um eine Filterbedingung hinzuzufÃŧgen", + "add_location": "Standort hinzufÃŧgen", + "add_more_users": "Mehr Benutzer hinzufÃŧgen", + "add_partner": "Partner hinzufÃŧgen", + "add_path": "Pfad hinzufÃŧgen", + "add_photos": "Fotos hinzufÃŧgen", + "add_tag": "Tag hinzufÃŧgen", + "add_to": "HinzufÃŧgen zuâ€Ļ", + "add_to_album": "Zu Album hinzufÃŧgen", + "add_to_album_bottom_sheet_added": "Zu {album} hinzugefÃŧgt", + "add_to_album_bottom_sheet_already_exists": "Bereits in {album}", + "add_to_album_bottom_sheet_some_local_assets": "Einige lokale Dateien konnten nicht zum Album hinzugefÃŧgt werden", + "add_to_album_toggle": "Auswahl umschalten fÃŧr {album}", + "add_to_albums": "Zu Alben hinzufÃŧgen", + "add_to_albums_count": "Zu Alben hinzufÃŧgen ({count})", + "add_to_bottom_bar": "HinzufÃŧgen zu", + "add_to_shared_album": "Zu geteiltem Album hinzufÃŧgen", + "add_upload_to_stack": "Upload zum Stapel hinzufÃŧgen", + "add_url": "URL hinzufÃŧgen", + "add_workflow_step": "Workflow-Schritt hinzufÃŧgen", + "added_to_archive": "Zum Archiv hinzugefÃŧgt", + "added_to_favorites": "Zu Favoriten hinzugefÃŧgt", + "added_to_favorites_count": "{count, number} zu Favoriten hinzugefÃŧgt", "admin": { - "add_exclusion_pattern_description": "Uusschlussmuster hinzuefÃŧge. Platzhalter, wie *, **, und ? wärded understÃŧtzt. Zum all Dateie i eim Verzeichnis namens „Raw\" ignoriere, „**/Raw/**“ verwände. Zum all Dateien ignorieren, wo uf „.tif“ änded, „**/*.tif“ verwände. Zum en absolute Pfad ignoriere, „/pfad/zum/ignoriere/**“ verwände.", - "admin_user": "Admin Benutzer", - "asset_offline_description": "Die Datei vonere externe Bibliothek isch nÃŧmme uf de Festplatte und isch in Papierchorb verschobe worde. Falls die Datei innerhalb vo de Bibliothek verschoben worde isch, ÃŧberprÃŧf dini Ziitleiste uf die neui entsprechendi Datei. Zum die Datei wiederherstelle, stell bitte sicher, dass Immich uf de unde stehendi Dateipfad chan zuegriife und scann d'Bibliothek.", - "authentication_settings": "Authentifizierigs Iistellige", - "authentication_settings_description": "Passwort, OAuth und anderi Authentifizierigseinstellige verwalte", - "authentication_settings_disable_all": "Bisch sicher, dass du alli Login-Methodä wotsch deaktivierä? S Login isch denn komplett deaktiviert.", - "authentication_settings_reenable": "Bruuch ein Server-Befehl zum reaktiviere.", - "background_task_job": "Hintergrund Ufgabä", - "backup_database": "Datenbank-Dump aalege", - "backup_database_enable_description": "Datenbank-Dumps aktiviere", - "backup_keep_last_amount": "Aazahl vo de vorherige Dumps, wo bhalte werde sÃļlle", - "backup_onboarding_1_description": "Offsite-Kopie i dä Cloud oder amene andere physische Standort.", - "backup_onboarding_2_description": "Lokali Kopie uf verschiedene Grät. Das beinhaltet d Hauptdateie und e lokali Sicherig vo dene Dateie.", - "backup_onboarding_3_description": "Total aazahl vo dine Dateikopie, inklusiv d Originaldateie. Das beinhaltet 1 Offsite-Kopie und 2 lokali Kopie.", - "backup_onboarding_description": "E 3-2-1-Backup-Strategie wird empfohle, zum dini Dateie z schÃŧtze. Du sÃļttsch sowohl Kopie vo dine ufgeladene Fotos/Videos wie au d Immich-Datenbank bhalte, fÃŧr e rundum sauberi Backup-LÃļsig.", - "backup_onboarding_footer": "FÃŧr meh Infos zum Backup vo Immich lueg bitte i d Dokumentation.", - "backup_onboarding_parts_title": "Es 3-2-1-Backup beinhaltet:", + "add_exclusion_pattern_description": "Ausschlussmuster hinzufÃŧgen. Platzhalter, wie *, **, und ? werden unterstÃŧtzt. Um alle Dateien in einem Verzeichnis namens „Raw“ zu ignorieren, „**/Raw/**“ verwenden. Um alle Dateien zu ignorieren, die auf „.tif“ enden, „**/*.tif“ verwenden. Um einen absoluten Pfad zu ignorieren, „/pfad/zum/ignorieren/**“ verwenden.", + "admin_user": "Administrator", + "asset_offline_description": "Diese Datei einer externen Bibliothek befindet sich nicht mehr auf der Festplatte und wurde in den Papierkorb verschoben. Falls die Datei innerhalb der Bibliothek verschoben wurde, ÃŧberprÃŧfe deine Zeitleiste auf die neue entsprechende Datei. Um diese Datei wiederherzustellen, stelle bitte sicher, dass Immich auf den unten stehenden Dateipfad zugreifen kann und scanne die Bibliothek.", + "authentication_settings": "Authentifizierungseinstellungen", + "authentication_settings_description": "Passwort-, OAuth- und andere Authentifizierungseinstellungen verwalten", + "authentication_settings_disable_all": "Bist du sicher, dass du alle Loginmethoden deaktivieren willst? Die Anmeldung wird vollständig deaktiviert.", + "authentication_settings_reenable": "Nutze einen Server-Befehl zur Reaktivierung.", + "background_task_job": "Hintergrundaufgaben", + "backup_database": "Datenbanksicherung erstellen", + "backup_database_enable_description": "Datenbank regelmässig sichern", + "backup_keep_last_amount": "Anzahl der aufzubewahrenden frÃŧheren Sicherungen", + "backup_onboarding_1_description": "Offsite-Kopie in der Cloud oder an einem anderen physischen Ort.", + "backup_onboarding_2_description": "lokale Kopien auf verschiedenen Geräten. Dazu gehÃļren die Hauptdateien und eine lokale Sicherung dieser Dateien.", + "backup_onboarding_3_description": "Kopien deiner Daten inklusive Originaldateien. Dies umfasst 1 Kopie an einem anderen Ort und 2 lokale Kopien.", + "backup_onboarding_description": "Eine 3-2-1 Sicherungsstrategie wird empfohlen, um deine Daten zu schÃŧtzen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende SicherungslÃļsung zu haben.", + "backup_onboarding_footer": "Weitere Informationen zum Sichern von Immich findest du in der Dokumentation.", + "backup_onboarding_parts_title": "Eine 3-2-1-Sicherung umfasst:", "backup_onboarding_title": "Backups", - "backup_settings": "Iistellige fÃŧr Datenbank-Dumps", - "backup_settings_description": "Datenbank-Dump-Iistellige verwalte.", - "cleared_jobs": "Jobs glÃļscht fÃŧr: {job}", - "config_set_by_file": "D Konfiguration isch aktuell dur e Konfigurationsdatei gsetzt", - "confirm_delete_library": "Bisch sicher, dass du d Bibliothek {library} wotsch lÃļsche?", - "confirm_delete_library_assets": "Bisch sicher, dass du die Bibliothek wotsch lÃļsche? Das lÃļscht {count, plural, one {# enthaltenes Asset} other {alli # enthaltene Assets}} us Immich und chan nÃļd rÃŧckgängig gmacht werde. D Dateie bliibed uf em Dateträger.", - "confirm_email_below": "Zum bestätige bitte \"{email}\" une iitippe", - "confirm_reprocess_all_faces": "Bisch sicher, dass du alli Gsichter neu verarbeite wotsch? Däbii werde au benannti Persone glÃļscht.", - "confirm_user_password_reset": "Bisch sicher, dass du s Passwort fÃŧr {user} mÃļchtisch zruggsetze?", - "confirm_user_pin_code_reset": "Bisch sicher, dass du de PIN-Code vo {user} mÃļchtisch zruggsetze?", - "copy_config_to_clipboard_description": "Kopier die aktuelli Systemkonfiguration als JSON-Objekt i d'ZwÃŧschenablage", - "create_job": "Uufgabe erstelle", - "cron_expression": "Cron-Ziitagabe", - "cron_expression_description": "Setz s Scanintervall im Cron-Format. Hilf mit däm Format bÃŧtet z. B. der Crontab Guru", - "cron_expression_presets": "Vorlage fÃŧr Cron-Uusdruck", - "disable_login": "Login deaktiviere", - "duplicate_detection_job_description": "Die Uufgab fÃŧehrt s maschinelle Lärne fÃŧr jedi Datei us, zum Duplikat finde. Die Uufgabe berueht uf de intelligente Suechi", - "exclusion_pattern_description": "Mit Uusschlussmuster chÃļnnd Dateie und Ordner bim Scanne vo dinere Bibliothek ignoriert wärde. Das isch nÃŧtzlich, wenn du Ordner häsch, wo Dateien drin händ, wo d nÃļd wotsch importiere, wie z. B. RAW-Dateie.", - "export_config_as_json_description": "Lad die aktuelli Systemkonfiguration als JSON-Datei abe", - "external_libraries_page_description": "Externi Bibliothekssiite fÃŧr Administratore", - "face_detection": "Gsichtserkennig", - "face_detection_description": "Die Uufgab erfasst Gsichter in Dateien dur maschinells Lerne. Bi Video wird nur d'Miniaturasicht brucht. „Aktualisiere“ verarbeitet all Dateie neu. „Zruggsetze“ setzt au no all Gsichter zrugg. „Fehlendi“ stellt nur nÃļd verarbeiteti Dateie in d'Warteschlange. Erfassti Gsichter wärdet zur Gsichtsidentifizierig in diWarteschlange gstellt, damit sie i bestehendi oder neui Persone z'gruppiere.", - "facial_recognition_job_description": "Die Uufgabe gruppiert im Anschluss an d'Gsichtserfassig die erfasste Gsichter zu Persone. „Zruggsetze“ gruppiert alli Gsichter neu und mit „Fehlendi“ werdet Gsichter ohni Zuordnig i d'Warteschlange gstellt.", - "failed_job_command": "Befehl {command} hät fÃŧr d'Uufgabe {job} nÃļd funktioniert", - "force_delete_user_warning": "WARNIG: Die Aktion lÃļscht dä Benutzer und all sini Dateie. Das chann nÃļd rÃŧckgängig gmacht wärde und d'Dateie chÃļnnd nÃļd wiederhergstellt wärde.", + "backup_settings": "Einstellungen fÃŧr Datenbanksicherung", + "backup_settings_description": "Einstellungen zur regelmässigen Sicherung der Datenbank.", + "cleared_jobs": "Folgende Aufgaben zurÃŧckgesetzt: {job}", + "config_set_by_file": "Die Konfiguration ist aktuell durch eine Konfigurationsdatei gsetzt", + "confirm_delete_library": "Bist du sicher, dass du die Bibliothek {library} lÃļschen willst?", + "confirm_delete_library_assets": "Bist du sicher, dass du diese Bibliothek lÃļschen willst? Dies lÃļscht {count, plural, one {# enthaltene Datei} other {alle # enthaltenen Dateien}} aus Immich und kann nicht rÃŧckgängig gemacht werden. Die Dateien bleiben auf der Festplatte erhalten.", + "confirm_email_below": "Zum Bestätigen, tippe unten \"{email}\" ein", + "confirm_reprocess_all_faces": "Bist du sicher, dass du alle Gesichter erneut verarbeiten mÃļchtest? Dies lÃļscht auch alle bereits benannten Personen.", + "confirm_user_password_reset": "Bist du sicher, dass du das Passwort fÃŧr {user} zurÃŧcksetzen mÃļchtest?", + "confirm_user_pin_code_reset": "Bist du sicher, dass du den PIN-Code von {user} zurÃŧcksetzen mÃļchtest?", + "copy_config_to_clipboard_description": "Aktuelle Systemkonfiguration als JSON-Objekt in die Zwischenablage kopieren", + "create_job": "Aufgabe erstellen", + "cron_expression": "Cron-Ausdruck", + "cron_expression_description": "Setze das Scanintervall im Cron-Format. FÃŧr mehr Informationen, siehe z. B. Crontab Guru", + "cron_expression_presets": "Vorlagen fÃŧr Cron-AusdrÃŧcke", + "disable_login": "Login deaktivieren", + "duplicate_detection_job_description": "Verwendet maschinelles Lernen auf den Dateien, um Duplikate zu finden. Baut auf der intelligenten Suche auf", + "exclusion_pattern_description": "Mit Ausschlussmustern kÃļnnen Dateien und Ordner beim Scannen deiner Bibliothek ignoriert werden. Dies ist nÃŧtzlich, wenn du Ordner hast, die Dateien enthalten, die du nicht importieren mÃļchtest, wie z. B. RAW-Dateien.", + "export_config_as_json_description": "Aktuelle Systemkonfiguration als JSON-Datei herunterladen", + "external_libraries_page_description": "Externe Bibliotheksseite fÃŧr Administratoren", + "face_detection": "Gesichtserkennung", + "face_detection_description": "Diese Aufgabe erkennt mit maschinellem Lernen Gesichter in Dateien. Bei Videos wird nur das Vorschaubild verwendet. „Aktualisieren“ verarbeitet alle Dateien neu. „ZurÃŧcksetzen“ setzt zusätzlich alle Gesichter zurÃŧck. „Fehlende“ fÃŧgt nur nicht verarbeitete Dateien in die Warteschlange ein. Erfasste Gesichter werden zur Gesichtsidentifizierung in die Warteschlange eingefÃŧgt, um sie in bestehende oder neue Personen zu gruppieren.", + "facial_recognition_job_description": "Diese Aufgabe gruppiert im Anschluss an die Gesichtserkennung die erkannten Gesichter zu Personen. „ZurÃŧcksetzen“ gruppiert alle Gesichter neu, während „Fehlende“ Gesichter ohne Zuordnung in die Warteschlange stellt.", + "failed_job_command": "Befehl {command} ist fÃŧr Aufgabe {job} fehlgeschlagen", + "force_delete_user_warning": "WARNUNG: Diese Aktion lÃļscht sofort den Benutzer und all seine Dateien. Dies kann nicht rÃŧckgängig gemacht werden und die Dateien kÃļnnen nicht wiederhergestellt werden.", "image_format": "Format", - "image_format_description": "WebP erzeugt chlineri Dateie we JPEG, isch aber es bitz langsamer i de Erstellig.", - "image_fullsize_description": "HochuflÃļsends Bild mit glÃļschte Metadate, wo bim Zoome brucht wird", - "image_fullsize_enabled": "HochuflÃļsendi Vorschaubilder aktiviere", - "image_fullsize_enabled_description": "Generiere hochauflÃļsende Vorschaubilder in OriginalauflÃļsung fÃŧr nicht web-kompatibel Formate. Wenn \"Eingebettete Vorschau bevorzugen\" aktiviert ist, werden eingebettete Vorschaubilder direkt verwendet. Hat keinen Einfluss auf web-kompatible Formate wie JPEG.", + "image_format_description": "WebP erzeugt kleinere Dateien als JPEG, ist aber etwas langsamer in der Erstellung.", + "image_fullsize_description": "HochauflÃļsendes Bild mit entfernten Metadaten, das beim Zoomen verwendet wird", + "image_fullsize_enabled": "HochauflÃļsende Vorschaubilder aktivieren", + "image_fullsize_enabled_description": "Generiere Vorschaubilder in OriginalauflÃļsung fÃŧr nicht web-kompatible Formate. Wenn \"Eingebettete Vorschau bevorzugen\" aktiviert ist, werden eingebettete Vorschaubilder direkt verwendet. Hat keinen Einfluss auf web-kompatible Formate wie JPEG.", "image_fullsize_quality_description": "Qualität der hochauflÃļsenden Vorschaubilder von 1-100. HÃļher ist besser, erzeugt aber grÃļssere Dateien.", "image_fullsize_title": "HochauflÃļsende Vorschaueinstellungen", "image_prefer_embedded_preview": "Eingebettete Vorschau bevorzugen", "image_prefer_embedded_preview_setting_description": "Verwende eingebettete Vorschaubilder in RAW-Fotos als Grundlage fÃŧr die Bildverarbeitung, sofern diese zur VerfÃŧgung stehen. Dies kann bei einigen Bildern genauere Farben erzeugen, allerdings ist die Qualität der Vorschau kameraabhängig und das Bild kann mehr Kompressionsartefakte aufweisen.", "image_prefer_wide_gamut": "Breites Spektrum bevorzugen", - "image_prefer_wide_gamut_setting_description": "Bruuch Display P3 fÃŧr Vorschaubildli. Das erhaltet d'Vitalität von Bildli mit grossem Farbruum besser. Uf alte Grät mit alte Browser chann das aber andersch uusgseh. sRGB-Bildli wärdet als sRGB bhalte zum Farbänderige vermiide.", - "image_preview_description": "Mittelgrossi Bildli ohni Metadate, bruuchts fÃŧr Einzelaasichte und fÃŧrs maschinelle Lärne", - "image_preview_quality_description": "Vorschauqualität vo 1-100. HÃļcher isch besser, git aber grÃļsseri Dateie und chan d'App Schwuppdizität reduziere. Z tÃŧffi Wert chÃļnnd s maschinelle Lärne beiträchtige.", - "image_preview_title": "Vorschauiistellige", + "image_prefer_wide_gamut_setting_description": "Display P3 (DCI-P3) fÃŧr Vorschaubilder verwenden. Dadurch bleibt die Lebendigkeit von Bildern mit breiten Farbräumen besser erhalten, aber die Bilder kÃļnnen auf älteren Geräten mit einer älteren Browserversion etwas anders aussehen. sRGB-Bilder werden im sRGB-Format belassen, um Farbverschiebungen zu vermeiden.", + "image_preview_description": "Mittelgrosses Bild mit entfernten Metadaten, das bei der Betrachtung einer einzelnen Datei und fÃŧr maschinelles Lernen verwendet wird", + "image_preview_quality_description": "Vorschauqualität von 1-100. Ein hÃļherer Wert ist besser, erzeugt dadurch aber grÃļssere Dateien und kann die Reaktionsfähigkeit der App beeinträchtigen. Ein niedriger Wert kann dafÃŧr aber die Qualität des maschinellen Lernens beeinträchtigen.", + "image_preview_title": "Vorschaueinstellungen", "image_progressive": "Fortlaufend", - "image_progressive_description": "Codier fortlaufendi JPEG-Bildi: Sie wärdet bim Lade aufbauend aazeiget. Das hät kei WÃŧrkig uf WebP-Bildi.", + "image_progressive_description": "JPEG-Bilder schrittweise kodieren, um ein stufenweises Laden zu ermÃļglichen. Dies hat keine Auswirkungen auf WebP-Bilder.", "image_quality": "Qualität", - "image_resolution": "UuflÃļsig", - "image_resolution_description": "HÃļcheri UuflÃļsig erhaltet meh Detail, gaht aber länger zum codiere, macht grÃļsseri Dateie und chan d'App Schuppdizität reduziere.", - "image_settings": "Bild-Iistellige", - "image_settings_description": "Qualität und UuflÃļsig von erstellte Bildli verwalte", - "image_thumbnail_description": "Chlini Vorschaubildli ohni Metadate, bruuchts fÃŧr Aasichte mit Gruppe vo FÃļteli wie i de Hauptziitachse", - "image_thumbnail_quality_description": "Vorschauqualität vo 1-100. HÃļcher isch besser, git aber grÃļsseri Dateie und chan d'App Schwuppdizität reduziere.", - "image_thumbnail_title": "Iistellige fÃŧr Vorschaubildli", - "import_config_from_json_description": "Systemkonfiguration importiere durs Ufelade vonere JSON-Datei", - "job_concurrency": "{job} Näbeläufigkeit", - "job_created": "Uufgab erstellt", - "job_not_concurrency_safe": "Die Uufgabe ist nÃļd fÃŧr ParalleluusfÃŧhrig gmacht.", - "job_settings": "Uufgabe-Iistellige", - "job_settings_description": "Uufgabe-Näbeläufigkeit verwalte", - "jobs_over_time": "Uufgabe in ziitliche Verlauf", + "image_resolution": "AuflÃļsung", + "image_resolution_description": "HÃļhere AuflÃļsungen kÃļnnen mehr Details erhalten, benÃļtigen aber mehr Zeit fÃŧr die Kodierung, haben grÃļssere DateigrÃļssen und kÃļnnen die Reaktionsfähigkeit der App beeinträchtigen.", + "image_settings": "Bildeinstellungen", + "image_settings_description": "Qualität und AuflÃļsung der generierten Bilder verwalten", + "image_thumbnail_description": "Kleines Vorschaubild mit entfernten Metadaten, die bei der Anzeige von Sammlungen von Fotos wie der Zeitleiste verwendet wird", + "image_thumbnail_quality_description": "Qualität der Vorschaubilder von 1-100. HÃļher ist besser, erzeugt aber grÃļssere Dateien und kann die Reaktionsfähigkeit der App beeinträchtigen.", + "image_thumbnail_title": "Einstellungen fÃŧr Vorschaubilder", + "import_config_from_json_description": "Systemkonfiguration von hochgeladener JSON-Konfigurationsdatei importieren", + "job_concurrency": "{job} (Anzahl gleichzeitig laufende Prozesse)", + "job_created": "Aufgabe erstellt", + "job_not_concurrency_safe": "Diese Aufgabe kann nicht mehrmals parallel laufen gelassen werden.", + "job_settings": "Aufgabeneinstellungen", + "job_settings_description": "Gleichzeitige AusfÃŧhrung von Aufgaben verwalten", + "jobs_over_time": "Jobs im Laufe der Zeit", "library_created": "Bibliothek erstellt: {library}", - "library_deleted": "Bibliothek glÃļscht", - "library_details": "Bibliotheks-Details", - "library_folder_description": "Gib en Order zum Importiere a. Dä Order mit sine Underordner wird nach Bildli und Videos durchsucht.", - "library_remove_exclusion_pattern_prompt": "Bisch sicher, dass das Uuschluss-Muster wotsch lÃļsche?", - "library_remove_folder_prompt": "Bisch sicher, dass dä Import-Ordner wotsch lÃļsche?", - "library_scanning": "Regelmässigi ÜberprÃŧefig" + "library_deleted": "Bibliothek gelÃļscht", + "library_details": "Bibliotheksdetails", + "library_folder_description": "Wähle einen Ordner zum Importieren. Dieser Ordner wird inklusive Unterordnern nach Bildern und Videos durchsucht.", + "library_remove_exclusion_pattern_prompt": "Bilst du sicher, dass du dieses Ausschlussmuster entfernen mÃļchtest?", + "library_remove_folder_prompt": "Bist du sicher, dass du diesen Import-Ordner entfernen mÃļchtest?", + "library_scanning": "Regelmässiges Scannen" } } diff --git a/i18n/el.json b/i18n/el.json index 851a4edb27..8cd20d04a4 100644 --- a/i18n/el.json +++ b/i18n/el.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Ο Ī‡ĪÎŽĪƒĪ„ÎˇĪ‚ {email} ÎąĪ†ÎąÎšĪÎ­Î¸ÎˇÎēÎĩ ÎŧÎĩ ÎĩĪ€ÎšĪ„Ī…Ī‡Î¯Îą.", "users_page_description": "ÎŖÎĩÎģÎ¯Î´Îą Ī‡ĪÎˇĪƒĪ„ĪŽÎŊ Î´ÎšÎąĪ‡ÎĩÎšĪÎšĪƒĪ„ÎŽ", "version_check_enabled_description": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ÎĩÎģÎ­ÎŗĪ‡ÎŋĪ… έÎēδÎŋĪƒÎˇĪ‚", - "version_check_implications": "Η ÎģÎĩÎšĪ„ÎŋĪ…ĪÎŗÎ¯Îą ÎĩÎģÎ­ÎŗĪ‡ÎŋĪ… έÎēδÎŋĪƒÎˇĪ‚, ÎĩÎžÎąĪĪ„ÎŦĪ„ÎąÎš ÎąĪ€ĪŒ Ī„ÎˇÎŊ Ī€ÎĩĪÎšÎŋδΚÎēÎŽ ÎĩĪ€ÎšÎēÎŋΚÎŊΉÎŊÎ¯Îą ÎŧÎĩ Ī„Îŋ github.com", + "version_check_implications": "Η ÎģÎĩÎšĪ„ÎŋĪ…ĪÎŗÎ¯Îą ÎĩÎģÎ­ÎŗĪ‡ÎŋĪ… έÎēδÎŋĪƒÎˇĪ‚, ÎĩÎžÎąĪĪ„ÎŦĪ„ÎąÎš ÎąĪ€ĪŒ Ī„ÎˇÎŊ Ī€ÎĩĪÎšÎŋδΚÎēÎŽ ÎĩĪ€ÎšÎēÎŋΚÎŊΉÎŊÎ¯Îą ÎŧÎĩ Ī„Îŋ {server}", "version_check_settings": "ΈÎģÎĩÎŗĪ‡ÎŋĪ‚ ÎĩÎēδÎŋĪƒÎˇĪ‚", "version_check_settings_description": "ΕÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ/ÎąĪ€ÎĩÎŊÎĩĪÎŗÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ Ī„ÎˇĪ‚ ÎĩΚδÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇĪ‚ ÎŗÎšÎą ÎŊέι έÎēδÎŋĪƒÎˇ", "video_conversion_job": "ΜÎĩĪ„ÎąĪ„ĪÎŋĪ€ÎŽ Î˛Î¯ÎŊĪ„ÎĩÎŋ", @@ -849,9 +849,12 @@ "create_link_to_share": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ĪƒĪ…ÎŊÎ´Î­ĪƒÎŧÎŋĪ… ÎŗÎšÎą δΚιÎŧÎŋÎšĪÎąĪƒÎŧΌ", "create_link_to_share_description": "Î•Ī€ÎšĪ„ĪÎ­ĪˆĪ„Îĩ ΃Îĩ ÎŋĪ€ÎŋΚÎŋÎŊÎ´ÎŽĪ€ÎŋĪ„Îĩ Î­Ī‡ÎĩΚ Ī„ÎŋÎŊ ĪƒĪÎŊδÎĩ΃ÎŧÎŋ ÎŊÎą δÎĩΚ Ī„Îˇ/Ī„ÎšĪ‚ ÎĩĪ€ÎšÎģÎĩÎŗÎŧέÎŊΡ/ÎĩĪ‚ ΆΉ΄ÎŋÎŗĪÎąĪ†Î¯Îą/ÎĩĪ‚", "create_new": "ΔΗΜΙΟÎĨΡΓΙΑ ΝΕΟÎĨ", - "create_new_person": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎŊέÎŋĪ… ΀΁ÎŋĪƒĪŽĪ€ÎŋĪ…", + "create_new_face": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎŊέÎŋĪ… ΀΁ÎŋĪƒĪŽĪ€ÎŋĪ…", + "create_new_person": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎŊέÎŋĪ… ÎąĪ„ĪŒÎŧÎŋĪ…", "create_new_person_hint": "ΑÎŊĪ„ÎšĪƒĪ„ÎŋÎ¯Ī‡ÎšĪƒÎˇ ΄ΉÎŊ ÎĩĪ€ÎšÎģÎĩÎŗÎŧέÎŊΉÎŊ ÎąĪĪ‡ÎĩÎ¯Ī‰ÎŊ ΃Îĩ έÎŊÎą ÎŊέÎŋ Ī€ĪĪŒĪƒĪ‰Ī€Îŋ", "create_new_user": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎŊέÎŋĪ… Ī‡ĪÎŽĪƒĪ„Îˇ", + "create_person": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎąĪ„ĪŒÎŧÎŋĪ…", + "create_person_subtitle": "Î ĪÎŋĪƒÎ¸Î­ĪƒĪ„Îĩ έÎŊÎą ΌÎŊÎŋÎŧÎą ĪƒĪ„Îŋ ÎĩĪ€ÎšÎģÎĩÎŗÎŧέÎŊÎŋ Ī€ĪĪŒĪƒĪ‰Ī€Îŋ ÎŗÎšÎą ÎŊÎą δΡÎŧΚÎŋĪ…ĪÎŗÎˇÎ¸Îĩί ÎēιΚ ÎŊÎą ÎĩĪ€ÎšĪƒÎˇÎŧÎąÎŊθÎĩί Ī„Îŋ ÎŊέÎŋ ÎŦĪ„ÎŋÎŧÎŋ", "create_shared_album_page_share_add_assets": "Î ÎĄÎŸÎŖÎ˜Î—ÎšÎ— ÎŖÎ¤ÎŸÎ™Î§Î•Î™ÎŠÎ", "create_shared_album_page_share_select_photos": "Î•Ī€ÎšÎģÎ­ÎžĪ„Îĩ ÎĻΉ΄ÎŋÎŗĪÎąĪ†Î¯ÎĩĪ‚", "create_shared_link": "ΔηÎŧΚÎŋĪ…ĪÎŗÎ¯Îą ÎēÎŋΚÎŊĪŒĪ‡ĪÎˇĪƒĪ„ÎŋĪ… ĪƒĪ…ÎŊÎ´Î­ĪƒÎŧÎŋĪ…", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "ΔιÎŋĪÎ¸ĪŽÎ¸ÎˇÎēÎĩ", "crop_aspect_ratio_free": "ΕÎģÎĩĪÎ¸Îĩ΁Îŋ", "crop_aspect_ratio_original": "Î‘Ī…Î¸ÎĩÎŊĪ„ÎšÎēΌ", + "crop_aspect_ratio_square": "ΤÎĩ΄΁ÎŦÎŗĪ‰ÎŊÎŋ", "curated_object_page_title": "Î ĪÎŦÎŗÎŧÎąĪ„Îą", "current_device": "Î¤ĪÎ­Ī‡ÎŋĪ…ĪƒÎą ĪƒĪ…ĪƒÎēÎĩĪ…ÎŽ", "current_pin_code": "Î¤ĪÎ­Ī‡Ī‰ÎŊ ÎēĪ‰Î´ÎšÎēĪŒĪ‚ PIN", @@ -880,7 +884,7 @@ "daily_title_text_date": "Ε, MMM dd", "daily_title_text_date_year": "Ε, MMM dd, yyyy", "dark": "ÎŖÎēÎŋĪĪÎŋ", - "dark_theme": "ΕÎŊÎąÎģÎģÎąÎŗÎŽ ΃ÎēÎŋĪ„ÎĩΚÎŊÎŽĪ‚ ÎĩÎŧΆÎŦÎŊÎšĪƒÎˇĪ‚", + "dark_theme": "ΜÎĩĪ„ÎŦÎ˛ÎąĪƒÎˇ ΃Îĩ ΃ÎēÎŋĪ„ÎĩΚÎŊΌ θέÎŧÎą", "date": "ΗÎŧÎĩ΁ÎŋÎŧΡÎŊÎ¯Îą", "date_after": "ΗÎŧÎĩ΁ÎŋÎŧΡÎŊÎ¯Îą ÎŧÎĩĪ„ÎŦ", "date_and_time": "ΗÎŧÎĩ΁ÎŋÎŧΡÎŊÎ¯Îą ÎēιΚ ĪŽĪÎą", @@ -891,10 +895,8 @@ "day": "ΗÎŧÎ­ĪÎą", "days": "ΗÎŧÎ­ĪÎĩĪ‚", "deduplicate_all": "Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇ ΌÎģΉÎŊ ΄ΉÎŊ Î´ÎšĪ€ÎģĪŒĪ„Ī…Ī€Ī‰ÎŊ", - "deduplication_criteria_1": "ÎœÎ­ÎŗÎĩθÎŋĪ‚ ÎĩΚÎēΌÎŊÎąĪ‚ ΃Îĩ byte", - "deduplication_criteria_2": "Î‘ĪÎšÎ¸ÎŧĪŒĪ‚ δÎĩδÎŋÎŧέÎŊΉÎŊ EXIF", - "deduplication_info": "ΠÎģÎˇĪÎŋΆÎŋĪÎ¯ÎĩĪ‚ Î‘Ī†ÎąÎ¯ĪÎĩĪƒÎˇĪ‚ Î”ÎšĪ€ÎģÎŋĪ„ĪĪ€Ī‰ÎŊ", - "deduplication_info_description": "Για ÎŊÎą ΀΁ÎŋÎĩĪ€ÎšÎģέΞÎŋĪ…ÎŧÎĩ ÎąĪ…Ī„ĪŒÎŧÎąĪ„Îą Ī„Îą ÎąĪĪ‡ÎĩÎ¯Îą ÎēιΚ ÎŊÎą ÎąĪ†ÎąÎšĪÎ­ĪƒÎŋĪ…ÎŧÎĩ Ī„Îą Î´ÎšĪ€ÎģĪŒĪ„Ī…Ī€Îą ΃Îĩ ÎŧÎąÎļΚÎēÎŽ ÎĩĪ€ÎĩΞÎĩĪÎŗÎąĪƒÎ¯Îą, ÎĩΞÎĩĪ„ÎŦÎļÎŋĪ…ÎŧÎĩ ΃Îĩ:", + "default_locale": "Î ĪÎŋÎĩĪ€ÎšÎģÎĩÎŗÎŧέÎŊΡ ÎŗÎģĪŽĪƒĪƒÎą", + "default_locale_description": "ΜÎŋ΁ΆÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ΡÎŧÎĩ΁ÎŋÎŧΡÎŊÎšĪŽÎŊ ÎēιΚ ÎąĪÎšÎ¸ÎŧĪŽÎŊ, βÎŦĪƒÎˇ Ī„ÎˇĪ‚ ÎŗÎģĪŽĪƒĪƒÎąĪ‚ Ī„ÎŋĪ… ΀΁ÎŋÎŗĪÎŦÎŧÎŧÎąĪ„ÎŋĪ‚ Ī€ÎĩĪÎšÎŽÎŗÎˇĪƒÎˇĪ‚", "delete": "Î”ÎšÎąÎŗĪÎąĪ†ÎŽ", "delete_action_confirmation_message": "Î•Î¯ĪƒĪ„Îĩ ĪƒÎ¯ÎŗÎŋ΅΁ÎŋΚ ĪŒĪ„Îš θέÎģÎĩĪ„Îĩ ÎŊÎą Î´ÎšÎąÎŗĪÎŦΈÎĩĪ„Îĩ ÎąĪ…Ī„ĪŒ Ī„Îŋ ÎąĪĪ‡ÎĩίÎŋ; Î‘Ī…Ī„ÎŽ Ρ ÎĩÎŊÎ­ĪÎŗÎĩΚι θι Ī„Îŋ ÎŧÎĩĪ„ÎąÎēΚÎŊÎŽĪƒÎĩΚ ĪƒĪ„ÎŋÎŊ ÎēÎŦδÎŋ ÎąĪ€ÎŋĪĪÎšÎŧÎŧÎŦ΄ΉÎŊ Ī„ÎŋĪ… δΚιÎēÎŋÎŧÎšĪƒĪ„ÎŽ ÎēιΚ θι ÎĩÎŧĪ†ÎąÎŊÎšĪƒĪ„Îĩί ÎŧÎŽÎŊĪ…ÎŧÎą ÎŗÎšÎą Ī„Îŋ ÎąÎŊ θέÎģÎĩĪ„Îĩ ÎŊÎą Ī„Îŋ Î´ÎšÎąÎŗĪÎŦΈÎĩĪ„Îĩ ÎēιΚ Ī„ÎŋĪ€ÎšÎēÎŦ", "delete_action_prompt": "{count} Î´ÎšÎąÎŗĪÎŦĪ†ÎˇÎēÎąÎŊ", @@ -970,7 +972,7 @@ "downloading_media": "Î›ÎŽĪˆÎˇ Ī€ÎŋÎģĪ…ÎŧÎ­ĪƒĪ‰ÎŊ", "drop_files_to_upload": "ÎŖĪĪÎĩĪ„Îĩ ÎąĪĪ‡ÎĩÎ¯Îą ÎĩÎ´ĪŽ ÎŗÎšÎą ÎŊÎą Ī„Îą ÎąÎŊÎĩβÎŦ΃ÎĩĪ„Îĩ", "duplicates": "Î”ÎšĪ€ÎģĪŒĪ„Ī…Ī€Îą", - "duplicates_description": "Î•Ī€ÎšÎģĪĪƒĪ„Îĩ ÎēÎŦθÎĩ ÎŋÎŧÎŦδι Ī…Ī€ÎŋδÎĩΚÎēÎŊĪÎŋÎŊĪ„ÎąĪ‚ Ī€ÎŋΚÎĩĪ‚ ÎĩίÎŊιΚ Î´ÎšĪ€ÎģĪŒĪ„Ī…Ī€ÎĩĪ‚, ÎĩÎŦÎŊ Ī…Ī€ÎŦ΁·ÎŋĪ…ÎŊ", + "duplicates_description": "Î•Ī€ÎšÎģĪĪƒĪ„Îĩ ÎēÎŦθÎĩ ÎŋÎŧÎŦδι Ī…Ī€ÎŋδÎĩΚÎēÎŊĪÎŋÎŊĪ„ÎąĪ‚ Ī€ÎŋΚÎĩĪ‚, ÎĩÎŦÎŊ Ī…Ī€ÎŦ΁·ÎŋĪ…ÎŊ, ÎĩίÎŊιΚ Î´ÎšĪ€ÎģĪŒĪ„Ī…Ī€ÎĩĪ‚.", "duration": "ΔιÎŦ΁ÎēÎĩΚι", "edit": "Î•Ī€ÎĩΞÎĩĪÎŗÎąĪƒÎ¯Îą", "edit_album": "Î•Ī€ÎĩΞÎĩĪÎŗÎąĪƒÎ¯Îą ÎŦÎģÎŧĪ€ÎŋĪ…Îŧ", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Î¤Î¯Ī„ÎģÎŋĪ‚ ÎŦÎģÎŧĪ€ÎŋĪ…Îŧ", "licenses": "ΆδÎĩΚÎĩĪ‚", "light": "ÎĻΉ΄ÎĩΚÎŊΌ", + "light_theme": "ΜÎĩĪ„ÎŦÎ˛ÎąĪƒÎˇ ΃Îĩ ΆΉ΄ÎĩΚÎŊΌ θέÎŧÎą", "like": "ΜÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ", "like_deleted": "ΤÎŋ \"ÎŧÎŋĪ… ÎąĪÎ­ĪƒÎĩΚ\" Î´ÎšÎąÎŗĪÎŦĪ†ÎˇÎēÎĩ", "link_motion_video": "ÎŖĪÎŊδÎĩ΃Îĩ Î˛Î¯ÎŊĪ„ÎĩÎŋ ÎēίÎŊÎˇĪƒÎˇĪ‚", + "link_to_docs": "Για Ī€ÎĩĪÎšĪƒĪƒĪŒĪ„Îĩ΁ÎĩĪ‚ Ī€ÎģÎˇĪÎŋΆÎŋĪÎ¯ÎĩĪ‚, ÎąÎŊÎąĪ„ĪÎ­ÎžĪ„Îĩ ĪƒĪ„ÎˇÎŊ Ī„ÎĩÎēÎŧÎˇĪÎ¯Ī‰ĪƒÎˇ.", "link_to_oauth": "ÎŖĪÎŊδÎĩĪƒÎˇ ĪƒĪ„ÎŋÎŊ OAuth", "linked_oauth_account": "Ο OAuth ÎģÎŋÎŗÎąĪÎšÎąĪƒÎŧĪŒĪ‚ ĪƒĪ…ÎŊδέθΡÎēÎĩ", "list": "Î›Î¯ĪƒĪ„Îą", @@ -2213,6 +2217,7 @@ "tag": "Î•Ī„ÎšÎēÎ­Ī„Îą", "tag_assets": "Î•Ī„ÎšÎēÎĩĪ„ÎŋĪ€ÎŋÎ¯ÎˇĪƒÎˇ ĪƒĪ„ÎŋÎšĪ‡ÎĩÎ¯Ī‰ÎŊ", "tag_created": "ΔηÎŧΚÎŋĪ…ĪÎŗÎŽÎ¸ÎˇÎēÎĩ ÎĩĪ„ÎšÎēÎ­Ī„Îą: {tag}", + "tag_face": "Î•Ī€ÎšĪƒÎŽÎŧÎąÎŊĪƒÎˇ ΀΁ÎŋĪƒĪŽĪ€ÎŋĪ…", "tag_feature_description": "ΠÎĩĪÎšÎŽÎŗÎˇĪƒÎˇ ΃Îĩ ΆΉ΄ÎŋÎŗĪÎąĪ†Î¯ÎĩĪ‚ ÎēιΚ Î˛Î¯ÎŊĪ„ÎĩÎŋ Ī€ÎŋĪ… ÎĩίÎŊιΚ ÎŋĪÎŗÎąÎŊΉÎŧέÎŊÎą ĪƒĪÎŧΆΉÎŊÎą ÎŧÎĩ ÎģÎŋÎŗÎšÎēÎŦ θέÎŧÎąĪ„Îą ÎĩĪ„ÎšÎēÎĩĪ„ĪŽÎŊ", "tag_not_found_question": "ΔÎĩÎŊ ÎŧĪ€Îŋ΁ÎĩÎ¯Ī„Îĩ ÎŊÎą Î˛ĪÎĩÎ¯Ī„Îĩ ÎŧΚι ÎĩĪ„ÎšÎēÎ­Ī„Îą; ΔηÎŧΚÎŋĪ…ĪÎŗÎŽĪƒĪ„Îĩ ÎŧΚι ÎŊέι ÎĩĪ„ÎšÎēÎ­Ī„Îą.", "tag_people": "Î•Ī€ÎšĪƒÎŽÎŧÎąÎŊĪƒÎˇ ÎąĪ„ĪŒÎŧΉÎŊ", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "ÎšÎąĪ„ÎŦĪÎŗÎˇĪƒÎˇ ÎąĪ€ĪŒ Ī„Îˇ ÎŖĪ„ÎŋÎ¯Î˛Îą", "viewer_stack_use_as_main_asset": "Î§ĪÎŽĪƒÎˇ Ή΂ ÎšĪĪÎšÎŋ ÎŖĪ„ÎŋÎšĪ‡ÎĩίÎŋ", "viewer_unstack": "Î‘Ī€ÎŋĪƒĪ„ÎŋÎ¯Î˛ÎąÎžÎĩ", + "visibility": "ÎŸĪÎąĪ„ĪŒĪ„ÎˇĪ„Îą", "visibility_changed": "Η ÎŋĪÎąĪ„ĪŒĪ„ÎˇĪ„Îą ÎŦÎģÎģιΞÎĩ ÎŗÎšÎą {count, plural, one {# ÎŦĪ„ÎŋÎŧÎŋ} other {# ÎŦĪ„ÎŋÎŧÎą}}", "visual": "ÎŸĪ€Ī„ÎšÎēΌ", "visual_builder": "ÎŸĪ€Ī„ÎšÎēĪŒĪ‚ δΡÎŧΚÎŋĪ…ĪÎŗĪŒĪ‚", diff --git a/i18n/en.json b/i18n/en.json index 956ed03989..4f2922f35d 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -441,7 +441,7 @@ "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_implications": "The version check feature relies on periodic communication with {server}", "version_check_settings": "Version Check", "version_check_settings_description": "Enable/disable the new version notification", "video_conversion_job": "Transcode videos", @@ -849,9 +849,12 @@ "create_link_to_share": "Create link to share", "create_link_to_share_description": "Let anyone with the link see the selected photo(s)", "create_new": "CREATE NEW", + "create_new_face": "Create new face", "create_new_person": "Create new person", "create_new_person_hint": "Assign selected assets to a new person", "create_new_user": "Create new user", + "create_person": "Create person", + "create_person_subtitle": "Add a name to the selected face to create and tag the new person", "create_shared_album_page_share_add_assets": "ADD ASSETS", "create_shared_album_page_share_select_photos": "Select Photos", "create_shared_link": "Create shared link", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixed", "crop_aspect_ratio_free": "Free", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Square", "curated_object_page_title": "Things", "current_device": "Current device", "current_pin_code": "Current PIN code", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "Dark", - "dark_theme": "Toggle dark theme", + "dark_theme": "Switch to dark theme", "date": "Date", "date_after": "Date after", "date_and_time": "Date and Time", @@ -891,10 +895,8 @@ "day": "Day", "days": "Days", "deduplicate_all": "Deduplicate All", - "deduplication_criteria_1": "Image size in bytes", - "deduplication_criteria_2": "Count of EXIF data", - "deduplication_info": "Deduplication Info", - "deduplication_info_description": "To automatically preselect assets and remove duplicates in bulk, we look at:", + "default_locale": "Default Locale", + "default_locale_description": "Format dates and numbers based on your browser locale", "delete": "Delete", "delete_action_confirmation_message": "Are you sure you want to delete this asset? This action will move the asset to the server's trash and will prompt if you want to delete it locally", "delete_action_prompt": "{count} deleted", @@ -970,7 +972,7 @@ "downloading_media": "Downloading media", "drop_files_to_upload": "Drop files anywhere to upload", "duplicates": "Duplicates", - "duplicates_description": "Resolve each group by indicating which, if any, are duplicates", + "duplicates_description": "Resolve each group by indicating which, if any, are duplicates.", "duration": "Duration", "edit": "Edit", "edit_album": "Edit album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Album title", "licenses": "Licenses", "light": "Light", + "light_theme": "Switch to light theme", "like": "Like", "like_deleted": "Like deleted", "link_motion_video": "Link motion video", + "link_to_docs": "For more information, refer to the documentation.", "link_to_oauth": "Link to OAuth", "linked_oauth_account": "Linked OAuth account", "list": "List", @@ -2213,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Tag assets", "tag_created": "Created tag: {tag}", + "tag_face": "Tag face", "tag_feature_description": "Browsing photos and videos grouped by logical tag topics", "tag_not_found_question": "Cannot find a tag? Create a new tag.", "tag_people": "Tag People", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Remove from Stack", "viewer_stack_use_as_main_asset": "Use as Main Asset", "viewer_unstack": "Un-Stack", + "visibility": "Visibility", "visibility_changed": "Visibility changed for {count, plural, one {# person} other {# people}}", "visual": "Visual", "visual_builder": "Visual builder", diff --git a/i18n/eo.json b/i18n/eo.json index 8e89e960c4..5bc956b284 100644 --- a/i18n/eo.json +++ b/i18n/eo.json @@ -59,12 +59,12 @@ "backup_database_enable_description": "Ebligi kreon de kopioj de datumbazo", "backup_keep_last_amount": "Nombro de antaÅ­aj kopioj konservendaj", "backup_onboarding_1_description": "fora kopio, ĉu en nubo ĉu en alia fizika loko.", - "backup_onboarding_2_description": "lokaj kopioj ĉe diversaj aparatoj, inkluzive ĉefajn dosierojn kaj lokan sekurkopion de tiuj dosieroj.", + "backup_onboarding_2_description": "lokaj kopioj ĉe diversaj aparatoj, inkluzive ĉefajn dosierojn kaj lokan savkopion de tiuj dosieroj.", "backup_onboarding_3_description": "suma nombro de kopioj de viaj datumoj, inkluzive la originajn dosierojn, t.e. 1 fora kopio kaj 2 lokaj kopioj.", - "backup_onboarding_description": "Ni rekomendas strategion de 3-2-1 por protekti viajn datumojn. Vi devus havi sekurkopiojn kaj de viaj fotoj/videoj kaj de la datumbazo de Immich por esti plene sekura.", - "backup_onboarding_footer": "Por pli da informoj pri sekurkopioj kun Immich, bonvolu legi la dokumentaron.", + "backup_onboarding_description": "Ni rekomendas strategion de 3-2-1 por protekti viajn datumojn. Vi devus havi savkopiojn kaj de viaj fotoj/videoj kaj de la datumbazo de Immich por esti plene sekura.", + "backup_onboarding_footer": "Por pli da informoj pri savkopioj kun Immich, bonvolu legi la dokumentaron.", "backup_onboarding_parts_title": "Sekur-kopioj laÅ­ strategio 3-2-1 inkluzivas:", - "backup_onboarding_title": "Sekurkopioj", + "backup_onboarding_title": "Savkopioj", "backup_settings": "AgordaÄĩoj de kopiado de datumbazo", "backup_settings_description": "Administri agordojn pri datumbazo-nekropsio.", "cleared_jobs": "Taskoj forigitaj por: {job}", @@ -192,19 +192,19 @@ "machine_learning_url_description": "La URL-o de la maŝin-lerna servilo. Se vi donas pli ol unu URL-o, la sistemo provos ĉiun servilon unu post la alia ĝis kiam unu sukcese respondas, de la unua ĝis la lasta. Serviloj, kiuj ne respondas, estos dumtempe ignoritaj.", "maintenance_delete_backup": "Forigi savkopion", "maintenance_delete_backup_description": "La dosiero estos por ĉiam forigita.", - "maintenance_delete_error": "Malsukcesis forigi sekurkopion.", + "maintenance_delete_error": "Malsukcesis forigi savkopion.", "maintenance_restore_backup": "RestaÅ­ri savkopion", - "maintenance_restore_backup_description": "Immich estos forigita kaj reinstalita de la elektita sekurkopio. Nova sekurkopio estos kreita antaÅ­e.", - "maintenance_restore_backup_different_version": "Tiu ĉi sekurkopio estis kreita per alia versio de Immich!", - "maintenance_restore_backup_unknown_version": "Ne eblis ektrovi version de la sekurkopio.", - "maintenance_restore_database_backup": "RestaÅ­ri datumbazon el sekurkopio", - "maintenance_restore_database_backup_description": "Reveni al antaÅ­a stato de datumbazo pere de sekurkopio", + "maintenance_restore_backup_description": "Immich estos forigita kaj reinstalita de la elektita savkopio. Nova savkopio estos kreita antaÅ­e.", + "maintenance_restore_backup_different_version": "Tiu ĉi savkopio estis kreita per alia versio de Immich!", + "maintenance_restore_backup_unknown_version": "Ne eblis ektrovi version de la savkopio.", + "maintenance_restore_database_backup": "RestaÅ­ri datumbazon el savkopio", + "maintenance_restore_database_backup_description": "Reveni al antaÅ­a stato de datumbazo pere de savkopio", "maintenance_settings": "Funkcitenado", "maintenance_settings_description": "Ŝalti la funkcitenadan reĝimon de Immich.", "maintenance_start": "Ŝanĝi al funkci-tenada reĝimo", "maintenance_start_error": "Malsukcesis ŝalti funkci-tenadan reĝimon.", - "maintenance_upload_backup": "Alŝuti dosieron de sekurkopio de datumbazo", - "maintenance_upload_backup_error": "Malsukcesis alŝuti sekurkopion, ĉu ĝi havas formaton .sql aÅ­ .sql.gz?", + "maintenance_upload_backup": "Alŝuti dosieron de savkopio de datumbazo", + "maintenance_upload_backup_error": "Malsukcesis alŝuti savkopion, ĉu ĝi havas formaton .sql aÅ­ .sql.gz?", "manage_concurrency": "Administri samtempajn taskojn", "manage_concurrency_description": "Vizitu la paĝon Taskoj por agordi la nombron de samtempaj taskoj", "manage_log_settings": "Administri agordojn pri protokolado", @@ -259,14 +259,14 @@ "notification_email_secure": "SMTPS", "notification_email_secure_description": "Uzi SMTPS (SMTP pere de TLS)", "notification_email_sent_test_email_button": "Sendi testmesaĝon kaj konservi", - "notification_email_setting_description": "Agordoj pri atentigoj per retmesaĝoj", + "notification_email_setting_description": "Agordoj pri sciigoj per retmesaĝoj", "notification_email_test_email": "Sendi testmesaĝon", "notification_email_test_email_failed": "Malsukcesis sendi testmesaĝon, kontrolu la agordaÄĩojn", "notification_email_test_email_sent": "Testmesaĝo estas sendita al {email}. Bonvolu kontroli ĉu ĝi bone alvenis.", "notification_email_username_description": "Uzantonomo por uzi kun la retmesaĝa servilo", - "notification_enable_email_notifications": "Ŝalti retmesaĝajn atentigilojn", - "notification_settings": "Agordoj pri atentigiloj", - "notification_settings_description": "Administri agordojn pri atentigiloj, inkluzive tiujn per retmesaĝoj", + "notification_enable_email_notifications": "Ŝalti sciigojn per retmesaĝo", + "notification_settings": "Agordoj pri sciigoj", + "notification_settings_description": "Administri agordojn pri sciigoj, inkluzive tiujn per retmesaĝoj", "oauth_auto_launch": "Startigi aÅ­tomate", "oauth_auto_launch_description": "AÅ­tomate startigi la OAuth-procezon tuj ĉe la ensaluta paĝo", "oauth_auto_register": "Registri aÅ­tomate", @@ -348,8 +348,8 @@ "template_email_settings": "Ŝablonoj de retmesaĝoj", "template_email_update_album": "Ŝablono por retmesaĝo por ĝisdatigi albumon", "template_email_welcome": "Ŝablono de bonvena retmesaĝo", - "template_settings": "Ŝablonoj de atentigiloj", - "template_settings_description": "Administri tajloritajn skemojn por atentigiloj", + "template_settings": "Ŝablonoj de sciigoj", + "template_settings_description": "Administri tajloritajn skemojn por sciigoj", "theme_custom_css_settings": "Tajlorita CSS", "theme_custom_css_settings_description": "Vi povas ŝanĝi la vidan aspekton de Immich per CSS.", "theme_settings": "Agordoj de la etoso", @@ -441,9 +441,9 @@ "user_successfully_removed": "La uzanto {email} estas forigita.", "users_page_description": "Paĝo por administri uzantojn", "version_check_enabled_description": "Ebligi kontrolon de versio", - "version_check_implications": "La funkcio de kontrolado de versio bezonas de temp' al tempan komunikadon kun github.com", + "version_check_implications": "La funkcio de kontrolado de versio bezonas de temp' al tempan komunikadon kun {server}", "version_check_settings": "Kontrolo de versio", - "version_check_settings_description": "Ŝalti/malŝalti atentigilon pri novaj versioj", + "version_check_settings_description": "Ŝalti/malŝalti sciigojn pri novaj versioj", "video_conversion_job": "Transkodado de videoj", "video_conversion_job_description": "Transkodi videojn por pli vasta kongruo kun retumiloj kaj aparatoj" }, @@ -451,8 +451,8 @@ "admin_password": "Pasvorto de administranto", "administration": "Administrado", "advanced": "Altnivelaj agordoj", - "advanced_settings_clear_image_cache": "Malplenigi kaŝmemoron de bildoj", - "advanced_settings_clear_image_cache_error": "Malsukcesis malplenigi kaŝmemoron", + "advanced_settings_clear_image_cache": "Forviŝi kaŝmemoron de bildoj", + "advanced_settings_clear_image_cache_error": "Malsukcesis forviŝi kaŝmemoron", "advanced_settings_clear_image_cache_success": "Sukcesis liberigi {size}", "advanced_settings_enable_alternate_media_filter_subtitle": "Uzu tiun ĉi agordon por filtri elementojn dum sinkronigo laÅ­ alternativaj kriterioj. Uzu tion ĉi nur se vi vidas, ke la apo ne sukcesas trovi ĉiujn albumojn.", "advanced_settings_enable_alternate_media_filter_title": "[TESTATA] Uzi alternativan filtrilon por sinkronigi albumojn", @@ -527,7 +527,7 @@ "alt_text_qr_code": "Bildo de QR-kodo", "always_keep": "Ĉiam konservi", "always_keep_photos_hint": "La funkcio 'Liberigi spacon' konservos ĉiujn fotojn en tiu ĉi aparato.", - "always_keep_videos_hint": "La funkcio 'Liberigi spacon\" konservos ĉiujn videojn en tiu ĉi aparato.", + "always_keep_videos_hint": "La funkcio 'Liberigi spacon' konservos ĉiujn videojn en tiu ĉi aparato.", "anti_clockwise": "KontraÅ­-horloĝdirekte", "api_key": "API-ŝlosilo", "api_key_description": "Tio ĉi montriĝos nur unufoje. Certiĝu, ke vi kopiis ĝin antaÅ­ ol fermi la fenestron.", @@ -547,7 +547,7 @@ "archive_action_prompt": "{count} aldonita(j) al arÄĨivo", "archive_or_unarchive_photo": "EnarÄĨivigi aÅ­ elarÄĨivigi foton", "archive_page_no_archived_assets": "Neniuj elementoj trovitaj en arÄĨivo", - "archive_page_title": "ArÄĨivo ({count})", + "archive_page_title": "ArÄĨivigi ({count})", "archive_size": "Grandeco de arÄĨivo", "archive_size_description": "Agordu la grandecon de arÄĨivaj dosieroj por elŝuti (en GiB)", "archived": "EnarÄĨivigita(j)", @@ -615,11 +615,11 @@ "autoplay_slideshow": "AÅ­tomate vidigi bildserion", "back": "MalantaÅ­en", "back_close_deselect": "MalantaÅ­en, fermi, aÅ­ malelekti", - "background_backup_running_error": "Sekurkopiado jam estas fone okazanta, do ne eblas nun lanĉi alian sekurkopiadon", + "background_backup_running_error": "Savkopiado jam estas fone okazanta, do ne eblas nun lanĉi alian savkopiadon", "background_location_permission": "Rajtigo fone uzi geografian lokon", "background_location_permission_content": "Por ŝanĝi retaliron dum fona funkciado, Immich devas *ĉiam* havi atingorajton al lokiga informo, por povi legi nomojn de vifiaj retoj", "background_options": "Agordoj pri fonaj funkcioj", - "backup": "Sekurkopio", + "backup": "Savkopio", "backup_album_selection_page_albums_device": "Albumoj en la aparato ({count})", "backup_album_selection_page_albums_tap": "Tuŝeti por inkluzivi, duoble tuŝeti por ekskludi", "backup_album_selection_page_assets_scatter": "Foje elementoj troviĝas disÄĩetitaj al pluraj albumoj, do albumoj povas esti inkluzivitaj aÅ­ ekskluzivitaj de la savkopiado.", @@ -675,36 +675,476 @@ "backup_controller_page_total_sub": "Ĉiuj unikaj fotoj kaj videoj el elektitaj albumoj", "backup_controller_page_turn_off": "Malŝalti malfonan savkopiadon", "backup_controller_page_turn_on": "Ŝalti malfonan savkopiadon", + "backup_controller_page_uploading_file_info": "Alŝutiĝas informoj pri dosiero", + "backup_err_only_album": "Ne eblas forigi la solan albumon", + "backup_error_sync_failed": "Sinkronigo malsukcesis.", + "backup_info_card_assets": "elementoj", + "backup_manual_cancelled": "Nuligita", + "backup_manual_in_progress": "Alŝuto jam progresas. Provu poste", + "backup_manual_success": "Sukceso", + "backup_manual_title": "Statuso de alŝuto", + "backup_options": "Agordoj pri savkopioj", + "backup_options_page_title": "Agordoj pri savkopioj", "backup_setting_subtitle": "Administri agordojn pri fona kaj malfona alŝutado", "backup_settings_subtitle": "Administri agordojn pri alŝutado", + "backup_upload_details_page_more_details": "Tuŝu ĉi tie por pli da detaloj", + "backward": "MalantaÅ­en", + "biometric_auth_enabled": "Biometria ensaluto ŝaltita", + "biometric_locked_out": "Via biometria ensalutkapablo estas blokita", + "biometric_no_options": "Neniuj biometriaj ebloj estas disponeblaj", + "biometric_not_available": "Tiu ĉi aparato ne havas funkcion por biometria ensaluto", + "birthdate_saved": "Naskiĝdato ŝukcese konservita", + "birthdate_set_description": "La naskiĝdato estas uzita por kalkuli la aĝon de la homo je la momento de iu foto.", + "blurred_background": "Malklarigita fono", + "bugs_and_feature_requests": "Cimoj kaj petoj por novaj funkcioj", + "build": "Versio", + "build_image": "Bildo de la versio", + "bulk_delete_duplicates_confirmation": "Ĉu vi certas, ke vi volas amase forigi {count, plural, one {# duoblaÄĩon} other {# duoblaÄĩojn}}? Tiel, vi konservos la plej grandan elementon el ĉiu grupo kaj porĉiame forigos duoblaÄĩojn. Ne eblas malfari tion!", + "bulk_keep_duplicates_confirmation": "Ĉu vi certas, ke vi volas konservi {count, plural, one {# duoblaÄĩon} other {# duoblaÄĩojn}}? Tio solvos ĉiujn duoblajn grupojn sen forigi ion ajn.", + "bulk_trash_duplicates_confirmation": "Ĉu vi certas, ke vi volas amase forigi {count, plural, one {# duoblaÄĩon} other {# duoblaÄĩojn}}? Tiel, vi konservos la plej grandan elementon el ĉiu grupo kaj porĉiame forigos duoblaÄĩojn.", + "buy": "Aĉeti Immich", + "cache_settings_clear_cache_button": "Forviŝi kaŝmemoron", + "cache_settings_clear_cache_button_title": "Forviŝas la kaŝmemoron de la apo. Tio malrapidigos la apon ĝis kiam ĝi finos rekonstrui la kaŝon.", + "cache_settings_duplicated_assets_clear_button": "FORVIŜI", + "cache_settings_duplicated_assets_subtitle": "Fotoj kaj videoj ignoritaj de la apo", + "cache_settings_duplicated_assets_title": "DuoblaÄĩoj ({count})", + "cache_settings_statistics_album": "Bildetoj de la biblioteko", + "cache_settings_statistics_full": "Plenaj bildoj", + "cache_settings_statistics_shared": "Bildetoj de dividitaj albumoj", + "cache_settings_statistics_thumbnail": "Bildetoj", + "cache_settings_statistics_title": "Uzo de kaŝmemoro", + "cache_settings_subtitle": "Regas la uzadon de kaŝmemoro fare de la apo", + "cache_settings_tile_subtitle": "Regas konduton pri loka stokado", + "cache_settings_tile_title": "Loka stokado", + "cache_settings_title": "Agordoj pri kaŝmemoro", + "camera": "Fotilo", + "camera_brand": "Fabrikanto de fotilo", + "camera_model": "Modelo de fotilo", + "cancel": "Nuligi", + "cancel_search": "Nuligi serĉon", + "canceled": "Nuligita", + "canceling": "Nuligado", + "cannot_merge_people": "Ne eblas kunfandi tiujn homojn", + "cannot_undo_this_action": "Ne eblas malfari tion!", + "cannot_update_the_description": "Ne eblas ĝisdatigi la priskribon", + "cast": "Elsendi", + "cast_description": "Agordi disponeblajn celojn por elsendoj", + "change_date": "Ŝanĝi daton", + "change_description": "Ŝanĝi priskribon", + "change_display_order": "Ŝanĝi vicordon de vidigo", + "change_expiration_time": "Ŝanĝi horon de eksvalidiĝo", + "change_location": "Ŝanĝi lokon", + "change_name": "Ŝanĝi nomon", + "change_name_successfully": "Nomo sukcese ŝanĝita", + "change_password": "Ŝanĝi pasvorton", + "change_password_description": "AÅ­ tio ĉi estas via unua ensaluto, aÅ­ la sistemo ricevis peton ŝanĝigi vian pasvorton. Bonvolu tajpi novan pasvorton ĉi-sube.", + "change_password_form_confirm_password": "Konfirmu pasvorton", + "change_password_form_description": "Saluton {name},\n\nAÅ­ tio ĉi estas via unua ensaluto, aÅ­ la sistemo ricevis peton ŝanĝigi vian pasvorton. Bonvolu tajpi novan pasvorton ĉi-sube.", + "change_password_form_log_out": "Elsalutu ĉe ĉiuj aliaj aparatoj", + "change_password_form_log_out_description": "Oni rekomendas elsaluti ĉe ĉiuj aliaj aparatoj", + "change_password_form_new_password": "Nova pasvorto", + "change_password_form_password_mismatch": "Pasvortoj ne kongruas", + "change_password_form_reenter_new_password": "Re-tajpu novan pasvorton", + "change_pin_code": "Ŝanĝi PIN-kodon", + "change_trigger": "Ŝanĝi ekagilon", + "change_trigger_prompt": "Ĉu vi certas, ke vi volas ŝanĝi la ekagilon? Tio forigos ĉiujn ekzistantajn agojn kaj filtrilojn.", + "change_your_password": "Ŝanĝi vian pasvorton", + "changed_visibility_successfully": "Sukcese ŝanĝis videblecon", + "charging": "Ŝargado", + "charging_requirement_mobile_backup": "Por fona savkopiado, vi devas konekti la aparaton al ŝargilo", + "check_corrupt_asset_backup": "Kontroli por koruptitaj savkopioj de elementoj", + "check_corrupt_asset_backup_button": "Kontroli", + "check_corrupt_asset_backup_description": "Fari tiun ĉi kontrolon nur per vifio kaj post kiam ĉiuj elementoj havas savkopion. La kontrolo povas daÅ­ri kelkajn minutojn.", + "check_logs": "Kontroli protokolojn", + "checksum": "Kontrolsumo", + "choose_matching_people_to_merge": "Elekti duobligitajn homojn por kunfandi", + "city": "Urbo", + "cleanup_confirm_description": "Immich trovis savkopion en la servilo de {count} elementoj (kreitajn antaÅ­ {date}). Ĉu vi volas forigi la kopiojn de el tiu ĉi aparato?", + "cleanup_confirm_prompt_title": "Forigi el tiu ĉi aparato?", + "cleanup_deleted_assets": "Movis {count} elementojn al la rubujo de la aparato", + "cleanup_deleting": "Movado al rubujo...", + "cleanup_found_assets": "Trovis {count} elementojn kun savkopio", + "cleanup_found_assets_with_size": "Trovis {count} elementojn kun savkopio ({size})", "cleanup_icloud_shared_albums_excluded": "Dividitaj albumoj ĉe iCloud estas ekskluditaj de la analizado", - "cleanup_step3_description": "Serĉi fotojn kaj videojn kun sekurkopio ĉe la servilo, laÅ­ la elektita limdato kaj filtriloj.", + "cleanup_no_assets_found": "Neniuj elementoj trovitaj per la ĉi-supraj kriterioj. La funkcio 'Liberigi spacon' forigas nur elementojn, kiuj havas savkopion ĉe la servilo", + "cleanup_preview_title": "Forigotaj elementoj ({count})", + "cleanup_step3_description": "Serĉi fotojn kaj videojn kun savkopio ĉe la servilo, laÅ­ la elektita limdato kaj filtriloj.", + "cleanup_step4_summary": "{count} elementoj (kreitaj antaÅ­ {date}) forigotaj de via aparato. Fotoj restos disponeblaj (pere de la servilo) en la apo Immich.", + "cleanup_trash_hint": "Por povi reuzi la liberigitan spacon, malfermu la 'galeria' apo de via aparato kaj malplenigu la rubujon", + "clear": "Forviŝi", + "clear_all": "Forviŝi ĉiujn kampojn", + "clear_all_recent_searches": "Forviŝi ĉiujn lastatempajn serĉojn", + "clear_file_cache": "Forviŝi dosier-kaŝon", + "clear_message": "Forviŝi mesaĝon", + "clear_value": "Forviŝi valoron", + "client_cert_dialog_msg_confirm": "Bone", + "client_cert_enter_password": "Tajpu pasvorton", + "client_cert_import": "Importi", + "client_cert_import_success_msg": "Atestilo sukcese importita", + "client_cert_invalid_msg": "Nevalida atestilo-dosiero, aÅ­ malĝusta pasvorto", + "client_cert_password_message": "Tajpu la pasvorton por tiu ĉi atestilo", + "client_cert_password_title": "Pasvorto de atestilo", + "client_cert_remove_msg": "Klient-atestilo forigita", + "client_cert_subtitle": "Nur la formato PKCS12 (.p12, .pfx) estas akceptita. Eblas importi/forigi atestilon nur antaÅ­ ol ensaluti", + "client_cert_title": "Klient-atestilo SSL [EKSPERIMENTA]", + "clockwise": "Horloĝdirekte", + "close": "Fermi", + "collapse": "Maletendi", + "collapse_all": "Maletendi ĉiujn", + "color": "Koloro", + "color_theme": "Kolor-temo", + "command": "Komando", + "command_palette_prompt": "Rapide trovi paĝojn, agojn aÅ­ komandojn", + "command_palette_to_close": "por fermi", + "command_palette_to_navigate": "por eniri", + "command_palette_to_select": "por elekti", + "command_palette_to_show_all": "por ĉion montri", + "comment_deleted": "Komento forigita", + "comment_options": "Agoj pri komento", + "comments_and_likes": "Komentoj kaj ŝatoj", + "comments_are_disabled": "Komentoj estas malebligitaj", + "common_create_new_album": "Krei novan albumon", + "completed": "Finfarita", + "confirm": "Konfirmi", + "confirm_admin_password": "Konfirmi administran pasvorton", + "confirm_delete_face": "Ĉu vi certas ke vi volas forigi la vizaĝon de {name} de tiu elemento?", + "confirm_delete_shared_link": "Ĉu vi certas, ke vi volas forigi tiun ligilon?", + "confirm_keep_this_delete_others": "Ĉiuj elementoj en la stako krom tiu ĉi estos forigitaj. Ĉu vi certas, ke vi volas tion?", + "confirm_new_pin_code": "Konfirmi novan PIN-kodon", + "confirm_password": "Konfirmi pasvorton", + "confirm_tag_face": "Ĉu vi volas etikedi tiun ĉi vizaĝon kiel {name}?", + "confirm_tag_face_unnamed": "Ĉu vi volas etikedi tiun ĉi vizaĝon?", + "connected_device": "Konektita aparato", + "connected_to": "Konektita al", + "contain": "Alĝustigi", + "context": "Kunteksto", + "continue": "DaÅ­rigi", + "control_bottom_app_bar_create_new_album": "Krei novan albumon", + "control_bottom_app_bar_delete_from_immich": "Forigi el Immich", + "control_bottom_app_bar_delete_from_local": "Forigi el aparato", + "control_bottom_app_bar_edit_location": "Redakti lokon", + "control_bottom_app_bar_edit_time": "Redakti daton kaj horon", + "control_bottom_app_bar_share_link": "Dividi ligilon", + "control_bottom_app_bar_share_to": "Dividi al", + "control_bottom_app_bar_trash_from_immich": "Movi al rubujo", + "copied_image_to_clipboard": "Bildo kopiita al tondujo.", + "copied_to_clipboard": "Kopiita al tondujo!", + "copy_error": "Kopii eraron", + "copy_file_path": "Kopii dosiervojon", + "copy_image": "Kopii bildon", + "copy_link": "Kopii ligilon", + "copy_link_to_clipboard": "Kopii ligilon al tondujo", + "copy_password": "Kopii pasvorton", + "copy_to_clipboard": "Kopii al tondujo", + "country": "Lando", + "cover": "Kovri", + "covers": "Kovriloj", + "create": "Krei", + "create_album": "Krei albumon", + "create_album_page_untitled": "Sen titolo", + "create_api_key": "Krei API-ŝlosilon", + "create_first_workflow": "Krei unuan laborfluon", + "create_library": "Krei bibliotekon", + "create_link": "Krei ligilon", + "create_link_to_share": "Krei ligilon por dividi", + "create_link_to_share_description": "Permesi, ke iu ajn kun la ligilo povu vidi la elektita(j)n foto(j)n", + "create_new": "KREI NOVAN", + "create_new_face": "Krei novan vizaĝon", + "create_new_person": "Krei novan homon", + "create_new_person_hint": "Atribui elektitajn elementojn al nova homo", + "create_new_user": "Krei novan uzanton", + "create_person": "Krei homon", + "create_person_subtitle": "Aldoni nomon al la elektita vizaĝo por krei kaj etikedi novan homon", + "create_shared_album_page_share_add_assets": "ALDONI ELEMENTOJN", + "create_shared_album_page_share_select_photos": "Elekti fotojn", + "create_shared_link": "Krei dividitan ligilon", + "create_tag": "Krei etikedon", + "create_tag_description": "Krei novan etikedon. Por ingitaj etikedoj, bonvolu tajpi la plenan vojon de la etikedo, inkluzive suprenstrekoj (\"/\").", + "create_user": "Krei uzanton", + "create_workflow": "Krei laborfluon", + "created": "Kreita", + "created_at": "Kreita", + "creating_linked_albums": "Kreado de ligitaj albumoj...", + "crop": "Stuci", + "crop_aspect_ratio_fixed": "Fiksita", + "crop_aspect_ratio_free": "Libera", + "crop_aspect_ratio_original": "Originala", + "crop_aspect_ratio_square": "Kvadrata", + "curated_object_page_title": "Objektoj", + "current_device": "Aktuala aparato", + "current_pin_code": "Aktuala PIN-kodo", + "current_server_address": "Aktuala adreso de servilo", + "custom_date": "Elekti propran daton", + "custom_locale": "Propra lokaÄĩaro", + "custom_locale_description": "Prezenti datojn, horojn kaj numerojn laÅ­ la elektita lingvo kaj regiono", + "custom_url": "Propra URL", + "cutoff_date_description": "Konservi fotojn el la lastajâ€Ļ", + "cutoff_day": "{count, plural, one {tago} other {tagoj}}", + "cutoff_year": "{count, plural, one {jaro} other {jaroj}}", + "daily_title_text_date": "E, dd MMM", + "daily_title_text_date_year": "E, dd MMM, yyyy", + "dark": "Malhela", + "dark_theme": "Ŝanĝi al hela reĝimo", + "date": "Dato", + "date_after": "Dato post", + "date_and_time": "Dato kaj horo", + "date_before": "Dato antaÅ­", + "date_format": "E, LLL d, y â€ĸ h:mm a", + "date_of_birth_saved": "Naskiĝdato sukcese registrita", + "date_range": "Dato-intervalo", + "day": "Tago", + "days": "Tagoj", + "deduplicate_all": "SenduoblaÄĩigi ĉion", + "default_locale": "DefaÅ­lta lokaÄĩaro", + "default_locale_description": "Prezenti datojn kaj numerojn laÅ­ la lokaÄĩaro de via retumilo", + "delete": "Forigi", + "delete_action_confirmation_message": "Ĉu vi certas, ke vi volas forigi tiun ĉi elementon? Tiu ago movos ĝin al la rubujo ĉe la servilo, kaj demandos ĉu vi volas forigi ĝin de via aparato", + "delete_action_prompt": "{count} forigita(j)", + "delete_album": "Forigi albumon", + "delete_api_key_prompt": "Ĉu vi certas, ke vi volas forigi tiu ĉi API-ŝlosilon?", + "delete_dialog_alert": "Tiuj elementoj estos porĉiame forigitaj de Immich kaj de via aparato", + "delete_dialog_alert_local": "Tiuj ĉi elementoj estos forigitaj de via aparato, sed restos disponeblaj ĉe la servilo de Immich", + "delete_dialog_alert_local_non_backed_up": "Kelkaj el tiuj elementoj ne havas savkopion ĉe Immich kaj estos porĉiame forigitaj de via aparato", + "delete_dialog_alert_remote": "Tiuj elementoj estos porĉiame forigitaj de la Immich-servilo", + "delete_dialog_ok_force": "Forigi ĉiuokaze", + "delete_dialog_title": "Forigi por ĉiam", + "delete_duplicates_confirmation": "Ĉu vi certas, ke vi volas porĉiame forigi tiujn ĉi duoblaÄĩojn?", + "delete_face": "Forigi vizaĝon", + "delete_key": "Forigi ŝlosilon", + "delete_library": "Forigi bibliotekon", + "delete_link": "Forigi ligilon", + "delete_local_action_prompt": "{count} loke forigita(j)", + "delete_local_dialog_ok_backed_up_only": "Forigi nur elementojn, kiuj havas savkopiojn", + "delete_local_dialog_ok_force": "Forigi ĉiuokaze", + "delete_others": "Forigi la aliajn", + "delete_permanently": "Forigi por ĉiam", + "delete_permanently_action_prompt": "{count} forigita(j) por ĉiam", + "delete_shared_link": "Forigi dividitan ligilon", + "delete_shared_link_dialog_title": "Forigi dividitan ligilon", + "delete_tag": "Forigi etikedon", + "delete_tag_confirmation_prompt": "Ĉu vi certas, ke vi volas forigi la etikedon {tagName}?", + "delete_user": "Forigi uzanton", + "deleted_shared_link": "Dividita ligilo nun forigita", + "deletes_missing_assets": "Forigas elementojn, kiuj mankas ĉe la disko", + "description": "Priskribo", + "description_input_hint_text": "Aldoni priskribon...", + "description_input_submit_error": "Eraro okazis dum ĝisdatigo de priskribo. Kontrolu protokolon por pli da detaloj", + "deselect_all": "Malelekti ĉion", + "details": "Detaloj", + "direction": "Direkto", + "disable": "Malebligi", + "disabled": "Malebligita", + "disallow_edits": "Malpermesi redaktojn", + "discord": "Discord", + "discover": "Malkovri", + "discovered_devices": "Malkovritaj aparatoj", + "dismiss_all_errors": "Ignori ĉiujn erarojn", + "dismiss_error": "Ignori eraron", + "display_options": "Vidigi tiajn elementojn", + "display_order": "Vicordo de vidigo", + "display_original_photos": "Montri originalajn fotojn", + "display_original_photos_setting_description": "Prefere montri originalan foton anstataÅ­ bildeton se la originalo havas retumil-kongruan formaton. Tio povas malrapidigi vidigon de elementoj.", + "do_not_show_again": "Ne plu montri tiun ĉi mesaĝon", + "documentation": "Dokumentaro", + "done": "Finite", + "download": "Elŝuti", + "download_action_prompt": "Elŝutado de {count} elementoj", + "download_canceled": "Elŝuto nuligita", + "download_complete": "Elŝuto finita", + "download_enqueue": "Elŝuto en atendovico", + "download_error": "Eraro de elŝuto", + "download_failed": "Elŝuto malsukcesis", + "download_finished": "Elŝuto finiĝis", + "download_include_embedded_motion_videos": "Enkorpigitaj videoj", + "download_include_embedded_motion_videos_description": "Inkluzivi videon, enkorpigitan en mov-fotoj, kiel apartan dosieron", + "download_notfound": "Elŝuto ne trovita", + "download_original": "Elŝuti originalon", + "download_paused": "Elŝuto paÅ­zita", + "download_settings": "Elŝutado", "download_settings_description": "Administri agordojn pri elŝutado de elementoj", + "download_started": "Elŝuto komenciĝis", + "download_sucess": "Elŝuto sukcesis", + "download_sucess_android": "La elemento estas elŝutita al DCIM/Immich", + "download_waiting_to_retry": "BaldaÅ­ reprovos elŝuton", + "downloading": "Elŝutado", + "downloading_asset_filename": "Elŝutado de elemento {filename}", + "downloading_from_icloud": "Elŝutado el iCloud", + "downloading_media": "Elŝutado de elementoj", + "drop_files_to_upload": "Demetu dosierojn ĉi tien por alŝuti", + "duplicates": "DuoblaÄĩoj", + "duplicates_description": "Solvu ĉiun grupon indikante tiujn, kiuj estas eventualaj duoblaÄĩoj.", + "duration": "DaÅ­ro", + "edit": "Redakti", + "edit_album": "Redakti albumon", + "edit_avatar": "Redakti profilbildon", + "edit_birthday": "Redakti naskiĝtagon", + "edit_date": "Redakti daton", + "edit_date_and_time": "Redakti daton kaj horon", + "edit_date_and_time_action_prompt": "{count} datoj kaj horoj redaktitaj", + "edit_date_and_time_by_offset": "Deŝovi daton", + "edit_date_and_time_by_offset_interval": "Nova intervalo: de {from} ĝis {to}", + "edit_description": "Redakti priskribon", + "edit_description_prompt": "Bonvolu elekti novan priskribon:", "edit_exclusion_pattern": "Redakti skemon de ekskludo", + "edit_faces": "Redakti vizaĝojn", + "edit_key": "Redakti ŝlosilon", + "edit_link": "Redakti ligilon", + "edit_location": "Redakti lokon", + "edit_location_action_prompt": "{count} loko(j) redaktita(j)", + "edit_location_dialog_title": "Loko", + "edit_name": "Redakti nomon", + "edit_people": "Redakti homojn", + "edit_tag": "Redakti etikedon", + "edit_title": "Redakti titolon", + "edit_user": "Redakti uzanton", + "edit_workflow": "Redakti laborfluon", + "editor": "Redaktilo", + "editor_close_without_save_prompt": "La ŝanĝoj ne konserviĝos", + "editor_close_without_save_title": "Ĉu fermi redaktilon?", + "editor_confirm_reset_all_changes": "Ĉu vi certas, ke vi volas forÄĩeti ĉiujn ŝanĝojn?", + "editor_discard_edits_confirm": "ForÄĩeti ŝanĝojn", + "editor_discard_edits_prompt": "Vi havas nekonservitajn ŝanĝojn. Ĉu vi certas, ke vi volas forigi ilin?", + "editor_discard_edits_title": "ForÄĩeti ŝanĝojn?", + "editor_edits_applied_error": "Malsukcesis apliki redaktojn", + "editor_edits_applied_success": "Redaktoj sukcese aplikiĝis", + "editor_flip_horizontal": "Inversigi horizontale", + "editor_flip_vertical": "Inversigi vertikale", + "editor_handle_corner": "{corner, select, top_left {Supra-maldekstra} top_right {Supra-dekstra} bottom_left {Suba-maldekstra} bottom_right {Suba-dekstra} other {Ajna}} angula tenilo", + "editor_handle_edge": "{edge, select, top {Supra} bottom {Suba} left {Maldekstra} right {Dekstra} other {Ajna}} randa tenilo", + "editor_orientation": "Orientiĝo", + "editor_reset_all_changes": "Forviŝi ŝanĝojn", + "editor_rotate_left": "Turni 90Âē kontraÅ­-horloĝdirekte", + "editor_rotate_right": "Turni 90Âē horloĝdirekte", + "email": "Retadreso", + "email_notifications": "Sciigoj per retmesaĝo", + "empty_folder": "Tiu ĉi dosierujo estas malplena", + "empty_trash": "Malplenigi rubujon", + "empty_trash_confirmation": "Ĉu vi certas, ke vi volas malplenigi la rubujon? Ĉiuj elementoj en la rubujo estas por ĉiam forigitaj de Immich.\nNe eblas malfari tion!", + "enable": "Ŝalti", + "enable_backup": "Ŝalti savkopiadon", + "enable_biometric_auth_description": "Tajpu vian PIN-kodon por ŝalti biometrian ensalutadon", + "enabled": "Ŝaltita", + "end_date": "Fina dato", + "enqueued": "En atendovico", + "enter_wifi_name": "Tajpu nomon de vifio", + "enter_your_pin_code": "Tajpu vian PIN-kodon", + "enter_your_pin_code_subtitle": "Tajpu vian PIN-kodon por atingi la ŝlositan dosierujon", + "error": "Eraro", + "error_change_sort_album": "Malsukcesis ŝanĝi vicordon de album-elementoj", + "error_delete_face": "Eraro dum forigo de vizaĝo el elemento", + "error_getting_places": "Eraro dum serĉo de lokoj", + "error_loading_albums": "Eraro dum ŝargado de albumoj", + "error_loading_image": "Eraro dum ŝargado de bildo", + "error_loading_partners": "Eraro dum ŝargado de partneroj: {error}", + "error_retrieving_asset_information": "Eraro dum ŝargado de informoj pri elemento", + "error_saving_image": "Eraro: {error}", + "error_tag_face_bounding_box": "Eraro dum etikedado de vizaĝo - ne eblis trovi koordinatojn de kadro", + "error_title": "Eraro - io misis", + "error_while_navigating": "Eraro dum navigado al elemento", "errors": { + "cannot_navigate_next_asset": "Ne eblis navigi al sekva elemento", + "cannot_navigate_previous_asset": "Ne eblas navigi al antaÅ­a elemento", + "cant_apply_changes": "Ne eblas apliki ŝanĝojn", + "cant_change_activity": "Ne eblas {enabled, select, true {malŝalti} other {ŝalti}} tiun agon", + "cant_change_asset_favorite": "Ne eblas ŝanĝi preferon por tiu elemento", + "cant_change_metadata_assets_count": "Ne eblas ŝanĝi metadatumojn de {count, plural, one {# elemento} other {# elementoj}}", + "cant_get_faces": "Ne eblas trovi vizaĝojn", + "cant_get_number_of_comments": "Ne eblas trovi nombron da komentoj", + "cant_search_people": "Ne eblas serĉi homojn", + "cant_search_places": "Ne eblas serĉi lokojn", + "error_adding_assets_to_album": "Eraro dum ŝargado de elementoj al albumo", + "error_adding_users_to_album": "Eraro dum aldono de uzantoj al albumo", + "error_deleting_shared_user": "Eraro dum forigo de dividita uzanto", + "error_downloading": "Eraro dum elŝuto de {filename}", + "error_hiding_buy_button": "Eraro dum kaŝado de butono 'aĉeti'", + "error_removing_assets_from_album": "Eraro dum forigo de elementoj el albumo; kontrolu konzolon por detaloj", + "error_selecting_all_assets": "Eraro dum elekto de ĉiuj elementoj", "exclusion_pattern_already_exists": "Tiu ĉi skemo de ekskludo jam ekzistas.", + "failed_to_create_album": "Malsukcesis krei albumon", + "failed_to_create_shared_link": "Malsukcesis krei dividitan ligilon", + "failed_to_edit_shared_link": "Malsukcesis redakti dividitan ligilon", + "failed_to_get_people": "Malsukcesis trovi homojn", + "failed_to_keep_this_delete_others": "Malsukcesis konservi tiun ĉi elementon kaj forigi la aliajn", + "failed_to_load_asset": "Malsukcesis ŝargi elementon", + "failed_to_load_assets": "Malsukcesis ŝargi elementojn", + "failed_to_load_notifications": "Malsukcesis ŝargi sciigojn", + "failed_to_load_people": "Malsukcesis ŝargi homojn", + "failed_to_remove_product_key": "Malsukcesis forigi var-ŝalosilon", + "failed_to_reset_pin_code": "Malsukcesis restarigi PIN-kodon", + "failed_to_stack_assets": "Malsukcesis staki elementojn", + "failed_to_unstack_assets": "Malsukcesis malstaki elementojn", + "failed_to_update_notification_status": "Malsukcesis ĝisdatigi statuson de sciigoj", + "incorrect_email_or_password": "Neĝusta retadreso aÅ­ pasvorto", + "library_folder_already_exists": "Tiu ĉi import-vojo jam ekzistas.", + "page_not_found": "Paĝo ne trovita", + "paths_validation_failed": "Evidentiĝis, ke {paths, plural, one {# vojo estas nevalida} other {# vojoj estas nevalidaj}}", + "profile_picture_transparent_pixels": "Ne eblas havi travideblaj bilderoj en profilbildo. Bonvolu zomi kaj/aÅ­ ŝovi la bildon al loko sen tiaj bilderoj.", + "quota_higher_than_disk_size": "Vi donis kvoton pli grandan ol la disko mem", + "something_went_wrong": "Io misis", + "unable_to_add_album_users": "Ne eblas aldoni uzantojn al la albumo", + "unable_to_add_assets_to_shared_link": "Ne eblas aldoni elementojn al la dividita ligilo", + "unable_to_add_comment": "Ne eblas aldoni komenton", "unable_to_add_exclusion_pattern": "Ne eblas aldoni skemon de ekskludo", + "unable_to_add_partners": "Ne eblas aldoni partnerojn", + "unable_to_add_remove_archive": "Ne eblas {archived, select, true {forigi elementon de} other {aldoni elementon al}} la arÄĨivo", + "unable_to_add_remove_favorites": "Ne eblas {favorite, select, true {aldoni elementon al} other {forigi elementon de}} preferataÄĩoj", + "unable_to_change_favorite": "Ne eblas ŝanĝi preferon por tiu elemento", + "unable_to_create": "Ne eblis krei laborfluon", "unable_to_delete_exclusion_pattern": "Ne eblas forigi skemon de ekskludo", + "unable_to_delete_workflow": "Ne eblis forigi laborfluon", "unable_to_edit_exclusion_pattern": "Ne eblas redakti skemon de ekskludo", "unable_to_scan_libraries": "Ne eblas analizi biblitekojn", - "unable_to_scan_library": "Ne eblas analizi biblitekon" + "unable_to_scan_library": "Ne eblas analizi biblitekon", + "unable_to_update_workflow": "Ne eblis ĝisdatigi laborfluon" }, "exclusion_pattern": "Skemo de ekskludo", + "expand": "Etendi", + "expand_all": "Etendi ĉiujn", "explore": "Esplori", "explorer": "Foliumilo", + "favorite": "PreferataÄĩo", + "favorite_action_prompt": "{count} aldonita(j) al PreferataÄĩoj", + "favorite_or_unfavorite_photo": "Aldoni/forigi foton al/de preferataÄĩoj", + "favorites": "PreferataÄĩoj", + "favorites_page_no_favorites": "Neniuj preferataj elementoj trovitaj", + "free_up_space": "Liberigi spacon", + "free_up_space_description": "Vi forigos fotojn kaj/aÅ­ videojn, kiuj havas savkopiojn en la servilo, por liberigi spacon en via aparato. La kopioj en la servilo restos.", "general": "Ĝeneralaj", + "home_page_favorite_err_local": "AnkoraÅ­ ne eblas aldoni lokajn elementojn al PreferataÄĩoj; ignorita(j)", + "home_page_favorite_err_partner": "AnkoraÅ­ ne eblas aldoni elementojn de partnero al PreferataÄĩoj; ignorita(j)", + "keep_favorites": "Konservi preferataÄĩojn", "manage_media_access_settings": "Malfermi agordaÄĩaron", "manage_the_app_settings": "Agordi la apon", + "map_settings_only_show_favorites": "Montri nur preferataÄĩojn", "missing": "Netraktitaj", "networking_subtitle": "Administri agordojn pri finpunktoj de la servilo", "no_devices": "Neniuj aprobitaj aparatoj", "no_explore_results_message": "Alŝutu pli da fotoj por esplori vian kolekton.", + "no_favorites_message": "Aldoni al PreferataÄĩoj por rapide retrovi viajn plej bonajn bildojn kaj videojn", + "no_notifications": "Neniuj sciigoj", "no_results_description": "Provu sinonimon aÅ­ pli ĝeneralan ŝlosilvorton", + "notification_permission_dialog_content": "Por ŝalti sciigojn, iru al Agordoj kaj elektu 'permesi'.", + "notification_permission_list_tile_content": "Donu permeson por ŝalti sciigojn.", + "notification_permission_list_tile_enable_button": "Ŝalti sciigojn", + "notification_permission_list_tile_title": "Permeso pri sciigoj", + "notification_toggle_setting_description": "Ŝalti sciigojn per retmesaĝo", + "notifications": "Sciigoj", + "notifications_setting_description": "Administri sciigojn", + "only_favorites": "Nur preferataÄĩoj", "preferences_settings_subtitle": "Administri agordojn pri la apo", "purchase_settings_server_activated": "La administranto respondecas pri la ŝlosilo de aÅ­tentikeco por la servilo", + "rating_clear": "Forviŝi pritakson", "refresh": "Denove", + "remove_from_favorites": "Forigi el preferataÄĩoj", + "removed_from_favorites": "Forigita(j) el preferataÄĩoj", + "removed_from_favorites_count": "{count, plural, other {Forigis #}} el PreferataÄĩoj", "rescan": "Reanalizi", "reset": "Restartigi", + "reset_sqlite_clear_app_data": "Forviŝi datumojn", + "reset_sqlite_confirmation": "Ĉu vi certas, ke vi volas forviŝi la datumojn de la apo? Tio forigos ĉiujn agordojn kaj elsalutigos vin.", + "reset_sqlite_confirmation_note": "Noto: vi devos relanĉi la apon por la forviŝo.", + "reset_sqlite_done": "Datumoj de la apo estas forviŝitaj. Bonvolu relanĉi Immich kaj ensalutu denove.", + "scaffold_body_error_unrecoverable": "Neriparebla eraro okazis. Bonvolu sendi al ni la eraron kaj la stakspuron per Discord aÅ­ per Github por ke ni povu helpi. Vi povas forviŝi la ĉi-subajn datumojn de la apo se vi volas.", "scan": "Analizi", "scan_all_libraries": "Analizi ĉiujn bibliotekojn", "scan_library": "Analizi", @@ -712,12 +1152,34 @@ "scanning": "Analizado", "scanning_for_album": "Serĉado de albumo...", "search_suggestion_list_smart_search_hint_1": "Inteligenta serĉado defaÅ­lte estas ŝaltita. Por serĉi metadatumojn, uzu sintakson tiel ", + "setting_notifications_subtitle": "Redakti viajn preferojn pri sciigoj", + "start_date": "Komenca dato", + "start_date_before_end_date": "Komenca dato devas esti antaÅ­ fina dato", + "to_favorite": "Aldoni al preferataÄĩoj", + "trigger_description": "Evento, kiu ekfunkciigas la laborfluon", + "unfavorite": "Forigi el preferataÄĩoj", + "unfavorite_action_prompt": "{count} forigita(j) el PreferataÄĩoj", + "untitled_workflow": "Sentitola laborfluo", "upload_concurrency": "Nombro da samtempaj alŝutoj", "user_pin_code_settings_description": "Administri vian PIN-kodon", "user_purchase_settings_description": "Administri vian aĉeton", "view_links": "Vidi ligilojn", "week": "Semajno", "wifi_name": "Nomo de Vifireto", + "workflow_delete_prompt": "Ĉu vi certas, ke vi volas forigi tiun ĉi laborfluon?", + "workflow_deleted": "Laborfluo forigita", + "workflow_description": "Priskribo de laborfluo", + "workflow_info": "Informoj pri laborfluo", + "workflow_json": "JSON de laborfluo", + "workflow_json_help": "Redakti la agordojn pri la laborfluo per formato JSON. La ŝanĝoj sinkroniĝos al la vidiga konstruilo.", + "workflow_name": "Nomo de laborfluo", + "workflow_navigation_prompt": "Ĉu vi certas, ke vi volas foriri sen konservi viajn ŝanĝojn?", + "workflow_summary": "Resumo de laborfluo", + "workflow_update_success": "Laborfluo sukcese ĝisdatigita", + "workflow_updated": "Laborfluo ĝisdatigita", + "workflows": "Laborfluoj", + "workflows_help_text": "Laborfluo aÅ­tomatigas agojn pri elementoj, laÅ­ ekigiloj kaj filtriloj", "year": "Jaro", - "yes": "Jes" + "yes": "Jes", + "zero_to_clear_rating": "tuŝu 0 por forviŝi la pritakson de la elemento" } diff --git a/i18n/es.json b/i18n/es.json index fe82e3a093..722c8fd98c 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -17,13 +17,13 @@ "add_a_name": "AÃąadir un nombre", "add_a_title": "AÃąadir título", "add_action": "AÃąadir acciÃŗn", - "add_action_description": "Haga clic para aÃąadir una acciÃŗn a realizar", + "add_action_description": "Haz clic para aÃąadir una acciÃŗn a realizar", "add_assets": "AÃąadir recursos", "add_birthday": "AÃąadir un cumpleaÃąos", "add_endpoint": "AÃąadir punto final", "add_exclusion_pattern": "AÃąadir patrÃŗn de exclusiÃŗn", "add_filter": "AÃąadir filtro", - "add_filter_description": "Haga clic para aÃąadir una condiciÃŗn de filtro", + "add_filter_description": "Haz clic para aÃąadir una condiciÃŗn de filtro", "add_location": "AÃąadir ubicaciÃŗn", "add_more_users": "AÃąadir mÃĄs usuarios", "add_partner": "AÃąadir miembro", @@ -372,7 +372,7 @@ "transcoding_audio_codec": "Codec de audio", "transcoding_audio_codec_description": "Opus es la opciÃŗn de mayor calidad, pero tiene menor compatibilidad con dispositivos o software antiguos.", "transcoding_bitrate_description": "Vídeos con una tasa de bits superior a la mÃĄxima o que no estÃĄn en un formato aceptado", - "transcoding_codecs_learn_more": "Para obtener mÃĄs informaciÃŗn sobre la terminología utilizada aquí, consulte la documentaciÃŗn de FFmpeg sobre el cÃŗdec H.264, el cÃŗdec HEVC y el cÃŗdec VP9.", + "transcoding_codecs_learn_more": "Para obtener mÃĄs informaciÃŗn sobre la terminología utilizada aquí, consulta la documentaciÃŗn de FFmpeg sobre el cÃŗdec H.264, el cÃŗdec HEVC y el cÃŗdec VP9.", "transcoding_constant_quality_mode": "Modo de calidad constante", "transcoding_constant_quality_mode_description": "ICQ es mejor que CQP, pero algunos dispositivos de aceleraciÃŗn de hardware no admiten este modo. Al configurar esta opciÃŗn, se preferirÃĄ el modo especificado cuando se utilice codificaciÃŗn basada en calidad. NVENC lo ignora porque no es compatible con ICQ.", "transcoding_constant_rate_factor": "Factor de tasa constante (-crf)", @@ -441,7 +441,7 @@ "user_successfully_removed": "El usuario {email} ha sido eliminado con Êxito.", "users_page_description": "PÃĄgina de usuarios administradores", "version_check_enabled_description": "Activar la comprobaciÃŗn de la versiÃŗn", - "version_check_implications": "La funciÃŗn de comprobaciÃŗn de versiones depende de la comunicaciÃŗn periÃŗdica con github.com", + "version_check_implications": "La funciÃŗn de comprobaciÃŗn de versiones depende de la comunicaciÃŗn periÃŗdica con {server}", "version_check_settings": "Verificar versiÃŗn", "version_check_settings_description": "Activar/desactivar la notificaciÃŗn de nueva versiÃŗn", "video_conversion_job": "Transcodificar vídeos", @@ -849,9 +849,12 @@ "create_link_to_share": "Crear enlace compartido", "create_link_to_share_description": "Permitir que cualquier persona con el enlace vea la(s) foto(s) seleccionada(s)", "create_new": "CREAR NUEVO", + "create_new_face": "Crear nueva cara", "create_new_person": "Crear nueva persona", "create_new_person_hint": "Asignar los recursos seleccionados a una nueva persona", "create_new_user": "Crear nuevo usuario", + "create_person": "Crear persona", + "create_person_subtitle": "AÃąade un nombre a la cara seleccionada para crear y etiquetar a la nueva persona", "create_shared_album_page_share_add_assets": "AÑADIR RECURSOS", "create_shared_album_page_share_select_photos": "Seleccionar fotos", "create_shared_link": "Crear un enlace compartido", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fijado", "crop_aspect_ratio_free": "Libre", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Cuadrado", "curated_object_page_title": "Objetos", "current_device": "Dispositivo actual", "current_pin_code": "PIN actual", @@ -880,7 +884,7 @@ "daily_title_text_date": "E dd, MMM", "daily_title_text_date_year": "E dd de MMM, yyyy", "dark": "Oscuro", - "dark_theme": "Alternar tema oscuro", + "dark_theme": "Cambiar a tema oscuro", "date": "Fecha", "date_after": "Fecha posterior", "date_and_time": "Fecha y hora", @@ -891,10 +895,8 @@ "day": "Día", "days": "Días", "deduplicate_all": "Deduplicar todo", - "deduplication_criteria_1": "TamaÃąo de imagen en bytes", - "deduplication_criteria_2": "Conteo de datos EXIF", - "deduplication_info": "InformaciÃŗn de DeduplicaciÃŗn", - "deduplication_info_description": "Para automÃĄticamente preseleccionar recursos y eliminar duplicados en conjunto, nosotros consideramos lo siguiente:", + "default_locale": "ConfiguraciÃŗn regional predeterminada", + "default_locale_description": "Formatear fechas y nÃēmeros segÃēn la configuraciÃŗn regional del navegador", "delete": "Eliminar", "delete_action_confirmation_message": "ÂŋEstÃĄ seguro que desea eliminar este recurso? Esta acciÃŗn lo moverÃĄ a la papelera del servidor y le preguntarÃĄ si desea eliminarlo localmente", "delete_action_prompt": "{count} eliminados", @@ -970,7 +972,7 @@ "downloading_media": "Descargando medios", "drop_files_to_upload": "Suelta los archivos en cualquier lugar para subirlos", "duplicates": "Duplicados", - "duplicates_description": "Resuelva cada grupo indicando, en cada caso, cuales estÃĄn duplicados", + "duplicates_description": "Resuelve cada grupo indicando cuÃĄles son duplicados, si los hay.", "duration": "DuraciÃŗn", "edit": "Editar", "edit_album": "Editar ÃĄlbum", @@ -1023,7 +1025,7 @@ "enable_biometric_auth_description": "Introduce tu cÃŗdigo PIN para habilitar la autentificaciÃŗn biomÊtrica", "enabled": "Habilitado", "end_date": "Fecha final", - "enqueued": "Agregado a la cola", + "enqueued": "AÃąadido a la cola", "enter_wifi_name": "Introduce el nombre Wi-Fi", "enter_your_pin_code": "Introduce tu cÃŗdigo PIN", "enter_your_pin_code_subtitle": "Introduce tu cÃŗdigo PIN para acceder a la carpeta protegida", @@ -1086,7 +1088,7 @@ "unable_to_add_partners": "No se pueden aÃąadir miembros", "unable_to_add_remove_archive": "No se pudo {archived, select, true {eliminar el recurso del} other {aÃąadir el recurso al}} archivo", "unable_to_add_remove_favorites": "No se pudo {favorite, select, true {aÃąadir el recuso a} other {eliminar el recurso de}} los favoritos", - "unable_to_archive_unarchive": "No se pudo {archived, select, true {agregar el elemento al} other {quitar el elemento del}} archivo", + "unable_to_archive_unarchive": "No se pudo {archived, select, true {aÃąadir el elemento al} other {quitar el elemento del}} archivo", "unable_to_change_album_user_role": "No se puede cambiar la funciÃŗn del usuario del ÃĄlbum", "unable_to_change_date": "No se puede cambiar la fecha", "unable_to_change_description": "Imposible cambiar la descripciÃŗn", @@ -1165,7 +1167,7 @@ }, "errors_text": "Errores", "exclusion_pattern": "PatrÃŗn de exclusiÃŗn", - "exif": "EXIF", + "exif": "Exif", "exif_bottom_sheet_description": "AÃąadir descripciÃŗnâ€Ļ", "exif_bottom_sheet_description_error": "Error al actualizar la descripciÃŗn", "exif_bottom_sheet_details": "DETALLES", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Título del ÃĄlbum", "licenses": "Licencias", "light": "Claro", + "light_theme": "Cambiar a tema claro", "like": "Me gusta", "like_deleted": "Me gusta eliminado", "link_motion_video": "Enlazar vídeo en movimiento", + "link_to_docs": "Para mÃĄs informaciÃŗn, consulta la documentaciÃŗn.", "link_to_oauth": "Enlace a OAuth", "linked_oauth_account": "Cuenta OAuth vinculada", "list": "Lista", @@ -2213,6 +2217,7 @@ "tag": "Etiqueta", "tag_assets": "Etiquetar recursos", "tag_created": "Etiqueta creada: {tag}", + "tag_face": "Etiquetar cara", "tag_feature_description": "Explore fotos y videos agrupados por temas de etiquetas lÃŗgicas", "tag_not_found_question": "ÂŋNo encuentra una etiqueta? Crea una nueva etiqueta.", "tag_people": "Etiquetar personas", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Quitar de la pila", "viewer_stack_use_as_main_asset": "Usar como recurso principal", "viewer_unstack": "Desapilar", + "visibility": "Visibilidad", "visibility_changed": "Visibilidad cambiada para {count, plural, one {# persona} other {# personas}}", "visual": "Visual", "visual_builder": "Constructor visual", diff --git a/i18n/et.json b/i18n/et.json index f2726add15..201b341d15 100644 --- a/i18n/et.json +++ b/i18n/et.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Kasutaja {email} edukalt eemaldatud.", "users_page_description": "Kasutajate haldamise leht", "version_check_enabled_description": "Luba versioonikontroll", - "version_check_implications": "Versioonikontroll vajab perioodilist Ãŧhendumist github.com-iga", + "version_check_implications": "Versioonikontroll vajab perioodilist Ãŧhendumist {server}-iga", "version_check_settings": "Versioonikontroll", "version_check_settings_description": "Luba/keela uue versiooni teavitus", "video_conversion_job": "Videote transkodeerimine", @@ -849,9 +849,12 @@ "create_link_to_share": "Lisa jagamiseks link", "create_link_to_share_description": "Luba kÃĩigil, kellel on link, valitud pilte näha", "create_new": "LISA UUS", + "create_new_face": "Lisa uus nägu", "create_new_person": "Lisa uus isik", "create_new_person_hint": "Seosta valitud Ãŧksused uue isikuga", "create_new_user": "Lisa uus kasutaja", + "create_person": "Lisa isik", + "create_person_subtitle": "Lisa valitud näole nimi, et uus isik lisada ja sildistada", "create_shared_album_page_share_add_assets": "LISA ÜKSUSEID", "create_shared_album_page_share_select_photos": "Vali fotod", "create_shared_link": "Loo jagatud link", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fikseeritud", "crop_aspect_ratio_free": "Vaba", "crop_aspect_ratio_original": "Originaalne", + "crop_aspect_ratio_square": "Ruut", "curated_object_page_title": "Asjad", "current_device": "Praegune seade", "current_pin_code": "Praegune PIN-kood", @@ -880,7 +884,7 @@ "daily_title_text_date": "d. MMMM", "daily_title_text_date_year": "d. MMMM yyyy", "dark": "Tume", - "dark_theme": "LÃŧlita tume teema", + "dark_theme": "Vali tume teema", "date": "Kuupäev", "date_after": "Kuupäev pärast", "date_and_time": "Kuupäev ja kellaaeg", @@ -891,10 +895,8 @@ "day": "Päev", "days": "Päeva", "deduplicate_all": "Dedubleeri kÃĩik", - "deduplication_criteria_1": "Pildi suurus baitides", - "deduplication_criteria_2": "EXIF andmete hulk", - "deduplication_info": "Dedubleerimise info", - "deduplication_info_description": "Üksuste automaatsel eelvalimisel ja duplikaatide eemaldamisel vÃĩetakse arvesse:", + "default_locale": "Vaikimisi lokaat", + "default_locale_description": "Vorminda kuupäevad ja arvud vastavalt brauseri lokaadile", "delete": "Kustuta", "delete_action_confirmation_message": "Kas oled kindel, et soovid selle Ãŧksuse kustutada? See toiming liigutab Ãŧksuse serveri prÃŧgikasti ja kÃŧsib, kas soovid selle lokaalselt kustutada", "delete_action_prompt": "{count} kustutatud", @@ -970,7 +972,7 @@ "downloading_media": "Üksuste allalaadimine", "drop_files_to_upload": "Failide Ãŧleslaadimiseks sikuta need ÃŧkskÃĩik kuhu", "duplicates": "Duplikaadid", - "duplicates_description": "Lahenda iga grupp, valides duplikaadid, kui neid on", + "duplicates_description": "Lahenda iga grupp, valides duplikaadid, kui neid on.", "duration": "Kestus", "edit": "Muuda", "edit_album": "Muuda albumit", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Albumi pealkiri", "licenses": "Litsentsid", "light": "Hele", + "light_theme": "Vali hele teema", "like": "Meeldib", "like_deleted": "Meeldimine kustutatud", "link_motion_video": "Lingi liikuv video", + "link_to_docs": "Rohkema info saamiseks vaata dokumentatsiooni.", "link_to_oauth": "Ühenda OAuth", "linked_oauth_account": "OAuth konto Ãŧhendatud", "list": "Loend", @@ -2213,6 +2217,7 @@ "tag": "Silt", "tag_assets": "Sildista Ãŧksuseid", "tag_created": "Lisatud silt: {tag}", + "tag_face": "Sildista nägu", "tag_feature_description": "Fotode ja videote lehitsemine siltide kaupa grupeeritult", "tag_not_found_question": "Ei leia silti? Lisa uus silt.", "tag_people": "Sildista inimesi", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Eemalda virnast", "viewer_stack_use_as_main_asset": "Kasuta peamise Ãŧksusena", "viewer_unstack": "Eralda", + "visibility": "Nähtavus", "visibility_changed": "{count, plural, one {# isiku} other {# isiku}} nähtavus muudetud", "visual": "Visuaalne", "visual_builder": "Visuaalne koostaja", diff --git a/i18n/eu.json b/i18n/eu.json index 04443a14f8..2ac0bc6e32 100644 --- a/i18n/eu.json +++ b/i18n/eu.json @@ -5,8 +5,10 @@ "acknowledge": "Onartu", "action": "Ekintza", "action_common_update": "Eguneratu", + "action_description": "Ekintza multzoa iragazitako aktiboetan aplikatzeko", "actions": "Ekintzak", "active": "Aktibo", + "active_count": "Aktibo: {count}", "activity": "Jarduera", "activity_changed": "Jarduera {enabled, select, true {ezarrita dago} other {ez dago ezarrita}}", "add": "Gehitu", @@ -20,6 +22,8 @@ "add_birthday": "Urtebetetzea gehitu", "add_endpoint": "Endpoint-a gehitu", "add_exclusion_pattern": "Bazterketa eredua gehitu", + "add_filter": "Gehitu iragazkia", + "add_filter_description": "Klik egin iragazki baldintza bat gehitzeko", "add_location": "Kokapena gehitu", "add_more_users": "Erabiltzaile gehiago gehitu", "add_partner": "Kidea gehitu", @@ -30,41 +34,78 @@ "add_to_album": "Albumera gehitu", "add_to_album_bottom_sheet_added": "{album} -(e)ra gehitu", "add_to_album_bottom_sheet_already_exists": "Dagoeneko {album} albumenean", + "add_to_album_bottom_sheet_some_local_assets": "Aktibo lokal batzuk ezin izan dira albumera gehitu", + "add_to_album_toggle": "Txandakatu aukeraketa {album}-arentzat", "add_to_albums": "Albumetara gehitu", "add_to_albums_count": "Albumetara gehitu ({count})", + "add_to_bottom_bar": "Gehitu hona", "add_to_shared_album": "Gehitu partekatutako albumera", + "add_upload_to_stack": "Gehitu karga pilara", "add_url": "URL-a gehitu", + "add_workflow_step": "Gehitu fluxu pausoa", "added_to_archive": "Artxibategira gehituta", - "added_to_favorites": "Faboritoetara gehituta", - "added_to_favorites_count": "{count, number} faboritoetara gehituta", + "added_to_favorites": "Gogokoetara gehituta", + "added_to_favorites_count": "{count, number} gogokoetara gehituta", "admin": { "add_exclusion_pattern_description": "Gehitu baztertze patroiak. *, ** eta ? karakterak erabil ditzazkezu (globbing). Adibideak: \"Raw\" izeneko edozein direktorioko fitxategi guztiak baztertzeko, erabili \"**/Raw/**\". \".tif\" amaitzen diren fitxategi guztiak baztertzeko, erabili \"**/*.tif\". Bide absolutu bat baztertzeko, erabili \"/baztertu/beharreko/bidea/**\".", "admin_user": "Administradore erabiltzailea", + "asset_offline_description": "Kanpo-liburutegiko aktibo hau es da diskoan aurkitu eta zaborrontzira mugitu da. Fitxategia liburutegian bertan mugitu bada, bilatu denbora lerroan dagokion aktibo berria. Aktiboa berreskuratzeko, mesedez ziurtatu fitxategiaren helbidea Immich-ek eskuratu dezakela eta eskaneatu liburutegia.", "authentication_settings": "Segurtasun Ezarpenak", "authentication_settings_description": "Kudeatu pasahitza, OAuth edo beste segurtasun konfigurazio bat", "authentication_settings_disable_all": "Seguru zaude saioa hasteko modu guztiak desgaitu nahi dituzula? Saioa hastea guztiz desgaitua izango da.", "authentication_settings_reenable": "Berriro gaitzeko, erabili Server Command.", "background_task_job": "Atzealdeko Lanak", + "backup_database": "Sortu datubasearen dump-a", + "backup_database_enable_description": "Gaitu datu base dump-ak", + "backup_keep_last_amount": "Mantendu beharreko dump kopurua", + "backup_onboarding_1_description": "kanpo kopia hodeiean edo beste kokaleku fisiko batean.", + "backup_onboarding_2_description": "kopia lokalak gailu ezberdinetan. Honek fitxategi nagusiak eta fitxategi horien babeskopia lokalak barneratzen ditu.", + "backup_onboarding_3_description": "datuen kopiak guztira, fitxategi originalak barne. Honek kanpo kopia 1 eta 2 kopia lokal barne ditu.", + "backup_onboarding_description": "3-2-1 babeskopia estrategia gomendatzen da zure datuak babesteko. Babeskopia soluzio osoa lortzeko, kargatutako irudien/bideoen kopiak gorde beharko zenituzke. Immich datu-basearena baita ere.", "backup_onboarding_footer": "Immich-en babes kopiei buruzko informazio gehiago nahi baduzu, mesedez irakurri dokumentazioa.", + "backup_onboarding_parts_title": "3-2-1 babes-kopia batek barne hartzen du:", "backup_onboarding_title": "Babes Kopiak", + "backup_settings": "Datu-base Dump-aren Ezarpenak", + "backup_settings_description": "Datu-base dump-aren ezarpenak kudeatu.", + "cleared_jobs": "Garbitutako lanak honentzak: {job}", + "config_set_by_file": "Konfigurazioa konfigurazio-fitxategi baten bidez dago ezarria", "confirm_delete_library": "Seguru zaude {library} ezabatu nahi duzula?", "confirm_email_below": "Konfirmatzeko, idatzi \"{email}\" azpian", "confirm_reprocess_all_faces": "Seguru zaude aurpegi guztiak berriro prozesatu nahi dituzula? Erabakiak jendearen izenak ere borratuko ditu.", "confirm_user_password_reset": "Seguru zaude {user}-ren pasahitza berrezarri nahi duzula?", "confirm_user_pin_code_reset": "Seguru zaude {user}-ren PIN kodea berrezarri nahi duzula?", + "copy_config_to_clipboard_description": "Kopiatu momentuko sistema-konfigurazioa JSON objetu formatuan arbelean", "create_job": "Gehitu zeregina", + "cron_expression": "Cron adierazpena", + "cron_expression_description": "Ezarri eskaneatzeko tartea cron formatua erabiliz. Informazio gehiago lortzeko, jo mesedez Crontab Guru adibidera", + "cron_expression_presets": "Cron adierazpenaren aurrezarpenak", "disable_login": "Desgaitu saio hastea", + "duplicate_detection_job_description": "Exekutatu ikasketa automatikoa aktiboetan antzeko irudiak detektatzeko. Bilaketa Adimendunean oinarritzen da", + "export_config_as_json_description": "Deskargatu momentuko sistema konfigurazioa JSON fitxategi moduan", + "external_libraries_page_description": "Administratzailearen kanpo liburutegi orrialdea", "face_detection": "Aurpegi detekzioa", "failed_job_command": "{command} komandoak hutsegin du {job} zereginerako", "image_format": "Formatua", "image_format_description": "WebP ereduak JPEG baino fitxategi txikiagoak sortzen ditu, baina motelagoa da kodifikatzen.", + "image_prefer_embedded_preview": "Nahiago aurrebista txertatua", + "image_prefer_wide_gamut": "Nahiago gamut zabala", "image_preview_title": "Aurreikusiaen Konfigurazioa", + "image_progressive": "Progresiboa", "image_quality": "Kalitatea", "image_resolution": "Erresoluzioa", "image_settings": "Argazkien Konfigurazioa", + "image_settings_description": "Kudeatu sortutako irudien kalitatea eta erresoluzioa", "image_thumbnail_title": "Argazki Txikien Konfigurazioa", + "import_config_from_json_description": "Inportatu sistema konfigurazioa JSON konfigurazio fitxategia kargatuz", + "job_concurrency": "{job} konkurrentzia", "job_created": "Zeregina sortuta", "job_settings": "Zereginaren konfigurazioa", + "job_settings_description": "Kudeatu lanen konkurrentzia", + "jobs_over_time": "Lanak denboran zehar", + "library_created": "Sortutako liburutegia: {library}", + "library_deleted": "Liburutegia ezabatuta", + "library_details": "Liburutegiaren xehetasunak", + "library_remove_folder_prompt": "Ziur zaude inportazio karpeta hau ezabatu nahi duzula?", "logging_enable_description": "Gaitu erregistroak", "logging_level_description": "Erregistroak gaituta daudenean, nolako erregistro maila erabili.", "logging_settings": "Erregistroak", diff --git a/i18n/fa.json b/i18n/fa.json index e7d681d92f..0a29a09d83 100644 --- a/i18n/fa.json +++ b/i18n/fa.json @@ -5,6 +5,7 @@ "acknowledge": "Ų…ØĒ؈ØŦŲ‡ Ø´Ø¯Ų…", "action": "ØšŲ…Ų„ÚŠØąØ¯", "action_common_update": "Ø¨Ų‡â€Œ ØąŲˆØ˛â€ŒØąØŗØ§Ų†ÛŒ", + "action_description": "ØĒؚدادی ØšŲ…Ų„ÛŒØ§ØĒ Ø¨ØąØ§ÛŒ Ø§Ų†ØŦØ§Ų… ØąŲˆÛŒ Ø¯Ø§Ø¯Ų‡â€ŒŲ‡Ø§ÛŒ ŲÛŒŲ„ØĒØą Ø´Ø¯Ų‡", "actions": "ØšŲ…Ų„ÚŠØąØ¯", "active": "ŲØšØ§Ų„", "active_count": "ŲØšØ§Ų„: {count}", @@ -14,8 +15,14 @@ "add_a_location": "Ø§ŲØ˛ŲˆØ¯Ų† یڊ Ų…ÚŠØ§Ų†", "add_a_name": "Ø§ŲØ˛ŲˆØ¯Ų† Ų†Ø§Ų…", "add_a_title": "Ø§ŲØ˛ŲˆØ¯Ų† ØšŲ†ŲˆØ§Ų†", + "add_action": "Ø§ŲØ˛ŲˆØ¯Ų† ØšŲ…Ų„ÛŒØ§ØĒ", + "add_action_description": "Ø¨ØąØ§ÛŒ Ø§ŲØ˛ŲˆØ¯Ų† ؈ Ø§ØšŲ…Ø§Ų„ یڊ ØšŲ…Ų„ÛŒØ§ØĒ ÚŠŲ„ÛŒÚŠ ÚŠŲ†ÛŒØ¯", + "add_assets": "Ø§ŲØ˛ŲˆØ¯Ų† ØšÚŠØŗ یا ŲÛŒŲ„Ų…", "add_birthday": "Ø§ŲØ˛ŲˆØ¯Ų† ØĒØ§ØąÛŒØŽ ØĒŲˆŲ„Ø¯", + "add_endpoint": "Ø§ŲØ˛ŲˆØ¯Ų† ŲžØ§ÛŒØ§Ų†Ų‡", "add_exclusion_pattern": "Ø§ŲØ˛ŲˆØ¯Ų† Ø§Ų„Ú¯ŲˆÛŒ Ø§ØŗØĒØĢŲ†Ø§", + "add_filter": "Ø§ŲØ˛ŲˆØ¯Ų† ŲÛŒŲ„ØĒØą", + "add_filter_description": "Ø¨ØąØ§ÛŒ Ø§ŲØ˛ŲˆØ¯Ų† یڊ Ø´ØąØˇ ŲÛŒŲ„ØĒØą ÚŠŲ„ÛŒÚŠ ÚŠŲ†ÛŒØ¯", "add_location": "Ø§ŲØ˛ŲˆØ¯Ų† Ų…ÚŠØ§Ų†", "add_more_users": "Ø§ŲØ˛ŲˆØ¯Ų† ÚŠØ§ØąØ¨ØąŲ‡Ø§ÛŒ بیشØĒØą", "add_partner": "Ø§ŲØ˛ŲˆØ¯Ų† Ø´ØąÛŒÚŠ", @@ -27,25 +34,38 @@ "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_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", + "add_workflow_step": "Ø§ŲØ˛ŲˆØ¯Ų† یڊ Ų…ØąØ­Ų„Ų‡ Ø¨Ų‡ ØąŲˆŲ†Ø¯ ÚŠØ§Øą", "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": "Ø§Ø¯Ų…ÛŒŲ†", + "asset_offline_description": "Ø§ÛŒŲ† ÚŠØĒØ§Ø¨ØŽØ§Ų†Ų‡ Ø¯Ø§Ø¯Ų‡â€ŒÛŒ Ø¨ÛŒØąŲˆŲ†ÛŒ ØąŲˆÛŒ Ų…Ø­Ų„ Ø°ØŽÛŒØąŲ‡â€ŒØŗØ§Ø˛ÛŒ ŲžÛŒØ¯Ø§ Ų†Ø´Ø¯ ؈ Ø¨Ų‡ ØŗØˇŲ„ ØĸØ´ØēŲ„ Ų…Ų†ØĒŲ‚Ų„ شد. Ø§Ú¯Øą ŲØ§ÛŒŲ„ Ų…ŲˆØąØ¯ Ų†Ø¸Øą Ø¯Øą Ø¯Ø§ØŽŲ„ ÚŠØĒØ§Ø¨ØŽØ§Ų†Ų‡ ØŦابØŦØ§Ø¯Ų‡ Ø´Ø¯Ų‡ØŒ ØĒØ§ÛŒŲ…Ų„Ø§ÛŒŲ† ØŽŲˆØ¯ ØąØ§ Ø¨ØąØ§ÛŒ Ø¯Ø§Ø¯Ų‡â€ŒÛŒ ØŦدید چک ÚŠŲ†ÛŒØ¯. Ø¨ØąØ§ÛŒ Ø¨Ø§Ø˛ÛŒØ§Ø¨ÛŒ Ø§ÛŒŲ† Ø¯Ø§Ø¯Ų‡ Ų„ØˇŲØ§ Ų…ØˇŲ…ØĻŲ† Ø´ŲˆÛŒØ¯ ÚŠŲ‡ Ų…ØŗÛŒØą ŲØ§ÛŒŲ„ Ø˛ÛŒØą ØĒŲˆØŗØˇ Immich Ų‚Ø§Ø¨Ų„ Ø¯ØŗØĒØąØŗ Ø§ØŗØĒ ØŗŲžØŗ ÚŠØĒØ§Ø¨ØŽØ§Ų†Ų‡ ØąØ§ Ø§ØŗÚŠŲ† ÚŠŲ†ÛŒØ¯.", "authentication_settings": "ØĒŲ†Ø¸ÛŒŲ…Ø§ØĒ Ø§Ø­ØąØ§Ø˛ Ų‡ŲˆÛŒØĒ", "authentication_settings_description": "Ų…Ø¯ÛŒØąÛŒØĒ ØąŲ…Ø˛ ØšØ¨ŲˆØąØŒ OAuth، ؈ ØŗØ§ÛŒØą ØĒŲ†Ø¸ÛŒŲ…Ø§ØĒ Ø§Ø­ØąØ§Ø˛ Ų‡ŲˆÛŒØĒ", "authentication_settings_disable_all": "Øĸیا Ų…ØˇŲ…ØĻŲ† Ų‡ØŗØĒید ÚŠŲ‡ Ų…ÛŒâ€ŒØŽŲˆØ§Ų‡ÛŒØ¯ ØĒŲ…Ø§Ų… ØąŲˆØ´â€ŒŲ‡Ø§ÛŒ ŲˆØąŲˆØ¯ ØąØ§ ØēÛŒØąŲØšØ§Ų„ ÚŠŲ†ÛŒØ¯ØŸ ŲˆØąŲˆØ¯ Ø¨Ų‡ ØˇŲˆØą ÚŠØ§Ų…Ų„ ØēÛŒØąŲØšØ§Ų„ ØŽŲˆØ§Ų‡Ø¯ شد.", "authentication_settings_reenable": "Ø¨ØąØ§ÛŒ ŲØšØ§Ų„ ØŗØ§Ø˛ÛŒ Ų…ØŦدد Ø§Ø˛ Ø¯ØŗØĒŲˆØą ØŗØąŲˆØą Ø§ØŗØĒŲØ§Ø¯Ų‡ ÚŠŲ†ÛŒØ¯.", "background_task_job": "ŲˆØ¸Ø§ÛŒŲ ŲžØŗâ€ŒØ˛Ų…ÛŒŲ†Ų‡", + "backup_database": "اØļØ§ŲŲ‡ ÚŠØąØ¯Ų† یڊ Ų†ØŗØŽŲ‡ ÚŠŲžÛŒ Ø§Ø˛ دیØĒØ§Ø¨ÛŒØŗ", + "backup_database_enable_description": "ŲØšØ§Ų„ ÚŠØąØ¯Ų† ÚŠŲžÛŒ Ø§Ø˛ دیØĒØ§Ø¨ÛŒØŗ", + "backup_keep_last_amount": "ØĒؚداد ÚŠŲžÛŒâ€ŒŲ‡Ø§ÛŒ Ų‚Ø¨Ų„ÛŒ Ø¨ØąØ§ÛŒ Ų†Ú¯Ų‡ داشØĒŲ†", + "backup_onboarding_1_description": "ÚŠŲžÛŒ ØŽØ§ØąØŦی ØąŲˆÛŒ ؁Øļای Ø§Ø¨ØąÛŒ یا یڊ Ų…Ø­Ų„ ŲÛŒØ˛ÛŒÚŠÛŒ Ø¯ÛŒÚ¯Øą.", + "backup_onboarding_2_description": "ÚŠŲžÛŒâ€ŒŲ‡Ø§ÛŒ Ų…Ø­Ų„ÛŒ ØąŲˆÛŒ Ø¯ØŗØĒÚ¯Ø§Ų‡â€ŒŲ‡Ø§ÛŒ Ø¯ÛŒÚ¯Øą. Ø§ÛŒŲ† Ø´Ø§Ų…Ų„ ŲØ§ÛŒŲ„â€ŒŲ‡Ø§ÛŒ اØĩŲ„ÛŒ ؈ ŲžØ´ØĒÛŒØ¨Ø§Ų†â€ŒŲ‡Ø§ÛŒ Ų…Ø­Ų„ÛŒ Ø§Ø˛ ØĸŲ† ŲØ§ÛŒŲ„â€ŒŲ‡Ø§ Ų…ÛŒâ€ŒØ¨Ø§Ø´Ø¯.", + "backup_onboarding_3_description": "Ų…ØŦŲ…ŲˆØš ÚŠŲžÛŒâ€ŒŲ‡Ø§ÛŒ Ø¯Ø§Ø¯Ų‡â€ŒŲ‡Ø§ÛŒ Ø´Ų…Ø§ØŒ Ø¨Ų‡ Ų‡Ų…ØąØ§Ų‡ ŲØ§ÛŒŲ„â€ŒŲ‡Ø§ÛŒ اØĩŲ„ÛŒ. Ø§ÛŒŲ† Ø´Ø§Ų…Ų„ Ûą ÚŠŲžÛŒ ØŽØ§ØąØŦی ؈ Û˛ ÚŠŲžÛŒ Ų…Ø­Ų„ÛŒ Ų…ÛŒâ€ŒØ¨Ø§Ø´Ø¯.", + "backup_onboarding_description": "Ø¨ØąØ§ÛŒ Ø­ŲØ§Ø¸ØĒ Ø§Ø˛ Ø§ØˇŲ„Ø§ØšØ§ØĒ Ø´Ų…Ø§ یڊ ØąŲˆØ´ ŲžØ´ØĒÛŒØ¨Ø§Ų†ÛŒ Ûŗ-Û˛-Ûą ŲžÛŒØ´Ų†Ų‡Ø§Ø¯ Ų…ÛŒâ€ŒØ´ŲˆØ¯. Ø¨ØąØ§ÛŒ یڊ ŲžØ´ØĒÛŒØ¨Ø§Ų†ÛŒ ØŦØ§Ų…ØšØŒ Ø´Ų…Ø§ باید ÚŠŲžÛŒâ€ŒŲ‡Ø§ÛŒÛŒ Ø§Ø˛ ØšÚŠØŗâ€ŒŲ‡Ø§/ŲˆÛŒØ¯ÛŒŲˆŲ‡Ø§ÛŒ ØĸŲžŲ„ŲˆØ¯ Ø´Ø¯Ų‡ ØŽŲˆØ¯ Ø¨Ų‡ Ų‡Ų…ØąØ§Ų‡ دیØĒØ§Ø¨ÛŒØŗ Immich Ų†Ú¯Ų‡ Ø¯Ø§ØąÛŒØ¯.", "backup_onboarding_footer": "Ø¨ØąØ§ÛŒ Ø§ØˇŲ„Ø§ØšØ§ØĒ بیشØĒØą Ø¯ØąØ¨Ø§ØąŲ‡ بڊ ØĸŲž Ú¯ÛŒØąÛŒ Ø§Ø˛ Immich، Ų„ØˇŲØ§ Ø¨Ų‡ Ų…ØŗØĒŲ†Ø¯Ø§ØĒ Ų…ØąØ§ØŦØšŲ‡ ÚŠŲ†ÛŒØ¯.", + "backup_onboarding_parts_title": "ØąŲˆØ´ ŲžØ´ØĒÛŒØ¨Ø§Ų†ÛŒ Ûŗ-Û˛-Ûą Ø´Ø§Ų…Ų„:", "backup_onboarding_title": "بڊ ØĸŲž Ų‡Ø§", + "backup_settings": "ØĒŲ†Ø¸ÛŒŲ…Ø§ØĒ ÚŠŲžÛŒâ€ŒØ¨ØąØ¯Ø§ØąÛŒ Ø§Ø˛ دیØĒØ§Ø¨ÛŒØŗ", + "backup_settings_description": "Ų…Ø¯ÛŒØąÛŒØĒ ØĒŲ†Ø¸ÛŒŲ…Ø§ØĒ ÚŠŲžÛŒâ€ŒØ¨ØąØ¯Ø§ØąØ¨ÛŒ Ø§Ø˛ دیØĒØ§Ø¨ÛŒØŗ.", "cleared_jobs": "ŲˆØ¸Ø§ÛŒŲ ŲžØ§ÚŠ Ø´Ø¯Ų‡ Ø¨ØąØ§ÛŒ:{job}", "config_set_by_file": "ØĒŲ†Ø¸ÛŒŲ… ŲØšŲ„ÛŒ ØĒŲˆØŗØˇ یڊ ŲØ§ÛŒŲ„ ŲžÛŒÚŠØąØ¨Ų†Ø¯ÛŒ Ø§Ų†ØŦØ§Ų… Ø´Ø¯Ų‡ Ø§ØŗØĒ", "confirm_delete_library": "Øĸیا Ų…ØˇŲ…ØĻŲ† Ų‡ØŗØĒید ÚŠŲ‡ Ų…ÛŒâ€ŒØŽŲˆØ§Ų‡ÛŒØ¯ ÚŠØĒØ§Ø¨ØŽØ§Ų†Ų‡ {library} ØąØ§ Ø­Ø°Ų ÚŠŲ†ÛŒØ¯ØŸ", @@ -365,7 +385,7 @@ "user_successfully_removed": "ÚŠØ§ØąØ¨Øą {email} با Ų…ŲˆŲŲ‚ÛŒØĒ Ø­Ø°Ų شد.", "users_page_description": "ØĩŲØ­Ų‡ Ų…Ø¯ÛŒØąÛŒØĒ ÚŠØ§ØąØ¨ØąØ§Ų†", "version_check_enabled_description": "ŲØšØ§Ų„â€ŒØŗØ§Ø˛ÛŒ Ø¨ØąØąØŗÛŒ Ų†ØŗØŽŲ‡", - "version_check_implications": "ŲˆÛŒÚ˜Ú¯ÛŒ Ø¨ØąØąØŗÛŒ Ų†ØŗØŽŲ‡ Ø¨Ų‡ Ø§ØąØĒØ¨Ø§Øˇ Ø¯ŲˆØąŲ‡ ای با github.com Ų…ØĒÚŠÛŒ Ø§ØŗØĒ", + "version_check_implications": "ŲˆÛŒÚ˜Ú¯ÛŒ Ø¨ØąØąØŗÛŒ Ų†ØŗØŽŲ‡ Ø¨Ų‡ Ø§ØąØĒØ¨Ø§Øˇ Ø¯ŲˆØąŲ‡ ای با {server} Ų…ØĒÚŠÛŒ Ø§ØŗØĒ", "version_check_settings": "Ø¨ØąØąØŗÛŒ Ų†ØŗØŽŲ‡", "version_check_settings_description": "ŲØšØ§Ų„ یا ØēÛŒØąŲØšØ§Ų„ ÚŠØąØ¯Ų† Ø§ØšŲ„Ø§Ų† Ų†ØŗØŽŲ‡ ØŦدید", "video_conversion_job": "ØĒØ¨Ø¯ÛŒŲ„ (ØąŲ…Ø˛Ú¯Ø°Ø§ØąÛŒ) ŲˆÛŒØ¯ÛŒŲˆŲ‡Ø§", diff --git a/i18n/fi.json b/i18n/fi.json index 084540324a..aaa2ee2bc1 100644 --- a/i18n/fi.json +++ b/i18n/fi.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Käyttäjä {email} on poistettu onnistuneesti.", "users_page_description": "Ylläpitäjän käyttäjien lista", "version_check_enabled_description": "Ota käyttÃļÃļn versiotarkastus", - "version_check_implications": "Versiotarkistus vaatii säännÃļllisen yhteyden github.comiin", + "version_check_implications": "Versiotarkistus vaatii säännÃļllisen yhteyden {server}iin", "version_check_settings": "Versiotarkistus", "version_check_settings_description": "Ota käyttÃļÃļn ilmoitukset, kun uusi versio on saatavilla", "video_conversion_job": "Transkoodaa videot", @@ -849,9 +849,12 @@ "create_link_to_share": "Luo linkki jaettavaksi", "create_link_to_share_description": "Salli kaikkien linkin saaneiden nähdä valitut kuvat", "create_new": "LUO UUSI", + "create_new_face": "Luo uudet kasvot", "create_new_person": "Luo uusi henkilÃļ", "create_new_person_hint": "Määritä valitut mediat uudelle henkilÃļlle", "create_new_user": "Luo uusi käyttäjä", + "create_person": "Luo henkilÃļ", + "create_person_subtitle": "Lisää nimi valituille kasvoille luodaksesi uudelle henkilÃļlle tunnisteen", "create_shared_album_page_share_add_assets": "LISÄÄ KOHTEITA", "create_shared_album_page_share_select_photos": "Valitse kuvat", "create_shared_link": "Luo jakolinkki", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Kiinteä", "crop_aspect_ratio_free": "Vapaa", "crop_aspect_ratio_original": "Alkuperäinen", + "crop_aspect_ratio_square": "NeliÃļ", "curated_object_page_title": "Asiat", "current_device": "Nykyinen laite", "current_pin_code": "Nykyinen PIN-koodi", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Tumma", - "dark_theme": "Vaihda tumma teema", + "dark_theme": "Vaihda tummaan teemaan", "date": "Päivämäärä", "date_after": "Päivämäärän jälkeen", "date_and_time": "Päivämäärä ja aika", @@ -891,10 +895,8 @@ "day": "Päivä", "days": "Päivää", "deduplicate_all": "Poista kaikkien kaksoiskappaleet", - "deduplication_criteria_1": "Kuvan koko tavuina", - "deduplication_criteria_2": "EXIF-datan määrä", - "deduplication_info": "Deduplikaatiotieto", - "deduplication_info_description": "Jotta voimme automaattisesti esivalita aineistot ja poistaa kaksoiskappaleet suurina erinä, tarkastelemme:", + "default_locale": "Oletuskieli", + "default_locale_description": "Muotoile päivämäärät ja luvut selaimesi kieliasetusten mukaan", "delete": "Poista", "delete_action_confirmation_message": "Haluatko varmasti poistaa tämän aineiston? Tämä toiminto siirtää aineiston palvelimen roskakoriin ja kysyy, haluatko poistaa sen myÃļs paikallisesti", "delete_action_prompt": "{count} poistettu", @@ -970,7 +972,7 @@ "downloading_media": "Median lataaminen", "drop_files_to_upload": "Pudota tiedostot mihin tahansa ladataksesi ne", "duplicates": "Kaksoiskappaleet", - "duplicates_description": "Selvitä jokaisen kohdalla mitkä (jos mitkään) ovat kaksoiskappaleita", + "duplicates_description": "Selvitä jokaisen kohdalla mitkä (jos mitkään) ovat kaksoiskappaleita.", "duration": "Kesto", "edit": "Muokkaa", "edit_album": "Muokkaa albumia", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Muutokset otettu käyttÃļÃļn", "editor_flip_horizontal": "Käännä vaakatasossa", "editor_flip_vertical": "Käännä pystytasossa", + "editor_handle_corner": "{corner, select, top_left {Vasen yläkulma} top_right {Oikea yläkulma} bottom_left {Vasen alakulma} bottom_right {Oikea alakulma} other {A}} kulman kahva", + "editor_handle_edge": "{edge, select, top {Yläreuna} bottom {Alareuna} left {Vasen reuna} right {Oikea reuna} other {En}} reunan kahva", "editor_orientation": "Suunta", "editor_reset_all_changes": "Nollaa muutokset", "editor_rotate_left": "Kierrä 90° vastapäivään", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Albumin otsikko", "licenses": "Lisenssit", "light": "Vaalea", + "light_theme": "Vaihda vaaleaan teemaan", "like": "Tykkää", "like_deleted": "Tykkäys poistettu", "link_motion_video": "Linkitä liikevideo", + "link_to_docs": "Lisätietoja lÃļytyy dokumentaatiosta.", "link_to_oauth": "Linkki OAuth", "linked_oauth_account": "Linkitetty OAuth-tili", "list": "Lista", @@ -2211,6 +2217,7 @@ "tag": "Tunniste", "tag_assets": "Lisää tunnisteita", "tag_created": "Luotu tunniste: {tag}", + "tag_face": "Merkitse kasvot", "tag_feature_description": "Selaa valokuvia ja videoita, jotka on ryhmitelty loogisten tunnisteotsikoiden mukaan", "tag_not_found_question": "EtkÃļ lÃļydä tunnistetta? Luo uusi tunniste.", "tag_people": "Merkitse henkilÃļ tunnisteella", @@ -2392,6 +2399,7 @@ "viewer_remove_from_stack": "Poista pinosta", "viewer_stack_use_as_main_asset": "Käytä pääkohteena", "viewer_unstack": "Pura pino", + "visibility": "Näkyvyys", "visibility_changed": "{count, plural, one {# henkilÃļn} other {# henkilÃļiden}} näkyvyys vaihdettu", "visual": "Visuaalinen", "visual_builder": "Visuaalinen koostaja", diff --git a/i18n/fr.json b/i18n/fr.json index ddbbe1dd13..f15931b0d6 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -441,7 +441,7 @@ "user_successfully_removed": "L'utilisateur {email} a ÊtÊ supprimÊ avec succès.", "users_page_description": "Page d'administration des utilisateurs", "version_check_enabled_description": "Activer la vÊrification pÊriodique de nouvelle version", - "version_check_implications": "Le contrôle de version repose sur une communication pÊriodique avec github.com", + "version_check_implications": "Le contrôle de version repose sur une communication pÊriodique avec {server}", "version_check_settings": "VÊrification de la version", "version_check_settings_description": "GÊrer la vÊrification de nouvelle version d'Immich", "video_conversion_job": "Transcodage des vidÊos", @@ -849,9 +849,12 @@ "create_link_to_share": "CrÊer un lien pour partager", "create_link_to_share_description": "Permettre à n'importe qui ayant le lien de voir la(es) photo(s) sÊlectionnÊe(s)", "create_new": "NOUVEAU", + "create_new_face": "CrÊer un nouveau visage", "create_new_person": "CrÊer une nouvelle personne", "create_new_person_hint": "Attribuer les mÊdias sÊlectionnÊs à une nouvelle personne", "create_new_user": "CrÊer un nouvel utilisateur", + "create_person": "CrÊer une personne", + "create_person_subtitle": "Ajouter un nom au visage sÊlectionnÊ pour crÊer et Êtiqueter la nouvelle personne", "create_shared_album_page_share_add_assets": "AJOUTER DES ÉLÉMENTS", "create_shared_album_page_share_select_photos": "SÊlectionner les photos", "create_shared_link": "CrÊer un lien partagÊ", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "FigÊ", "crop_aspect_ratio_free": "Libre", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "CarrÊ", "curated_object_page_title": "Objets", "current_device": "Appareil actuel", "current_pin_code": "Code PIN actuel", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Sombre", - "dark_theme": "Activer le thème sombre", + "dark_theme": "Basculer sur le thème sombre", "date": "Date", "date_after": "Date après", "date_and_time": "Date et heure", @@ -891,10 +895,8 @@ "day": "Jour", "days": "Jours", "deduplicate_all": "DÊdupliquer tout", - "deduplication_criteria_1": "Taille de l'image en octets", - "deduplication_criteria_2": "Nombre de donnÊes EXIF", - "deduplication_info": "Info de dÊduplication", - "deduplication_info_description": "Pour prÊsÊlectionner automatiquement les mÊdias et supprimer les doublons en masse, nous examinons :", + "default_locale": "Langue par dÊfaut", + "default_locale_description": "Mettre en forme les dates et nombres en fonction de la langue de votre navigateur", "delete": "Supprimer", "delete_action_confirmation_message": "Êtes-vous sÃģr de vouloir supprimer ce mÊdia ? Cela dÊplacera le mÊdia dans la poubelle du serveur et vous demandera si vous voulez le supprimer localement", "delete_action_prompt": "{count} supprimÊ(s)", @@ -970,7 +972,7 @@ "downloading_media": "TÊlÊchargement du mÊdia", "drop_files_to_upload": "DÊposez les fichiers n'importe oÚ pour envoyer", "duplicates": "Doublons", - "duplicates_description": "Examiner chaque groupe et indiquer s'il y a des doublons", + "duplicates_description": "Examiner chaque groupe et indiquer s'il y a des doublons.", "duration": "DurÊe", "edit": "Modifier", "edit_album": "Modifier l'album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Titre de l'album", "licenses": "Licences", "light": "Clair", + "light_theme": "Basculer sur le thème clair", "like": "J'aime", "like_deleted": "RÊaction ÂĢ J'aime Âģ supprimÊe", "link_motion_video": "Lier la photo animÊe", + "link_to_docs": "Pour plus d'informations, se rÊfÊrer à la documentation.", "link_to_oauth": "Lien au service OAuth", "linked_oauth_account": "Compte OAuth rattachÊ", "list": "Liste", @@ -2213,6 +2217,7 @@ "tag": "Étiquette", "tag_assets": "Étiqueter les mÊdias", "tag_created": "Étiquette crÊÊe : {tag}", + "tag_face": "Étiqueter le visage", "tag_feature_description": "Parcourir les photos et vidÊos groupÊes par thèmes logiques", "tag_not_found_question": "Vous ne trouvez pas une Êtiquette ? CrÊer une nouvelle Êtiquette.", "tag_people": "Étiqueter les personnes", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Retirer de la pile", "viewer_stack_use_as_main_asset": "Utiliser comme ÊlÊment principal", "viewer_unstack": "DÊpiler", + "visibility": "VisibilitÊ", "visibility_changed": "VisibilitÊ changÊe pour {count, plural, one {# personne} other {# personnes}}", "visual": "Visuel", "visual_builder": "Constructeur visuel", diff --git a/i18n/ga.json b/i18n/ga.json index 8cdcf03fbe..d493e3fe23 100644 --- a/i18n/ga.json +++ b/i18n/ga.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Baineadh an t-ÃēsÃĄideoir {email} go rathÃēil.", "users_page_description": "Leathanach ÃēsÃĄideoirí riarthÃŗra", "version_check_enabled_description": "Cumasaigh seiceÃĄil leagan", - "version_check_implications": "Braitheann an ghnÊ seiceÃĄla leagan ar chumarsÃĄid thrÊimhsiÃēil le github.com", + "version_check_implications": "Braitheann an ghnÊ seiceÃĄla leagan ar chumarsÃĄid thrÊimhsiÃēil le {server}", "version_check_settings": "SeiceÃĄil Leagan", "version_check_settings_description": "Cumasaigh/díchumasaigh an fÃŗgra faoin leagan nua", "video_conversion_job": "FíseÃĄin TraschÃŗdaithe", @@ -849,9 +849,12 @@ "create_link_to_share": "Cruthaigh nasc le roinnt", "create_link_to_share_description": "Lig do dhuine ar bith a bhfuil an nasc aige/aici an/na grianghraf/na grianghraif roghnaithe a fheiceÃĄil", "create_new": "CRUTHAIGH NUA", + "create_new_face": "Cruthaigh aghaidh nua", "create_new_person": "Cruthaigh duine nua", "create_new_person_hint": "Sannadh sÃŗcmhainní roghnaithe do dhuine nua", "create_new_user": "Cruthaigh ÃēsÃĄideoir nua", + "create_person": "Cruthaigh duine", + "create_person_subtitle": "Cuir ainm leis an aghaidh roghnaithe chun an duine nua a chruthÃē agus a chlibeÃĄil", "create_shared_album_page_share_add_assets": "CUIR SÓCMHAINNÍ LEIS", "create_shared_album_page_share_select_photos": "Roghnaigh Grianghraif", "create_shared_link": "Cruthaigh nasc comhroinnte", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Seasta", "crop_aspect_ratio_free": "Saor in aisce", "crop_aspect_ratio_original": "Bunaidh", + "crop_aspect_ratio_square": "CearnÃŗg", "curated_object_page_title": "Rudaí", "current_device": "GlÊas reatha", "current_pin_code": "CÃŗd PIN reatha", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Dorcha", - "dark_theme": "ScorÃĄnaigh an tÊama dorcha", + "dark_theme": "Athraigh go tÊama dorcha", "date": "DÃĄta", "date_after": "DÃĄta i ndiaidh", "date_and_time": "DÃĄta agus Am", @@ -891,10 +895,8 @@ "day": "LÃĄ", "days": "Laethanta", "deduplicate_all": "DídhÃēblaigh Gach Rud", - "deduplication_criteria_1": "MÊid na híomhÃĄ i mbÊiteanna", - "deduplication_criteria_2": "Líon sonraí EXIF", - "deduplication_info": "Eolas DídhÃēblÃĄla", - "deduplication_info_description": "Chun sÃŗcmhainní a rÊamhroghnÃē go huathoibríoch agus dÃēblaigh a bhaint i mÃŗrchÃŗir, fÊachaimid ar:", + "default_locale": "LogÃĄn RÊamhshocraithe", + "default_locale_description": "FormÃĄidigh dÃĄtaí agus uimhreacha bunaithe ar shuíomh do bhrabhsÃĄlaí", "delete": "Scrios", "delete_action_confirmation_message": "An bhfuil tÃē cinnte gur mian leat an tsÃŗcmhainn seo a scriosadh? Bogfaidh an gníomh seo an tsÃŗcmhainn go dtí bruscar an fhreastalaí agus fiafrÃŗidh sÊ díot an mian leat í a scriosadh go hÃĄitiÃēil", "delete_action_prompt": "{count} scriosta", @@ -970,7 +972,7 @@ "downloading_media": "Ag íoslÃŗdÃĄil na meÃĄn", "drop_files_to_upload": "Scaoil comhaid ÃĄit ar bith le huaslÃŗdÃĄil", "duplicates": "DÃēblaigh", - "duplicates_description": "RÊitigh gach grÃēpa trína lÊiriÃē cÊ acu de na dÃēblaigh, mÃĄs ann dÃŗibh", + "duplicates_description": "RÊitigh gach grÃēpa trína lÊiriÃē cÊ acu de na dÃēblaigh, mÃĄs ann dÃŗibh.", "duration": "Fad", "edit": "Cuir in Eagar", "edit_album": "Cuir albam in eagar", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Teideal an albaim", "licenses": "CeadÃēnais", "light": "Solas", + "light_theme": "Athraigh go tÊama Êadrom", "like": "Is maith liom", "like_deleted": "Scriosadh an rud is maith liom", "link_motion_video": "FíseÃĄn gluaiseachta nasctha", + "link_to_docs": "Le haghaidh tuilleadh eolais, fÊach ar an doicimÊadÃē.", "link_to_oauth": "Nasc le OAuth", "linked_oauth_account": "Cuntas OAuth nasctha", "list": "Liosta", @@ -2213,6 +2217,7 @@ "tag": "Clib", "tag_assets": "SÃŗcmhainní clibe", "tag_created": "Clib cruthaithe: {tag}", + "tag_face": "Aghaidh clibe", "tag_feature_description": "Ag brabhsÃĄil grianghraif agus físeÃĄin grÃēpÃĄilte de rÊir topaicí clibeanna loighciÃēla", "tag_not_found_question": "Ní fÊidir clib a aimsiÃē? Cruthaigh clib nua.", "tag_people": "Daoine a ChlibeÃĄil", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Bain den Chruach", "viewer_stack_use_as_main_asset": "ÚsÃĄid mar PhríomhshÃŗcmhainn", "viewer_unstack": "Dí-Chruach", + "visibility": "Infheictheacht", "visibility_changed": "Athraíodh infheictheacht do {count, plural, one {# duine} other {# daoine}}", "visual": "Amhairc", "visual_builder": "TÃŗgÃĄlaí amhairc", diff --git a/i18n/gl.json b/i18n/gl.json index 63faaec9a8..201f718998 100644 --- a/i18n/gl.json +++ b/i18n/gl.json @@ -441,7 +441,7 @@ "user_successfully_removed": "O usuario {email} foi eliminado satisfactoriamente.", "users_page_description": "PÃĄxina de usuarios administradores", "version_check_enabled_description": "Activar comprobaciÃŗn de versiÃŗn", - "version_check_implications": "A funciÃŗn de comprobaciÃŗn de versiÃŗn depende da comunicaciÃŗn periÃŗdica con github.com", + "version_check_implications": "A funciÃŗn de comprobaciÃŗn de versiÃŗn depende da comunicaciÃŗn periÃŗdica con {server}", "version_check_settings": "ComprobaciÃŗn de VersiÃŗn", "version_check_settings_description": "Activar/desactivar a notificaciÃŗn de nova versiÃŗn", "video_conversion_job": "Transcodificar vídeos", @@ -849,9 +849,12 @@ "create_link_to_share": "Crear ligazÃŗn para compartir", "create_link_to_share_description": "Permitir que calquera persoa coa ligazÃŗn vexa a(s) foto(s) seleccionada(s)", "create_new": "CREAR NOVO", + "create_new_face": "Crear nova cara", "create_new_person": "Crear nova persoa", "create_new_person_hint": "Asignar activos seleccionados a unha nova persoa", "create_new_user": "Crear novo usuario", + "create_person": "Crear persona", + "create_person_subtitle": "Engade un nome ÃĄ cara seleccionada para crear e etiquetar ÃĄ nova persona", "create_shared_album_page_share_add_assets": "ENGADIR ACTIVOS", "create_shared_album_page_share_select_photos": "Seleccionar Fotos", "create_shared_link": "Crear ligazÃŗn compartida", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixado", "crop_aspect_ratio_free": "Libre", "crop_aspect_ratio_original": "Orixinal", + "crop_aspect_ratio_square": "Cadrado", "curated_object_page_title": "Cousas", "current_device": "Dispositivo actual", "current_pin_code": "CÃŗdigo PIN actual", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Escuro", - "dark_theme": "Alternar tema escuro", + "dark_theme": "Alternar a tema escuro", "date": "Data", "date_after": "Data posterior a", "date_and_time": "Data e Hora", @@ -891,10 +895,8 @@ "day": "Día", "days": "Días", "deduplicate_all": "Eliminar todos os duplicados", - "deduplication_criteria_1": "TamaÃąo da imaxe en bytes", - "deduplication_criteria_2": "Reconto de datos EXIF", - "deduplication_info": "InformaciÃŗn de DeduplicaciÃŗn", - "deduplication_info_description": "Para preseleccionar automaticamente activos e eliminar duplicados masivamente, miramos:", + "default_locale": "ConfiguraciÃŗn rexional predeterminada", + "default_locale_description": "Formatee as datas e os nÃēmeros segÃēn a configuraciÃŗn rexional do seu navegador", "delete": "Eliminar", "delete_action_confirmation_message": "EstÃĄ seguro de que quere eliminar este ficheiro? Esta acciÃŗn moverÃĄ o ficheiro ao lixo do servidor e preguntaralle se tamÊn quere eliminalo localmente", "delete_action_prompt": "{count} eliminado(s)", @@ -970,7 +972,7 @@ "downloading_media": "Descargando medios", "drop_files_to_upload": "Solte ficheiros en calquera lugar para cargar", "duplicates": "Duplicados", - "duplicates_description": "Resolve cada grupo indicando cales, se os houber, son duplicados", + "duplicates_description": "Resolve cada grupo indicando cales, se os houber, son duplicados.", "duration": "DuraciÃŗn", "edit": "Editar", "edit_album": "Editar ÃĄlbum", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Título do ÃĄlbum", "licenses": "Licenzas", "light": "Claro", + "light_theme": "Cambiar a tema claro", "like": "GÃēstame", "like_deleted": "GÃēstame eliminado", "link_motion_video": "Ligar vídeo en movemento", + "link_to_docs": "Para mÃĄis informaciÃŗn, consulte a documentaciÃŗn.", "link_to_oauth": "Ligar a OAuth", "linked_oauth_account": "Conta OAuth ligada", "list": "Lista", @@ -2213,6 +2217,7 @@ "tag": "Etiqueta", "tag_assets": "Etiquetar activos", "tag_created": "Etiqueta creada: {tag}", + "tag_face": "Etiquetar cara", "tag_feature_description": "Navegar por fotos e vídeos agrupados por temas de etiquetas lÃŗxicas", "tag_not_found_question": "Non atopa unha etiqueta? Crear unha nova etiqueta.", "tag_people": "Etiquetar Persoas", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Eliminar da Pila", "viewer_stack_use_as_main_asset": "Usar como Activo Principal", "viewer_unstack": "Desapilar", + "visibility": "Visibilidade", "visibility_changed": "Visibilidade cambiada para {count, plural, one {# persoa} other {# persoas}}", "visual": "Visual", "visual_builder": "Construtor visual", diff --git a/i18n/gsw.json b/i18n/gsw.json index bad2816ad9..7893ea1482 100644 --- a/i18n/gsw.json +++ b/i18n/gsw.json @@ -422,7 +422,7 @@ "user_successfully_removed": "Dr Benutzer {email} isch erfolgrich entfernt worde.", "users_page_description": "Administrator-Benutzersiite", "version_check_enabled_description": "VersionsprÃŧefig akivierä", - "version_check_implications": "D’Funktion zur VersionsprÃŧefig basiert uf regelmässiger Kommunikazion mit GitHub.com", + "version_check_implications": "D’Funktion zur VersionsprÃŧefig basiert uf regelmässiger Kommunikazion mit {server}", "version_check_settings": "VersionsprÃŧefig", "version_check_settings_description": "Aktiviere/Deaktivier d’Benochrichtigung Ãŧber neui Versione", "video_conversion_job": "Videos transkodiere", @@ -835,10 +835,6 @@ "day": "Tag", "days": "Täg", "deduplicate_all": "Alli Duplikate entfernä", - "deduplication_criteria_1": "BildgrÃļssi in Bytes", - "deduplication_criteria_2": "Anzahl vo de EXIF Date", - "deduplication_info": "Deduplizierungsinformatione", - "deduplication_info_description": "FÃŧr d’automatischi Datei-Voruswahl und s’Dedupliziere vo allne Dateie berÃŧcksichtige mir:", "delete": "LÃļsche", "delete_action_confirmation_message": "Bisch du sicher, dass du dies Objekt lÃļsche wotsch? Die Aktion verschiebt s’Objekt i de Papirkorb vom Server und fragt dich, ob du’s lokal lÃļÃļsche wotsch", "delete_action_prompt": "{count} glÃļscht", diff --git a/i18n/he.json b/i18n/he.json index 629f8166cb..3169c356ec 100644 --- a/i18n/he.json +++ b/i18n/he.json @@ -20,7 +20,7 @@ "add_action_description": "לח×Ĩ כדי ×œ×”×•×Ą×™×Ŗ פ×ĸולה לבי×Ļו×ĸ", "add_assets": "×”×•×Ą×Ŗ ×Ēמונו×Ē", "add_birthday": "הוספ×Ē ×™×•× הולד×Ē", - "add_endpoint": "×”×•×Ą×Ŗ כ×Ēוב×Ē URL", + "add_endpoint": "הוספ×Ē ×›×Ēוב×Ē ×§×Ļה", "add_exclusion_pattern": "הוספ×Ē ×“×¤×•×Ą החרגה", "add_filter": "×”×•×Ą×Ŗ סינון", "add_filter_description": "לח×Ĩ כדי ×œ×”×•×Ą×™×Ŗ ×Ēנאי לסינון", @@ -53,7 +53,7 @@ "authentication_settings": "הגדרו×Ē ×”×Ēחברו×Ē", "authentication_settings_description": "ניהול סיסמה, OAuth, והגדרו×Ē ×”×Ēחברו×Ē ××—×¨×•×Ē", "authentication_settings_disable_all": "האם בר×Ļונך להשבי×Ē ××Ē ×›×œ שיטו×Ē ×”×”×Ēחברו×Ē? כניסה למ×ĸרכ×Ē ×Ēהיה מושב×Ē×Ē ×œ×—×œ×•×˜×™×Ÿ.", - "authentication_settings_reenable": "כדי לאפשר מחדש, יש להש×Ēמ׊ בפקוד×Ē ×Š×¨×Ē.", + "authentication_settings_reenable": "כדי לאפשר מחדש, יש להש×Ēמ׊ בפקוד×Ē ×Š×¨×Ē.", "background_task_job": "משימו×Ē ×¨×§×ĸ", "backup_database": "גיבוי מסד × ×Ēונים", "backup_database_enable_description": "אפ׊ר גיבויי מסד × ×Ēונים", @@ -62,7 +62,7 @@ "backup_onboarding_2_description": "ה×ĸ×Ēקים מקומיים במכשירים שונים. זה כולל א×Ē ×”×§×‘×Ļים הראשיים וגיבוי של הקב×Ļים האלה באופן מקומי.", "backup_onboarding_3_description": "סך כל הה×ĸ×Ēקים של הנ×Ēונים שלך, כולל הקב×Ļים המקוריים. זה כולל ה×ĸ×Ē×§ אחד מחו×Ĩ למקום השר×Ē ×•×Š× ×™ ה×ĸ×Ēקים מקומיים.", "backup_onboarding_description": "אסטרטגיי×Ē ×’×™×‘×•×™ 3-2-1 הינה מומל×Ļ×Ē ×ĸל מנ×Ē ×œ×”×’×Ÿ ×ĸל הנ×Ēונים שלך. ×ĸליך להשאיר ה×ĸ×Ēקים של ×Ēמונו×Ē/סרטונים שהו×ĸלו כמו גם א×Ē ×ž×Ą×“ הנ×Ēונים של Immich ×ĸבור פ×Ēרון גיבוי ×ž×§×™×Ŗ.", - "backup_onboarding_footer": "×ĸבור מיד×ĸ × ×•×Ą×Ŗ ×ĸל גיבוי Immich, נא לפנו×Ē ××œ ה×Ēי×ĸוד.", + "backup_onboarding_footer": "×ĸבור מיד×ĸ × ×•×Ą×Ŗ ×ĸל גיבוי Immich, נא לפנו×Ē ××œ ה×Ēי×ĸוד.", "backup_onboarding_parts_title": "גיבוי 3-2-1 כולל:", "backup_onboarding_title": "גיבויים", "backup_settings": "הגדרו×Ē ×’×™×‘×•×™", @@ -281,7 +281,7 @@ "oauth_role_claim_description": "ה×ĸ× ×§ גיש×Ē ×ž× ×”×œ באופן אוטומטי אם ×Ēבי×ĸה זו קיימ×Ē. ×ĸרך ה×Ēבי×ĸה יכול להיו×Ē 'user' או 'admin'.", "oauth_settings": "OAuth", "oauth_settings_description": "ניהול הגדרו×Ē ×”×Ēחברו×Ē ×ĸם OAuth", - "oauth_settings_more_details": "למיד×ĸ × ×•×Ą×Ŗ אודו×Ē ×Ēכונה זו, בדוק א×Ē ×”×Ēי×ĸוד.", + "oauth_settings_more_details": "למיד×ĸ × ×•×Ą×Ŗ אודו×Ē ×Ēכונה זו, בדוק א×Ē ×”×Ēי×ĸוד.", "oauth_storage_label_claim": "דריש×Ē ×Ēווי×Ē ××—×Ą×•×Ÿ", "oauth_storage_label_claim_description": "הגדר אוטומטי×Ē ××Ē ×Ēווי×Ē ×”××—×Ą×•×Ÿ של המש×Ēמ׊ ל×ĸרך של דרישה זו.", "oauth_storage_quota_claim": "דריש×Ē ×ž×›×Ą×Ē ××—×Ą×•×Ÿ", @@ -330,7 +330,7 @@ "storage_template_hash_verification_enabled": "אימו×Ē ×’×™×‘×•×‘ מופ×ĸל", "storage_template_hash_verification_enabled_description": "מאפ׊ר אימו×Ē ×’×™×‘×•×‘, אין להשבי×Ē ×–××Ē ××œ× אם יש לך ודאו×Ē ×œ×’×‘×™ ההשלכו×Ē", "storage_template_migration": "ה×ĸבר×Ē ×Ēבני×Ē ××—×Ą×•×Ÿ", - "storage_template_migration_description": "החל א×Ē ×”{template} הנוכחי×Ē ×ĸל ×Ēמונו×Ē ×Š×”×•×ĸלו ב×ĸבר", + "storage_template_migration_description": "החל×Ē ×”{template} הנוכחי ×ĸל ×Ēמונו×Ē ×Š×”×•×ĸלו ב×ĸבר", "storage_template_migration_info": "×Ēבני×Ē ×”××—×Ą×•×Ÿ ×Ēמיר א×Ē ×›×œ ההרחבו×Ē ×œ××•×Ēיו×Ē ×§×˜× ×•×Ē. שינויים ב×Ēבני×Ē ×™×—×•×œ×• רק ×ĸל ×Ēמונו×Ē ×—×“×Š×•×Ē. כדי להחיל באופן רטרואקטיבי א×Ē ×”×Ēבני×Ē ×ĸל ×Ēמונו×Ē ×Š×”×•×ĸלו ב×ĸבר, הפ×ĸל א×Ē {job}.", "storage_template_migration_job": "משימ×Ē ×”×ĸבר×Ē ×Ēבני×Ē ××—×Ą×•×Ÿ", "storage_template_more_details": "לפרטים נוספים אודו×Ē ×Ēכונה זו, ×ĸיין ב×Ēבני×Ē ×”××—×Ą×•×Ÿ ובהשלכו×Ēיה", @@ -441,7 +441,7 @@ "user_successfully_removed": "המש×Ēמ׊ {email} הוסר בה×Ļלחה.", "users_page_description": "×ĸמוד ניהול מ׊×Ēמשים", "version_check_enabled_description": "אפ׊ר בדיק×Ē ×’×¨×Ą×”", - "version_check_implications": "×Ēכונ×Ē ×‘×“×™×§×Ē ×”×’×¨×Ą×” מס×Ēמכ×Ē ×ĸל ×Ēקשור×Ē ×Ēקופ×Ēי×Ē ×ĸם github.com", + "version_check_implications": "×Ēכונ×Ē ×‘×“×™×§×Ē ×”×’×¨×Ą×” מס×Ēמכ×Ē ×ĸל ×Ēקשור×Ē ×Ēקופ×Ēי×Ē ×ĸם {server}", "version_check_settings": "בדיק×Ē ×’×¨×Ą×”", "version_check_settings_description": "הפ×ĸל/השב×Ē ××Ē ×”×”×Ēראה ×ĸל גרסה חדשה", "video_conversion_job": "המר×Ē ×§×™×“×•×“ סרטונים", @@ -866,6 +866,7 @@ "crop_aspect_ratio_fixed": "×Ēוקן", "crop_aspect_ratio_free": "חינם", "crop_aspect_ratio_original": "מקורי", + "crop_aspect_ratio_square": "ריבו×ĸ", "curated_object_page_title": "דברים", "current_device": "מכשיר נוכחי", "current_pin_code": "קוד PIN הנוכחי", @@ -880,7 +881,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "כהה", - "dark_theme": "הפ×ĸל/כבה מ×Ļב כהה", + "dark_theme": "מ×ĸבר ל×ĸרכ×Ē × ×•×Š× כהה", "date": "×Ēאריך", "date_after": "×Ēאריך אחרי", "date_and_time": "×Ēאריך וש×ĸה", @@ -891,10 +892,8 @@ "day": "יום", "days": "ימים", "deduplicate_all": "ביטול כל הכפילויו×Ē", - "deduplication_criteria_1": "גודל ×Ēמונה בב×Ēים", - "deduplication_criteria_2": "כמו×Ē × ×Ēוני EXIF", - "deduplication_info": "מיד×ĸ ×ĸל ביטול כפילויו×Ē", - "deduplication_info_description": "כדי לבחור מרא׊ ×Ēמונו×Ē ×‘××•×¤×Ÿ אוטומטי ולהסיר כפילויו×Ē ×‘×›×ž×•×Ē ×’×“×•×œ×”, אנו מס×Ēכלים ×ĸל:", + "default_locale": "אזור שפה בריר×Ē ×ž×—×“×œ", + "default_locale_description": "×ĸי×Ļוב ×Ēאריכים ומספרים בה×Ēבסס ×ĸל אזור השפה של הדפדפן שלך", "delete": "מחק", "delete_action_confirmation_message": "האם א×Ēה בטוח שבר×Ļונך למחוק א×Ē ×”×Ēמונה הזא×Ē? פ×ĸולה זו ×Ē×ĸביר או×Ēו לאשפה של השר×Ē, ו×Ēשאל אם בר×Ļונך למחוק או×Ēו גם מהמכשיר המקומי", "delete_action_prompt": "{count} נמחקו", @@ -970,7 +969,7 @@ "downloading_media": "מוריד מדיה", "drop_files_to_upload": "שחרר קב×Ļים בכל מקום כדי לה×ĸלו×Ē", "duplicates": "כפילויו×Ē", - "duplicates_description": "הפרד כל קבו×Ļה ×ĸל ידי ×Ļיון אילו, אם בכלל, הן כפילויו×Ē", + "duplicates_description": "הפרד כל קבו×Ļה ×ĸל ידי ×Ļיון אילו, אם בכלל, הן כפילויו×Ē.", "duration": "משך זמן", "edit": "×ĸרוך", "edit_album": "×ĸרוך אלבום", @@ -1007,6 +1006,8 @@ "editor_edits_applied_success": "×ĸריכו×Ē ×™×•×Š×ž×• בה×Ļלחה", "editor_flip_horizontal": "הפוך אופקי×Ē", "editor_flip_vertical": "הפוך אנכי×Ē", + "editor_handle_corner": "ידי×Ē ×”×¤×™× ×” {corner, select, top_left {השמאלי×ĒÖž×ĸליונה} top_right {הימני×ĒÖž×ĸליונה} bottom_left {השמאלי×ĒÖž×Ēח×Ēונה} bottom_right {הימני×ĒÖž×Ēח×Ēונה} other {}}", + "editor_handle_edge": "ידי×Ē ×”×§×Ļה {edge, select, top {ה×ĸליון} bottom {ה×Ēח×Ēון} left {השמאלי} right {הימני} other {}}", "editor_orientation": "כיוון", "editor_reset_all_changes": "איפוס שינויים", "editor_rotate_left": "סיבוב 90° נגד כיוון הש×ĸון", @@ -1072,7 +1073,7 @@ "failed_to_update_notification_status": "שגיאה ב×ĸדכון הה×Ēראה", "incorrect_email_or_password": "דוא\"ל או סיסמה שגויים", "library_folder_already_exists": "× ×Ēיב הייבוא כבר מוגדר.", - "page_not_found": "ה×ĸמוד לא נמ×Ļא â€Ē:/â€Ŧ", + "page_not_found": "ה×ĸמוד לא נמ×Ļא", "paths_validation_failed": "{paths, plural, one {× ×Ēיב # נכשל} other {# × ×Ēיבים נכשלו}} אימו×Ē", "profile_picture_transparent_pixels": "×Ēמונו×Ē ×¤×¨×•×¤×™×œ אינן יכולו×Ē ×œ×›×œ×•×œ פיקסלים שקופים. נא להגדיל ו/או להזיז א×Ē ×”×Ēמונה.", "quota_higher_than_disk_size": "הגדר×Ē ×ž×›×Ą×” גבוהה יו×Ēר מגודל הדיסק", @@ -1385,9 +1386,11 @@ "library_page_sort_title": "כו×Ēר×Ē ××œ×‘×•×", "licenses": "רישיונו×Ē", "light": "בהיר", + "light_theme": "החלפה ל×ĸרכ×Ē × ×•×Š× בהירה", "like": "אהב×Ēי", "like_deleted": "לייק נמחק", "link_motion_video": "ק׊ר סרטון ×Ēנו×ĸה", + "link_to_docs": "למיד×ĸ × ×•×Ą×Ŗ, יש ל×ĸיין ב×Ēי×ĸוד.", "link_to_oauth": "קישור ל-OAuth", "linked_oauth_account": "חשבון OAuth מקושר", "list": "רשימה", @@ -1566,7 +1569,7 @@ "network_requirements": "דרישו×Ē ×¨×Š×Ē", "network_requirements_updated": "דרישו×Ē ×”×¨×Š×Ē ×”×Š×Ēנו, ×Ēור הגיבוי אופס", "networking_settings": "ר׊×Ē", - "networking_subtitle": "ניהול הגדרו×Ē ×›×Ēוב×Ē URL של השר×Ē", + "networking_subtitle": "ניהול הגדרו×Ē ×›×Ēוב×Ē ×”×Š×¨×Ē", "never": "את פ×ĸם", "new_album": "אלבום חדש", "new_api_key": "מפ×Ēח API חדש", @@ -1649,6 +1652,7 @@ "only_favorites": "רק מו×ĸדפים", "open": "פ×Ēח", "open_calendar": "פ×Ēיח×Ē ×œ×•×— שנה", + "open_in_browser": "פ×Ēיחה בדפדפן", "open_in_map_view": "פ×Ēח ב×Ē×Ļוג×Ē ×ž×¤×”", "open_in_openstreetmap": "פ×Ēח ב-OpenStreetMap", "open_the_search_filters": "פ×Ēח א×Ē ×ž×Ą× × ×™ החיפוש", @@ -2009,7 +2013,7 @@ "selected_gps_coordinates": "קואורדינטו×Ē GPS שנבחרו", "send_message": "שלח הוד×ĸה", "send_welcome_email": "שלח דוא\"ל קבל×Ē ×¤× ×™×", - "server_endpoint": "כ×Ēוב×Ē URL של השר×Ē", + "server_endpoint": "כ×Ēוב×Ē ×”×Š×¨×Ē", "server_info_box_app_version": "גרס×Ē ×™×™×Š×•×", "server_info_box_server_url": "כ×Ēוב×Ē ×Š×¨×Ē", "server_offline": "השר×Ē ×ž× ×•×Ē×§", @@ -2211,7 +2215,7 @@ "tag_assets": "×Ēיוג ×Ēמונו×Ē", "tag_created": "נו×Ļר ×Ēג: {tag}", "tag_feature_description": "×ĸיון ב×Ēמונו×Ē ×•×Ą×¨×˜×•× ×™× שקוב×Ļו ×ĸל ידי נושאי ×Ēג לוגיים", - "tag_not_found_question": "לא מ×Ļליח למ×Ļוא ×Ēג? ×Ļור ×Ēג חדש", + "tag_not_found_question": "לא ני×Ēן למ×Ļוא ×Ēג? י×Ļיר×Ē ×Ēג חדש.", "tag_people": "×Ēייג אנשים", "tag_updated": "×Ēג מ×ĸודכן: {tag}", "tagged_assets": "×Ēויגו {count, plural, one {×Ēמונה #} other {# ×Ēמונו×Ē}}", @@ -2391,6 +2395,7 @@ "viewer_remove_from_stack": "הסר מ×ĸרימה", "viewer_stack_use_as_main_asset": "הש×Ēמ׊ כ×Ēמונה ראשי×Ē", "viewer_unstack": "ביטול ×ĸרימה", + "visibility": "נראו×Ē", "visibility_changed": "הנראו×Ē ×”×Š×Ē× ×Ēה ×ĸבור {count, plural, one {אדם #} other {# אנשים}}", "visual": "חזו×Ēי", "visual_builder": "בונה חזו×Ēי", diff --git a/i18n/hi.json b/i18n/hi.json index c7d439e5a0..668952775a 100644 --- a/i18n/hi.json +++ b/i18n/hi.json @@ -441,7 +441,7 @@ "user_successfully_removed": "⤉ā¤Ē⤝āĨ‹ā¤—⤕⤰āĨā¤¤ā¤ž {email} ⤕āĨ‹ ⤏ā¤Ģā¤˛ā¤¤ā¤žā¤ĒāĨ‚⤰āĨā¤ĩ⤕ ā¤šā¤Ÿā¤ž ā¤Ļā¤ŋā¤¯ā¤ž ā¤—ā¤¯ā¤ž ā¤šāĨˆāĨ¤", "users_page_description": "ā¤ĒāĨā¤°ā¤ļā¤žā¤¸ā¤• (Admin) ⤉ā¤Ē⤝āĨ‹ā¤—⤕⤰āĨā¤¤ā¤ž ā¤ĒāĨ‡ā¤œ", "version_check_enabled_description": "⤍⤈ ⤰ā¤ŋ⤞āĨ€ā¤œā¤ŧ ⤕āĨ€ ā¤œā¤žā¤ā¤š ⤕āĨ‡ ⤞ā¤ŋā¤ GitHub ā¤Ē⤰ ⤆ā¤ĩ⤧ā¤ŋ⤕ ⤅⤍āĨā¤°āĨ‹ā¤§ ⤏⤕āĨā¤ˇā¤Ž ⤕⤰āĨ‡ā¤‚", - "version_check_implications": "⤏⤂⤏āĨā¤•⤰⤪ ā¤œā¤žā¤ā¤š ⤏āĨā¤ĩā¤ŋā¤§ā¤ž github.com ⤕āĨ‡ ā¤¸ā¤žā¤Ĩ ⤆ā¤ĩ⤧ā¤ŋ⤕ ā¤¸ā¤‚ā¤šā¤žā¤° ā¤Ē⤰ ⤍ā¤ŋ⤰āĨā¤­ā¤° ⤕⤰⤤āĨ€ ā¤šāĨˆ", + "version_check_implications": "⤏⤂⤏āĨā¤•⤰⤪ ā¤œā¤žā¤ā¤š ⤏āĨā¤ĩā¤ŋā¤§ā¤ž {server} ⤕āĨ‡ ā¤¸ā¤žā¤Ĩ ⤆ā¤ĩ⤧ā¤ŋ⤕ ā¤¸ā¤‚ā¤šā¤žā¤° ā¤Ē⤰ ⤍ā¤ŋ⤰āĨā¤­ā¤° ⤕⤰⤤āĨ€ ā¤šāĨˆ", "version_check_settings": "⤏⤂⤏āĨā¤•⤰⤪ ⤚āĨ‡ā¤•", "version_check_settings_description": "ā¤¨ā¤ ⤏⤂⤏āĨā¤•⤰⤪ ⤅⤧ā¤ŋ⤏āĨ‚ā¤šā¤¨ā¤ž ⤕āĨ‹ ⤏⤕āĨā¤ˇā¤Ž/⤅⤕āĨā¤ˇā¤Ž ⤕⤰āĨ‡ā¤‚", "video_conversion_job": "⤟āĨā¤°ā¤žā¤‚⤏⤕āĨ‹ā¤Ą ā¤ĩāĨ€ā¤Ąā¤ŋ⤝āĨ‹", @@ -891,10 +891,6 @@ "day": "ā¤Ļā¤ŋ⤍", "days": "ā¤Ļā¤ŋ⤍", "deduplicate_all": "⤏⤭āĨ€ ⤕āĨ‹ ā¤ĄāĨā¤ĒāĨā¤˛ā¤ŋ⤕āĨ‡ā¤Ÿ ⤕⤰āĨ‡ā¤‚", - "deduplication_criteria_1": "⤛ā¤ĩā¤ŋ ā¤•ā¤ž ā¤†ā¤•ā¤žā¤° ā¤Ŧā¤žā¤‡ā¤ŸāĨā¤¸ ā¤ŽāĨ‡ā¤‚", - "deduplication_criteria_2": "EXIF ā¤ĄāĨ‡ā¤Ÿā¤ž ⤕āĨ€ ⤏⤂⤖āĨā¤¯ā¤ž", - "deduplication_info": "ā¤ĄāĨā¤ĒāĨā¤˛āĨ€ā¤•āĨ‡ā¤ļ⤍ ā¤šā¤Ÿā¤žā¤¨āĨ‡ ⤕āĨ€ ā¤œā¤žā¤¨ā¤•ā¤žā¤°āĨ€", - "deduplication_info_description": "ā¤Ē⤰ā¤ŋ⤏⤂ā¤Ē⤤āĨā¤¤ā¤ŋ⤝āĨ‹ā¤‚ ā¤•ā¤ž ⤏āĨā¤ĩā¤šā¤žā¤˛ā¤ŋ⤤ ⤰āĨ‚ā¤Ē ⤏āĨ‡ ā¤ĒāĨ‚⤰āĨā¤ĩ-⤚⤝⤍ ⤕⤰⤍āĨ‡ ⤔⤰ ā¤ĄāĨā¤ĒāĨā¤˛ā¤ŋ⤕āĨ‡ā¤Ÿ ⤕āĨ‹ ā¤ĨāĨ‹ā¤• ā¤ŽāĨ‡ā¤‚ ā¤šā¤Ÿā¤žā¤¨āĨ‡ ⤕āĨ‡ ⤞ā¤ŋā¤, ā¤šā¤Ž ⤍ā¤ŋā¤ŽāĨā¤¨ ā¤Ē⤰ ⤧āĨā¤¯ā¤žā¤¨ ā¤ĻāĨ‡ā¤¤āĨ‡ ā¤šāĨˆā¤‚:", "delete": "ā¤šā¤Ÿā¤žā¤ā¤", "delete_action_confirmation_message": "⤕āĨā¤¯ā¤ž ⤆ā¤Ē ā¤ĩā¤žā¤•ā¤ˆ ⤇⤏ ā¤†ā¤‡ā¤Ÿā¤Ž ⤕āĨ‹ ā¤šā¤Ÿā¤žā¤¨ā¤ž ā¤šā¤žā¤šā¤¤āĨ‡ ā¤šāĨˆā¤‚? ā¤¯ā¤š ā¤•ā¤žā¤°āĨā¤°ā¤ĩā¤žā¤ˆ ā¤†ā¤‡ā¤Ÿā¤Ž ⤕āĨ‹ ⤏⤰āĨā¤ĩ⤰ ⤕āĨ€ ⤟āĨā¤°āĨˆā¤ļ ā¤ŽāĨ‡ā¤‚ ⤞āĨ‡ ā¤œā¤žā¤ā¤—āĨ€ ⤔⤰ ⤏āĨā¤Ĩā¤žā¤¨āĨ€ā¤¯ ⤰āĨ‚ā¤Ē ⤏āĨ‡ ā¤šā¤Ÿā¤žā¤¨āĨ‡ ⤕āĨ‡ ⤞ā¤ŋā¤ ā¤ĒāĨā¤ˇāĨā¤Ÿā¤ŋ ā¤Žā¤žā¤‚ā¤—āĨ‡ā¤—āĨ€", "delete_action_prompt": "{count} ā¤šā¤Ÿā¤žā¤ ā¤—ā¤", diff --git a/i18n/hr.json b/i18n/hr.json index 3337235102..0ed46addf9 100644 --- a/i18n/hr.json +++ b/i18n/hr.json @@ -5,7 +5,7 @@ "acknowledge": "Potvrdi", "action": "Akcija", "action_common_update": "AÅžuriranje", - "action_description": "Skup radnji koje se izvrÅĄavaju nad filtriran", + "action_description": "Skup radnji koje se izvrÅĄavaju nad filtriranim stavkama", "actions": "Akcije", "active": "Aktivno", "active_count": "Aktivno:{count}", @@ -203,7 +203,10 @@ "maintenance_settings_description": "Stavi Immich u način odrÅžavanja.", "maintenance_start": "Prebaci se u način odrÅžavanja", "maintenance_start_error": "Neuspjelo pokretanje načina odrÅžavanja.", + "maintenance_upload_backup": "Prenesi bakup baze podataka", + "maintenance_upload_backup_error": "Prijenos sigurnosne kopije nesuopjeÅĄan, je li datoteka tipa .sql-.sql.gz?", "manage_concurrency": "Upravljanje IstovremenoÅĄÄ‡u", + "manage_concurrency_description": "Idi na stranicu poslova za upravljanje konkurentoÅĄÄ‡u", "manage_log_settings": "Upravljanje postavkama zapisivanje", "map_dark_style": "Tamni stil", "map_enable_description": "Omogući značajke karte", @@ -269,7 +272,7 @@ "oauth_auto_register": "Automatska registracija", "oauth_auto_register_description": "Automatski registrirajte nove korisnike nakon prijave s OAuth", "oauth_button_text": "Tekst gumba", - "oauth_client_secret_description": "Obavezno ukoliko PKCE (Proof Key for Code Exchange) nije podrÅžan od strane OAuth pruÅžatelja", + "oauth_client_secret_description": "Obaveznoya privatnog klijenta ili ukoliko PKCE (Proof Key for Code Exchange) nije podrÅžan od javnog klijenta.", "oauth_enable_description": "Prijavite se putem OAutha", "oauth_mobile_redirect_uri": "Mobilnog Preusmjeravanja URI", "oauth_mobile_redirect_uri_override": "Nadjačavanje URI-preusmjeravanja za mobilne uređaje", @@ -287,15 +290,20 @@ "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", + "ocr_job_description": "Koristi strojno učenje za prepoznavanje teksta na slikama", "password_enable_description": "Prijava s email adresom i zaporkom", "password_settings": "Prijava zaporkom", "password_settings_description": "Upravljanje postavkama za prijavu zaporkom", "paths_validated_successfully": "Sve su putanje uspjeÅĄno potvrđene", "person_cleanup_job": "ČiÅĄÄ‡enje lica", + "queue_details": "Detalji reda čekanja", + "queues": "Posloviu redu čekanja", + "queues_page_description": "Administracija redova čekanja", "quota_size_gib": "Veličina kvote (GiB)", "refreshing_all_libraries": "OsvjeÅžavanje svih biblioteka", "registration": "Registracija administratora", "registration_description": "Budući da ste prvi korisnik na sustavu, bit ćete dodijeljeni administratorsku ulogu i odgovorni ste za administrativne poslove, a dodatne korisnike kreirat ćete sami.", + "remove_failed_jobs": "Makni neuspjeÅĄne poslove", "require_password_change_on_login": "Zahtijevajte od korisnika promjenu lozinke pri prvoj prijavi", "reset_settings_to_default": "Vrati postavke na zadane", "reset_settings_to_recent_saved": "Resetirajte postavke na nedavno spremljene postavke", @@ -303,13 +311,15 @@ "search_jobs": "TraÅži zadatkeâ€Ļ", "send_welcome_email": "PoÅĄaljite email dobrodoÅĄlice", "server_external_domain_settings": "Vanjska domena", - "server_external_domain_settings_description": "Domena za javno dijeljene linkove, uključujući http(s)://", + "server_external_domain_settings_description": "Domena za vanjske poveznice", "server_public_users": "Javni korisnici", "server_public_users_description": "Svi korisnici (ime i e-poÅĄta) navedeni su prilikom dodavanja korisnika u dijeljene albume. Kada je onemogućeno, popis korisnika bit će dostupan samo korisnicima administratora.", "server_settings": "Postavke servera", "server_settings_description": "Upravljanje postavkama servera", + "server_stats_page_description": "Statistika servera za administratore", "server_welcome_message": "Poruka dobrodoÅĄlice", "server_welcome_message_description": "Poruka koja je prikazana na prijavi.", + "settings_page_description": "Administratorske postavke", "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", @@ -401,7 +411,7 @@ "transcoding_tone_mapping": "Tonsko preslikavanje", "transcoding_tone_mapping_description": "PokuÅĄava sačuvati izgled HDR videozapisa kada se pretvori u SDR. Svaki algoritam čini različite kompromise za boju, detalje i svjetlinu. Hable čuva detalje, Mobius čuva boju, a Reinhard svjetlinu.", "transcoding_transcode_policy": "Pravila transkodiranja", - "transcoding_transcode_policy_description": "Pravila o tome kada se video treba transkodirati. HDR videozapisi uvijek će biti transkodirani (osim ako je transkodiranje onemogućeno).", + "transcoding_transcode_policy_description": "Pravila o tome kada se video treba transkodirati. HDR videozapisi i videozapisi sa formatoom piksela razlicitim od ZUV 4:2:0 uvijek će biti transkodirani (osim ako je transkodiranje onemogućeno).", "transcoding_two_pass_encoding": "Kodiranje u dva prolaza", "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", @@ -428,8 +438,10 @@ "user_restore_scheduled_removal": "Vrati korisnika - zakazano uklanjanje {date, date, long}", "user_settings": "Korisničke postavke", "user_settings_description": "Upravljanje korisničkim postavkama", + "user_successfully_removed": "Korisnik {email} je uspjeÅĄno uklonjen.", + "users_page_description": "Administracija korisnika stranica", "version_check_enabled_description": "Omogući provjeru verzije", - "version_check_implications": "Značajka provjere verzije oslanja se na periodičnu komunikaciju s github.com", + "version_check_implications": "Značajka provjere verzije oslanja se na periodičnu komunikaciju s {server}", "version_check_settings": "Provjera verzije", "version_check_settings_description": "Omogućite/onemogućite obavijest o novoj verziji", "video_conversion_job": "Transkodiranje videozapisa", @@ -439,6 +451,9 @@ "admin_password": "Admin lozinka", "administration": "Administracija", "advanced": "Napredno", + "advanced_settings_clear_image_cache": "ObriÅĄi međuspremnik slika", + "advanced_settings_clear_image_cache_error": "NeuspjeÅĄno čiÅĄÄ‡enje međuspremnika slika", + "advanced_settings_clear_image_cache_success": "UspjeÅĄno očiÅĄÄ‡eno {size}", "advanced_settings_enable_alternate_media_filter_subtitle": "Koristite ovu opciju za filtriranje medija tijekom sinkronizacije na temelju alternativnih kriterija. PokuÅĄajte ovo samo ako imate problema s aplikacijom koja ne prepoznaje sve albume.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTALNO] Koristite alternativni filter za sinkronizaciju albuma na uređaju", "advanced_settings_log_level_title": "Razina zapisivanja: {level}", @@ -458,6 +473,7 @@ "age_months": "Dob {months, plural, one {# mjesec} other {# mjeseca}}", "age_year_months": "Dob 1 godina, {months, plural, one {# mjesec} other {# mjeseca}}", "age_years": "{years, plural, other {Dob #}}", + "album": "Album", "album_added": "Album dodan", "album_added_notification_setting_description": "Primite obavijest e-poÅĄtom kada ste dodani u dijeljeni album", "album_cover_updated": "Naslovnica albuma aÅžurirana", @@ -474,10 +490,12 @@ "album_remove_user": "Ukloni korisnika?", "album_remove_user_confirmation": "Jeste li sigurni da Åželite ukloniti {user}?", "album_search_not_found": "Nema albuma koji odgovaraju vaÅĄem pretraÅživanju", + "album_selected": "Album odabran", "album_share_no_users": "Čini se da ste podijelili ovaj album sa svim korisnicima ili nemate nijednog korisnika s kojim biste ga dijelili.", "album_summary": "SaÅžetak albuma", "album_updated": "Album aÅžuriran", "album_updated_setting_description": "Primite obavijest e-poÅĄtom kada dijeljeni album ima nove stavke", + "album_upload_assets": "Učitaj stavku s vlastitog računala i dodaj u album", "album_user_left": "NapuÅĄten {album}", "album_user_removed": "Uklonjen {user}", "album_viewer_appbar_delete_confirm": "Jeste li sigurni da Åželite izbrisati ovaj album s vaÅĄeg računa?", @@ -495,15 +513,21 @@ "albums_default_sort_order_description": "Početni redoslijed sortiranja stavki prilikom izrade novih albuma.", "albums_feature_description": "Zbirke stavki koje se mogu dijeliti s drugim korisnicima.", "albums_on_device_count": "Albumi na uređaju ({count})", + "albums_selected": "{count, plural, one {# odabrani album} other {# odabrani albumi}}", "all": "Sve", "all_albums": "Svi albumi", "all_people": "Sve osobe", + "all_photos": "Sve slike", "all_videos": "Svi videi", "allow_dark_mode": "Dozvoli tamni način", "allow_edits": "Dozvoli izmjene", "allow_public_user_to_download": "Dopusti javnom korisniku preuzimanje", "allow_public_user_to_upload": "Dopusti javnom korisniku učitavanje", + "allowed": "DopuÅĄteno", "alt_text_qr_code": "Slika QR koda", + "always_keep": "Uvijek zadrÅži", + "always_keep_photos_hint": "Oslobodi prostora će zadrÅžati sve slike na ovom uređaju.", + "always_keep_videos_hint": "Oslobodi prostora će zadrÅžati sve videe na ovom uređaju.", "anti_clockwise": "Suprotno smjeru kazaljke na satu", "api_key": "API Ključ", "api_key_description": "Ova će vrijednost biti prikazana samo jednom. Obavezno ju kopirajte prije zatvaranja prozora.", @@ -529,10 +553,12 @@ "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?", + "array_field_not_fully_supported": "Polja niza zahtijevaju ručno JSON editiranje", "asset_action_delete_err_read_only": "Nije moguće izbrisati stavke samo za čitanje, preskakanje", "asset_action_share_err_offline": "Nije moguće dohvatiti izvanmreÅžne stavke, preskakanje", "asset_added_to_album": "Dodano u album", "asset_adding_to_album": "Dodavanje u albumâ€Ļ", + "asset_created": "Stavka stvorena", "asset_description_updated": "Opis stavke je aÅžuriran", "asset_filename_is_offline": "Stavka {filename} je izvan mreÅže", "asset_has_unassigned_faces": "Stavka ima nedodijeljena lica", @@ -545,6 +571,9 @@ "asset_list_layout_sub_title": "Raspored", "asset_list_settings_subtitle": "Postavke izgleda MreÅže fotografija", "asset_list_settings_title": "MreÅža fotografija", + "asset_not_found_on_device_android": "Stavka nije pronađena na ovom uređaju", + "asset_not_found_on_device_ios": "Stavka nije pronađena na ovom uređaju. Ako koristite iCloud, stavka je moÅžda nedostupna zbog loÅĄe datoteke spremljena na iCloud", + "asset_not_found_on_icloud": "Stavka nije pronađena na iCloud. Stavka je moÅžda nedostupna zbog loÅĄe datoteke spremljena na iCloud", "asset_offline": "Stavka izvan mreÅže", "asset_offline_description": "Ova vanjska stavka nije pronađena na disku. Za pomoć se obratite Immich administratoru.", "asset_restored_successfully": "Stavka uspjeÅĄno obnovljena", @@ -657,6 +686,7 @@ "backup_options_page_title": "Opcije sigurnosnog kopiranja", "backup_setting_subtitle": "Upravljajte postavkama učitavanja u pozadini i prvom planu", "backup_settings_subtitle": "Upravljaj postavkama slanja", + "backup_upload_details_page_more_details": "Pritisnite za vise informacija", "backward": "Unazad", "biometric_auth_enabled": "Biometrijska autentikacija omogućena", "biometric_locked_out": "Zaključani ste iz biometrijske autentikacije", @@ -723,8 +753,21 @@ "check_corrupt_asset_backup_button": "IzvrÅĄi provjeru", "check_corrupt_asset_backup_description": "Pokrenite ovu provjeru samo putem Wi-Fi mreÅže i nakon ÅĄto su sve stavke sigurnosno kopirane. Postupak moÅže potrajati nekoliko minuta.", "check_logs": "Provjera Zapisa", + "checksum": "Kontrolni zbroj", "choose_matching_people_to_merge": "Odaberite odgovarajuće osobe za spajanje", "city": "Grad", + "cleanup_confirm_description": "Immich je pronaÅĄao {count} stavki (stvorene prije {date}) sigurno spremljene na serveru. Ukloni lokalne kopije s ovog uređaja?", + "cleanup_confirm_prompt_title": "Ukloni s ovog uređaja?", + "cleanup_deleted_assets": "Prebačeno {count} stavki u smeće uređaja", + "cleanup_deleting": "Prebacivanje u smeće...", + "cleanup_found_assets": "Pronađeno {count} sigurnosno spremljenih stavki", + "cleanup_found_assets_with_size": "Pronađeno {count} sigurnosno spremljenih stavki ({size})", + "cleanup_icloud_shared_albums_excluded": "iCloud dijeljeni albumi nisu uključeni u skeniranje", + "cleanup_no_assets_found": "Nisu pronađene stavki koje zadovoljavaju gore kriterij. Oslobodi prostor moÅže ukloniti samo stavke koje su sigurno kopirane na serveru", + "cleanup_preview_title": "Stavke za ukloniti ({count})", + "cleanup_step3_description": "Skeniraj sigurnosnu kopiju stavki koje zadovoljavaju vaÅĄ datum i zadrÅži opcije.", + "cleanup_step4_summary": "{count} stavki (stvorene prije {date}) za ukloniti s vaÅĄeg lokalnog uređaja. Slike će ostat dostupne s Immich aplikacije.", + "cleanup_trash_hint": "Kako bi u potpunosti oslobodili prostor, otvorite sistemsku aplikaciju za galeriju i očistite smeće", "clear": "Očisti", "clear_all": "Očisti sve", "clear_all_recent_searches": "IzbriÅĄi sva nedavna pretraÅživanja", @@ -736,6 +779,8 @@ "client_cert_import": "Uvezi", "client_cert_import_success_msg": "Klijentski certifikat je uvezen", "client_cert_invalid_msg": "Neispravna datoteka certifikata ili pogreÅĄna lozinka", + "client_cert_password_message": "Unesite lozinku za ovaj certifikat", + "client_cert_password_title": "Lozinka certifikata", "client_cert_remove_msg": "Klijentski certifikat je uklonjen", "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]", @@ -746,6 +791,11 @@ "color": "Boja", "color_theme": "Tema boja", "command": "Naredba", + "command_palette_prompt": "Brzo nađi stranice, akcije ili naredbe", + "command_palette_to_close": "za zatvoriti", + "command_palette_to_navigate": "za pristupiti", + "command_palette_to_select": "za selektirati", + "command_palette_to_show_all": "za prikazati sve", "comment_deleted": "Komentar izbrisan", "comment_options": "Opcije komentara", "comments_and_likes": "Komentari i lajkovi", @@ -795,9 +845,12 @@ "create_link_to_share": "Izradite vezu za dijeljenje", "create_link_to_share_description": "Dopusti svakome s vezom da vidi odabrane fotografije", "create_new": "KREIRAJ NOVO", + "create_new_face": "Stvori novo lice", "create_new_person": "Stvorite novu osobu", "create_new_person_hint": "Dodijelite odabrane stavke novoj osobi", "create_new_user": "Kreiraj novog korisnika", + "create_person": "Stvori novu osobu", + "create_person_subtitle": "Dodaj ime odabranom licu kako bi stvorio i tagirao novu osobu", "create_shared_album_page_share_add_assets": "DODAJ STAVKE", "create_shared_album_page_share_select_photos": "Odaberi fotografije", "create_shared_link": "Kreiraj dijeljeni link", @@ -808,17 +861,25 @@ "created_at": "Kreirano", "creating_linked_albums": "Izradi povezane albume...", "crop": "ObreÅži", + "crop_aspect_ratio_fixed": "Popravljeno", + "crop_aspect_ratio_free": "Slobodno", + "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Kvadrat", "curated_object_page_title": "Stvari", "current_device": "Trenutačni uređaj", "current_pin_code": "Trenutni PIN kod", "current_server_address": "Trenutna adresa posluÅžitelja", - "custom_locale": "Prilagođena Lokalizacija", - "custom_locale_description": "Formatiranje datuma i brojeva na temelju jezika i regije", + "custom_date": "Specifičan datum", + "custom_locale": "Prilagođena lokalizacija", + "custom_locale_description": "Formatiranje datuma, vremena i brojeva na temelju selektiranog jezika i regije", "custom_url": "Prilagođena URL adresa", + "cutoff_date_description": "ZadrÅži slike od zadnjihâ€Ļ", + "cutoff_day": "{count, plural, one {dan} other {dana}}", + "cutoff_year": "{count, plural, one {godina} other {godine}}", "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "Tamno", - "dark_theme": "Prebaci tamnu temu", + "dark_theme": "Prebaci u tamnu temu", "date": "Datum", "date_after": "Datum nakon", "date_and_time": "Datum i Vrijeme", @@ -829,10 +890,6 @@ "day": "Dan", "days": "Dani", "deduplicate_all": "Dedupliciraj Sve", - "deduplication_criteria_1": "Veličina slike u bajtovima", - "deduplication_criteria_2": "Broj EXIF podataka", - "deduplication_info": "Informacije o uklanjanju duplikata", - "deduplication_info_description": "Za automatski odabir stavki i masovno uklanjanje duplikata, uzimamo u obzir:", "delete": "IzbriÅĄi", "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", @@ -868,6 +925,7 @@ "deselect_all": "PoniÅĄti odabir svih", "details": "Detalji", "direction": "Smjer", + "disable": "Onesposobi", "disabled": "Onemogućeno", "disallow_edits": "Zabrani izmjene", "discord": "Discord", @@ -893,6 +951,7 @@ "download_include_embedded_motion_videos": "Ugrađeni videozapisi", "download_include_embedded_motion_videos_description": "Uključite videozapise ugrađene u fotografije s pokretom kao zasebnu datoteku", "download_notfound": "Preuzimanje nije pronađeno", + "download_original": "Preuzmi original", "download_paused": "Preuzimanje pauzirano", "download_settings": "Preuzmi", "download_settings_description": "Upravljajte postavkama vezanim uz preuzimanje stavki", @@ -902,10 +961,11 @@ "download_waiting_to_retry": "Čeka se ponovni pokuÅĄaj", "downloading": "Preuzimanje", "downloading_asset_filename": "Preuzimanje stavke {filename}", + "downloading_from_icloud": "Preuzmi s iCloud", "downloading_media": "Preuzimanje medija", "drop_files_to_upload": "Ispustite datoteke bilo gdje za prijenos", "duplicates": "Duplikati", - "duplicates_description": "RazrijeÅĄite svaku grupu tako da naznačite koji su duplikati, ako ih ima", + "duplicates_description": "RazrijeÅĄite svaku grupu tako da naznačite koji su duplikati, ako ih ima.", "duration": "Trajanje", "edit": "Izmjena", "edit_album": "Uredi album", @@ -933,6 +993,12 @@ "editor": "Urednik", "editor_close_without_save_prompt": "Promjene neće biti spremljene", "editor_close_without_save_title": "Zatvoriti uređivač?", + "editor_confirm_reset_all_changes": "Jeste li sigurni da Åželite resetirati sve opcije?", + "editor_discard_edits_confirm": "Odbaci izmjene", + "editor_discard_edits_prompt": "Imate nesačuvane izmjene. Jeste li sigurni da ih Åželite odbaciti?", + "editor_discard_edits_title": "Odbaci izmjene?", + "editor_rotate_left": "Rotiraj 90° u suprotnom smjeru kazaljke na satu", + "editor_rotate_right": "Rotiraj 90° u smjeru kazaljke na satu", "email": "E-poÅĄta", "email_notifications": "Obavijesti putem e-maila", "empty_folder": "Ova mapa je prazna", @@ -956,6 +1022,7 @@ "error_saving_image": "PogreÅĄka: {error}", "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", + "error_while_navigating": "GreÅĄka prilikom navigiranja do stavki", "errors": { "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", @@ -991,6 +1058,7 @@ "failed_to_update_notification_status": "NeuspjeÅĄno aÅžuriranje statusa obavijesti", "incorrect_email_or_password": "Netočna adresa e-poÅĄte ili lozinka", "library_folder_already_exists": "Ova putanja unosa već postoji.", + "page_not_found": "Stranica nije pronađena", "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", @@ -1075,6 +1143,7 @@ "unable_to_update_user": "Nije moguće aÅžurirati korisnika", "unable_to_upload_file": "Nije moguće učitati datoteku" }, + "errors_text": "GreÅĄke", "exclusion_pattern": "Uzorak isključenja", "exif": "Exif", "exif_bottom_sheet_description": "Dodaj opis...", @@ -1085,6 +1154,7 @@ "exif_bottom_sheet_people": "OSOBE", "exif_bottom_sheet_person_add_person": "Dodaj ime", "exit_slideshow": "Izađi iz projekcije slideova", + "expand": "ProÅĄiri", "expand_all": "ProÅĄiri sve", "experimental_settings_new_asset_list_subtitle": "Rad u tijeku", "experimental_settings_new_asset_list_title": "Omogući eksperimentalnu mreÅžu fotografija", @@ -1120,6 +1190,8 @@ "features_in_development": "Značajke u razvoju", "features_setting_description": "Upravljajte značajkama aplikacije", "file_name_or_extension": "Naziv ili ekstenzija datoteke", + "file_name_text": "Ime datoteke", + "file_name_with_value": "Ime datoteke: {file_name}", "file_size": "Veličina datoteke", "filename": "Naziv datoteke", "filetype": "Vrsta datoteke", diff --git a/i18n/hu.json b/i18n/hu.json index 2521d21922..c4788b9915 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -441,7 +441,7 @@ "user_successfully_removed": "{email} felhasznÃĄlÃŗ sikeresen eltÃĄvolítva.", "users_page_description": "Admin felhasznÃĄlÃŗk oldala", "version_check_enabled_description": "Új verziÃŗk elÊrhetősÊgÊnek ellenőrzÊse", - "version_check_implications": "Az Ãēj verziÃŗk ellenőrzÊse időszakos kommunikÃĄciÃŗt igÊnyel a github.com oldallal", + "version_check_implications": "Az Ãēj verziÃŗk ellenőrzÊse időszakos kommunikÃĄciÃŗt igÊnyel a {server} oldallal", "version_check_settings": "VerziÃŗ ellenőrzÊs", "version_check_settings_description": "Az Ãēj verziÃŗrÃŗl valÃŗ ÊrtesítÊs be- Ês kikapcsolÃĄsa", "video_conversion_job": "VideÃŗk ÁtkÃŗdolÃĄsa", @@ -866,6 +866,7 @@ "crop_aspect_ratio_fixed": "RÃļgzített", "crop_aspect_ratio_free": "Tetszőleges", "crop_aspect_ratio_original": "Eredeti", + "crop_aspect_ratio_square": "NÊgyzet", "curated_object_page_title": "Dolgok", "current_device": "Ez az eszkÃļz", "current_pin_code": "AktuÃĄlis PIN kÃŗd", @@ -880,7 +881,7 @@ "daily_title_text_date": "MMM dd (E)", "daily_title_text_date_year": "yyyy MMM dd (E)", "dark": "SÃļtÊt", - "dark_theme": "SÃļtÊt tÊma kapcsolÃĄsa", + "dark_theme": "SÃļtÊt tÊmÃĄra vÃĄltÃĄs", "date": "DÃĄtum", "date_after": "DÃĄtumtÃŗl", "date_and_time": "DÃĄtum Ês idő", @@ -891,10 +892,8 @@ "day": "Nap", "days": "Napok", "deduplicate_all": "Összes deduplikÃĄlÃĄsa", - "deduplication_criteria_1": "KÊp mÊrete bÃĄjtokban", - "deduplication_criteria_2": "EXIF adatok mennyisÊge", - "deduplication_info": "DeduplikÃĄciÃŗs infÃŗ", - "deduplication_info_description": "Az automatikus elővÃĄlogatÃĄshoz Ês a duplikÃĄtumok tÃļmeges eltÃĄvolítÃĄsÃĄhoz a kÃļvetkezőket vizsgÃĄljuk:", + "default_locale": "AlapÊrtelmezett nyelvi beÃĄllítÃĄs", + "default_locale_description": "A dÃĄtumok Ês szÃĄmok formÃĄzÃĄsa a bÃļngÊsző nyelvi beÃĄllítÃĄsai alapjÃĄn", "delete": "TÃļrlÊs", "delete_action_confirmation_message": "Biztosan tÃļrÃļlni szeretnÊd ezt az elemet? Így az elem a szerver lomtÃĄrÃĄba kerÃŧl, Ês megkÊrdezi, hogy tÃļrÃļlni szeretnÊd-e a az eszkÃļzÃļn is", "delete_action_prompt": "{count} tÃļrÃļlve", @@ -970,7 +969,7 @@ "downloading_media": "MÊdia letÃļltÊse", "drop_files_to_upload": "A feltÃļltÊshez hÃēzd bÃĄrhova a fÃĄjlokat", "duplicates": "DuplikÃĄtumok", - "duplicates_description": "JelÃļld meg a duplikÃĄtumokat (ha lÊteznek) a csoportokban", + "duplicates_description": "JelÃļld meg a duplikÃĄtumokat (ha lÊteznek) a csoportokban.", "duration": "Időtartam", "edit": "SzerkesztÊs", "edit_album": "Album mÃŗdosítÃĄsa", @@ -1387,9 +1386,11 @@ "library_page_sort_title": "Album címe", "licenses": "Licencek", "light": "VilÃĄgos", + "light_theme": "VilÃĄgos tÊmÃĄra vÃĄltÃĄs", "like": "Tetszik", "like_deleted": "ReakciÃŗ tÃļrÃļlve", "link_motion_video": "Motion videÃŗ hozzÃĄrendelÊse", + "link_to_docs": "TovÃĄbbi informÃĄciÃŗÃŠrt nÊzd meg a dokumentÃĄciÃŗt.", "link_to_oauth": "CsatlakoztatÃĄs OAuth-hoz", "linked_oauth_account": "Csatlakoztatott OAuth fiÃŗk", "list": "Lista", @@ -1651,6 +1652,7 @@ "only_favorites": "Csak kedvencek", "open": "Nyitva", "open_calendar": "NaptÃĄr megnyitÃĄsa", + "open_in_browser": "MegnyitÃĄs bÃļngÊszőben", "open_in_map_view": "MegnyitÃĄs tÊrkÊp nÊzetben", "open_in_openstreetmap": "MegnyitÃĄs OpenStreetMap-ben", "open_the_search_filters": "KeresÊsi szÅąrők megnyitÃĄsa", @@ -2393,6 +2395,7 @@ "viewer_remove_from_stack": "EltÃĄvolítÃĄs a csoportbÃŗl", "viewer_stack_use_as_main_asset": "Fő elemnek beÃĄllítÃĄs", "viewer_unstack": "Csoport megszÃŧntetÊse", + "visibility": "LÃĄthatÃŗsÃĄg", "visibility_changed": "{count, plural, other {# szemÊly}} lÃĄthatÃŗsÃĄga megvÃĄltozott", "visual": "VizuÃĄlis", "visual_builder": "VizuÃĄlis ÃļsszerakÃŗ", diff --git a/i18n/id.json b/i18n/id.json index cae842d1c6..f2d34116cb 100644 --- a/i18n/id.json +++ b/i18n/id.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Pengguna {email} berhasil dihapus.", "users_page_description": "Halaman pengguna admin", "version_check_enabled_description": "Aktifkan pemeriksaan versi", - "version_check_implications": "Fitur pemeriksaan versi tergantung pada komunikasi berkala dengan github.com", + "version_check_implications": "Fitur pemeriksaan versi tergantung pada komunikasi berkala dengan {server}", "version_check_settings": "Pemeriksaan Versi", "version_check_settings_description": "Aktifkan/nonaktifkan notifikasi versi baru", "video_conversion_job": "Transkode video", @@ -849,9 +849,12 @@ "create_link_to_share": "Buat tautan untuk dibagikan", "create_link_to_share_description": "Biarkan siapa pun dengan tautan melihat foto yang dipilih", "create_new": "BUAT BARU", + "create_new_face": "Buat wajah baru", "create_new_person": "Buat orang baru", "create_new_person_hint": "Tetapkan aset yang dipilih ke orang yang baru", "create_new_user": "Buat pengguna baru", + "create_person": "Buat orang", + "create_person_subtitle": "Tambahkan nama pada wajah yang dipilih untuk membuat dan menandai orang baru", "create_shared_album_page_share_add_assets": "TAMBAHKAN ASET", "create_shared_album_page_share_select_photos": "Pilih Foto", "create_shared_link": "Buat tautan bersama", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Diperbaiki", "crop_aspect_ratio_free": "Bebas", "crop_aspect_ratio_original": "Asli", + "crop_aspect_ratio_square": "Persegi", "curated_object_page_title": "Benda", "current_device": "Perangkat saat ini", "current_pin_code": "Kode PIN saat ini", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM yyyy", "dark": "Gelap", - "dark_theme": "Nyalakan mode gelap", + "dark_theme": "Beralih ke tema gelap", "date": "Tanggal", "date_after": "Tanggal setelah", "date_and_time": "Tanggal dan Waktu", @@ -891,10 +895,8 @@ "day": "Hari", "days": "Hari", "deduplicate_all": "Hapus semua duplikat", - "deduplication_criteria_1": "Ukuran gambar dalam bita", - "deduplication_criteria_2": "Hitungan data EXIF", - "deduplication_info": "Info deduplikasi", - "deduplication_info_description": "Untuk memilih aset secara otomatis dan menghapus duplikat secara massal, kami melihat:", + "default_locale": "Bahasa Default", + "default_locale_description": "Sesuaikan format tanggal dan angka sesuai dengan pengaturan wilayah browser Anda", "delete": "Hapus", "delete_action_confirmation_message": "Yakin ingin menghapus aset ini? Tindakan ini akan memindahkan aset ke tempat sampah pada server dan akan mengkonfirmasi apakah Anda ingin menghapusnya juga secara lokal", "delete_action_prompt": "{count} item telah dihapus", @@ -970,7 +972,7 @@ "downloading_media": "Mengunduh media", "drop_files_to_upload": "Lepaskan file di mana saja untuk mengunggah", "duplicates": "Duplikat", - "duplicates_description": "Selesaikan setiap kelompok dengan menunjukkan mana, jika ada, yang merupakan duplikat", + "duplicates_description": "Selesaikan setiap kelompok dengan menunjukkan mana saja yang merupakan duplikat, jika ada.", "duration": "Durasi", "edit": "Edit", "edit_album": "Edit album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Judul album", "licenses": "Lisensi", "light": "Terang", + "light_theme": "Ganti ke mode terang", "like": "Suka", "like_deleted": "Suka dihapus", "link_motion_video": "Tautan video gerak", + "link_to_docs": "Untuk informasi lebih lanjut, silakan lihat dokumentasi.", "link_to_oauth": "Tautkan ke OAuth", "linked_oauth_account": "Akun OAuth tertaut", "list": "Daftar", @@ -2213,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Tag aset", "tag_created": "Tag yang dibuat: {tag}", + "tag_face": "Tandai wajah", "tag_feature_description": "Menjelajahi foto dan video yang dikelompokkan berdasarkan topik tag yang logis", "tag_not_found_question": "Tidak dapat menemukan tag? Buat tag baru.", "tag_people": "Beri Tag Orang", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Keluarkan dari Tumpukan", "viewer_stack_use_as_main_asset": "Gunakan sebagai aset utama", "viewer_unstack": "Lepas tumpukan", + "visibility": "Visibilitas", "visibility_changed": "Keterlihatan diubah untuk {count, plural, one {# orang} other {# orang}}", "visual": "Visual", "visual_builder": "Pembangun visual", diff --git a/i18n/is.json b/i18n/is.json index a355b71661..7d15b0fd69 100644 --- a/i18n/is.json +++ b/i18n/is.json @@ -421,7 +421,7 @@ "user_successfully_removed": "Notandi {email} hefur verið fjarlÃĻgður.", "users_page_description": "Síða stjÃŗrnunarnotanda", "version_check_enabled_description": "Virkja athugun ÃĄ ÃētgÃĄfu", - "version_check_implications": "Þessi athugun hefur lotubundin samskipti við github.com", + "version_check_implications": "Þessi athugun hefur lotubundin samskipti við {server}", "version_check_settings": "Athugun ÃētgÃĄfu", "version_check_settings_description": "Af-/virkja meldingu um nÃŊja ÃētgÃĄfu", "video_conversion_job": "UmkÃŗÃ°a myndbÃļnd", diff --git a/i18n/it.json b/i18n/it.json index 75e230654b..d51e45b37b 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -441,7 +441,7 @@ "user_successfully_removed": "L'utente {email} è stato rimosso con successo.", "users_page_description": "Pagina utenti (admin)", "version_check_enabled_description": "Abilita controllo della versione", - "version_check_implications": "La funzione di controllo della versione fa uso di una comunicazione periodica con github.com", + "version_check_implications": "La funzione di controllo della versione fa uso di una comunicazione periodica con {server}", "version_check_settings": "Controllo Versione", "version_check_settings_description": "Abilita/disabilita la notifica per nuove versioni", "video_conversion_job": "Transcodifica video", @@ -849,9 +849,12 @@ "create_link_to_share": "Crea link da condividere", "create_link_to_share_description": "Permetti a chiunque con il link di vedere le foto selezionate", "create_new": "CREA NUOVO", + "create_new_face": "Crea nuova faccia", "create_new_person": "Crea nuova persona", "create_new_person_hint": "Assegna le risorse selezionate a una nuova persona", "create_new_user": "Crea nuovo utente", + "create_person": "Crea persona", + "create_person_subtitle": "Aggiungi un nome alla faccia selezionata per creare e taggare la nuova persona", "create_shared_album_page_share_add_assets": "AGGIUNGI RISORSE", "create_shared_album_page_share_select_photos": "Seleziona foto", "create_shared_link": "Crea link condiviso", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fisso", "crop_aspect_ratio_free": "Libero", "crop_aspect_ratio_original": "Originale", + "crop_aspect_ratio_square": "Quadrato", "curated_object_page_title": "Oggetti", "current_device": "Dispositivo attuale", "current_pin_code": "Attuale codice PIN", @@ -891,10 +895,8 @@ "day": "Giorno", "days": "Giorni", "deduplicate_all": "Elimina tutti i doppioni", - "deduplication_criteria_1": "Dimensione immagine in bytes", - "deduplication_criteria_2": "Numero di dati EXIF", - "deduplication_info": "Informazioni di deduplicazione", - "deduplication_info_description": "Per preselezionare automaticamente le risorse e rimuovere i duplicati in massa, verifichiamo:", + "default_locale": "Predefinito Locale", + "default_locale_description": "Formatta le date e i numeri sulla base del tuo browser locale", "delete": "Elimina", "delete_action_confirmation_message": "Vuoi davvero eliminare questa risorsa? Questa azione sposterà la risorsa nel cestino del server e ti chiederà se desideri eliminarla dal dispositivo", "delete_action_prompt": "{count} elementi eliminati", @@ -970,7 +972,7 @@ "downloading_media": "Scaricamento file multimediali", "drop_files_to_upload": "Rilascia i file ovunque per caricarli", "duplicates": "Duplicati", - "duplicates_description": "Risolvi ciascun gruppo indicando quali sono, se esistono, i duplicati", + "duplicates_description": "Risolvi ciascun gruppo indicando quali sono, se esistono, i duplicati.", "duration": "Durata", "edit": "Modifica", "edit_album": "Modifica album", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Modifiche applicate con successo", "editor_flip_horizontal": "Capovolgi in orizzontale", "editor_flip_vertical": "Capovolgi in verticale", + "editor_handle_corner": "angolo {corner, select, top_left {Alto a sinistra} top_right {Alto a destra} bottom_left {Basso a sinistra} bottom_right {Basso a destra} other {A}}", + "editor_handle_edge": "bordo {edge, select, top {Alto} bottom {Basso} left {Sinistro} right {Destro} other {Altro}}", "editor_orientation": "Orientamento", "editor_reset_all_changes": "Annulla modifiche", "editor_rotate_left": "Ruota di 90° antiorario", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Titolo album", "licenses": "Licenze", "light": "Chiaro", + "light_theme": "Cambia a tema chiaro", "like": "Mi piace", "like_deleted": "Mi piace rimosso", "link_motion_video": "Collega video in movimento", + "link_to_docs": "Per maggiori informazioni, riferirsi al documentazione.", "link_to_oauth": "Collegamento a OAuth", "linked_oauth_account": "Account OAuth collegato", "list": "Lista", @@ -2211,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Tagga risorse", "tag_created": "Tag creato: {tag}", + "tag_face": "Tagga la faccia", "tag_feature_description": "Navigazione foto e video raggruppati per argomenti tag logici", "tag_not_found_question": "Non riesci a trovare un tag? Creane uno nuovo.", "tag_people": "Tagga persone", @@ -2392,6 +2399,7 @@ "viewer_remove_from_stack": "Rimuovi dal gruppo", "viewer_stack_use_as_main_asset": "Usa come risorsa principale", "viewer_unstack": "Separa dal gruppo", + "visibility": "Visibilità", "visibility_changed": "Visibilità modificata per {count, plural, one {# persona} other {# persone}}", "visual": "Visuale", "visual_builder": "Costruttore di visuale", diff --git a/i18n/ja.json b/i18n/ja.json index cd98b391ef..144c52ba83 100644 --- a/i18n/ja.json +++ b/i18n/ja.json @@ -53,7 +53,7 @@ "authentication_settings": "čĒč¨ŧč¨­åŽš", "authentication_settings_description": "čĒč¨ŧč¨­åŽšãŽįŽĄį†īŧˆãƒ‘゚ワãƒŧド、OAuth、そぎäģ–īŧ‰", "authentication_settings_disable_all": "æœŦåŊ“ãĢすずãĻãŽãƒ­ã‚°ã‚¤ãƒŗæ–šæŗ•ã‚’į„ĄåŠšãĢしぞすかīŧŸ ãƒ­ã‚°ã‚¤ãƒŗãŒåŽŒå…¨ãĢできãĒくãĒりぞす。", - "authentication_settings_reenable": "å†ãŗæœ‰åŠšãĢするãĢは、ã‚ĩãƒŧバãƒŧã‚ŗãƒžãƒŗãƒ‰ã‚’äŊŋį”¨ã—ãĻください。", + "authentication_settings_reenable": "再åēĻæœ‰åŠšãĢするãĢは、ã‚ĩãƒŧバãƒŧã‚ŗãƒžãƒŗãƒ‰ã‚’äŊŋį”¨ã—ãĻください。", "background_task_job": "バックグナã‚Ļãƒŗãƒ‰ã‚ŋ゚ク", "backup_database": "デãƒŧã‚ŋベãƒŧ゚ぎバックã‚ĸップをäŊœæˆ", "backup_database_enable_description": "デãƒŧã‚ŋベãƒŧ゚ぎバックã‚ĸップを有劚ãĢする", @@ -62,7 +62,7 @@ "backup_onboarding_2_description": "åˆĨ々ぎデバイ゚上ぎロãƒŧã‚ĢãƒĢã‚ŗãƒ”ãƒŧã€‚ã“ã‚Œã¯ãƒĄã‚¤ãƒŗãƒ•ã‚Ąã‚¤ãƒĢやそぎロãƒŧã‚ĢãƒĢバックã‚ĸãƒƒãƒ—ãƒ•ã‚Ąã‚¤ãƒĢをåĢãŋぞす。", "backup_onboarding_3_description": "あãĒたぎすずãĻぎデãƒŧã‚ŋ(1つぎã‚Ēフã‚ĩã‚¤ãƒˆã‚ŗãƒ”ãƒŧと2つぎロãƒŧã‚ĢãƒĢã‚ŗãƒ”ãƒŧをåĢむ)ãŽã‚ŗãƒ”ãƒŧ。", "backup_onboarding_description": "デãƒŧã‚ŋäŋč­ˇãĢは、3-2-1バックã‚ĸップæˆĻį•ĨãŽåˆŠį”¨ã‚’æŽ¨åĨ¨ã—ãžã™ã€‚å†™įœŸãƒģ動į”ģデãƒŧã‚ŋとImmichぎデãƒŧã‚ŋベãƒŧ゚をあわせãĻバックã‚ĸップすることで、より厉全ãĢäŋįŽĄã§ããžã™ã€‚", - "backup_onboarding_footer": "Immichぎバックã‚ĸップãĢé–ĸã™ã‚‹æƒ…å ąã¯ã€ãƒ‰ã‚­ãƒĨãƒĄãƒŗãƒ†ãƒŧã‚ˇãƒ§ãƒŗã‚’įĸēčĒã—ãĻください。", + "backup_onboarding_footer": "Immichぎバックã‚ĸップãĢé–ĸã™ã‚‹æƒ…å ąã¯ã€ãƒ‰ã‚­ãƒĨãƒĄãƒŗãƒˆã‚’įĸēčĒã—ãĻください。", "backup_onboarding_parts_title": "3-2-1バックã‚ĸップ:", "backup_onboarding_title": "バックã‚ĸップ", "backup_settings": "デãƒŧã‚ŋベãƒŧ゚ぎバックã‚ĸãƒƒãƒ—ãŽč¨­åŽš", @@ -126,7 +126,7 @@ "library_created": "äŊœæˆã•れたナイブナãƒĒīŧš{library}", "library_deleted": "ナイブナãƒĒは削除されぞした", "library_details": "ナイブナãƒĒãŽčŠŗį´°", - "library_folder_description": "ã‚¤ãƒŗãƒãƒŧトするフりãƒĢダを指厚しãĻください、ã‚ĩブフりãƒĢダãƒŧ内をåĢむį”ģ像と動į”ģãŒã‚šã‚­ãƒŖãƒŗã•ã‚Œãžã™", + "library_folder_description": "ã‚¤ãƒŗãƒãƒŧトするフりãƒĢダを指厚しãĻください。こぎフりãƒĢダ内(ã‚ĩブフりãƒĢダをåĢむ)ぎį”ģ像と動į”ģãŒã‚šã‚­ãƒŖãƒŗã•ã‚Œãžã™ã€‚", "library_remove_exclusion_pattern_prompt": "こぎ除外パã‚ŋãƒŧãƒŗã‚’å‰Šé™¤ã—ãĻよいですかīŧŸ", "library_remove_folder_prompt": "ã“ãŽã‚¤ãƒŗãƒãƒŧトフりãƒĢãƒ€ã‚’č§Ŗé™¤ã—ãžã™ã‹īŧŸ", "library_scanning": "åŽšæœŸã‚šã‚­ãƒŖãƒŗ", @@ -150,7 +150,7 @@ "machine_learning_availability_checks_timeout": "ãƒĒクエ゚トã‚ŋイムã‚ĸã‚Ļト", "machine_learning_availability_checks_timeout_description": "å¯į”¨æ€§ãƒã‚§ãƒƒã‚¯ãŽã‚ŋイムã‚ĸã‚Ļト時間īŧˆãƒŸãƒĒį§’å˜äŊīŧ‰", "machine_learning_clip_model": "ClipãƒĸデãƒĢ", - "machine_learning_clip_model_description": "CLIP ãƒĸデãƒĢぎ名前はここãĢãƒĒ゚トされãĻいぞす。ãƒĸデãƒĢを変更した場合は、すずãĻãŽã‚¤ãƒĄãƒŧジãĢ寞しãĻ「゚マãƒŧト検į´ĸã€ã‚¸ãƒ§ãƒ–ã‚’å†åŽŸčĄŒã™ã‚‹åŋ…čĻãŒã‚ã‚Šãžã™ã€‚", + "machine_learning_clip_model_description": "ã“ãĄã‚‰ãĢ記čŧ‰ã•れãĻいるCLIPãƒĸデãƒĢãŽåį§°ã‚’æŒ‡åŽšã—ãžã™ã€‚ãƒĸデãƒĢを変更した場合は、すずãĻぎį”ģ像ãĢ寞しãĻ「゚マãƒŧト検į´ĸã€ã‚¸ãƒ§ãƒ–ã‚’å†åŽŸčĄŒã™ã‚‹åŋ…čĻãŒã‚ã‚Šãžã™ã€‚", "machine_learning_duplicate_detection": "é‡č¤‡æ¤œå‡ē", "machine_learning_duplicate_detection_enabled": "é‡č¤‡æ¤œå‡ēぎ有劚化", "machine_learning_duplicate_detection_enabled_description": "į„ĄåŠšãĢした場合でも、厌全ãĢ同一ã‚ĸã‚ģãƒƒãƒˆãŽé‡č¤‡ã¯æŽ’é™¤ã•ã‚Œãžã™ã€‚", @@ -272,7 +272,7 @@ "oauth_auto_register": "č‡Ē動į™ģ錞", "oauth_auto_register_description": "OAuthでã‚ĩã‚¤ãƒŗã‚¤ãƒŗã—ãŸã‚ã¨ã€č‡Ēå‹•įš„ãĢ新čĻãƒĻãƒŧã‚ļãƒŧをį™ģéŒ˛ã™ã‚‹", "oauth_button_text": "ボã‚ŋãƒŗãƒ†ã‚­ã‚šãƒˆ", - "oauth_client_secret_description": "OAuthプロバイダãƒŧがPKCEをã‚ĩポãƒŧトしãĻいãĒい場合はåŋ…čρ", + "oauth_client_secret_description": "抟密クナイã‚ĸãƒŗãƒˆã€ãžãŸã¯å…Ŧ開クナイã‚ĸãƒŗãƒˆã§PKCEがã‚ĩポãƒŧトされãĻいãĒい場合ãĢåŋ…須です。", "oauth_enable_description": "OAuthã§ãƒ­ã‚°ã‚¤ãƒŗ", "oauth_mobile_redirect_uri": "ãƒĸバイãƒĢᔍãƒĒダイãƒŦクトURI", "oauth_mobile_redirect_uri_override": "ãƒĸバイãƒĢᔍãƒĒダイãƒŦクトURIīŧˆä¸Šæ›¸ãīŧ‰", @@ -311,7 +311,7 @@ "search_jobs": "ジョブを検į´ĸâ€Ļ", "send_welcome_email": "ã‚ĻェãƒĢã‚Ģム ãƒĄãƒŧãƒĢ を送äŋĄã—ぞす", "server_external_domain_settings": "å¤–éƒ¨ãƒ‰ãƒĄã‚¤ãƒŗ", - "server_external_domain_settings_description": "å…Ŧé–‹å…ąæœ‰ãƒĒãƒŗã‚¯į”¨ãŽãƒ‰ãƒĄã‚¤ãƒŗīŧˆ http(s):// をåĢめるīŧ‰", + "server_external_domain_settings_description": "外部ãƒĒãƒŗã‚¯į”¨ãŽãƒ‰ãƒĄã‚¤ãƒŗ", "server_public_users": "å…Ŧ開ãƒĻãƒŧã‚ļãƒŧ", "server_public_users_description": "å…ąæœ‰ã‚ĸãƒĢバムãĢãƒĻãƒŧã‚ļãƒŧをčŋŊ加するとすずãĻぎãƒĻãƒŧã‚ļãƒŧ (åå‰ã¨ãƒĄãƒŧãƒĢã‚ĸドãƒŦ゚) がãƒĒã‚šãƒˆåŒ–ã•ã‚Œãžã™ã€‚į„ĄåŠšãĢするとãƒĻãƒŧã‚ļãƒŧãƒĒã‚šãƒˆã¯įŽĄį†č€…ãŽãŋåˆŠį”¨å¯čƒŊãĢãĒりぞす。", "server_settings": "ã‚ĩãƒŧバãƒŧč¨­åŽš", @@ -333,7 +333,7 @@ "storage_template_migration_description": "įžåœ¨ãŽ{template}をäģĨ前ãĢã‚ĸップロãƒŧドされたã‚ĸã‚ģットãĢéŠį”¨", "storage_template_migration_info": "゚トãƒŦãƒŧã‚¸ãƒ†ãƒŗãƒ—ãƒŦãƒŧトは全ãĻãŽæ‹Ąåŧĩ子を小文字ãĢå¤‰æ›ã—ãžã™ã€‚ãƒ†ãƒŗãƒ—ãƒŦãƒŧトぎ変更は新しいã‚ĸã‚ģットãĢぎãŋéŠį”¨ã•ã‚Œãžã™ã€‚ äģĨ前ãĢã‚ĸップロãƒŧドしたã‚ĸã‚ģットãĢãƒ†ãƒŗãƒ—ãƒŦãƒŧãƒˆã‚’éĄãŖãĻéŠį”¨ã™ã‚‹ãĢは、{job} ã‚’åŽŸčĄŒã—ãĻください。", "storage_template_migration_job": "゚トãƒŦãƒŧã‚¸ãƒ†ãƒŗãƒ—ãƒŦãƒŧトį§ģčĄŒã‚¸ãƒ§ãƒ–", - "storage_template_more_details": "こぎ抟čƒŊãŽčŠŗį´°ãĢついãĻは、゚トãƒŦãƒŧã‚¸ãƒ†ãƒŗãƒ—ãƒŦãƒŧトとそぎåŊąéŸŋã‚’å‚į…§ã—ãĻください", + "storage_template_more_details": "こぎ抟čƒŊãŽčŠŗį´°ãĢついãĻは、゚トãƒŦãƒŧã‚¸ãƒ†ãƒŗãƒ—ãƒŦãƒŧãƒˆãŠã‚ˆãŗããŽåŊąéŸŋäē‹é …ã‚’å‚į…§ã—ãĻください", "storage_template_onboarding_description_v2": "ã“ãŽč¨­åŽšã‚’ã‚ĒãƒŗãĢすると、ãƒĻãƒŧã‚ļãƒŧãŽåŽšįžŠã—ãŸãƒ†ãƒŗãƒ—ãƒŦãƒŧトãĢåž“ãŖãĻč‡Ēå‹•ã§ãƒ•ã‚Ąã‚¤ãƒĢãŒæ•´į†ã•ã‚Œãžã™ã€‚čŠŗã—ã„æƒ…å ąã¯ãƒ‰ã‚­ãƒĨãƒĄãƒŗãƒ†ãƒŧã‚ˇãƒ§ãƒŗã§įĸēčĒã—ãĻください。", "storage_template_path_length": "ãŠãŠã‚ˆããŽãƒ‘ã‚šé•ˇãŽåˆļ限: {length, number}/{limit, number}", "storage_template_settings": "゚トãƒŦãƒŧジ ãƒ†ãƒŗãƒ—ãƒŦãƒŧト", @@ -411,7 +411,7 @@ "transcoding_tone_mapping": "トãƒŧãƒŗãƒžãƒƒãƒ”ãƒŗã‚°", "transcoding_tone_mapping_description": "HDR動į”ģをSDRãĢ変換する際ãĢčĻ‹ãŸį›Žã‚’įļ­æŒã—ようとčŠĻãŋぞす。各ã‚ĸãƒĢゴãƒĒã‚ēãƒ ã¯ã€č‰˛ã€čŠŗį´°ã€æ˜Žã‚‹ã•ãĢ寞しãĻį•°ãĒるトãƒŦãƒŧドã‚Ēãƒ•ã‚’čĄŒã„ãžã™ã€‚Hableã¯čŠŗį´°ã‚’įļ­æŒã—、Mobiusã¯č‰˛ã‚’įļ­æŒã—、Reinhardは明るさをįļ­æŒã—ぞす。", "transcoding_transcode_policy": "ãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧドポãƒĒã‚ˇãƒŧ", - "transcoding_transcode_policy_description": "動į”ģãŒãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧドされるずきかをæąēめるポãƒĒã‚ˇãƒŧ。HDR動į”ģは常ãĢãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧドされぞす(ãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧãƒ‰ãŒį„ĄåŠšåŒ–ã•ã‚ŒãĻいる場合を除く)。", + "transcoding_transcode_policy_description": "動į”ģãŽãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧドポãƒĒã‚ˇãƒŧ。HDR動į”ģã€ãŠã‚ˆãŗYUV 4:2:0äģĨ外ぎピクã‚ģãƒĢフりãƒŧマットぎ動į”ģは、常ãĢãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧドされぞす。(ãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧãƒ‰ãŒį„ĄåŠšãĒ場合を除く)", "transcoding_two_pass_encoding": "Two-passã‚¨ãƒŗã‚ŗãƒŧド", "transcoding_two_pass_encoding_setting_description": "äēŒã¤ãŽãƒ‘ã‚šã§ãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧãƒ‰ã—ã€ã‚ˆã‚Šã‚ˆãã‚¨ãƒŗã‚ŗãƒŧドされた動į”ģã‚’į”Ÿæˆã—ãžã™ã€‚æœ€å¤§ãƒ“ãƒƒãƒˆãƒŦãƒŧトが有劚ãĢãĒãŖãĻいる場合(H.264とHEVCが動äŊœã™ã‚‹ãŸã‚ãĢåŋ…čρ)、こぎãƒĸãƒŧドは最大ビットãƒŦãƒŧトをåŸēãĢしたビットãƒŦãƒŧãƒˆãŽį¯„å›˛ã‚’äŊŋį”¨ã—ã€CRFã‚’į„ĄčĻ–ã—ãžã™ã€‚VP9ãĢついãĻは最大ビットãƒŦãƒŧãƒˆãŽį„ĄåŠšæ™‚ãĢCRFをäŊŋうことができぞす。", "transcoding_video_codec": "動į”ģã‚ŗãƒŧデック", @@ -441,7 +441,7 @@ "user_successfully_removed": "ãƒĻãƒŧã‚ļãƒŧ {email} ã¯æ­Ŗå¸¸ãĢ削除されぞした。", "users_page_description": "įŽĄį†č€…į”¨ ãƒĻãƒŧã‚ļãƒŧ ペãƒŧジ", "version_check_enabled_description": "バãƒŧã‚¸ãƒ§ãƒŗãŽįĸēčĒã‚’æœ‰åŠšãĢする", - "version_check_implications": "こぎバãƒŧã‚¸ãƒ§ãƒŗįĸēčĒæŠŸčƒŊã¯åŽšæœŸįš„ãĒgithub.comとぎ通äŋĄãĢよりぞす", + "version_check_implications": "こぎバãƒŧã‚¸ãƒ§ãƒŗįĸēčĒæŠŸčƒŊã¯åŽšæœŸįš„ãĒ{server}とぎ通äŋĄãĢよりぞす", "version_check_settings": "バãƒŧã‚¸ãƒ§ãƒŗãƒã‚§ãƒƒã‚¯", "version_check_settings_description": "新しいバãƒŧã‚¸ãƒ§ãƒŗãŽé€šįŸĨを有劚/į„ĄåŠšãĢしぞす", "video_conversion_job": "動į”ģã‚’ãƒˆãƒŠãƒŗã‚šã‚ŗãƒŧド", @@ -794,6 +794,11 @@ "color": "ã‚Ģナãƒŧ", "color_theme": "ã‚Ģナãƒŧテãƒŧマ", "command": "ã‚ŗãƒžãƒŗãƒ‰", + "command_palette_prompt": "ペãƒŧジ、ã‚ĸã‚¯ã‚ˇãƒ§ãƒŗã€ã‚ŗãƒžãƒŗãƒ‰ã‚’į´ æ—Šãæ¤œį´ĸ", + "command_palette_to_close": "閉じる", + "command_palette_to_navigate": "æąē厚", + "command_palette_to_select": "選択", + "command_palette_to_show_all": "すずãĻ襨į¤ē", "comment_deleted": "ã‚ŗãƒĄãƒŗãƒˆãŒå‰Šé™¤ã•ã‚Œãžã—ãŸ", "comment_options": "ã‚ŗãƒĄãƒŗãƒˆč¨­åŽš", "comments_and_likes": "ã‚ŗãƒĄãƒŗãƒˆã¨ã„ã„ã­", @@ -844,9 +849,12 @@ "create_link_to_share": "å…ąæœ‰ãƒĒãƒŗã‚¯ã‚’äŊœã‚‹", "create_link_to_share_description": "ãƒĒãƒŗã‚¯ã‚’įŸĨãŖãĻいるäēēå…¨å“ĄãŒé¸æŠžã—ãŸå†™įœŸã‚’é–˛čĻ§ã§ãã‚‹ã‚ˆã†ãĢãĒりぞす", "create_new": "新čĻäŊœæˆ", + "create_new_face": "æ–°ã—ã„éĄ”ã‚’äŊœæˆ", "create_new_person": "新しいäēēį‰Šã‚’äŊœæˆ", "create_new_person_hint": "é¸æŠžã—ãŸå†™įœŸ/動į”ģを新しいäēēį‰Šã¨ã—ãĻå‰˛ã‚ŠåŊ“ãĻ", "create_new_user": "新čĻãƒĻãƒŧã‚ļãƒŧぎäŊœæˆ", + "create_person": "äēēをäŊœæˆ", + "create_person_subtitle": "é¸æŠžã—ãŸéĄ”ãĢ名前をäģ˜ã‘ãĻ、新しいäēēį‰Šã‚’į™ģ錞ãƒģã‚ŋグäģ˜ã‘する", "create_shared_album_page_share_add_assets": "å†™įœŸã‚’čŋŊ加", "create_shared_album_page_share_select_photos": "å†™įœŸã‚’é¸æŠž", "create_shared_link": "å…ąæœ‰ãƒĒãƒŗã‚¯ã‚’äŊœæˆ", @@ -861,13 +869,14 @@ "crop_aspect_ratio_fixed": "å›ē厚", "crop_aspect_ratio_free": "č‡Ēį”ą", "crop_aspect_ratio_original": "ã‚ĒãƒĒジナãƒĢ", + "crop_aspect_ratio_square": "゚クエã‚ĸ", "curated_object_page_title": "čĸĢ写äŊ“", "current_device": "įžåœ¨ãŽãƒ‡ãƒã‚¤ã‚š", "current_pin_code": "įžåœ¨ãŽPINã‚ŗãƒŧド", "current_server_address": "įžåœ¨ãŽã‚ĩãƒŧバãƒŧURL", "custom_date": "ã‚Ģ゚ã‚ŋムæ—Ĩäģ˜", - "custom_locale": "ã‚Ģ゚ã‚ŋãƒ ãƒ­ã‚ąãƒŧãƒĢ", - "custom_locale_description": "言čĒžã¨åœ°åŸŸãĢåŸēãĨいãĻæ—Ĩäģ˜ã¨æ•°å€¤ã‚’フりãƒŧマットしぞす", + "custom_locale": "言čĒžã¨åœ°åŸŸãŽæ‰‹å‹•č¨­åŽš", + "custom_locale_description": "é¸æŠžã—ãŸč¨€čĒžã¨åœ°åŸŸãŽč¨­åŽšãĢåž“ãŖãĻ、æ—Ĩäģ˜ãƒģ時åˆģãƒģ数値を書åŧč¨­åŽšã—ãžã™", "custom_url": "ã‚Ģ゚ã‚ŋムURL", "cutoff_date_description": "å†™įœŸã‚’äŋæŒã™ã‚‹æœŸé–“:", "cutoff_day": "{count, plural, one {(æ—Ĩ)} other {(æ—Ĩ)}}", @@ -875,7 +884,7 @@ "daily_title_text_date": "MM DD, EE", "daily_title_text_date_year": "yyyy MM DD, EE", "dark": "ダãƒŧクãƒĸãƒŧド", - "dark_theme": "ダãƒŧクãƒĸãƒŧド切りæ›ŋえ", + "dark_theme": "ダãƒŧクãƒĸãƒŧドãĢ切りæ›ŋえ", "date": "æ—Ĩäģ˜", "date_after": "こぎæ—ĨäģĨ降", "date_and_time": "æ—Ĩäģ˜ã¨æ™‚é–“", @@ -886,10 +895,8 @@ "day": "ナイトãƒĸãƒŧド", "days": "æ—Ĩ", "deduplicate_all": "全ãĻé‡č¤‡æŽ’é™¤", - "deduplication_criteria_1": "バイト単äŊãŽį”ģ像ã‚ĩイã‚ē", - "deduplication_criteria_2": "EXIFデãƒŧã‚ŋ数", - "deduplication_info": "é‡č¤‡æŽ’é™¤æƒ…å ą", - "deduplication_info_description": "å†™įœŸ/動į”ģをč‡Ēå‹•įš„ãĢ選択しãĻé‡č¤‡ã‚’ä¸€æ‹Ŧで削除するãĢはæŦĄãŽã‚ˆã†ãĢしぞす:", + "default_locale": "デフりãƒĢãƒˆãŽč¨€čĒžã¨åœ°åŸŸ", + "default_locale_description": "ブナã‚Ļã‚ļãŽč¨€čĒžã¨åœ°åŸŸãŽč¨­åŽšãĢåŸēãĨいãĻ、æ—Ĩäģ˜ã¨æ•°å€¤ã‚’フりãƒŧマットしぞす", "delete": "削除", "delete_action_confirmation_message": "ã“ãŽé …į›Žã‚’å‰Šé™¤ã—ãžã™ã‹īŧŸãžãšã€ã“ãŽé …į›Žã¯ã‚ĩãƒŧバãƒŧä¸ŠãŽã‚´ãƒŸįŽąã¸į§ģ動されぞす。そぎ垌、あãĒたぎデバイ゚上から削除するかをæąēめãĻいただきぞす", "delete_action_prompt": "{count}é …į›Žã‚’å‰Šé™¤ã—ãžã—ãŸ", @@ -965,7 +972,7 @@ "downloading_media": "ダã‚Ļãƒŗãƒ­ãƒŧド中", "drop_files_to_upload": "ãƒ•ã‚Ąã‚¤ãƒĢをドロップしãĻã‚ĸップロãƒŧド", "duplicates": "重複", - "duplicates_description": "ã‚‚ã—ã‚ã‚Œã°ã€é‡č¤‡ã—ãĻいるグãƒĢãƒŧプをį¤ēã™ã“ã¨ã§č§Ŗæąēしぞす", + "duplicates_description": "各グãƒĢãƒŧプをįĸēčĒã—ã€é‡č¤‡ã—ãĻã„ã‚‹é …į›Žã‚’æ•´į†ã—ãĻください。", "duration": "間隔", "edit": "ᎍ集", "edit_album": "ã‚ĸãƒĢãƒãƒ ã‚’įˇ¨é›†", @@ -1002,6 +1009,8 @@ "editor_edits_applied_success": "įˇ¨é›†ãŒæ­Ŗå¸¸ãĢ反映されぞした", "editor_flip_horizontal": "æ°´åšŗæ–šå‘ãĢ反čģĸ", "editor_flip_vertical": "åž‚į›´ãĢ反čģĸ", + "editor_handle_corner": "{corner, select, top_left {åˇĻ上ぎ} top_right {åŗä¸ŠãŽ} bottom_left {åˇĻ下ぎ} bottom_right {åŗä¸‹ãŽ} other {}}ã‚ŗãƒŧナãƒŧãƒãƒŗãƒ‰ãƒĢ", + "editor_handle_edge": "{edge, select, top {上ぎ} bottom {下ぎ} left {åˇĻぎ} right {åŗãŽ} other {}} ã‚ĩã‚¤ãƒ‰ãƒãƒŗãƒ‰ãƒĢ", "editor_orientation": "向き", "editor_reset_all_changes": "変更をãƒĒã‚ģット", "editor_rotate_left": "åæ™‚č¨ˆå›žã‚ŠãĢ90°回čģĸ", @@ -1067,6 +1076,7 @@ "failed_to_update_notification_status": "通įŸĨ゚テãƒŧã‚ŋ゚ぎ更新ãĢå¤ąæ•—ã—ãžã—ãŸ", "incorrect_email_or_password": "ãƒĄãƒŧãƒĢã‚ĸドãƒŦ゚ぞたはパ゚ワãƒŧãƒ‰ãŒé–“é•ãŖãĻいぞす", "library_folder_already_exists": "ã“ãŽã‚¤ãƒŗãƒãƒŧトパ゚はæ—ĸãĢ存在しぞす。", + "page_not_found": "ペãƒŧジがčĻ‹ã¤ã‹ã‚Šãžã›ã‚“", "paths_validation_failed": "{paths, plural, one {#個} other {#個}}ぎパ゚ぎ検č¨ŧãĢå¤ąæ•—ã—ãžã—ãŸ", "profile_picture_transparent_pixels": "ãƒ—ãƒ­ãƒ•ã‚ŖãƒŧãƒĢå†™įœŸãĢは透明ピクã‚ģãƒĢをåĢめることはできぞせん。į”ģåƒã‚’æ‹Ąå¤§/į¸Žå°ã—ãŸã‚Šį§ģ動しãĻください。", "quota_higher_than_disk_size": "ãƒ‡ã‚Ŗã‚šã‚¯åŽšé‡ã‚ˆã‚Šå¤§ãã„åŽšé‡ãŒæŒ‡åŽšã•ã‚Œãžã—ãŸ", @@ -1166,6 +1176,7 @@ "exif_bottom_sheet_people": "äēēį‰Š", "exif_bottom_sheet_person_add_person": "名前をčŋŊ加", "exit_slideshow": "ã‚šãƒŠã‚¤ãƒ‰ã‚ˇãƒ§ãƒŧをįĩ‚わる", + "expand": "åą•é–‹", "expand_all": "全ãĻåą•é–‹", "experimental_settings_new_asset_list_subtitle": "čŖŊäŊœé€”中 (WIP)", "experimental_settings_new_asset_list_title": "čŠĻé¨“įš„ãĒグãƒĒッドを有劚化", @@ -1210,6 +1221,7 @@ "filter_description": "å¯žčąĄã¨ã™ã‚‹ã‚ĸã‚ģットぎæŠŊå‡ēæĄäģļ", "filter_people": "äēēį‰Šã‚’įĩžã‚Ščžŧãŋ", "filter_places": "å ´æ‰€ã‚’ãƒ•ã‚ŖãƒĢã‚ŋãƒŧ", + "filter_tags": "ã‚ŋグでįĩžã‚Ščžŧむ", "filters": "ãƒ•ã‚ŖãƒĢã‚ŋãƒŧ", "find_them_fast": "名前で検į´ĸしãĻį´ æ—Šãį™ēčĻ‹", "first": "はじめ", @@ -1377,9 +1389,11 @@ "library_page_sort_title": "ã‚ĸãƒĢバム名", "licenses": "ナイã‚ģãƒŗã‚š", "light": "ナイトãƒĸãƒŧド", + "light_theme": "ナイトテãƒŧマãĢ切りæ›ŋえ", "like": "いいね", "like_deleted": "いいねが削除されぞした", "link_motion_video": "ãƒĸãƒŧã‚ˇãƒ§ãƒŗãƒ“ãƒ‡ã‚ĒぎãƒĒãƒŗã‚¯", + "link_to_docs": "čŠŗį´°ã¯ãƒ‰ã‚­ãƒĨãƒĄãƒŗãƒˆã‚’å‚į…§ã—ãĻください。", "link_to_oauth": "OAuthへãƒĒãƒŗã‚¯ã™ã‚‹", "linked_oauth_account": "ãƒĒãƒŗã‚¯ã•ã‚ŒãŸOAuthã‚ĸã‚Ģã‚Ļãƒŗãƒˆ", "list": "ãƒĒ゚ト", @@ -1640,6 +1654,8 @@ "online": "ã‚ĒãƒŗãƒŠã‚¤ãƒŗ", "only_favorites": "お気ãĢå…Ĩりぎãŋ", "open": "開く", + "open_calendar": "ã‚ĢãƒŦãƒŗãƒ€ãƒŧを開く", + "open_in_browser": "ブナã‚Ļã‚ļで開く", "open_in_map_view": "åœ°å›ŗčĄ¨į¤ēでčĻ‹ã‚‹", "open_in_openstreetmap": "OpenStreetMapで開く", "open_the_search_filters": "検į´ĸãƒ•ã‚ŖãƒĢã‚ŋを開く", @@ -1799,7 +1815,7 @@ "rate_asset": "é …į›Žã‚’čŠ•äžĄã™ã‚‹", "rating": "æ˜Ÿã§ãŽčŠ•äžĄ", "rating_clear": "čŠ•äžĄã‚’å–ã‚Šæļˆã™", - "rating_count": "星{count, plural, one {#つ} other {#つ}}", + "rating_count": "{count, plural, =0 {æœĒ評価} one {星#つ} other {星#つ}}", "rating_description": "æƒ…å ąæŦ„ãĢEXIFãŽčŠ•äžĄã‚’čĄ¨į¤ē", "reaction_options": "ãƒĒã‚ĸã‚¯ã‚ˇãƒ§ãƒŗãŽé¸æŠž", "read_changelog": "変更åąĨ歴をčĒ­ã‚€", @@ -1872,7 +1888,10 @@ "reset_pin_code_success": "æ­Ŗå¸¸ãĢPINã‚ŗãƒŧドをãƒĒã‚ģットしぞした", "reset_pin_code_with_password": "PINã‚ŗãƒŧドはいつでもパ゚ワãƒŧドをäŊŋãŖãĻãƒĒã‚ģットできぞす", "reset_sqlite": "SQLiteデãƒŧã‚ŋベãƒŧ゚をãƒĒã‚ģット", - "reset_sqlite_confirmation": "SQLiteをæœŦåŊ“ãĢãƒĒã‚ģットしぞすかīŧŸãƒ‡ãƒŧã‚ŋã‚’å†ãŗåŒæœŸã™ã‚‹ãŸã‚ãĢログã‚ĸã‚Ļãƒˆã—å†ãƒ­ã‚°ã‚¤ãƒŗã‚’ã™ã‚‹åŋ…čĻãŒã‚ã‚Šãžã™", + "reset_sqlite_clear_app_data": "デãƒŧã‚ŋをæļˆåŽģ", + "reset_sqlite_confirmation": "æœŦåŊ“ãĢã‚ĸプãƒĒぎデãƒŧã‚ŋをæļˆåŽģしぞすかīŧŸã™ãšãĻãŽč¨­åŽšãŒå‰Šé™¤ã•ã‚Œã€ã‚ĩã‚¤ãƒŗã‚ĸã‚Ļトされぞす。", + "reset_sqlite_confirmation_note": "æŗ¨æ„: æļˆåŽģした垌はã‚ĸプãƒĒを再čĩˇå‹•するåŋ…čĻãŒã‚ã‚Šãžã™ã€‚", + "reset_sqlite_done": "ã‚ĸプãƒĒぎデãƒŧã‚ŋをæļˆåŽģしぞした。ã‚ĸプãƒĒを再čĩˇå‹•し、もう一åēĻãƒ­ã‚°ã‚¤ãƒŗã—ãĻください。", "reset_sqlite_success": "SQLiteデãƒŧã‚ŋベãƒŧ゚ぎãƒĒã‚ģットãĢ成功しぞした", "reset_to_default": "デフりãƒĢトãĢãƒĒã‚ģット", "resolution": "č§ŖåƒåēĻ", @@ -1900,6 +1919,7 @@ "saved_settings": "č¨­åŽšã‚’äŋå­˜ã—ぞした", "say_something": "äŊ•か書きčžŧãŋぞしょう", "scaffold_body_error_occurred": "エナãƒŧがį™ēį”Ÿã—ãžã—ãŸ", + "scaffold_body_error_unrecoverable": "ä爿œŸã—ãĒいエナãƒŧがį™ēį”Ÿã—ãžã—ãŸã€‚č§Ŗæąēぎため、エナãƒŧ内厚と゚ã‚ŋックトãƒŦãƒŧ゚をDiscordぞたはGitHubã§å…ąæœ‰ã—ãĻください。指į¤ēãŒã‚ãŖãŸå ´åˆã¯ã€äģĨ下ぎボã‚ŋãƒŗã‹ã‚‰ã‚ĸプãƒĒデãƒŧã‚ŋをæļˆåŽģできぞす。", "scan": "ã‚šã‚­ãƒŖãƒŗ", "scan_all_libraries": "全ãĻぎナイブナãƒĒã‚’ã‚šã‚­ãƒŖãƒŗ", "scan_library": "ã‚šã‚­ãƒŖãƒŗ", @@ -1935,6 +1955,7 @@ "search_filter_ocr": "OCRで検į´ĸ", "search_filter_people_title": "äēēį‰Šã‚’é¸æŠž", "search_filter_star_rating": "æ˜ŸčŠ•äžĄ", + "search_filter_tags_title": "ã‚ŋグを選択", "search_for": "検į´ĸ", "search_for_existing_person": "æ—ĸ存ぎäēēį‰Šã‚’æ¤œį´ĸ", "search_no_more_result": "検į´ĸįĩæžœäģĨ上", @@ -2014,6 +2035,9 @@ "set_profile_picture": "ãƒ—ãƒ­ãƒ•ã‚ŖãƒŧãƒĢį”ģåƒã‚’č¨­åŽš", "set_slideshow_to_fullscreen": "ã‚šãƒŠã‚¤ãƒ‰ã‚ˇãƒ§ãƒŧをフãƒĢ゚クãƒĒãƒŧãƒŗãĢする", "set_stack_primary_asset": "ãƒĄã‚¤ãƒŗãŽå†™įœŸã¨ã—ãĻč¨­åŽš", + "setting_image_navigation_enable_subtitle": "有劚ãĢすると、į”ģéĸぎåˇĻįĢ¯ãžãŸã¯åŗįĢ¯ãŽ4分ぎ1ぎエãƒĒã‚ĸをã‚ŋップしãĻ、前ぎį”ģ像やæŦĄãŽį”ģ像へį§ģ動できぞす。", + "setting_image_navigation_enable_title": "ã‚ŋップ操äŊœã§į§ģ動", + "setting_image_navigation_title": "į”ģ像ぎ操äŊœ", "setting_image_viewer_help": "å†™įœŸã‚’ã‚ŋップするとã‚ĩムネイãƒĢãƒģ中į”ģčŗĒãƒģã‚ĒãƒĒジナãƒĢぎ順ãĢčĒ­ãŋčžŧãŋぞす", "setting_image_viewer_original_subtitle": "ã‚ĒãƒĒジナãƒĢぎį”ģåƒã‚’čĄ¨į¤ēしたいときãĢã‚ĒãƒŗãĢしãĻください。(最大į”ģčŗĒã§čĄ¨į¤ēされるぎで、デãƒŧã‚ŋとį̝æœĢぎ゚トãƒŦãƒŧジぎæļˆč˛ģ量がåĸ—えぞす)", "setting_image_viewer_original_title": "ã‚ĒãƒĒジナãƒĢをčĒ­ãŋčžŧむ", @@ -2180,6 +2204,7 @@ "support": "ã‚ĩポãƒŧト", "support_and_feedback": "ã‚ĩポãƒŧãƒˆã¨ãƒ•ã‚Ŗãƒŧドバック", "support_third_party_description": "ImmichãŽã‚¤ãƒŗã‚šãƒˆãƒŧãƒĢはã‚ĩãƒŧドパãƒŧãƒ†ã‚ŖãƒŧãĢã‚ˆãŖãĻãƒ‘ãƒƒã‚ąãƒŧジ化されãĻã„ãžã™ã€‚é­é‡ã—ãŸå•éĄŒã¯ããŽãƒ‘ãƒƒã‚ąãƒŧジãĢčĩˇå› ã—ãĻいる可čƒŊ性があるぎでäģĨ下ぎãƒĒãƒŗã‚¯ã‚’äŊŋãŖãĻ最初ãĢããŽãƒ‘ãƒƒã‚ąãƒŧジãĢå•éĄŒã‚’æčĩˇã—ãĻください。", + "supporter": "Supporter", "swap_merge_direction": "įĩąåˆã™ã‚‹æ–šå‘ã‚’å…Ĩれæ›ŋえ", "sync": "同期", "sync_albums": "ã‚ĸãƒĢバムを同期", @@ -2192,6 +2217,7 @@ "tag": "ã‚ŋグäģ˜ã‘する", "tag_assets": "å†™įœŸ/動į”ģãĢã‚ŋグäģ˜ã‘する", "tag_created": "ã‚ŋグ: {tag} をäŊœæˆã—ぞした", + "tag_face": "éĄ”ã‚’ã‚ŋグäģ˜ã‘", "tag_feature_description": "æ„å‘ŗã‚’æŒãŸã›ãŸã‚ŋグトでグãƒĢãƒŧプ化しãĻå†™įœŸã¨å‹•į”ģã‚’é–˛čĻ§ã™ã‚‹", "tag_not_found_question": "ã‚ŋグがčĻ‹ã¤ã‹ã‚Šãžã›ã‚“ã‹? ã“ãĄã‚‰ã‹ã‚‰ã‚ŋグをäŊœæˆã§ããžã™", "tag_people": "äēēį‰Šã‚ŋグ", @@ -2291,6 +2317,7 @@ "unstack_action_prompt": "{count}é …į›ŽãŽé‡ã­åˆã‚ã›ã‚’č§Ŗé™¤", "unstacked_assets_count": "{count, plural, one {#個} other {#個}}ãŽå†™įœŸ/動į”ģを゚ã‚ŋãƒƒã‚¯ã‹ã‚‰č§Ŗé™¤ã—ãžã—ãŸ", "unsupported_field_type": "ã‚ĩポãƒŧトされãĻいãĒã„ãƒ•ã‚ŖãƒŧãƒĢドã‚ŋイプ", + "unsupported_file_type": "ãƒ•ã‚Ąã‚¤ãƒĢåŊĸåŧã€Œ{type}」はã‚ĩポãƒŧトされãĻいãĒã„ãŸã‚ã€ãƒ•ã‚Ąã‚¤ãƒĢ「{file}」をã‚ĸップロãƒŧドできぞせん。", "untagged": "ã‚ŋã‚°ã‚’č§Ŗé™¤", "untitled_workflow": "į„ĄéĄŒãŽãƒ¯ãƒŧクフロãƒŧ", "up_next": "æŦĄã¸", @@ -2317,6 +2344,8 @@ "url": "URL", "usage": "äŊŋį”¨åŽšé‡", "use_biometric": "į”ŸäŊ“čĒč¨ŧã‚’ã”åˆŠį”¨ãã ã•ã„", + "use_browser_locale": "ブナã‚Ļã‚ļãŽč¨€čĒžã¨åœ°åŸŸãŽč¨­åŽšãĢ垓う", + "use_browser_locale_description": "ブナã‚Ļã‚ļãŽč¨€čĒžã¨åœ°åŸŸãŽč¨­åŽšãĢåž“ãŖãĻ、æ—Ĩäģ˜ãƒģ時åˆģãƒģ数値を書åŧč¨­åŽšã—ãžã™", "use_current_connection": "įžåœ¨ãŽæŽĨįƒ…å ąã‚’äŊŋᔍ", "use_custom_date_range": "äģŖã‚ã‚ŠãĢã‚Ģ゚ã‚ŋムæ—Ĩäģ˜į¯„å›˛ã‚’äŊŋᔍ", "user": "ãƒĻãƒŧã‚ļãƒŧ", @@ -2370,6 +2399,7 @@ "viewer_remove_from_stack": "゚ã‚ŋックから外す", "viewer_stack_use_as_main_asset": "ãƒĄã‚¤ãƒŗãŽį”ģ像としãĻäŊŋį”¨ã™ã‚‹", "viewer_unstack": "゚ã‚ŋãƒƒã‚¯ã‚’č§Ŗé™¤", + "visibility": "襨į¤ēč¨­åŽš", "visibility_changed": "{count, plural, one {#äēē} other {#äēē}}ぎäēēį‰ŠãŽéžčĄ¨į¤ēč¨­åŽšãŒå¤‰æ›´ã•ã‚Œãžã—ãŸ", "visual": "ビジãƒĨã‚ĸãƒĢ", "visual_builder": "ビジãƒĨã‚ĸãƒĢビãƒĢダãƒŧ", diff --git a/i18n/ka.json b/i18n/ka.json index f386a1e357..6ed5cdd6ce 100644 --- a/i18n/ka.json +++ b/i18n/ka.json @@ -2,13 +2,13 @@ "about": "შესახებ", "account": "ანგარიში", "account_settings": "ანგარიშის პარამეáƒĸრები", - "acknowledge": "მიáƒĻება", + "acknowledge": "გასაგებია", "action": "áƒĨმედება", - "action_common_update": "განაახლე", + "action_common_update": "განახლება", "action_description": "მოáƒĨმედებები გაფილáƒĸáƒ áƒŖáƒš áƒ áƒ”áƒĄáƒŖáƒ áƒĄáƒ”áƒ‘áƒ–áƒ”", "actions": "áƒĨმედებები", "active": "აáƒĨáƒĸáƒ˜áƒŖáƒ áƒ˜", - "active_count": "aáƒĨáƒĸáƒ˜áƒŖáƒ áƒ˜: {count}", + "active_count": "აáƒĨáƒĸáƒ˜áƒŖáƒ áƒ˜: {count}", "activity": "აáƒĨáƒĸივობა", "activity_changed": "აáƒĨáƒĸივობა {enabled, select, true {áƒŠáƒáƒ áƒ—áƒŖáƒšáƒ˜} other {áƒ’áƒáƒ›áƒáƒ áƒ—áƒŖáƒšáƒ˜}}", "add": "დაამაáƒĸე", @@ -35,10 +35,12 @@ "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_album_toggle": "გადართე მონიშვნა {album}_სთვის", "add_to_albums": "დაამაáƒĸე ალბომებში", "add_to_albums_count": "დაამაáƒĸე ალბომში ({count})", - "add_to_bottom_bar": "დამაáƒĸება სად", + "add_to_bottom_bar": "დაამაáƒĸე ...ში", "add_to_shared_album": "დაამაáƒĸე საზიარო ალბომში", + "add_upload_to_stack": "დაამაáƒĸე აáƒĸáƒ•áƒ˜áƒ áƒ—áƒŖáƒšáƒ˜ ქáƒĸეკში", "add_url": "დაამაáƒĸე URL", "added_to_archive": "დაარáƒĨივდა", "added_to_favorites": "დაამაáƒĸე áƒ áƒŠáƒ”áƒŖáƒšáƒ”áƒ‘áƒ¨áƒ˜", @@ -51,9 +53,15 @@ "authentication_settings_disable_all": "ნამდვილად გინდა ავáƒĸორიზაáƒĒიიქ ყველა მეთოდის გამორთვა? ავáƒĸორიზაáƒĒიაქ ვეáƒĻარანაირად შეáƒĢლებ.", "authentication_settings_reenable": "რეაáƒĨáƒĸივაáƒĒიისთვის, გამოიყენე სერვერის ბრáƒĢანება.", "background_task_job": "áƒ¤áƒáƒœáƒŖáƒ áƒ˜ დავალებები", - "backup_database": "ბაზის დამპის შეáƒĨმნა", - "backup_database_enable_description": "ბაზის დამპების ჩართვა", + "backup_database": "მონაáƒĒემთა ბაზის დამპის შეáƒĨმნა", + "backup_database_enable_description": "მონაáƒĒემთა ბაზის დამპების ჩართვა", "backup_keep_last_amount": "áƒŦინა დამპების áƒ¨áƒ”áƒĄáƒáƒœáƒáƒ áƒŠáƒŖáƒœáƒ”áƒ‘áƒ”áƒšáƒ˜ რაოდენობა", + "backup_onboarding_1_description": "გარე ასლი Cloud_ში ან სხვა áƒ¤áƒ˜áƒ–áƒ˜áƒ™áƒŖáƒ  ადგილას.", + "backup_onboarding_2_description": "áƒšáƒáƒ™áƒáƒšáƒŖáƒ áƒ˜ ასლები სხვადასხვა მოáƒŦყობილობებზე. ეს მოიáƒĒავს მთავარ ფაილებს და მთავარი ფაილების ასლებს áƒšáƒáƒ™áƒáƒšáƒŖáƒ áƒáƒ“.", + "backup_onboarding_3_description": "შენი მონაáƒĒემების მთლიანი ასლები, მათ შორის ორიგინალი ფაილები. ეს მოიáƒĒავს 1 გარე ასლს და 2 áƒšáƒáƒ™áƒáƒšáƒŖáƒ  ასლს.", + "backup_onboarding_description": " 3-2-1 სარეზერვო ქიქáƒĸემა არიქ áƒ áƒ”áƒ™áƒáƒ›áƒ”áƒœáƒ“áƒ˜áƒ áƒ”áƒ‘áƒŖáƒšáƒ˜ შენი მონაáƒĒემების დასაáƒĒავად. შენ áƒŖáƒœáƒ“áƒ შეინახო აáƒĸáƒ•áƒ˜áƒ áƒ—áƒŖáƒšáƒ˜ ფოáƒĸო/ვიდეოების და ასევე immich-იქ ბაზის ასლები ყოვლისმომáƒĒველი სარეზერვო გზისთვის.", + "backup_onboarding_footer": "მეáƒĸი ინფორმაáƒĒიისთვის immich-იქ დასარეზერვებლად , გთხოვთ მიმართეთ áƒ“áƒáƒ™áƒŖáƒ›áƒ”áƒœáƒĸაáƒĒიაქ.", + "backup_onboarding_parts_title": "3-2-1 სარეზერვო ქიქáƒĸემა მოიáƒĒავს:", "backup_onboarding_title": "მარáƒĨაფები", "backup_settings": "მონაáƒĒემთა ბაზის დამპის მორგება", "backup_settings_description": "მონაáƒĒემთა ბაზის დამპის პარამეáƒĸრების მართვა.", @@ -64,27 +72,68 @@ "confirm_email_below": "დასადასáƒĸáƒŖáƒ áƒ”áƒ‘áƒšáƒáƒ“, áƒĨვემოთ აკრიფე \"{email}\"", "confirm_reprocess_all_faces": "მართლა áƒ’áƒĄáƒŖáƒ áƒ— ყველა ქა჎იქ თავიდან áƒ“áƒáƒ›áƒŖáƒ¨áƒáƒ•áƒ”áƒ‘áƒ? ეს áƒĨმედება ხალხისათვის áƒ›áƒ˜áƒœáƒ˜áƒ­áƒ”áƒ‘áƒŖáƒš სახელებს გაáƒŦმენდს.", "confirm_user_password_reset": "ნამდვილად გინდა {user}-(ი)ქ პაროლის დარესეáƒĸება?", + "confirm_user_pin_code_reset": "დარáƒŦáƒ›áƒŖáƒœáƒ”áƒ‘áƒŖáƒšáƒ˜ ხართ, რომ áƒ’áƒĄáƒŖáƒ áƒ— {user}-იქ PIN კოდის დარესეáƒĸება?", + "copy_config_to_clipboard_description": "მიმდინარე ქიქáƒĸემის áƒ™áƒáƒœáƒ¤áƒ˜áƒ’áƒŖáƒ áƒáƒĒიიქ JSON ობიეáƒĨáƒĸიქ სახით კოპირება áƒ‘áƒŖáƒ¤áƒ”áƒ áƒ¨áƒ˜", "create_job": "შეáƒĨმენი დავალება", "cron_expression": "Cron áƒ’áƒáƒ›áƒáƒĄáƒáƒŽáƒŖáƒšáƒ”áƒ‘áƒ", + "cron_expression_description": "სკანირების ინáƒĸერვალი დააყენეთ cron ფორმაáƒĸიქ გამოყენებით. დამაáƒĸებითი ინფორმაáƒĒიისთვის იხილეთ მაგ. Crontab Guru", "disable_login": "გამორთე ავáƒĸორიზაáƒĒია", + "duplicate_detection_job_description": "მსგავსი áƒĄáƒŖáƒ áƒáƒ—áƒ”áƒ‘áƒ˜áƒĄ აáƒĻმოსაჩენად, აáƒĨáƒĸივებზე მანáƒĨáƒáƒœáƒŖáƒ áƒ˜ ქáƒŦავლების გაშვება. áƒ“áƒáƒ›áƒáƒ™áƒ˜áƒ“áƒ”áƒ‘áƒŖáƒšáƒ˜áƒ ჭკვიან áƒĢიებაზე", + "export_config_as_json_description": "ჩამოáƒĸვირთეთ მიმდინარე ქიქáƒĸემის áƒ™áƒáƒœáƒ¤áƒ˜áƒ’áƒŖáƒ áƒáƒĒია JSON ფაილის სახით", + "external_libraries_page_description": "ადმინისáƒĸრაáƒĸორის გარე ბიბლიოთეკის გვერდი", "face_detection": "ქა჎იქ ამოáƒĒნობა", + "facial_recognition_job_description": "აáƒĻმოჩენილი სახეები áƒ“áƒáƒáƒ¯áƒ’áƒŖáƒ¤áƒ”áƒ— ადამიანებად. ეს ნაბიჯი ქა჎იქ ამოáƒĒნობის áƒ“áƒáƒĄáƒ áƒŖáƒšáƒ”áƒ‘áƒ˜áƒĄ შემდეგ áƒ¨áƒ”áƒĄáƒ áƒŖáƒšáƒ“áƒ”áƒ‘áƒ. „გადაáƒĸვირთვა“ (ხელახლა) áƒáƒ¯áƒ’áƒŖáƒ¤áƒ”áƒ‘áƒĄ ყველა სახეს. â€žáƒ“áƒáƒ™áƒáƒ áƒ’áƒŖáƒšáƒ˜â€œ რიგში ათავსებს სახეებს, რომლებსაáƒĒ არ აáƒĨვთ áƒ›áƒ˜áƒœáƒ˜áƒ­áƒ”áƒ‘áƒŖáƒšáƒ˜ ადამიანი.", + "failed_job_command": "ბრáƒĢანება {command} ვერ მოხერხდა დავალების áƒ¨áƒ”áƒĄáƒáƒĄáƒ áƒŖáƒšáƒ”áƒ‘áƒšáƒáƒ“: {job}", + "force_delete_user_warning": "გაფრთხილება: ეს áƒ“áƒáƒŖáƒ§áƒáƒ•áƒœáƒ”áƒ‘áƒšáƒ˜áƒ• áƒŦაშლის მომხმარებელს და ყველა მასალას. ეს მოáƒĨმედება ვერ áƒ’áƒáƒŖáƒĨმდება და ფაილების აáƒĻდგენა áƒ¨áƒ”áƒŖáƒĢლებელია.", "image_format": "ფორმაáƒĸი", "image_format_description": "WebP ფორმაáƒĸი JPEG-ზე პაáƒĸარა ფაილებს აáƒŦარმოებს, მაგრამ მის დამზადებას áƒŖáƒ¤áƒ áƒ მეáƒĸი დრო სჭირდება.", + "image_fullsize_enabled": "ჩართე áƒĄáƒ áƒŖáƒšáƒ˜ ზომის ფოáƒĸოების გენერაáƒĒია", + "image_fullsize_enabled_description": "დააგენერირე მთლიანი ზომის ფოáƒĸოები არა ვებ áƒ›áƒ”áƒ’áƒáƒ‘áƒ áƒŖáƒšáƒ˜ ფორმაáƒĸებისთვის. როáƒĒა", + "image_fullsize_quality_description": "მთლიანი ზომის áƒĄáƒŖáƒ áƒáƒ—áƒ˜áƒĄ ჎არიქ჎ი 1-100მდეა. მეáƒĸი არიქ áƒŖáƒ™áƒ”áƒĸეთეში, მაგრამ áƒŦარმოáƒĨმნის áƒŖáƒ¤áƒ áƒ დიდ ფაილებს.", "image_fullsize_title": "áƒĄáƒ áƒŖáƒšáƒ˜ ზომის áƒ’áƒáƒ›áƒáƒĄáƒáƒŽáƒŖáƒšáƒ”áƒ‘áƒ˜áƒĄ პარამეáƒĸრები", + "image_prefer_embedded_preview": "áƒŠáƒáƒ¨áƒ”áƒœáƒ”áƒ‘áƒŖáƒšáƒ˜ გადახედვის áƒŖáƒžáƒ˜áƒ áƒáƒĸესობა", "image_prefer_wide_gamut": "áƒŖáƒžáƒ˜áƒ áƒáƒĸესობა მიენიჭოს ფერის ფართე დიაპაზონს", + "image_preview_description": "áƒĄáƒáƒ¨áƒŖáƒáƒšáƒ ზომის áƒĄáƒŖáƒ áƒáƒ—áƒ”áƒ‘áƒ˜ metadata-იქ გარეშე გამოიყენება როáƒĒა áƒœáƒáƒŽáƒŖáƒšáƒáƒ‘ 1 áƒ áƒ”áƒĄáƒĄáƒŖáƒ áƒĄ და მანáƒĨáƒáƒœáƒŖáƒ áƒ˜ ქáƒŦავლებისთვის", + "image_preview_quality_description": "გადახვედის ჎არიქ჎ი 1-100-მდე. მეáƒĸი არიქ áƒŖáƒ™áƒ”áƒ—áƒ”áƒĄáƒ˜, მაგრამ áƒŦარმოáƒĨმნის áƒŖáƒ¤áƒ áƒ დიდ ფაილს და áƒ¨áƒ”áƒŖáƒĢლია აპლიკაáƒĒიიქ შეფერხება. ნაკლები áƒĒიფრიქ დაáƒĸენებამ შეიáƒĢლება ეფეáƒĨáƒĸი იáƒĨონიოს მანáƒĨáƒáƒœáƒŖáƒ áƒ˜ ქáƒŦავლების ხარისხზე.", "image_preview_title": "áƒ’áƒáƒ›áƒáƒĄáƒáƒŽáƒŖáƒšáƒ”áƒ‘áƒ˜áƒĄ გადახედვის პარამეáƒĸრები", + "image_progressive": "áƒžáƒ áƒáƒ’áƒ áƒ”áƒĄáƒ˜áƒŖáƒšáƒ˜", + "image_progressive_description": "დააენკოდრი JPEG áƒĄáƒŖáƒ áƒáƒ—áƒ”áƒ‘áƒ˜ მიყოლებით ნელ-ნელი ჩათვირთვის ეკრანისთვის. ეს არ ეხება WebP áƒĄáƒŖáƒ áƒáƒ—áƒ”áƒ‘áƒĄ.", "image_quality": "჎არიქ჎ი", "image_resolution": "გაფართოება", + "image_resolution_description": "მაáƒĻალი გაფართოებას áƒ¨áƒ”áƒŖáƒĢლია შეინახოს მეáƒĸი დეáƒĸალი მაგრამ სჭირდება მეáƒĸი დრო ენკოდირებისთვის, დიდ ფაილებს áƒ¨áƒ”áƒŖáƒĢლიათ აპლიკაáƒĒიიქ შენელება.", "image_settings": "áƒ’áƒáƒ›áƒáƒĄáƒáƒŽáƒŖáƒšáƒ”áƒ‘áƒ˜áƒĄ პარამეáƒĸრები", - "image_settings_description": "áƒ’áƒ”áƒœáƒ”áƒ áƒ˜áƒ áƒ”áƒ‘áƒŖáƒšáƒ˜ ფოáƒĸოების ჎არიქ჎იქა და áƒ áƒ”áƒ–áƒáƒšáƒŖáƒĒიიქ მართვა", - "image_thumbnail_description": "მინიაáƒĸáƒŖáƒ áƒ მეáƒĸაინფორმაáƒĒიიქ გარეშე, რომელიáƒĒ ფოáƒĸოები áƒ¯áƒ’áƒŖáƒ¤áƒŖáƒ áƒáƒ“ თვალიერებისას გამოიყენება(მაგ. მთავარ თაიმლაინზე)", + "image_settings_description": "áƒ’áƒ”áƒœáƒ”áƒ áƒ˜áƒ áƒ”áƒ‘áƒŖáƒšáƒ˜ ფოáƒĸოების ჎არიქ჎იქა და გაფართოების მართვა", + "image_thumbnail_description": "პაáƒĸარა მინიაáƒĸáƒŖáƒ áƒ მეáƒĸაინფორმაáƒĒიიქ გარეშე, რომელიáƒĒ ფოáƒĸოები áƒ¯áƒ’áƒŖáƒ¤áƒŖáƒ áƒáƒ“ თვალიერებისას გამოიყენება(მაგ. მთავარ თაიმლაინზე)", "image_thumbnail_quality_description": "მინიაáƒĸáƒŖáƒ áƒ˜áƒĄ ჎არიქ჎ი 1-დან 100-მდე. დიდი რიáƒĒხვი შეესაბამება áƒŖáƒ™áƒ”áƒ—áƒ”áƒĄ ჎არიქ჎ქ, áƒ—áƒŖáƒ›áƒĒა, áƒŖáƒ¤áƒ áƒ დიდ ფაილებს და აპლიკაáƒĒიიქ შესაáƒĢლო შენელებას.", "image_thumbnail_title": "მინიაáƒĸáƒŖáƒ áƒ˜áƒĄ პარამეáƒĸრები", + "import_config_from_json_description": "დააიმპორáƒĸირე ქიქáƒĸემის áƒ™áƒáƒœáƒ¤áƒ˜áƒ’áƒŖáƒ áƒáƒĒია JSON áƒ™áƒáƒœáƒ¤áƒ˜áƒ’áƒŖáƒ áƒáƒĒიიქ ფაილის აáƒĸვირთვით", + "job_concurrency": "{job} áƒ™áƒáƒœáƒ™áƒŖáƒ áƒ”áƒœáƒĒია", + "job_created": "დავალება შეáƒĨმნილია", + "job_not_concurrency_safe": "ეს დავალება არ არიქ áƒ™áƒáƒœáƒ™áƒŖáƒ áƒ”áƒĒია-áƒŖáƒĄáƒáƒ¤áƒ áƒ—áƒŽáƒ.", + "job_settings": "დავალებების პარამეáƒĸრები", + "job_settings_description": "დავალების áƒ™áƒáƒœáƒ™áƒŖáƒ áƒ”áƒœáƒĒიიქ მენეჯმენáƒĸი", + "jobs_over_time": "დავალებები დროთა განმავლობაში", "library_created": "შეიáƒĨმნა ბიბლიოთეკა: {library}", "library_deleted": "ბიბლიოთეკა áƒŦაიშალა", + "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": "გარე ბიბლიოთეკების პარამეáƒĸრების მართვა", - "logging_settings": "áƒŸáƒŖáƒ áƒœáƒáƒšáƒ˜", + "library_tasks_description": "დაასკანირე გარე ბიბლიოთეკა ახალაი და/ან შეáƒĒვლილი áƒ áƒ”áƒĄáƒŖáƒ áƒĄáƒ”áƒ‘áƒ˜áƒĄáƒ—áƒ•áƒ˜áƒĄ", + "library_updated": "áƒ’áƒáƒœáƒáƒŽáƒšáƒ”áƒ‘áƒŖáƒšáƒ˜ ბიბლიოთეკა", + "library_watching_enable_description": "დააკვირდი გარე ბიბლიოთეკას ფაილის áƒĒვლილებისთვის", + "library_watching_settings": "ბიბლიოთეკის დაკვირვება [ეáƒĨსპერიმენáƒĸáƒáƒšáƒŖáƒ áƒ˜]", + "library_watching_settings_description": "ავáƒĸომაáƒĸáƒŖáƒ áƒáƒ“ დააკვირდი შეáƒĒვლილი ფაილებისთვის", + "logging_enable_description": "áƒŸáƒŖáƒ áƒœáƒáƒšáƒ˜áƒ áƒ”áƒ‘áƒ˜áƒĄ ჩართვა", + "logging_level_description": "როáƒĒა áƒŠáƒáƒ áƒ—áƒŖáƒšáƒ˜áƒ რომელი áƒŸáƒŖáƒ áƒœáƒáƒšáƒ˜áƒ áƒ”áƒ‘áƒ˜áƒĄ დონის გამოყენება.", + "logging_settings": "áƒŸáƒŖáƒ áƒœáƒáƒšáƒ˜áƒ áƒ”áƒ‘áƒ", + "machine_learning_availability_checks_description": "ავáƒĸომაáƒĸáƒŖáƒ áƒáƒ“ აáƒĻმოაჩინე და აირჩიე áƒ—áƒáƒ•áƒ˜áƒĄáƒŖáƒ¤áƒáƒšáƒ˜ მანáƒĨáƒáƒœáƒŖáƒ áƒ˜ ქáƒŦავლების სერვერები", + "machine_learning_availability_checks_interval": "შემოáƒŦმების ინáƒĸერვალი", "machine_learning_ocr": "OCR", "map_settings": "áƒ áƒŖáƒ™áƒ", "migration_job": "მიგრაáƒĒია", diff --git a/i18n/kn.json b/i18n/kn.json index 16079d48bf..6fe20c6794 100644 --- a/i18n/kn.json +++ b/i18n/kn.json @@ -439,7 +439,7 @@ "user_successfully_removed": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛° {email} ➅ā˛ĩā˛°ā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†.", "users_page_description": "➍ā˛ŋā˛°āŗā˛ĩā˛žā˛šā˛• ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ā˛Ē⺁➟", "version_check_enabled_description": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ā˛Ē➰ā˛ŋā˛ļāŗ€ā˛˛ā˛¨āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", - "version_check_implications": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ā˛Ē➰ā˛ŋā˛ļ⺀➞➍⺆ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛ĩ⺁ github.com ā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➆ā˛ĩā˛°āŗā˛¤ā˛• ➏➂ā˛ĩā˛šā˛¨ā˛ĩā˛¨āŗā˛¨āŗ ➅ā˛ĩ➞➂ā˛Ŧā˛ŋ➏ā˛ŋā˛Ļāŗ†", + "version_check_implications": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ā˛Ē➰ā˛ŋā˛ļ⺀➞➍⺆ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛ĩ⺁ {server} ā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➆ā˛ĩā˛°āŗā˛¤ā˛• ➏➂ā˛ĩā˛šā˛¨ā˛ĩā˛¨āŗā˛¨āŗ ➅ā˛ĩ➞➂ā˛Ŧā˛ŋ➏ā˛ŋā˛Ļāŗ†", "version_check_settings": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ā˛Ē➰ā˛ŋā˛ļ⺀➞➍⺆", "version_check_settings_description": "ā˛šāŗŠā˛¸ ➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ➝ ➅➧ā˛ŋā˛¸āŗ‚ā˛šā˛¨āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ/➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "video_conversion_job": "ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ÿāŗā˛°ā˛žā˛¨āŗā˛¸āŗâ€Œā˛•āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋ", @@ -519,6 +519,9 @@ "allow_edits": "➏➂ā˛Ēā˛žā˛Ļā˛¨āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➏ā˛ŋ", "allow_public_user_to_download": "ā˛¸ā˛žā˛°āŗā˛ĩ➜➍ā˛ŋ➕ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°āŗ ā˛ĄāŗŒā˛¨āŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➏ā˛ŋ", "allow_public_user_to_upload": "ā˛¸ā˛žā˛°āŗā˛ĩ➜➍ā˛ŋ➕ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛ŋ➗⺆ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➏ā˛ŋ", + "allowed": "ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "alt_text_qr_code": "QR ā˛•āŗ‹ā˛Ąāŗ ➚ā˛ŋā˛¤āŗā˛°", + "always_keep": "ā˛¯ā˛žā˛ĩā˛žā˛—ā˛˛āŗ‚ ā˛‡ā˛Ÿāŗā˛Ÿāŗā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ", "always_keep_photos_hint": "ā˛¸āŗā˛Ĩā˛ŗā˛žā˛ĩā˛•ā˛žā˛ļ ā˛Žāŗā˛•āŗā˛¤ā˛—āŗŠā˛ŗā˛ŋ➏⺁ā˛ĩ⺁ā˛Ļ➰ā˛ŋ➂ā˛Ļ ➈ ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➇➰ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "always_keep_videos_hint": "ā˛¸āŗā˛Ĩā˛ŗā˛žā˛ĩā˛•ā˛žā˛ļ ā˛Žāŗā˛•āŗā˛¤ā˛—āŗŠā˛ŗā˛ŋ➏⺁ā˛ĩ⺁ā˛Ļ➰ā˛ŋ➂ā˛Ļ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ ➈ ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➉➺ā˛ŋā˛¯āŗā˛¤āŗā˛¤ā˛ĩāŗ†.", "anti_clockwise": "➅ā˛Ēāŗā˛°ā˛Ļā˛•āŗā˛ˇā˛ŋā˛Ŗā˛žā˛•ā˛žā˛°ā˛ĩā˛žā˛—ā˛ŋ", @@ -533,6 +536,7 @@ "appears_in": "ā˛•ā˛žā˛Ŗā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ†", "archive": "ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ", "archive_or_unarchive_photo": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛Žā˛žā˛Ąā˛ŋ ➅ā˛Ĩā˛ĩā˛ž ā˛…ā˛¨āŗâ€Œā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "archive_page_no_archived_assets": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛˛āŗā˛˛", "archive_size_description": "ā˛ĄāŗŒā˛¨āŗâ€Œā˛˛āŗ‹ā˛Ąāŗâ€Œā˛—ā˛ŗā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛—ā˛žā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛•ā˛žā˛¨āŗā˛Ģā˛ŋā˛—ā˛°āŗ ā˛Žā˛žā˛Ąā˛ŋ (GiB ā˛¨ā˛˛āŗā˛˛ā˛ŋ)", "are_these_the_same_person": "➇ā˛ĩ➰⺁ ➒➂ā˛Ļāŗ‡ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ➝⺇?", "are_you_sure_to_do_this": "➍⺀ā˛ĩ⺁ ➇ā˛Ļā˛¨āŗā˛¨āŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", @@ -569,6 +573,7 @@ "asset_viewer_settings_subtitle": "➍ā˛ŋā˛Žāŗā˛Ž ā˛—āŗā˛¯ā˛žā˛˛ā˛°ā˛ŋ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛• ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", "asset_viewer_settings_title": "ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛•", "assets": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ", + "assets_deleted_permanently": "{count} ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(➗➺⺁) ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "assets_deleted_permanently_from_server": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ {count} ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(➗➺⺁) ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "assets_removed_permanently_from_device": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛ŋ➂ā˛Ļ {count} ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(ā˛—ā˛ŗā˛¨āŗā˛¨āŗ) ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "assets_restore_confirmation": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Žā˛˛āŗā˛˛ā˛ž ➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋ➏➞⺁ ➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➍⺀ā˛ĩ⺁ ➈ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➰ā˛Ļāŗā˛Ļāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛! ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ➆ā˛Ģāŗâ€Œā˛˛āŗˆā˛¨āŗ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➈ ➰⺀➤ā˛ŋā˛¯ā˛˛āŗā˛˛ā˛ŋ ā˛Žā˛°āŗā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛ ā˛Žā˛‚ā˛Ŧ⺁ā˛Ļā˛¨āŗā˛¨āŗ ā˛—ā˛Žā˛¨ā˛ŋ➏ā˛ŋ.", @@ -596,20 +601,44 @@ "backup_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩāŗ‚", "backup_background_service_backup_failed_message": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†. ā˛Žā˛°āŗā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†â€Ļ", "backup_background_service_connection_failed_message": "ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ➏➂ā˛Ēā˛°āŗā˛•ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†. ā˛Žā˛°āŗā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†â€Ļ", + "backup_background_service_default_notification": "ā˛šāŗŠā˛¸ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†â€Ļ", + "backup_background_service_in_progress_notification": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†â€Ļ", + "backup_background_service_upload_failure_notification": "{filename} ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "backup_controller_page_background_app_refresh_disabled_content": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Ŧ➺➏➞⺁ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗāŗ > ā˛¸ā˛žā˛Žā˛žā˛¨āŗā˛¯ > ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ.", + "backup_controller_page_background_app_refresh_disabled_title": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "backup_controller_page_background_battery_info_link": "ā˛šāŗ‡ā˛—āŗ†ā˛‚ā˛Ļ⺁ ➍➍➗⺆ ➤⺋➰ā˛ŋ➏ā˛ŋ", "backup_controller_page_background_battery_info_message": "ā˛…ā˛¤āŗā˛¯āŗā˛¤āŗā˛¤ā˛Ž ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ➅➍⺁➭ā˛ĩā˛•āŗā˛•ā˛žā˛—ā˛ŋ, ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛—ā˛žā˛—ā˛ŋ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➚➟⺁ā˛ĩ➟ā˛ŋā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛Ŧ➂➧ā˛ŋ➏⺁ā˛ĩ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛Ŧāŗā˛¯ā˛žā˛Ÿā˛°ā˛ŋ ➆ā˛Ēāŗā˛Ÿā˛ŋā˛Žāŗˆā˛¸āŗ‡ā˛ļā˛¨āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ.\n\n➇ā˛Ļ⺁ ā˛¸ā˛žā˛§ā˛¨-➍ā˛ŋā˛°āŗā˛Ļā˛ŋā˛ˇāŗā˛Ÿā˛ĩā˛žā˛—ā˛ŋ➰⺁ā˛ĩ⺁ā˛Ļ➰ā˛ŋ➂ā˛Ļ, ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸ā˛žā˛§ā˛¨ ā˛¤ā˛¯ā˛žā˛°ā˛•ā˛°ā˛ŋ➗⺆ ā˛…ā˛—ā˛¤āŗā˛¯ā˛ĩā˛ŋ➰⺁ā˛ĩ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛¨āŗ‹ā˛Ąā˛ŋ.", + "backup_controller_page_background_battery_info_ok": "➏➰ā˛ŋ", + "backup_controller_page_background_battery_info_title": "ā˛Ŧāŗā˛¯ā˛žā˛Ÿā˛°ā˛ŋ ➆ā˛Ēāŗā˛Ÿā˛ŋā˛Žāŗˆā˛¸āŗ‡ā˛ļā˛¨āŗâ€Œā˛—ā˛ŗāŗ", + "backup_controller_page_background_charging": "ā˛šā˛žā˛°āŗā˛œāŗ ā˛Žā˛žā˛Ąāŗā˛ĩā˛žā˛— ā˛Žā˛žā˛¤āŗā˛°", "backup_controller_page_background_configure_error": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➏⺇ā˛ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛•ā˛žā˛¨āŗā˛Ģā˛ŋā˛—ā˛°āŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "backup_controller_page_background_delay": "ā˛šāŗŠā˛¸ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛ĩā˛ŋ➺➂ā˛Ŧ: {duration}", "backup_controller_page_background_description": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➤⺆➰⺆➝ā˛Ļ⺆➝⺇ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛šāŗŠā˛¸ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➏⺇ā˛ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ", "backup_controller_page_background_is_off": "ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ➆ā˛Ģāŗ ➆➗ā˛ŋā˛Ļāŗ†", "backup_controller_page_background_is_on": "ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛†ā˛¨āŗ ➆➗ā˛ŋā˛Ļāŗ†", + "backup_controller_page_background_turn_off": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➏⺇ā˛ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➆ā˛Ģāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "backup_controller_page_background_turn_on": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ➏⺇ā˛ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "backup_controller_page_background_wifi": "ā˛ĩ⺈-ā˛Ģ⺈ ā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛Žā˛žā˛¤āŗā˛°", + "backup_controller_page_backup": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ", "backup_controller_page_backup_sub": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", + "backup_controller_page_created": "➰➚ā˛ŋā˛¸ā˛˛ā˛žā˛Ļ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•: {date}", "backup_controller_page_desc_backup": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➤⺆➰⺆➝⺁ā˛ĩā˛žā˛— ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ā˛šāŗŠā˛¸ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛Žāŗā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛†ā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ.", + "backup_controller_page_failed": "ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ† ({count})", + "backup_controller_page_filename": "ā˛Ģāŗˆā˛˛āŗ ā˛šāŗ†ā˛¸ā˛°āŗ: {filename} [{size}]", + "backup_controller_page_id": "ā˛ā˛Ąā˛ŋ: {id}", + "backup_controller_page_info": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋ", + "backup_controller_page_none_selected": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļā˛¨āŗā˛¨āŗ‚ ā˛†ā˛¯āŗā˛•āŗ† ā˛Žā˛žā˛Ąā˛ŋā˛˛āŗā˛˛", + "backup_controller_page_remainder": "ā˛ļ⺇➎", "backup_controller_page_remainder_sub": "ā˛†ā˛¯āŗā˛•āŗ†ā˛¯ā˛ŋ➂ā˛Ļ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ➉➺ā˛ŋā˛Ļā˛ŋ➰⺁ā˛ĩ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", + "backup_controller_page_server_storage": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛Ŗāŗ†", + "backup_controller_page_start_backup": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏ā˛ŋ", "backup_controller_page_status_off": "ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ ā˛Žāŗā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ➆ā˛Ģāŗ ➆➗ā˛ŋā˛Ļāŗ†", "backup_controller_page_status_on": "ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ ā˛Žāŗā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛†ā˛¨āŗ ➆➗ā˛ŋā˛Ļāŗ†", "backup_controller_page_to_backup": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛Ŧāŗ‡ā˛•ā˛žā˛Ļ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗāŗ", "backup_controller_page_total_sub": "ā˛†ā˛¯āŗā˛Ļ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛ŋ➂ā˛Ļ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛…ā˛¨ā˛¨āŗā˛¯ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", + "backup_controller_page_turn_off": "ā˛Žāŗā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ➆ā˛Ģāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "backup_controller_page_turn_on": "ā˛Žāŗā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛†ā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "backup_controller_page_uploading_file_info": "ā˛Ģāŗˆā˛˛āŗ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "backup_err_only_album": "➒➂ā˛Ļāŗ‡ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "backup_error_sync_failed": "➏ā˛ŋā˛‚ā˛•āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†. ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Ēāŗā˛°ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛.", "backup_info_card_assets": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ", @@ -629,22 +658,58 @@ "biometric_not_available": "➈ ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛Ŧā˛¯āŗ‹ā˛Žāŗ†ā˛Ÿāŗā˛°ā˛ŋā˛•āŗ ā˛Ļ⺃ā˛ĸ⺀➕➰➪ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "birthdate_saved": "ā˛œā˛¨āŗā˛Ž ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛ĩā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ➉➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "birthdate_set_description": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ ➤⺆➗⺆➝⺁ā˛ĩ ā˛¸ā˛Žā˛¯ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➆ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ➝ ā˛ĩā˛¯ā˛¸āŗā˛¸ā˛¨āŗā˛¨āŗ ā˛˛āŗ†ā˛•āŗā˛•ā˛šā˛žā˛•ā˛˛āŗ ā˛œā˛¨āŗā˛Ž ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧā˛ŗā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", + "blurred_background": "ā˛Žā˛¸āŗā˛•ā˛žā˛Ļ ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ†", "bugs_and_feature_requests": "ā˛Ļ⺋➎➗➺⺁ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ ā˛ĩā˛ŋ➍➂➤ā˛ŋ➗➺⺁", "build": "➍ā˛ŋā˛°āŗā˛Žā˛žā˛Ŗ", + "build_image": "➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛Žā˛ŋ➏ā˛ŋ", "bulk_delete_duplicates_confirmation": "➍⺀ā˛ĩ⺁ {count, plural, one {# duplicate asset} other {# duplicate assets}} ā˛…ā˛¨āŗā˛¨āŗ ā˛Ŧāŗƒā˛šā˛¤āŗ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ļā˛˛āŗā˛˛ā˛ŋ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➇ā˛Ļ⺁ ā˛Ēāŗā˛°ā˛¤ā˛ŋ ➗⺁➂ā˛Ēā˛ŋ➍ ➅➤ā˛ŋā˛ĻāŗŠā˛Ąāŗā˛Ą ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➉➺ā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ† ā˛Žā˛¤āŗā˛¤āŗ ➇➤➰ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¨ā˛•ā˛˛āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†. ➍⺀ā˛ĩ⺁ ➈ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➰ā˛Ļāŗā˛Ļāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛!", "bulk_keep_duplicates_confirmation": "➍⺀ā˛ĩ⺁ {count, plural, one {# duplicate asset} other {# duplicate assets}} ā˛…ā˛¨āŗā˛¨āŗ ➇➰ā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➇ā˛Ļ⺁ ā˛¯ā˛žā˛ĩ⺁ā˛Ļā˛¨āŗā˛¨āŗ‚ ➅➺ā˛ŋ➏ā˛Ļāŗ† ā˛Žā˛˛āŗā˛˛ā˛ž ➍➕➞ā˛ŋ ➗⺁➂ā˛Ēāŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛šā˛°ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "bulk_trash_duplicates_confirmation": "➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ➝⺂ ā˛Ŧā˛˛āŗā˛•āŗ ā˛Ÿāŗā˛°āŗā˛¯ā˛žā˛ļāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛Ŧā˛¯ā˛¸āŗā˛¤āŗā˛¤āŗ€ā˛°ā˛ž {count, plural, one {# duplicate asset} other {# duplicate assets}}? ➇ā˛Ļ⺁ ā˛Ēāŗā˛°ā˛¤ā˛ŋ ➗⺁➂ā˛Ēā˛ŋ➍ ➅➤ā˛ŋā˛ĻāŗŠā˛Ąāŗā˛Ą ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➉➺ā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ† ā˛Žā˛¤āŗā˛¤āŗ ➇➤➰ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¨ā˛•ā˛˛āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ÿāŗā˛°āŗā˛¯ā˛žā˛ļāŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛Ļāŗ†.", + "buy": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➖➰⺀ā˛Ļā˛ŋ➏ā˛ŋ", + "cache_settings_clear_cache_button": "ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "cache_settings_clear_cache_button_title": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ ā˛•āŗā˛¯ā˛žā˛ļāŗ ā˛…ā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†. ā˛•āŗā˛¯ā˛žā˛ļāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛¨ā˛ŋā˛°āŗā˛Žā˛ŋ➏⺁ā˛ĩā˛ĩ➰⺆➗⺆ ➇ā˛Ļ⺁ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ ā˛•ā˛žā˛°āŗā˛¯ā˛•āŗā˛ˇā˛Žā˛¤āŗ†ā˛¯ ā˛Žāŗ‡ā˛˛āŗ† ā˛—ā˛Žā˛¨ā˛žā˛°āŗā˛šā˛ĩā˛žā˛—ā˛ŋ ā˛Ē➰ā˛ŋā˛Ŗā˛žā˛Ž ā˛Ŧāŗ€ā˛°āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", + "cache_settings_duplicated_assets_clear_button": "➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "cache_settings_duplicated_assets_subtitle": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛Ēā˛Ÿāŗā˛Ÿā˛ŋ ā˛Žā˛žā˛Ąā˛ŋ➰⺁ā˛ĩ ➍ā˛ŋā˛°āŗā˛˛ā˛•āŗā˛ˇā˛ŋā˛¸ā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", + "cache_settings_duplicated_assets_title": "➍➕➞ā˛ŋ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ ({count})", + "cache_settings_statistics_album": "➞⺈ā˛Ŧāŗā˛°ā˛°ā˛ŋ ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗâ€Œā˛—ā˛ŗāŗ", + "cache_settings_statistics_full": "ā˛Ēāŗ‚ā˛°āŗā˛Ŗ ➚ā˛ŋā˛¤āŗā˛°ā˛—ā˛ŗāŗ", + "cache_settings_statistics_shared": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗâ€Œā˛—ā˛ŗāŗ", + "cache_settings_statistics_thumbnail": "ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗâ€Œā˛—ā˛ŗāŗ", + "cache_settings_statistics_title": "ā˛•āŗā˛¯ā˛žā˛ļāŗ ā˛Ŧ➺➕⺆", "cache_settings_subtitle": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛ŽāŗŠā˛Ŧāŗˆā˛˛āŗ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ ā˛•āŗā˛¯ā˛žā˛ļā˛ŋā˛‚ā˛—āŗ ā˛¨ā˛Ąā˛ĩ➺ā˛ŋā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛¯ā˛‚ā˛¤āŗā˛°ā˛ŋ➏ā˛ŋ", "cache_settings_tile_subtitle": "ā˛¸āŗā˛Ĩ➺⺀➝ ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛Ŗāŗ†ā˛¯ ā˛¨ā˛Ąā˛ĩ➺ā˛ŋā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛¯ā˛‚ā˛¤āŗā˛°ā˛ŋ➏ā˛ŋ", + "cache_settings_tile_title": "ā˛¸āŗā˛Ĩ➺⺀➝ ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛Ŗāŗ†", + "cache_settings_title": "ā˛•āŗā˛¯ā˛žā˛ļā˛ŋā˛‚ā˛—āŗ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗāŗ", "camera": "ā˛•āŗā˛¯ā˛žā˛Žāŗ†ā˛°ā˛ž", + "camera_brand": "ā˛•āŗā˛¯ā˛žā˛Žāŗ†ā˛°ā˛ž ā˛Ŧāŗā˛°āŗā˛¯ā˛žā˛‚ā˛Ąāŗ", + "camera_model": "ā˛•āŗā˛¯ā˛žā˛Žāŗ†ā˛°ā˛ž ā˛Žā˛žā˛Ļ➰ā˛ŋ", "cancel": "➰ā˛Ļāŗā˛Ļāŗā˛Žā˛žā˛Ąā˛ŋ", + "cancel_search": "ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿ ➰ā˛Ļāŗā˛Ļāŗā˛Žā˛žā˛Ąā˛ŋ", + "canceled": "➰ā˛Ļāŗā˛Ļāŗā˛Žā˛žā˛Ąā˛ŋā˛Ļāŗ†", + "canceling": "➰ā˛Ļāŗā˛Ļāŗā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", + "cannot_merge_people": "ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩā˛ŋā˛˛āŗ€ā˛¨ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "cannot_undo_this_action": "➍⺀ā˛ĩ⺁ ➈ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➰ā˛Ļāŗā˛Ļāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛!", "cannot_update_the_description": "ā˛ĩā˛ŋā˛ĩā˛°ā˛Ŗāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ĩ⺀➕➰ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", + "cast": "ā˛Ēā˛žā˛¤āŗā˛°ā˛ĩā˛°āŗā˛—", + "cast_description": "ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋ➰⺁ā˛ĩ ā˛Ŧā˛ŋā˛¤āŗā˛¤ā˛°ā˛ŋ➏⺁ā˛ĩā˛ŋ➕⺆ ā˛—ā˛Žāŗā˛¯ā˛¸āŗā˛Ĩā˛žā˛¨ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛•ā˛žā˛¨āŗā˛Ģā˛ŋā˛—ā˛°āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "change_date": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_description": "ā˛ĩā˛ŋā˛ĩā˛°ā˛Ŗāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_display_order": "ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļ➍ ā˛•āŗā˛°ā˛Žā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_expiration_time": "ā˛Žāŗā˛•āŗā˛¤ā˛žā˛¯ ā˛¸ā˛Žā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_location": "ā˛¸āŗā˛Ĩ➺ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_name": "ā˛šāŗ†ā˛¸ā˛°āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_name_successfully": "ā˛šāŗ†ā˛¸ā˛°ā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "change_password": "ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", "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": "ā˛šāŗŠā˛¸ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛¤āŗā˛¤āŗ† ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "change_pin_code": "ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "change_trigger": "ā˛Ÿāŗā˛°ā˛ŋā˛—āŗā˛—ā˛°āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", "change_trigger_prompt": "➍⺀ā˛ĩ⺁ ā˛Ÿāŗā˛°ā˛ŋā˛—āŗā˛—ā˛°āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➇ā˛Ļ⺁ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛•āŗā˛°ā˛ŋ➝⺆➗➺⺁ ā˛Žā˛¤āŗā˛¤āŗ ā˛Ģā˛ŋā˛˛āŗā˛Ÿā˛°āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "charging_requirement_mobile_backup": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗâ€Œā˛—āŗ† ā˛¸ā˛žā˛§ā˛¨ā˛ĩ⺁ ā˛šā˛žā˛°āŗā˛œāŗ ā˛†ā˛—āŗā˛¤āŗā˛¤ā˛ŋ➰ā˛Ŧ⺇➕⺁", "check_corrupt_asset_backup": "ā˛­āŗā˛°ā˛ˇāŗā˛Ÿ ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗâ€Œā˛—ā˛ŗā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ", @@ -661,15 +726,31 @@ "cleanup_step4_summary": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗā˛Ĩ➺⺀➝ ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛ŋ➂ā˛Ļ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ {count} ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ({date} ā˛•āŗā˛•ā˛ŋ➂➤ ā˛ŽāŗŠā˛Ļ➞⺁ ➰➚ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†). ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", "cleanup_trash_hint": "ā˛ļāŗ‡ā˛–ā˛°ā˛Ŗā˛ž ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ➏➂ā˛Ēāŗ‚ā˛°āŗā˛Ŗā˛ĩā˛žā˛—ā˛ŋ ā˛Žā˛°ā˛ŗā˛ŋ ā˛Ēā˛Ąāŗ†ā˛¯ā˛˛āŗ, ➏ā˛ŋā˛¸āŗā˛Ÿā˛Žāŗ ā˛—āŗā˛¯ā˛žā˛˛ā˛°ā˛ŋ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➤⺆➰⺆➝ā˛ŋ➰ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ➕➏ā˛ĩā˛¨āŗā˛¨āŗ ā˛–ā˛žā˛˛ā˛ŋ ā˛Žā˛žā˛Ąā˛ŋ", "clear": "➍ā˛ŋā˛°āŗā˛Žā˛˛", + "clear_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ‚ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "clear_all_recent_searches": "ā˛‡ā˛¤āŗā˛¤āŗ€ā˛šā˛ŋ➍ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "clear_file_cache": "ā˛Ģāŗˆā˛˛āŗ ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "clear_message": "➏➂ā˛Ļāŗ‡ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "clear_value": "ā˛ŽāŗŒā˛˛āŗā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "client_cert_dialog_msg_confirm": "➏➰ā˛ŋ", + "client_cert_enter_password": "ā˛Ēā˛žā˛¸āŗā˛ĩā˛°āŗā˛Ąāŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "client_cert_import": "ā˛†ā˛Žā˛Ļ⺁ ā˛Žā˛žā˛Ąā˛ŋ", + "client_cert_import_success_msg": "ā˛•āŗā˛˛āŗˆā˛‚ā˛Ÿāŗ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛Žā˛Ļ⺁ ā˛Žā˛žā˛Ąā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "client_cert_invalid_msg": "ā˛…ā˛Žā˛žā˛¨āŗā˛¯ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛° ā˛Ģāŗˆā˛˛āŗ ➅ā˛Ĩā˛ĩā˛ž ➤ā˛Ēāŗā˛Ē⺁ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ", "client_cert_password_message": "➈ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛°ā˛•āŗā˛•ā˛žā˛—ā˛ŋ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "client_cert_password_title": "ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛° ā˛Ēā˛žā˛¸āŗā˛ĩā˛°āŗā˛Ąāŗ", + "client_cert_remove_msg": "ā˛•āŗā˛˛āŗˆā˛‚ā˛Ÿāŗ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "client_cert_subtitle": "PKCS12 (.p12, .pfx) ā˛¸āŗā˛ĩ➰⺂ā˛Ēā˛ĩā˛¨āŗā˛¨āŗ ā˛Žā˛žā˛¤āŗā˛° ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†. ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ ➆➗⺁ā˛ĩ ā˛ŽāŗŠā˛Ļ➞⺁ ā˛Žā˛žā˛¤āŗā˛° ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛° ā˛†ā˛Žā˛Ļ⺁/➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛ĩā˛ŋ➕⺆ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†", + "client_cert_title": "SSL ā˛•āŗā˛˛āŗˆā˛‚ā˛Ÿāŗ ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ēā˛¤āŗā˛° [ā˛Ēāŗā˛°ā˛žā˛¯āŗ‹ā˛—ā˛ŋ➕]", "clockwise": "ā˛•āŗā˛˛ā˛žā˛•āŗâ€Œā˛ĩāŗˆā˛¸āŗ", "close": "ā˛Žāŗā˛šāŗā˛šā˛ŋ", "collapse": "ā˛•āŗā˛—āŗā˛—ā˛ŋ➏⺁", + "collapse_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ā˛•āŗā˛—āŗā˛—ā˛ŋ➏ā˛ŋ", "color": "ā˛Ŧā˛Ŗāŗā˛Ŗ", + "color_theme": "ā˛Ŧā˛Ŗāŗā˛Ŗ ā˛Ĩāŗ€ā˛Žāŗ", + "command": "ā˛†ā˛œāŗā˛žāŗ†", "command_palette_prompt": "ā˛Ēāŗā˛Ÿā˛—ā˛ŗāŗ, ā˛•āŗā˛°ā˛ŋ➝⺆➗➺⺁ ➅ā˛Ĩā˛ĩā˛ž ā˛†ā˛œāŗā˛žāŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¤āŗā˛ĩ➰ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛šāŗā˛Ąāŗā˛•ā˛ŋ", + "command_palette_to_close": "ā˛Žāŗā˛šāŗā˛šā˛˛āŗ", + "command_palette_to_navigate": "ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏➞⺁", "confirm": "ā˛Ļ⺃ā˛ĸ⺀➕➰ā˛ŋ➏ā˛ŋ", "confirm_delete_face": "➍⺀ā˛ĩ⺁ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛ŋ➍ā˛ŋ➂ā˛Ļ {name} ā˛Žāŗā˛–ā˛ĩā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "confirm_delete_shared_link": "➈ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", @@ -679,30 +760,81 @@ "contain": "ā˛’ā˛ŗā˛—āŗŠā˛‚ā˛Ąā˛ŋā˛°āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "context": "➏➂ā˛Ļā˛°āŗā˛­", "continue": "ā˛Žāŗā˛‚ā˛Ļ⺁ā˛ĩ➰ā˛ŋ➏ā˛ŋ", + "control_bottom_app_bar_edit_time": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛Žā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏ā˛ŋ", + "control_bottom_app_bar_share_to": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ", + "control_bottom_app_bar_trash_from_immich": "➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ā˛•āŗā˛•āŗ† ➏➰ā˛ŋ➏ā˛ŋ", "copied_image_to_clipboard": "➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛•āŗā˛˛ā˛ŋā˛Ēāŗâ€Œā˛Ŧāŗ‹ā˛°āŗā˛Ąāŗâ€Œā˛—āŗ† ➍➕➞ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†.", + "copied_to_clipboard": "ā˛•āŗā˛˛ā˛ŋā˛Ēāŗ ā˛Ŧāŗ‹ā˛°āŗā˛Ąāŗ ➗⺆ ➍➕➞ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†!", + "copy_error": "ā˛Ļ⺋➎ā˛ĩā˛¨āŗā˛¨āŗ ➍➕➞ā˛ŋ➏ā˛ŋ", + "copy_file_path": "ā˛Ģāŗˆā˛˛āŗ ā˛Žā˛žā˛°āŗā˛—ā˛ĩā˛¨āŗā˛¨āŗ ➍➕➞ā˛ŋ➏ā˛ŋ", + "copy_image": "➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ➍➕➞ā˛ŋ➏ā˛ŋ", + "copy_link": "➞ā˛ŋā˛‚ā˛•āŗ ➍➕➞ā˛ŋ➏ā˛ŋ", "copy_link_to_clipboard": "➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛•āŗā˛˛ā˛ŋā˛Ēāŗâ€Œā˛Ŧāŗ‹ā˛°āŗā˛Ąāŗâ€Œā˛—āŗ† ➍➕➞ā˛ŋ➏ā˛ŋ", + "copy_password": "ā˛Ēā˛žā˛¸āŗā˛ĩā˛°āŗā˛Ąāŗ ➍➕➞ā˛ŋ➏ā˛ŋ", + "copy_to_clipboard": "ā˛•āŗā˛˛ā˛ŋā˛Ēāŗ ā˛Ŧāŗ‹ā˛°āŗā˛Ąāŗ ➗⺆ ➍➕➞ā˛ŋ➏ā˛ŋ", "country": "ā˛Ļāŗ‡ā˛ļ", "cover": "➕ā˛ĩā˛°āŗ", "covers": "➕ā˛ĩā˛°āŗâ€Œā˛—ā˛ŗāŗ", "create": "➰➚ā˛ŋ➏ā˛ŋ", + "create_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_album_page_untitled": "ā˛ļāŗ€ā˛°āŗā˛ˇā˛ŋā˛•āŗ†ā˛°ā˛šā˛ŋ➤", + "create_api_key": "➰➚ā˛ŋ➏ā˛ŋ API ➕⺀", + "create_first_workflow": "ā˛ŽāŗŠā˛Ļ➞ ➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_library": "ā˛—āŗā˛°ā˛‚ā˛Ĩā˛žā˛˛ā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_link": "➞ā˛ŋā˛‚ā˛•āŗ ➰➚ā˛ŋ➏ā˛ŋ", "create_link_to_share": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ➞ā˛ŋā˛‚ā˛•āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_link_to_share_description": "➞ā˛ŋā˛‚ā˛•āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➰⺁ā˛ĩ ā˛¯ā˛žā˛°ā˛žā˛Ļ➰⺂ ā˛†ā˛¯āŗā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ‹ā˛Ąā˛˛ā˛ŋ", + "create_new": "ā˛šāŗŠā˛¸ā˛Ļā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_new_person": "ā˛šāŗŠā˛¸ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", "create_new_person_hint": "ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛¸ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ➗⺆ ➍ā˛ŋā˛¯āŗ‹ā˛œā˛ŋ➏ā˛ŋ", + "create_new_user": "ā˛šāŗŠā˛¸ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_shared_album_page_share_add_assets": "ā˛Žā˛Ąā˛ŋā˛Ąā˛ŋ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ", + "create_shared_album_page_share_select_photos": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "create_shared_link": "ā˛šā˛‚ā˛šā˛ŋā˛Ļ ➞ā˛ŋā˛‚ā˛•āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_tag": "ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ➰➚ā˛ŋ➏ā˛ŋ", "create_tag_description": "ā˛šāŗŠā˛¸ ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ➰➚ā˛ŋ➏ā˛ŋ. ā˛¨āŗ†ā˛¸āŗā˛Ÿāŗ†ā˛Ąāŗ ā˛Ÿāŗā˛¯ā˛žā˛—āŗâ€Œā˛—ā˛ŗā˛ŋā˛—ā˛žā˛—ā˛ŋ, ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛Ģā˛žā˛°āŗā˛ĩā˛°āŗā˛Ąāŗ ā˛¸āŗā˛˛āŗā˛¯ā˛žā˛ļāŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛’ā˛ŗā˛—āŗŠā˛‚ā˛Ąā˛‚ā˛¤āŗ† ā˛Ÿāŗā˛¯ā˛žā˛—āŗâ€Œā˛¨ ā˛Ēāŗ‚ā˛°āŗā˛Ŗ ā˛Žā˛žā˛°āŗā˛—ā˛ĩā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ.", + "create_user": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", + "create_workflow": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ", "created": "➰➚ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "created_at": "➰➚ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "creating_linked_albums": "➞ā˛ŋā˛‚ā˛•āŗā˛Ąāŗ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏⺁ā˛ĩ⺁ā˛Ļ⺁ ...", + "crop": "ā˛Ŧ⺆➺⺆", + "crop_aspect_ratio_fixed": "ā˛¸āŗā˛Ĩā˛ŋ➰", + "crop_aspect_ratio_free": "ā˛‰ā˛šā˛ŋ➤", + "crop_aspect_ratio_original": "ā˛Žāŗ‚ā˛˛", + "crop_aspect_ratio_square": "ā˛šāŗŒā˛•", + "curated_object_page_title": "ā˛ĩā˛ŋ➎➝➗➺⺁", + "current_device": "ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛¸ā˛žā˛§ā˛¨", + "current_pin_code": "ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ", + "current_server_address": "ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛ĩā˛ŋā˛ŗā˛žā˛¸", + "custom_date": "ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•", + "custom_locale": "ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ ā˛˛āŗŠā˛•āŗ‡ā˛˛āŗ", + "custom_locale_description": "ā˛†ā˛¯āŗā˛Ļ ā˛­ā˛žā˛ˇāŗ† ā˛Žā˛¤āŗā˛¤āŗ ā˛Ēāŗā˛°ā˛Ļāŗ‡ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ➆➧➰ā˛ŋ➏ā˛ŋā˛Ļ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛—ā˛ŗāŗ, ā˛¸ā˛Žā˛¯ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛‚ā˛–āŗā˛¯āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ģā˛žā˛°āŗā˛Žāŗā˛¯ā˛žā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "custom_url": "ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ URL", "cutoff_date_description": "ā˛šā˛ŋ➂ā˛Ļā˛ŋ➍ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➇➰ā˛ŋ➏ā˛ŋâ€Ļ", "dark": "ā˛•ā˛¤āŗā˛¤ā˛˛āŗ", + "dark_theme": "ā˛Ąā˛žā˛°āŗā˛•āŗ ā˛Ĩāŗ€ā˛Žāŗ ➗⺆ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", + "date": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•", + "date_and_time": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛Žā˛¯", + "date_before": "ā˛ŽāŗŠā˛Ļ➞⺁ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•", "date_of_birth_saved": "ā˛œā˛¨āŗā˛Ž ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛ĩā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ➉➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "date_range": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛ļāŗā˛°āŗ‡ā˛Ŗā˛ŋ", "day": "ā˛Ļā˛ŋ➍", - "deduplication_criteria_1": "➚ā˛ŋā˛¤āŗā˛°ā˛Ļ ā˛—ā˛žā˛¤āŗā˛° ā˛Ŧāŗˆā˛Ÿāŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ", - "deduplication_criteria_2": "EXIF ā˛Ąāŗ‡ā˛Ÿā˛žā˛Ļ ā˛Žā˛Ŗā˛ŋ➕⺆", - "deduplication_info_description": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ēāŗ‚ā˛°āŗā˛ĩ ā˛†ā˛¯āŗā˛•āŗ† ā˛Žā˛žā˛Ąā˛˛āŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¨ā˛•ā˛˛āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĻāŗŠā˛Ąāŗā˛Ą ā˛Ēāŗā˛°ā˛Žā˛žā˛Ŗā˛Ļā˛˛āŗā˛˛ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ, ā˛¨ā˛žā˛ĩ⺁ ā˛‡ā˛˛āŗā˛˛ā˛ŋ ā˛¨āŗ‹ā˛Ąāŗā˛¤āŗā˛¤āŗ‡ā˛ĩāŗ†:", + "days": "ā˛Ļā˛ŋ➍➗➺⺁", + "deduplicate_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ‚ ā˛¸ā˛Žā˛°āŗā˛Ēā˛ŋ➏ā˛ŋ", + "default_locale": "ā˛Ąāŗ€ā˛Ģā˛žā˛˛āŗā˛Ÿāŗ ā˛˛āŗŠā˛•āŗ‡ā˛˛āŗ", + "default_locale_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ŧāŗā˛°āŗŒā˛¸ā˛°āŗ ā˛˛āŗŠā˛•āŗ‡ā˛˛āŗ ā˛†ā˛§ā˛žā˛°ā˛ŋ➤ ā˛¸āŗā˛ĩ➰⺂ā˛Ē ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛‚ā˛–āŗā˛¯āŗ†ā˛—ā˛ŗāŗ", "delete": "➅➺ā˛ŋ➏ā˛ŋ", "delete_action_confirmation_message": "➍⺀ā˛ĩ⺁ ➈ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➈ ā˛•āŗā˛°ā˛ŋ➝⺆➝⺁ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛¨ ➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ā˛•āŗā˛•āŗ† ➏➰ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ† ā˛Žā˛¤āŗā˛¤āŗ ➍⺀ā˛ĩ⺁ ➅ā˛Ļā˛¨āŗā˛¨āŗ ā˛¸āŗā˛Ĩ➺⺀➝ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋ➏➞⺁ ā˛Ŧ➝➏ā˛ŋā˛Ļ➰⺆ ā˛•āŗ‡ā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "delete_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➅➺ā˛ŋ➏ā˛ŋ", "delete_api_key_prompt": "➈ API ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "delete_dialog_alert": "➈ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛ŋ➂ā˛Ļ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "delete_dialog_alert_local": "➈ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛ŋ➂ā˛Ļ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ† ➆ā˛Ļ➰⺆ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛‡ā˛¨āŗā˛¨āŗ‚ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛°āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "delete_dialog_alert_local_non_backed_up": "➕⺆➞ā˛ĩ⺁ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛—āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛˛āŗā˛˛ ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸ā˛žā˛§ā˛¨ā˛Ļā˛ŋ➂ā˛Ļ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "delete_dialog_alert_remote": "➈ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "delete_duplicates_confirmation": "➍⺀ā˛ĩ⺁ ➈ ā˛¨ā˛•ā˛˛āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "delete_local_dialog_ok_backed_up_only": "ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛ŋ➰⺁ā˛ĩ⺁ā˛Ļā˛¨āŗā˛¨āŗ ā˛Žā˛žā˛¤āŗā˛° ➅➺ā˛ŋ➏ā˛ŋ", + "delete_tag_confirmation_prompt": "➍⺀ā˛ĩ⺁ {tagName} ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "deletes_missing_assets": "ā˛Ąā˛ŋā˛¸āŗā˛•āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛•ā˛žā˛Ŗāŗ†ā˛¯ā˛žā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➅➺ā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "description": "ā˛ĩā˛ŋā˛ĩ➰➪⺆", "description_input_submit_error": "ā˛ĩā˛ŋā˛ĩā˛°ā˛Ŗāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ĩ⺀➕➰ā˛ŋ➏⺁ā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛Ļ⺋➎, ā˛šāŗ†ā˛šāŗā˛šā˛ŋ➍ ā˛ĩā˛ŋā˛ĩ➰➗➺ā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛˛ā˛žā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ", @@ -723,6 +855,7 @@ "downloading": "ā˛ĄāŗŒā˛¨āŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "drop_files_to_upload": "➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛Ģāŗˆā˛˛āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛˛āŗā˛˛ā˛ŋā˛¯ā˛žā˛Ļ➰⺂ ā˛Ŧā˛ŋā˛Ąā˛ŋ", "duplicates": "➍➕➞⺁➗➺⺁", + "duplicates_description": "ā˛Ēāŗā˛°ā˛¤ā˛ŋā˛¯āŗŠā˛‚ā˛Ļ⺁ ➗⺁➂ā˛Ēā˛¨āŗā˛¨āŗ, ā˛¯ā˛žā˛ĩ⺁ā˛Ļā˛žā˛Ļ➰⺂ ➇ā˛Ļāŗā˛Ļ➰⺆, ➍➕➞⺁➗➺⺁ ā˛Žā˛‚ā˛Ļ⺁ ā˛¸āŗ‚ā˛šā˛ŋ➏⺁ā˛ĩ ā˛Žāŗ‚ā˛˛ā˛• ā˛Ē➰ā˛ŋā˛šā˛°ā˛ŋ➏ā˛ŋ.", "duration": "➅ā˛ĩ➧ā˛ŋ", "edit": "➤ā˛ŋā˛Ļāŗā˛Ļ⺁", "edit_date_and_time": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛Žā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏ā˛ŋ", @@ -733,6 +866,7 @@ "editor_close_without_save_prompt": "ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩā˛Ŗāŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➉➺ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛ĩ⺁ā˛Ļā˛ŋā˛˛āŗā˛˛", "editor_confirm_reset_all_changes": "➍⺀ā˛ĩ⺁ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩā˛Ŗāŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "email": "ā˛‡ā˛Žāŗ†āŗ•ā˛˛āŗ", + "empty_folder": "➈ ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗ ā˛–ā˛žā˛˛ā˛ŋā˛¯ā˛žā˛—ā˛ŋā˛Ļāŗ†", "empty_trash_confirmation": "➍⺀ā˛ĩ⺁ ➕➏ā˛ĩā˛¨āŗā˛¨āŗ ā˛–ā˛žā˛˛ā˛ŋ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➇ā˛Ļ⺁ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ➕➏ā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛¤āŗā˛¤ā˛Ļāŗ†.\n➍⺀ā˛ĩ⺁ ➈ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➰ā˛Ļāŗā˛Ļāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛!", "enable": "ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "enable_biometric_auth_description": "ā˛Ŧā˛¯āŗ‹ā˛Žāŗ†ā˛Ÿāŗā˛°ā˛ŋā˛•āŗ ā˛Ļ⺃ā˛ĸ⺀➕➰➪ā˛ĩā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", @@ -753,12 +887,14 @@ "error_adding_users_to_album": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—āŗ† ➏⺇➰ā˛ŋ➏⺁ā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛Ļ⺋➎", "error_deleting_shared_user": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏⺁ā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛Ļ⺋➎", "error_hiding_buy_button": "➖➰⺀ā˛Ļā˛ŋ ā˛Ŧā˛Ÿā˛¨āŗ ā˛Žā˛°āŗ†ā˛Žā˛žā˛Ąāŗā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛Ļ⺋➎", + "error_removing_assets_from_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛Ļ⺋➎, ā˛šāŗ†ā˛šāŗā˛šā˛ŋ➍ ā˛ĩā˛ŋā˛ĩ➰➗➺ā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛•ā˛¨āŗā˛¸āŗ‹ā˛˛āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ", "error_selecting_all_assets": "ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ† ā˛Žā˛žā˛Ąāŗā˛ĩā˛žā˛— ā˛Ļ⺋➎ ā˛‰ā˛‚ā˛Ÿā˛žā˛—ā˛ŋā˛Ļāŗ†", "exclusion_pattern_already_exists": "➈ ā˛šāŗŠā˛°ā˛—ā˛ŋā˛Ąāŗā˛ĩ ā˛Žā˛žā˛Ļ➰ā˛ŋ ā˛ˆā˛—ā˛žā˛—ā˛˛āŗ‡ ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋā˛Ļāŗ†.", "failed_to_create_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➰➚ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_create_shared_link": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ➰➚ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_edit_shared_link": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_get_people": "ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ā˛Ēā˛Ąāŗ†ā˛¯āŗā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", + "failed_to_keep_this_delete_others": "➈ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ➉➺ā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ā˛Žā˛¤āŗā˛¤āŗ ➇➤➰ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_load_asset": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_load_assets": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "failed_to_load_people": "ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", @@ -770,6 +906,7 @@ "incorrect_email_or_password": "➤ā˛Ēāŗā˛Ēā˛žā˛Ļ ā˛‡ā˛Žāŗ‡ā˛˛āŗ ➅ā˛Ĩā˛ĩā˛ž ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ", "library_folder_already_exists": "➈ ā˛†ā˛Žā˛Ļ⺁ ā˛Žā˛žā˛°āŗā˛—ā˛ĩ⺁ ā˛ˆā˛—ā˛žā˛—ā˛˛āŗ‡ ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋā˛Ļāŗ†.", "profile_picture_transparent_pixels": "ā˛Ēāŗā˛°āŗŠā˛Ģāŗˆā˛˛āŗ ➚ā˛ŋā˛¤āŗā˛°ā˛—ā˛ŗāŗ ā˛Ēā˛žā˛°ā˛Ļā˛°āŗā˛ļ➕ ā˛Ēā˛ŋā˛•āŗā˛¸āŗ†ā˛˛āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➰ā˛Ŧā˛žā˛°ā˛Ļ⺁. ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛œāŗ‚ā˛Žāŗ ā˛‡ā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ/➅ā˛Ĩā˛ĩā˛ž ➏➰ā˛ŋ➏ā˛ŋ.", + "quota_higher_than_disk_size": "➍⺀ā˛ĩ⺁ ā˛Ąā˛ŋā˛¸āŗā˛•āŗ ā˛—ā˛žā˛¤āŗā˛°ā˛•āŗā˛•ā˛ŋ➂➤ ā˛šāŗ†ā˛šāŗā˛šā˛ŋ➍ ā˛•āŗ‹ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ", "unable_to_add_album_users": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—āŗ† ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➏⺇➰ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", "unable_to_add_assets_to_shared_link": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗâ€Œā˛—āŗ† ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➏⺇➰ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", "unable_to_add_comment": "ā˛•ā˛žā˛Žāŗ†ā˛‚ā˛Ÿāŗ ➏⺇➰ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", @@ -843,15 +980,23 @@ "unable_to_upload_file": "ā˛Ģāŗˆā˛˛āŗ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛" }, "exif": "ā˛Žā˛•āŗā˛¸ā˛ŋā˛Ģāŗ", + "experimental_settings_new_asset_list_title": "ā˛Ēāŗā˛°ā˛žā˛¯āŗ‹ā˛—ā˛ŋ➕ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ā˛—āŗā˛°ā˛ŋā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "experimental_settings_subtitle": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗā˛ĩ➂➤ ➅ā˛Ēā˛žā˛¯ā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛Ŧ➺➏ā˛ŋ!", "expired": "➅ā˛ĩ➧ā˛ŋ ā˛Žāŗ€ā˛°ā˛ŋā˛Ļāŗ†", "explore": "ā˛Ē➰ā˛ŋā˛ļ⺋➧ā˛ŋ➏⺁", "explorer": "ā˛Žā˛•āŗā˛¸āŗâ€Œā˛Ēāŗā˛˛āŗ‹ā˛°ā˛°āŗ", + "export": "➰ā˛Ģāŗā˛¤āŗ", + "extension": "ā˛ĩā˛ŋā˛¸āŗā˛¤ā˛°ā˛Ŗāŗ†", + "external": "ā˛Ŧā˛žā˛šāŗā˛¯", "external_network_sheet_info": "➍⺀ā˛ĩ⺁ ➆ā˛Ļāŗā˛¯ā˛¤āŗ†ā˛¯ ā˛ĩ⺈-ā˛Ģ⺈ ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛‡ā˛˛āŗā˛˛ā˛Ļā˛ŋ➰⺁ā˛ĩā˛žā˛—, ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛Žāŗ‡ā˛˛ā˛ŋ➍ā˛ŋ➂ā˛Ļ ā˛•āŗ†ā˛ŗā˛•āŗā˛•āŗ† ➤➞⺁ā˛Ēā˛Ŧā˛šāŗā˛Ļā˛žā˛Ļ ➕⺆➺➗ā˛ŋ➍ URL ā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ā˛ŽāŗŠā˛Ļ➞➍⺆➝ā˛Ļ➰ ā˛Žāŗ‚ā˛˛ā˛• ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ➏➂ā˛Ēā˛°āŗā˛•ā˛—āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ†", "face_unassigned": "➍ā˛ŋā˛¯āŗ‹ā˛œā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛˛āŗā˛˛", "failed_to_load_assets": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", + "failed_to_load_folder": "ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", + "favorite": "ā˛¨āŗ†ā˛šāŗā˛šā˛ŋ➍", "favorite_or_unfavorite_photo": "ā˛¨āŗ†ā˛šāŗā˛šā˛ŋ➍ ➅ā˛Ĩā˛ĩā˛ž ā˛Žāŗ†ā˛šāŗā˛šā˛ŋ➍ā˛Ļ➰ā˛ŋ➂ā˛Ļ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹", "favorites": "ā˛Žāŗ†ā˛šāŗā˛šā˛ŋ➍ā˛ĩ⺁➗➺⺁", + "favorites_page_no_favorites": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛¨āŗ†ā˛šāŗā˛šā˛ŋ➍ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛˛āŗā˛˛", + "features": "ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛—ā˛ŗāŗ", "features_setting_description": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", "file_name_or_extension": "ā˛Ģāŗˆā˛˛āŗ ā˛šāŗ†ā˛¸ā˛°āŗ ➅ā˛Ĩā˛ĩā˛ž ā˛ĩā˛ŋā˛¸āŗā˛¤ā˛°ā˛Ŗāŗ†", "filename": "ā˛Ģāŗˆā˛˛āŗ ā˛šāŗ†ā˛¸ā˛°āŗ", @@ -866,9 +1011,11 @@ "general": "ā˛œā˛¨ā˛°ā˛˛āŗ", "geolocation_instruction_location": "GPS ➍ā˛ŋā˛°āŗā˛Ļāŗ‡ā˛ļā˛žā˛‚ā˛•ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➰⺁ā˛ĩ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛ŋ➍ ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏➞⺁ ➅ā˛Ļ➰ ā˛Žāŗ‡ā˛˛āŗ† ā˛•āŗā˛˛ā˛ŋā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋ, ➅ā˛Ĩā˛ĩā˛ž ā˛¨ā˛•āŗā˛ˇāŗ†ā˛¯ā˛ŋ➂ā˛Ļ ➍⺇➰ā˛ĩā˛žā˛—ā˛ŋ ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", "get_wifiname_error": "ā˛ĩ⺈-ā˛Ģ⺈ ā˛šāŗ†ā˛¸ā˛°ā˛¨āŗā˛¨āŗ ā˛Ēā˛Ąāŗ†ā˛¯ā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—ā˛˛ā˛ŋā˛˛āŗā˛˛. ➍⺀ā˛ĩ⺁ ā˛…ā˛—ā˛¤āŗā˛¯ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ€ā˛Ąā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩ⺈-ā˛Ģ⺈ ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗâ€Œā˛—āŗ† ➏➂ā˛Ēā˛°āŗā˛•ā˛—āŗŠā˛‚ā˛Ąā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ ā˛Žā˛‚ā˛Ļ⺁ ā˛–ā˛šā˛ŋ➤ā˛Ēā˛Ąā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ", + "header_settings_field_validator_msg": "ā˛ŽāŗŒā˛˛āŗā˛¯ ā˛–ā˛žā˛˛ā˛ŋā˛¯ā˛žā˛—ā˛ŋ➰ā˛Ŧā˛žā˛°ā˛Ļ⺁", "home_page_add_to_album_conflicts": "{album} ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—āŗ† {added} ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➏⺇➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†. {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_delete_err_partner": "ā˛Ēā˛žā˛˛āŗā˛Ļā˛žā˛° ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛, ā˛Ŧā˛ŋā˛Ÿāŗā˛Ÿāŗā˛Ŧā˛ŋā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", @@ -901,24 +1048,40 @@ "language": "ā˛­ā˛žā˛ˇāŗ†", "language_no_results_subtitle": "➍ā˛ŋā˛Žāŗā˛Ž ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿ ā˛Ēā˛Ļā˛ĩā˛¨āŗā˛¨āŗ ➏➰ā˛ŋā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏➞⺁ ā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋ➏ā˛ŋ", "language_setting_description": "➍ā˛ŋā˛Žāŗā˛Ž ➆ā˛Ļāŗā˛¯ā˛¤āŗ†ā˛¯ ā˛­ā˛žā˛ˇāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "latitude": "ā˛…ā˛•āŗā˛ˇā˛žā˛‚ā˛ļ", "leave": "ā˛Ŧā˛ŋā˛Ąā˛ŋ", "level": "ā˛Žā˛Ÿāŗā˛Ÿ", + "library": "ā˛—āŗā˛°ā˛‚ā˛Ĩā˛žā˛˛ā˛¯", "light": "ā˛Ŧ⺆➺➕⺁", "list": "ā˛Ēā˛Ÿāŗā˛Ÿā˛ŋ", + "loading": "ā˛˛āŗ‹ā˛Ąāŗ ā˛†ā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "loading_search_results_failed": "ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿ ā˛Ģ➞ā˛ŋā˛¤ā˛žā˛‚ā˛ļā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąāŗā˛ĩā˛˛āŗā˛˛ā˛ŋ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "local_asset_cast_failed": "ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ā˛Ŧā˛ŋā˛¤āŗā˛¤ā˛°ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "local_network_sheet_info": "➍ā˛ŋā˛°āŗā˛Ļā˛ŋā˛ˇāŗā˛Ÿā˛Ēā˛Ąā˛ŋ➏ā˛ŋā˛Ļ ā˛ĩ⺈-ā˛Ģ⺈ ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗ ā˛Ŧ➺➏⺁ā˛ĩā˛žā˛— ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➈ URL ā˛Žāŗ‚ā˛˛ā˛• ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ➏➂ā˛Ēā˛°āŗā˛•ā˛—āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ†", "location_permission_content": "ā˛¸āŗā˛ĩ➝➂-ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩ➪⺆ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏➞⺁, ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛—āŗ† ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛ĩ⺈-ā˛Ģ⺈ ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗâ€Œā˛¨ ā˛šāŗ†ā˛¸ā˛°ā˛¨āŗā˛¨āŗ ➓ā˛Ļ➞⺁ ➍ā˛ŋ➖➰ā˛ĩā˛žā˛Ļ ā˛¸āŗā˛Ĩ➺ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➝ ā˛…ā˛—ā˛¤āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†", + "location_picker_latitude_error": "ā˛Žā˛žā˛¨āŗā˛¯ā˛ĩā˛žā˛Ļ ā˛…ā˛•āŗā˛ˇā˛žā˛‚ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "location_picker_latitude_hint": "➍ā˛ŋā˛Žāŗā˛Ž ā˛…ā˛•āŗā˛ˇā˛žā˛‚ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ā˛‡ā˛˛āŗā˛˛ā˛ŋ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "location_picker_longitude_error": "ā˛Žā˛žā˛¨āŗā˛¯ā˛ĩā˛žā˛Ļ ā˛°āŗ‡ā˛–ā˛žā˛‚ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "location_picker_longitude_hint": "➍ā˛ŋā˛Žāŗā˛Ž ā˛°āŗ‡ā˛–ā˛žā˛‚ā˛ļā˛ĩā˛¨āŗā˛¨āŗ ā˛‡ā˛˛āŗā˛˛ā˛ŋ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", "log_out_all_devices": "ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸ā˛žā˛§ā˛¨ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛ā˛žā˛—āŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛ŋ", "logged_out_all_devices": "ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸ā˛žā˛§ā˛¨ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛ā˛žā˛—āŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "login": "ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ", + "login_disabled": "ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "login_form_api_exception": "API ā˛ĩā˛ŋā˛¨ā˛žā˛¯ā˛ŋ➤ā˛ŋ. ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗ URL ā˛…ā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛Žā˛¤āŗā˛¤āŗ† ā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋ➏ā˛ŋ.", "login_form_err_http": "ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ http:// ➅ā˛Ĩā˛ĩā˛ž https:// ā˛…ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛Ļā˛ŋā˛ˇāŗā˛Ÿā˛Ēā˛Ąā˛ŋ➏ā˛ŋ", "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_server_empty": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ URL ā˛…ā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ.", "login_form_server_error": "ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ➏➂ā˛Ēā˛°āŗā˛•ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—ā˛˛ā˛ŋā˛˛āŗā˛˛.", "login_has_been_disabled": "ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†.", "login_password_changed_error": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ➍ā˛ĩ⺀➕➰ā˛ŋ➏⺁ā˛ĩā˛žā˛— ā˛Ļ⺋➎ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛Ļāŗ†", + "logout_all_device_confirmation": "➍⺀ā˛ĩ⺁ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸ā˛žā˛§ā˛¨ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛˛ā˛žā˛—āŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "logout_this_device_confirmation": "➍⺀ā˛ĩ⺁ ➈ ā˛¸ā˛žā˛§ā˛¨ā˛ĩā˛¨āŗā˛¨āŗ ā˛˛ā˛žā˛—āŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "longitude": "ā˛°āŗ‡ā˛–ā˛žā˛‚ā˛ļ", + "look": "ā˛¨āŗ‹ā˛Ąā˛ŋ", + "loop_videos_description": "ā˛ĩā˛ŋā˛ĩ➰ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛•ā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ā˛ĩā˛¨āŗā˛¨āŗ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ➞⺂ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ.", "main_branch_warning": "➍⺀ā˛ĩ⺁ ➅➭ā˛ŋā˛ĩ⺃ā˛Ļāŗā˛§ā˛ŋ ➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧā˛ŗā˛¸āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ; ā˛Ŧā˛ŋā˛Ąāŗā˛—ā˛Ąāŗ† ➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏➞⺁ ā˛¨ā˛žā˛ĩ⺁ ā˛Ŧ➞ā˛ĩā˛žā˛—ā˛ŋ ā˛ļā˛ŋā˛Ģā˛žā˛°ā˛¸āŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤āŗ‡ā˛ĩāŗ†!", "maintenance_description": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛…ā˛¨āŗā˛¨āŗ maintenance mode ā˛•āŗā˛•āŗ† ➇➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†.", "maintenance_end_error": "➍ā˛ŋā˛°āŗā˛ĩā˛šā˛Ŗā˛ž ā˛•āŗā˛°ā˛Žā˛ĩā˛¨āŗā˛¨āŗ ā˛•āŗŠā˛¨āŗ†ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†.", @@ -939,56 +1102,97 @@ "manage_your_devices": "➍ā˛ŋā˛Žāŗā˛Ž ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ ➆➗ā˛ŋ➰⺁ā˛ĩ ā˛¸ā˛žā˛§ā˛¨ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", "manage_your_oauth_connection": "➍ā˛ŋā˛Žāŗā˛Ž OAuth ➏➂ā˛Ēā˛°āŗā˛•ā˛ĩā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", "map": "ā˛¨ā˛•āŗā˛ˇāŗ†", + "map_cannot_get_user_location": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ēā˛Ąāŗ†ā˛¯ā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "map_location_service_disabled_content": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛¸āŗā˛Ĩ➺ā˛Ļā˛ŋ➂ā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏➞⺁ ā˛¸āŗā˛Ĩ➺ ➏⺇ā˛ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏⺁ā˛ĩ ā˛…ā˛—ā˛¤āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†. ➍⺀ā˛ĩ⺁ ā˛ˆā˛— ➅ā˛Ļā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "map_marker_for_images": "{city}, {country} ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➤⺆➗⺆ā˛Ļ ➚ā˛ŋā˛¤āŗā˛°ā˛—ā˛ŗā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛¨ā˛•āŗā˛ˇāŗ† ā˛Žā˛žā˛°āŗā˛•ā˛°āŗ", "map_marker_with_image": "➚ā˛ŋā˛¤āŗā˛°ā˛ĻāŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛¨ā˛•āŗā˛ˇāŗ† ā˛Žā˛žā˛°āŗā˛•ā˛°āŗ", "map_no_location_permission_content": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ā˛¸āŗā˛Ĩ➺ā˛Ļā˛ŋ➂ā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏➞⺁ ā˛¸āŗā˛Ĩ➺ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ ā˛…ā˛—ā˛¤āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†. ➍⺀ā˛ĩ⺁ ā˛ˆā˛— ➅ā˛Ļā˛¨āŗā˛¨āŗ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➏➞⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "map_zoom_to_see_photos": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ‹ā˛Ąā˛˛āŗ ā˛āŗ‚ā˛Žāŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "matches": "ā˛Ē➂ā˛Ļāŗā˛¯ā˛—ā˛ŗāŗ", "memories": "➍⺆➍ā˛Ē⺁➗➺⺁", "memories_check_back_tomorrow": "ā˛šāŗ†ā˛šāŗā˛šā˛ŋ➍ ➍⺆➍ā˛Ē⺁➗➺ā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛¨ā˛žā˛ŗāŗ† ā˛Žā˛¤āŗā˛¤āŗ† ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ", "memories_setting_description": "➍ā˛ŋā˛Žāŗā˛Ž ➍⺆➍ā˛Ēāŗā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ➍⺀ā˛ĩ⺁ ā˛¨āŗ‹ā˛Ąāŗā˛ĩ⺁ā˛Ļā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", + "memories_swipe_to_close": "ā˛Žāŗā˛šāŗā˛šā˛˛āŗ ā˛Žāŗ‡ā˛˛ā˛•āŗā˛•āŗ† ā˛¸āŗā˛ĩ⺈ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛ŋ", "memory": "➍⺆➍ā˛Ē⺁", + "menu": "ā˛Žāŗ†ā˛¨āŗ", + "merge": "ā˛ĩā˛ŋ➞⺀➍", "merge_people_limit": "➍⺀ā˛ĩ⺁ ā˛’ā˛Žāŗā˛Žāŗ†ā˛—āŗ† 5 ā˛Žāŗā˛–ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛žā˛¤āŗā˛° ā˛ĩā˛ŋā˛˛āŗ€ā˛¨ā˛—āŗŠā˛ŗā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁", "merge_people_prompt": "➍⺀ā˛ĩ⺁ ➈ ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩā˛ŋā˛˛āŗ€ā˛¨ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➈ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛ĩ⺁ā˛Ļā˛ŋā˛˛āŗā˛˛.", + "minimize": "➕➍ā˛ŋā˛ˇāŗā˛ āŗ€ā˛•ā˛°ā˛ŋ➏ā˛ŋ", + "minute": "➍ā˛ŋā˛Žā˛ŋ➎", + "missing": "ā˛•ā˛žā˛Ŗāŗ†ā˛¯ā˛žā˛—ā˛ŋā˛Ļāŗ†", "mobile_app_download_onboarding_note": "➈ ➕⺆➺➗ā˛ŋ➍ ā˛†ā˛¯āŗā˛•āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋā˛•āŗŠā˛‚ā˛Ąāŗ ➕➂ā˛Ēāŗā˛¯ā˛žā˛¨ā˛ŋā˛¯ā˛¨āŗ ā˛ŽāŗŠā˛Ŧāŗˆā˛˛āŗ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛ĄāŗŒā˛¨āŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "model": "ā˛Žā˛žā˛Ļ➰ā˛ŋ", + "month": "➤ā˛ŋ➂➗➺⺁", + "more": "ā˛‡ā˛¨āŗā˛¨ā˛ˇāŗā˛Ÿāŗ", "move_off_locked_folder": "ā˛˛ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛šāŗŠā˛°ā˛—āŗ† ➏➰ā˛ŋ➏ā˛ŋ", "move_to_lock_folder_action_prompt": "ā˛˛ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗâ€Œā˛—āŗ† {count} ➏⺇➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "move_to_locked_folder_confirmation": "➈ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛ŋ➂ā˛Ļ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ† ā˛Žā˛¤āŗā˛¤āŗ ā˛˛ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛Žā˛žā˛¤āŗā˛° ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļā˛žā˛—ā˛ŋā˛Ļāŗ†", "multiselect_grid_edit_date_time_err_read_only": "➓ā˛Ļ➞⺁ ā˛Žā˛žā˛¤āŗā˛° ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(➗➺) ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛ĩā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛, ā˛Ŧā˛ŋā˛Ÿāŗā˛Ÿāŗā˛Ŧā˛ŋā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "multiselect_grid_edit_gps_err_read_only": "➓ā˛Ļ➞⺁ ā˛Žā˛žā˛¤āŗā˛° ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(➗➺) ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛, ā˛Ŧā˛ŋā˛Ÿāŗā˛Ÿāŗā˛Ŧā˛ŋā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", + "name": "ā˛šāŗ†ā˛¸ā˛°āŗ", "network_requirement_photos_upload": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸āŗ†ā˛˛āŗā˛¯āŗā˛˛ā˛žā˛°āŗ ā˛Ąāŗ‡ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋ", "network_requirement_videos_upload": "ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸āŗ†ā˛˛āŗā˛¯āŗā˛˛ā˛žā˛°āŗ ā˛Ąāŗ‡ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋ", "network_requirements_updated": "ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗ ➅ā˛ĩā˛ļāŗā˛¯ā˛•ā˛¤āŗ†ā˛—ā˛ŗāŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛—ā˛ŋā˛ĩāŗ†, ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛•āŗā˛¯āŗ‚ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "networking_subtitle": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛Žā˛‚ā˛Ąāŗâ€Œā˛Ēā˛žā˛¯ā˛ŋā˛‚ā˛Ÿāŗ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", "new_pin_code_subtitle": "ā˛˛ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛Ģāŗ‹ā˛˛āŗā˛Ąā˛°āŗ ā˛…ā˛¨āŗā˛¨āŗ ➍⺀ā˛ĩ⺁ ā˛ŽāŗŠā˛Ļ➞ ā˛Ŧā˛žā˛°ā˛ŋ➗⺆ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ. ➈ ā˛Ē⺁➟ā˛ĩā˛¨āŗā˛¨āŗ ā˛¸āŗā˛°ā˛•āŗā˛ˇā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏➞⺁ ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ➰➚ā˛ŋ➏ā˛ŋ", + "no": "ā˛‡ā˛˛āŗā˛˛", + "no_albums_message": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸ā˛‚ā˛˜ā˛Ÿā˛ŋ➏➞⺁ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➰➚ā˛ŋ➏ā˛ŋ", "no_albums_with_name_yet": "➈ ā˛šāŗ†ā˛¸ā˛°ā˛ŋā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➍⺀ā˛ĩ⺁ ā˛‡ā˛¨āŗā˛¨āŗ‚ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛˛āŗā˛˛ ā˛Žā˛‚ā˛Ļ⺁ ā˛¤āŗ‹ā˛°āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†.", + "no_albums_yet": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ŧ➺ā˛ŋ ā˛‡ā˛¨āŗā˛¨āŗ‚ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛ŋā˛˛āŗā˛˛ ā˛Žā˛‚ā˛Ļ⺁ ā˛¤āŗ‹ā˛°āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†.", "no_archived_assets_message": "➍ā˛ŋā˛Žāŗā˛Ž Photos ā˛ĩāŗ€ā˛•āŗā˛ˇā˛Ŗāŗ†ā˛¯ā˛ŋ➂ā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗ†ā˛Žā˛žā˛Ąā˛˛āŗ ➅ā˛ĩāŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛Žā˛žā˛Ąā˛ŋ", "no_assets_message": "➍ā˛ŋā˛Žāŗā˛Ž ā˛ŽāŗŠā˛Ļ➞ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛•āŗā˛˛ā˛ŋā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "no_assets_to_show": "➤⺋➰ā˛ŋ➏➞⺁ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛ŋā˛˛āŗā˛˛", "no_checksum_local": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛šāŗ†ā˛•āŗā˛¸ā˛Žāŗ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛ - ā˛¸āŗā˛Ĩ➺⺀➝ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ēā˛Ąāŗ†ā˛¯ā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "no_checksum_remote": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛šāŗ†ā˛•āŗā˛¸ā˛Žāŗ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛ - ➰ā˛ŋā˛Žāŗ‹ā˛Ÿāŗ ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ēā˛Ąāŗ†ā˛¯ā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "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_remote_assets_found": "➈ ā˛šāŗ†ā˛•āŗā˛¸ā˛Žāŗâ€Œā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ➰ā˛ŋā˛Žāŗ‹ā˛Ÿāŗ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗāŗ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛˛āŗā˛˛", "no_results_description": "ā˛¸ā˛Žā˛žā˛¨ā˛žā˛°āŗā˛Ĩ➕ ā˛Ēā˛Ļ ➅ā˛Ĩā˛ĩā˛ž ā˛šāŗ†ā˛šāŗā˛šāŗ ā˛¸ā˛žā˛Žā˛žā˛¨āŗā˛¯ ➕⺀ā˛ĩā˛°āŗā˛Ąāŗ ā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋ➏ā˛ŋ", "no_shared_albums_message": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛œā˛¨ā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➰➚ā˛ŋ➏ā˛ŋ", "not_in_any_album": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋā˛˛āŗā˛˛", + "notes": "➟ā˛ŋā˛Ēāŗā˛Ē➪ā˛ŋ➗➺⺁", "notification_permission_dialog_content": "➅➧ā˛ŋā˛¸āŗ‚ā˛šā˛¨āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁, ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛ŋ➗⺆ ā˛šāŗ‹ā˛—ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ➏⺁ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ.", "notification_permission_list_tile_content": "➅➧ā˛ŋā˛¸āŗ‚ā˛šā˛¨āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ ā˛¨āŗ€ā˛Ąā˛ŋ.", + "notifications": "➅➧ā˛ŋā˛¸āŗ‚ā˛šā˛¨āŗ†ā˛—ā˛ŗāŗ", "obtainium_configurator_instructions": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➗ā˛ŋā˛Ÿāŗâ€Œā˛šā˛Ŧāŗâ€Œā˛¨ ā˛Ŧā˛ŋā˛Ąāŗā˛—ā˛Ąāŗ†ā˛¯ā˛ŋ➂ā˛Ļ ➍⺇➰ā˛ĩā˛žā˛—ā˛ŋ ā˛†ā˛‚ā˛Ąāŗā˛°ā˛žā˛¯āŗā˛Ąāŗ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋ➏➞⺁ ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ĩ⺀➕➰ā˛ŋ➏➞⺁ ā˛…ā˛Ÿāŗ‡ā˛Ÿā˛ŋ➍ā˛ŋā˛¯ā˛Žāŗ ā˛Ŧ➺➏ā˛ŋ. API ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛…ā˛Ÿāŗ‡ā˛Ÿā˛ŋ➍ā˛ŋā˛¯ā˛Žāŗ ā˛•ā˛žā˛¨āŗā˛Ģā˛ŋ➗➰⺇ā˛ļā˛¨āŗ ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏➞⺁ ➰⺂ā˛Ēā˛žā˛‚ā˛¤ā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "offline": "➆ā˛Ģāŗ ā˛˛āŗˆā˛¨āŗ", + "ok": "➏➰ā˛ŋ", + "onboarding": "ā˛†ā˛¨āŗ ā˛Ŧāŗ‹ā˛°āŗā˛Ąā˛ŋā˛‚ā˛—āŗ", "onboarding_locale_description": "➍ā˛ŋā˛Žāŗā˛Ž ➆ā˛Ļāŗā˛¯ā˛¤āŗ†ā˛¯ ā˛­ā˛žā˛ˇāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ. ➍⺀ā˛ĩ⺁ ➇ā˛Ļā˛¨āŗā˛¨āŗ ➍➂➤➰ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", "onboarding_privacy_description": "➕⺆➺➗ā˛ŋ➍ (ā˛ā˛šāŗā˛›ā˛ŋ➕) ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛—ā˛ŗāŗ ā˛Ŧā˛žā˛šāŗā˛¯ ➏⺇ā˛ĩāŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➅ā˛ĩ➞➂ā˛Ŧā˛ŋ➏ā˛ŋā˛ĩāŗ† ā˛Žā˛¤āŗā˛¤āŗ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛¸ā˛Žā˛¯ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", + "onboarding_server_welcome_description": "➍ā˛ŋā˛Žāŗā˛Ž ➍ā˛ŋā˛Ļā˛°āŗā˛ļ➍ā˛ĩā˛¨āŗā˛¨āŗ ➕⺆➞ā˛ĩ⺁ ā˛¸ā˛žā˛Žā˛žā˛¨āŗā˛¯ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗāŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏⺋➪.", "onboarding_theme_description": "➍ā˛ŋā˛Žāŗā˛Ž ➍ā˛ŋā˛Ļā˛°āŗā˛ļā˛¨ā˛•āŗā˛•āŗ† ā˛Ŧā˛Ŗāŗā˛Ŗā˛Ļ ā˛Ĩāŗ€ā˛Žāŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ. ➍⺀ā˛ĩ⺁ ➇ā˛Ļā˛¨āŗā˛¨āŗ ➍➂➤➰ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", + "online": "ā˛†ā˛¨āŗ ā˛˛āŗˆā˛¨āŗ", "open_in_map_view": "ā˛¨ā˛•āŗā˛ˇāŗ† ā˛ĩāŗ€ā˛•āŗā˛ˇā˛Ŗāŗ†ā˛¯ā˛˛āŗā˛˛ā˛ŋ ➤⺆➰⺆➝ā˛ŋ➰ā˛ŋ", "open_the_search_filters": "ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿ ā˛Ģā˛ŋā˛˛āŗā˛Ÿā˛°āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➰⺆➝ā˛ŋ➰ā˛ŋ", + "options": "ā˛†ā˛¯āŗā˛•āŗ†ā˛—ā˛ŗāŗ", + "or": "➅ā˛Ĩā˛ĩā˛ž", "organize_into_albums_description": "ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ➏ā˛ŋā˛‚ā˛•āŗ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋā˛•āŗŠā˛‚ā˛Ąāŗ ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ➇➰ā˛ŋ➏ā˛ŋ", + "original": "ā˛Žāŗ‚ā˛˛", + "other": "➇➤➰", + "owned": "ā˛Žā˛žā˛˛āŗ€ā˛•ā˛¤āŗā˛ĩ", + "owner": "ā˛Žā˛žā˛˛āŗ€ā˛•", + "partner": "ā˛Ēā˛žā˛˛āŗā˛Ļā˛žā˛°", "partner_can_access_assets": "ā˛†ā˛°āŗā˛•āŗˆā˛ĩāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛Ļ ā˛Žā˛¤āŗā˛¤āŗ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛°ā˛¤āŗā˛Ēā˛Ąā˛ŋ➏ā˛ŋ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", "partner_can_access_location": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļ ā˛¸āŗā˛Ĩ➺", "partner_page_empty_message": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛‡ā˛¨āŗā˛¨āŗ‚ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛Ēā˛žā˛˛āŗā˛Ļā˛žā˛°ā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ąā˛ŋā˛˛āŗā˛˛.", "partner_page_no_more_users": "➏⺇➰ā˛ŋ➏➞⺁ ā˛‡ā˛¨āŗā˛¨āŗ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛ŋā˛˛āŗā˛˛", + "partner_page_partner_add_failed": "ā˛Ēā˛žā˛˛āŗā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➏⺇➰ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", + "partner_page_stop_sharing_content": "{partner} ā˛‡ā˛¨āŗā˛¨āŗ ā˛Žāŗā˛‚ā˛Ļāŗ† ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛ĩ⺁ā˛Ļā˛ŋā˛˛āŗā˛˛.", + "partners": "ā˛Ēā˛žā˛˛āŗā˛Ļā˛žā˛°ā˛°āŗ", + "password": "ā˛Ēā˛žā˛¸āŗā˛ĩā˛°āŗā˛Ąāŗ", "password_does_not_match": "ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛•āŗ†ā˛¯ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", + "path": "ā˛šā˛žā˛Ļā˛ŋ", + "pattern": "ā˛Ēāŗā˛¯ā˛žā˛Ÿā˛°āŗā˛¨āŗ", + "pause": "ā˛ĩā˛ŋā˛°ā˛žā˛Ž", + "pending": "ā˛Ŧā˛žā˛•ā˛ŋ ➉➺ā˛ŋā˛Ļā˛ŋā˛Ļāŗ†", + "people": "➜➍➰⺁", "people_feature_description": "➜➍➰ā˛ŋ➂ā˛Ļ ➗⺁➂ā˛Ē⺁ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛°āŗŒā˛¸āŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", "people_sidebar_description": "ā˛¸āŗˆā˛Ąāŗâ€Œā˛Ŧā˛žā˛°āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ➜➍➰⺁ ā˛Žā˛‚ā˛Ŧ ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏ā˛ŋ", "permanent_deletion_warning_setting_description": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋ➏⺁ā˛ĩā˛žā˛— ā˛Žā˛šāŗā˛šā˛°ā˛ŋā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➤⺋➰ā˛ŋ➏ā˛ŋ", @@ -998,27 +1202,52 @@ "permission_onboarding_permission_granted": "ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ ā˛¨āŗ€ā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†! ➍⺀ā˛ĩ⺁ ➏ā˛ŋā˛Ļāŗā˛§ā˛°ā˛žā˛—ā˛ŋā˛Ļāŗā˛Ļ⺀➰ā˛ŋ.", "permission_onboarding_permission_limited": "ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ ā˛¸āŗ€ā˛Žā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†. ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➍ā˛ŋā˛Žāŗā˛Ž ➏➂ā˛Ēāŗ‚ā˛°āŗā˛Ŗ ā˛—āŗā˛¯ā˛žā˛˛ā˛°ā˛ŋ ā˛¸ā˛‚ā˛—āŗā˛°ā˛šā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏➞⺁, ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ€ā˛Ąā˛ŋ.", "permission_onboarding_request": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏➞⺁ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛—āŗ† ā˛…ā˛¨āŗā˛Žā˛¤ā˛ŋ ā˛Ŧ⺇➕⺁.", + "person": "ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ", "photo_shared_all_users": "➍⺀ā˛ĩ⺁ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ąā˛ŋ➰⺁ā˛ĩ➂➤⺆ ā˛•ā˛žā˛Ŗāŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ† ➅ā˛Ĩā˛ĩā˛ž ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ŧ➺ā˛ŋ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛ŋā˛˛āŗā˛˛.", + "photos": "ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ", "photos_from_previous_years": "ā˛šā˛ŋ➂ā˛Ļā˛ŋ➍ ā˛ĩā˛°āŗā˛ˇā˛—ā˛ŗ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ", "pin_code_setup_successfully": "ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "place": "ā˛¸āŗā˛Ĩ➺", + "places": "ā˛¸āŗā˛Ĩ➺➗➺⺁", + "play": "ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛ŋ", "play_or_pause_video": "ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛ŋ ➅ā˛Ĩā˛ĩā˛ž ā˛ĩā˛ŋā˛°ā˛žā˛Žā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", "play_original_video_setting_description": "ā˛Ÿāŗā˛°ā˛žā˛¨āŗā˛¸āŗâ€Œā˛•āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛ŋ➗ā˛ŋ➂➤ ā˛Žāŗ‚ā˛˛ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗ ā˛Ēāŗā˛˛āŗ‡ā˛Ŧāŗā˛¯ā˛žā˛•āŗâ€Œā˛—āŗ† ➆ā˛Ļāŗā˛¯ā˛¤āŗ† ā˛¨āŗ€ā˛Ąā˛ŋ. ā˛Žāŗ‚ā˛˛ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ ā˛šāŗŠā˛‚ā˛Ļā˛žā˛Ŗā˛ŋā˛•āŗ†ā˛¯ā˛žā˛—ā˛Ļā˛ŋā˛Ļāŗā˛Ļ➰⺆ ➅ā˛Ļ⺁ ➏➰ā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛Ēāŗā˛˛āŗ‡ā˛Ŧāŗā˛¯ā˛žā˛•āŗ ➆➗ā˛Ļā˛ŋ➰ā˛Ŧā˛šāŗā˛Ļ⺁.", + "port": "ā˛Ēāŗ‹ā˛°āŗā˛Ÿāŗ", + "preferences_settings_subtitle": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ ➆ā˛Ļāŗā˛¯ā˛¤āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", + "preset": "ā˛ŽāŗŠā˛Ļ➞⺇", + "preview": "ā˛Ēāŗ‚ā˛°āŗā˛ĩā˛ĩāŗ€ā˛•āŗā˛ˇā˛Ŗāŗ†", + "previous": "ā˛šā˛ŋ➂ā˛Ļā˛ŋ➍", + "primary": "ā˛Ēāŗā˛°ā˛žā˛Ĩā˛Žā˛ŋ➕", + "privacy": "ā˛—āŗŒā˛Ēāŗā˛¯ā˛¤āŗ†", "profile_drawer_client_server_up_to_date": "ā˛•āŗā˛˛āŗˆā˛‚ā˛Ÿāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛°āŗā˛ĩā˛°āŗ ➍ā˛ĩāŗ€ā˛•āŗƒā˛¤ā˛ĩā˛žā˛—ā˛ŋā˛ĩāŗ†", + "profile_drawer_readonly_mode": "➓ā˛Ļ➞⺁-ā˛Žā˛žā˛¤āŗā˛° ā˛Žāŗ‹ā˛Ąāŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†. ➍ā˛ŋā˛°āŗā˛—ā˛Žā˛ŋ➏➞⺁ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ➅ā˛ĩā˛¤ā˛žā˛°āŗ ā˛ā˛•ā˛žā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ļāŗ€ā˛°āŗā˛˜ā˛•ā˛žā˛˛ ā˛’ā˛¤āŗā˛¤ā˛ŋ➰ā˛ŋ.", "profile_image_of_user": "{user} ➰ ā˛Ēāŗā˛°āŗŠā˛Ģāŗˆā˛˛āŗ ➚ā˛ŋā˛¤āŗā˛°", + "purchase_account_info": "ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➗", "purchase_activated_subtitle": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛Žā˛¤āŗā˛¤āŗ ➓ā˛Ēā˛¨āŗ ā˛¸āŗ‹ā˛°āŗā˛¸āŗ ā˛¸ā˛žā˛Ģāŗā˛Ÿāŗâ€Œā˛ĩāŗ‡ā˛°āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļā˛•āŗā˛•ā˛žā˛—ā˛ŋ ā˛§ā˛¨āŗā˛¯ā˛ĩā˛žā˛Ļ➗➺⺁", "purchase_activated_title": "➍ā˛ŋā˛Žāŗā˛Ž ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "purchase_button_buy": "➖➰⺀ā˛Ļā˛ŋ➏ā˛ŋ", "purchase_button_reminder": "30 ā˛Ļā˛ŋā˛¨ā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ➍➍➗⺆ ➍⺆➍ā˛Ēā˛ŋ➏ā˛ŋ", + "purchase_button_select": "ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", "purchase_failed_activation": "ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†! ➏➰ā˛ŋā˛¯ā˛žā˛Ļ ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋā˛—ā˛žā˛—ā˛ŋ ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛‡ā˛Žāŗ‡ā˛˛āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏ā˛ŋ!", + "purchase_individual_title": "ā˛ĩāŗˆā˛¯ā˛•āŗā˛¤ā˛ŋ➕", "purchase_input_suggestion": "ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋ ➇ā˛Ļ⺆➝⺇? ➕⺆➺➗⺆ ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "purchase_license_subtitle": "➏⺇ā˛ĩ⺆➝ ➍ā˛ŋ➰➂➤➰ ➅➭ā˛ŋā˛ĩ⺃ā˛Ļāŗā˛§ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➏➞⺁ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛…ā˛¨āŗā˛¨āŗ ➖➰⺀ā˛Ļā˛ŋ➏ā˛ŋ", "purchase_panel_info_1": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➍ā˛ŋā˛°āŗā˛Žā˛žā˛Ŗā˛ĩ⺁ ā˛¸ā˛žā˛•ā˛ˇāŗā˛Ÿāŗ ā˛¸ā˛Žā˛¯ ā˛Žā˛¤āŗā˛¤āŗ ā˛ļāŗā˛°ā˛Žā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛Ļāŗ†, ā˛Žā˛¤āŗā˛¤āŗ ➅ā˛Ļā˛¨āŗā˛¨āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛Ļā˛ˇāŗā˛Ÿāŗ ā˛‰ā˛¤āŗā˛¤ā˛Žā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛¨ā˛žā˛ĩ⺁ ā˛Ēāŗ‚ā˛°āŗā˛Ŗ ā˛¸ā˛Žā˛¯ā˛Ļ ā˛Žā˛‚ā˛œā˛ŋ➍ā˛ŋā˛¯ā˛°āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛Ļāŗā˛Ļāŗ‡ā˛ĩāŗ†. ➓ā˛Ēā˛¨āŗ-ā˛¸āŗ‹ā˛°āŗā˛¸āŗ ā˛¸ā˛žā˛Ģāŗā˛Ÿāŗâ€Œā˛ĩāŗ‡ā˛°āŗ ā˛Žā˛¤āŗā˛¤āŗ ➍⺈➤ā˛ŋ➕ ā˛ĩāŗā˛¯ā˛ĩā˛šā˛žā˛° ā˛…ā˛­āŗā˛¯ā˛žā˛¸ā˛—ā˛ŗāŗ ā˛Ąāŗ†ā˛ĩ➞ā˛Ēā˛°āŗâ€Œā˛—ā˛ŗā˛ŋ➗⺆ ā˛¸āŗā˛¸āŗā˛Ĩā˛ŋ➰ ➆ā˛Ļā˛žā˛¯ā˛Ļ ā˛Žāŗ‚ā˛˛ā˛ĩā˛žā˛—āŗā˛ĩ⺁ā˛Ļ⺁ ā˛Žā˛¤āŗā˛¤āŗ ā˛ļ⺋➎➪⺆➝ ā˛•āŗā˛˛āŗŒā˛Ąāŗ ➏⺇ā˛ĩ⺆➗➺ā˛ŋ➗⺆ ➍ā˛ŋ➜ā˛ĩā˛žā˛Ļ ā˛Ēā˛°āŗā˛¯ā˛žā˛¯ā˛—ā˛ŗāŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛—āŗŒā˛Ēāŗā˛¯ā˛¤āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛—āŗŒā˛°ā˛ĩā˛ŋ➏⺁ā˛ĩ ā˛Ē➰ā˛ŋ➏➰ ā˛ĩāŗā˛¯ā˛ĩā˛¸āŗā˛Ĩāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏⺁ā˛ĩ⺁ā˛Ļ⺁ ā˛¨ā˛Žāŗā˛Ž ā˛§āŗā˛¯āŗ‡ā˛¯ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†.", "purchase_panel_info_2": "ā˛¨ā˛žā˛ĩ⺁ ā˛Ēāŗ‡ā˛ĩā˛žā˛˛āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➏⺇➰ā˛ŋ➏ā˛Ļā˛ŋ➰➞⺁ ā˛Ŧā˛Ļāŗā˛§ā˛°ā˛žā˛—ā˛ŋ➰⺁ā˛ĩ⺁ā˛Ļ➰ā˛ŋ➂ā˛Ļ, ➈ ➖➰⺀ā˛Ļā˛ŋ➝⺁ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ➍ā˛ŋā˛Žā˛—āŗ† ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛šāŗ†ā˛šāŗā˛šāŗā˛ĩ➰ā˛ŋ ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ€ā˛Ąāŗā˛ĩ⺁ā˛Ļā˛ŋā˛˛āŗā˛˛. ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛¨ ā˛¨ā˛Ąāŗ†ā˛¯āŗā˛¤āŗā˛¤ā˛ŋ➰⺁ā˛ĩ ➅➭ā˛ŋā˛ĩ⺃ā˛Ļāŗā˛§ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➏➞⺁ ā˛¨ā˛žā˛ĩ⺁ ➍ā˛ŋā˛Žāŗā˛Žā˛‚ā˛¤ā˛š ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➅ā˛ĩ➞➂ā˛Ŧā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļāŗ‡ā˛ĩāŗ†.", + "purchase_remove_product_key_prompt": "➍⺀ā˛ĩ⺁ ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "purchase_remove_server_product_key": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", "purchase_remove_server_product_key_prompt": "➍⺀ā˛ĩ⺁ ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "purchase_server_description_1": "ā˛‡ā˛Ąāŗ€ ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ†", + "purchase_server_title": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ", + "purchase_settings_server_activated": "ā˛¸ā˛°āŗā˛ĩā˛°āŗ ā˛‰ā˛¤āŗā˛Ēā˛¨āŗā˛¨ ➕⺀➞ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛žā˛šā˛•ā˛°āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛žā˛°āŗ†", "rating_description": "ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋ ā˛Ģ➞➕ā˛Ļā˛˛āŗā˛˛ā˛ŋ EXIF ā˛°āŗ‡ā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏ā˛ŋ", + "reassign": "ā˛Žā˛°āŗā˛šā˛‚ā˛šāŗā˛ĩā˛ŋ➕⺆", "reassigned_assets_to_existing_person": "{count, plural, one {# ā˛†ā˛¸āŗā˛¤ā˛ŋ} other {# ā˛†ā˛¸āŗā˛¤ā˛ŋ➗➺⺁}} ā˛…ā˛¨āŗā˛¨āŗ {name, select, null {➒➂ā˛Ļ⺁ ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ} other {{name}}} ➗⺆ ā˛Žā˛°āŗ ➍ā˛ŋā˛¯āŗ‹ā˛œā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "reassing_hint": "ā˛†ā˛¯āŗā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ➗⺆ ➍ā˛ŋā˛¯āŗ‹ā˛œā˛ŋ➏ā˛ŋ", + "refresh": "➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ", + "refreshed": "➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "refreshes_every_file": "ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛Žā˛¤āŗā˛¤āŗ ā˛šāŗŠā˛¸ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ģāŗˆā˛˛āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ē⺁➍➃ ➓ā˛Ļāŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "remove": "➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", "remove_assets_album_confirmation": "➍⺀ā˛ĩ⺁ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ {count, plural, one {# asset} other {# assets}} ā˛…ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "remove_assets_shared_link_confirmation": "➈ ā˛šā˛‚ā˛šā˛ŋ➕⺆➝ ➞ā˛ŋā˛‚ā˛•āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ {count, plural, one {# asset} other {# assets}} ā˛…ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛āŗ ➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", "remove_custom_date_range": "ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛ļāŗā˛°āŗ‡ā˛Ŗā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", @@ -1029,20 +1258,35 @@ "remove_photo_from_memory": "➈ ➍⺆➍ā˛Ēā˛ŋ➍ā˛ŋ➂ā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", "removed_api_key": "➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛Ļ API ➕⺀: {name}", "removed_photo_from_memory": "➍⺆➍ā˛Ēā˛ŋ➍ā˛ŋ➂ā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "rename": "ā˛Žā˛°āŗā˛šāŗ†ā˛¸ā˛°ā˛ŋ➏ā˛ŋ", + "repair": "ā˛Ļāŗā˛°ā˛¸āŗā˛¤ā˛ŋ", "repair_no_results_message": "ā˛Ÿāŗā˛°āŗā˛¯ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛Ļ ā˛Žā˛¤āŗā˛¤āŗ ā˛•ā˛žā˛Ŗāŗ†ā˛¯ā˛žā˛Ļ ā˛Ģāŗˆā˛˛āŗâ€Œā˛—ā˛ŗāŗ ā˛‡ā˛˛āŗā˛˛ā˛ŋ ā˛•ā˛žā˛Ŗā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛ĩāŗ†", + "repository": "➰⺆ā˛Ē⺊➏ā˛ŋ➟➰ā˛ŋ", "require_user_to_change_password_on_first_login": "ā˛ŽāŗŠā˛Ļ➞ ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°āŗ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛Ŧāŗ‡ā˛•ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "reset": "ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏ā˛ŋ", "reset_pin_code_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ➍⺀ā˛ĩ⺁ ā˛Žā˛°āŗ†ā˛¤ā˛ŋā˛Ļāŗā˛Ļ➰⺆, ➅ā˛Ļā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏➞⺁ ➍⺀ā˛ĩ⺁ ā˛¸ā˛°āŗā˛ĩā˛°āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛žā˛šā˛•ā˛°ā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛°āŗā˛•ā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁", + "reset_pin_code_with_password": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗâ€Œā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➍⺀ā˛ĩ⺁ ā˛¯ā˛žā˛ĩā˛žā˛—ā˛˛āŗ‚ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁", "reset_sqlite_confirmation": "➍⺀ā˛ĩ⺁ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛Ąāŗ‡ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➇ā˛Ļ⺁ ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛¤āŗā˛¤ā˛Ļāŗ† ā˛Žā˛¤āŗā˛¤āŗ ➍ā˛ŋā˛Žāŗā˛Žā˛¨āŗā˛¨āŗ ā˛¸āŗˆā˛¨āŗ ā˛”ā˛Ÿāŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "reset_sqlite_confirmation_note": "ā˛—ā˛Žā˛¨ā˛ŋ➏ā˛ŋ: ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋā˛Ļ ➍➂➤➰ ➍⺀ā˛ĩ⺁ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏ā˛Ŧāŗ‡ā˛•ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", + "reset_sqlite_done": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛Ąāŗ‡ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†. ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛Žā˛¤āŗā˛¤āŗ† ā˛˛ā˛žā˛—ā˛ŋā˛¨āŗ ā˛Žā˛žā˛Ąā˛ŋ.", "reset_sqlite_success": "SQLite ā˛Ąāŗ‡ā˛Ÿā˛žā˛Ŧāŗ‡ā˛¸āŗ ā˛…ā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛Žā˛°āŗā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "restore": "ā˛Žā˛°āŗā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋ➏ā˛ŋ", + "resume": "ā˛Ēāŗā˛¨ā˛°ā˛žā˛°ā˛‚ā˛­", + "role": "ā˛Ēā˛žā˛¤āŗā˛°", "scaffold_body_error_unrecoverable": "➏➰ā˛ŋā˛Ēā˛Ąā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛Ļ ā˛Ļ⺋➎ ➏➂➭ā˛ĩā˛ŋ➏ā˛ŋā˛Ļāŗ†. ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛Ļ⺋➎ā˛ĩā˛¨āŗā˛¨āŗ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛Ąā˛ŋā˛¸āŗā˛•ā˛žā˛°āŗā˛Ąāŗ ➅ā˛Ĩā˛ĩā˛ž ➗ā˛ŋā˛Ÿāŗâ€Œā˛šā˛Ŧāŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛Ÿāŗā˛°āŗ‡ā˛¸āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛¸āŗā˛Ÿāŗā˛¯ā˛žā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋ ➇ā˛Ļ➰ā˛ŋ➂ā˛Ļ ā˛¨ā˛žā˛ĩ⺁ ā˛¸ā˛šā˛žā˛¯ ā˛Žā˛žā˛Ąā˛Ŧā˛šāŗā˛Ļ⺁. ā˛¸ā˛˛ā˛šāŗ† ā˛¨āŗ€ā˛Ąā˛ŋā˛Ļ➰⺆, ➍⺀ā˛ĩ⺁ ➕⺆➺➗ā˛ŋ➍ ➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ā˛Ąāŗ‡ā˛Ÿā˛žā˛ĩā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", "search_by_description_example": "ā˛¸ā˛žā˛Ēā˛žā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛Ēā˛žā˛Ļā˛¯ā˛žā˛¤āŗā˛°āŗ†ā˛¯ ā˛Ļā˛ŋ➍", "search_by_filename": "ā˛Ģāŗˆā˛˛āŗ ā˛šāŗ†ā˛¸ā˛°āŗ ➅ā˛Ĩā˛ĩā˛ž ā˛ĩā˛ŋā˛¸āŗā˛¤ā˛°ā˛Ŗāŗ†ā˛¯ ā˛Žāŗ‚ā˛˛ā˛• ā˛šāŗā˛Ąāŗā˛•ā˛ŋ", "search_by_filename_example": "➅➂ā˛Ļ➰⺆ IMG_1234.JPG ➅ā˛Ĩā˛ĩā˛ž PNG", + "search_filter_date_title": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛ļāŗā˛°āŗ‡ā˛Ŗā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "search_filter_filename": "ā˛Ģāŗˆā˛˛āŗ ā˛šāŗ†ā˛¸ā˛°ā˛ŋ➍ ā˛Žāŗ‚ā˛˛ā˛• ā˛šāŗā˛Ąāŗā˛•ā˛ŋ", "search_for_existing_person": "ā˛…ā˛¸āŗā˛¤ā˛ŋā˛¤āŗā˛ĩā˛Ļā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛šāŗā˛Ąāŗā˛•ā˛ŋ", "search_no_people_named": "\"{name}\" ā˛šāŗ†ā˛¸ā˛°ā˛ŋ➍ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ➜➍➰ā˛ŋā˛˛āŗā˛˛", + "search_no_result": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛Ģ➞ā˛ŋā˛¤ā˛žā˛‚ā˛ļ➗➺⺁ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛˛āŗā˛˛, ā˛Ŧ⺇➰⺆ ā˛šāŗā˛Ąāŗā˛•ā˛žā˛Ÿ ā˛Ēā˛Ļ ➅ā˛Ĩā˛ĩā˛ž ā˛¸ā˛‚ā˛¯āŗ‹ā˛œā˛¨āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛¯ā˛¤āŗā˛¨ā˛ŋ➏ā˛ŋ", + "search_page_no_objects": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛ĩā˛¸āŗā˛¤āŗā˛—ā˛ŗ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", + "search_page_no_places": "ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛¸āŗā˛Ĩ➺➗➺ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛", "search_page_search_photos_videos": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗā˛Ąāŗā˛•ā˛ŋ", "select_person_to_tag": "ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "select_user_for_sharing_page_err_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➰➚ā˛ŋ➏➞⺁ ā˛ĩā˛ŋā˛Ģ➞ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ†", "server_restarting_description": "➈ ā˛Ē⺁➟ā˛ĩ⺁ ā˛•āŗā˛ˇā˛Ŗā˛Žā˛žā˛¤āŗā˛°ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ā˛†ā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "set_as_album_cover": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ➕ā˛ĩā˛°āŗ ➆➗ā˛ŋ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏ā˛ŋ", "set_as_featured_photo": "ā˛ĩ⺈ā˛ļā˛ŋā˛ˇāŗā˛Ÿāŗā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ ā˛Žā˛‚ā˛Ļ⺁ ā˛šāŗŠā˛‚ā˛Ļā˛ŋ➏ā˛ŋ", @@ -1053,66 +1297,278 @@ "setting_image_viewer_help": "ā˛ĩā˛ŋā˛ĩ➰ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛•ā˛ĩ⺁ ā˛ŽāŗŠā˛Ļ➞⺁ ā˛¸ā˛Ŗāŗā˛Ŗ ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛Ļāŗ†, ➍➂➤➰ ā˛Žā˛§āŗā˛¯ā˛Ž ā˛—ā˛žā˛¤āŗā˛°ā˛Ļ ā˛Ēāŗ‚ā˛°āŗā˛ĩā˛ĩāŗ€ā˛•āŗā˛ˇā˛Ŗāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛Ļāŗ† (ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļ➰⺆), ➅➂➤ā˛ŋā˛Žā˛ĩā˛žā˛—ā˛ŋ ā˛Žāŗ‚ā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛Ļāŗ† (ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļ➰⺆).", "setting_image_viewer_original_subtitle": "ā˛Žāŗ‚ā˛˛ ā˛Ēāŗ‚ā˛°āŗā˛Ŗ-ā˛°āŗ†ā˛¸ā˛˛āŗā˛¯āŗ‚ā˛ļā˛¨āŗ ➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ (ā˛ĻāŗŠā˛Ąāŗā˛Ąā˛Ļ⺁!). ā˛Ąāŗ‡ā˛Ÿā˛ž ā˛Ŧā˛ŗā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛•ā˛Ąā˛ŋā˛Žāŗ† ā˛Žā˛žā˛Ąā˛˛āŗ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ (ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛žā˛§ā˛¨ā˛Ļ ā˛¸ā˛‚ā˛—āŗā˛°ā˛š ā˛Žā˛°ā˛Ąā˛°ā˛˛āŗā˛˛āŗ‚).", "setting_image_viewer_preview_subtitle": "ā˛Žā˛§āŗā˛¯ā˛Ž ā˛°āŗ†ā˛¸ā˛˛āŗā˛¯āŗ‚ā˛ļā˛¨āŗ ➚ā˛ŋā˛¤āŗā˛°ā˛ĩā˛¨āŗā˛¨āŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ. ā˛Žāŗ‚ā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ➍⺇➰ā˛ĩā˛žā˛—ā˛ŋ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ➅ā˛Ĩā˛ĩā˛ž ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛žā˛¤āŗā˛° ā˛Ŧ➺➏➞⺁ ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ.", + "setting_languages_subtitle": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗâ€Œā˛¨ ā˛­ā˛žā˛ˇāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏ā˛ŋ", "setting_notifications_notify_failures_grace_period": "ā˛šā˛ŋā˛¨āŗā˛¨āŗ†ā˛˛āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛ĩ⺈ā˛Ģā˛˛āŗā˛¯ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¸āŗ‚ā˛šā˛ŋ➏ā˛ŋ: {duration}", "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_original_video_subtitle": "ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ā˛ĩā˛¨āŗā˛¨āŗ ā˛¸āŗā˛Ÿāŗā˛°āŗ€ā˛Žāŗ ā˛Žā˛žā˛Ąāŗā˛ĩā˛žā˛—, ā˛Ÿāŗā˛°ā˛žā˛¨āŗā˛¸āŗâ€Œā˛•āŗ‹ā˛Ąāŗ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗā˛Ļ➰⺂ ā˛¸ā˛š ā˛Žāŗ‚ā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛ŋ. ā˛Ŧā˛Ģ➰ā˛ŋā˛‚ā˛—āŗâ€Œā˛—āŗ† ā˛•ā˛žā˛°ā˛Ŗā˛ĩā˛žā˛—ā˛Ŧā˛šāŗā˛Ļ⺁. ➈ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛˛āŗ†ā˛•āŗā˛•ā˛ŋ➏ā˛Ļāŗ† ā˛¸āŗā˛Ĩ➺⺀➝ā˛ĩā˛žā˛—ā˛ŋ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋ➰⺁ā˛ĩ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žāŗ‚ā˛˛ ā˛—āŗā˛Ŗā˛Žā˛Ÿāŗā˛Ÿā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†.", "settings_require_restart": "➈ ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛…ā˛¨āŗā˛ĩ➝ā˛ŋ➏➞⺁ ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏ā˛ŋ", "shared_album_activity_remove_content": "➍⺀ā˛ĩ⺁ ➈ ➚➟⺁ā˛ĩ➟ā˛ŋā˛•āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "shared_album_section_people_action_error": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ā˛¤āŗŠā˛°āŗ†ā˛¯āŗā˛ĩā˛žā˛—/➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•āŗā˛ĩā˛žā˛— ā˛Ļ⺋➎ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛Ļāŗ†", + "shared_album_section_people_action_leave": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", + "shared_album_section_people_action_remove_user": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", + "shared_intent_upload_button_progress_text": "{current} / {total} ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "shared_link_create_error": "ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ➰➚ā˛ŋ➏⺁ā˛ĩā˛žā˛— ā˛Ļ⺋➎ ā˛•ā˛‚ā˛Ąāŗā˛Ŧ➂ā˛Ļā˛ŋā˛Ļāŗ†", "shared_link_custom_url_description": "ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ URL ā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➈ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏ā˛ŋ", + "shared_link_edit_description_hint": "ā˛šā˛‚ā˛šā˛ŋ➕⺆ ā˛ĩā˛ŋā˛ĩā˛°ā˛Ŗāŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "shared_link_edit_password_hint": "ā˛šā˛‚ā˛šā˛ŋ➕⺆ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", "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_second": "{count} ā˛¸āŗ†ā˛•āŗ†ā˛‚ā˛Ąāŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ➅ā˛ĩ➧ā˛ŋ ā˛Žāŗā˛—ā˛ŋā˛¯āŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "shared_link_expires_seconds": "{count} ā˛¸āŗ†ā˛•āŗ†ā˛‚ā˛Ąāŗā˛—ā˛ŗā˛˛āŗā˛˛ā˛ŋ ➅ā˛ĩ➧ā˛ŋ ā˛Žāŗā˛—ā˛ŋā˛¯āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "shared_link_password_description": "➈ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛ĩāŗ‡ā˛ļā˛ŋ➏➞⺁ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛…ā˛—ā˛¤āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†", "shared_links_description": "➞ā˛ŋā˛‚ā˛•āŗ ā˛Žāŗ‚ā˛˛ā˛• ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ", "sharing_enter_password": "➈ ā˛Ē⺁➟ā˛ĩā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏➞⺁ ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛Ēā˛žā˛¸āŗâ€Œā˛ĩā˛°āŗā˛Ąāŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ.", "sharing_page_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¨āŗ†ā˛Ÿāŗâ€Œā˛ĩā˛°āŗā˛•āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ➰⺁ā˛ĩ ā˛œā˛¨ā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ ā˛šā˛‚ā˛šā˛ŋā˛Ļ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➰➚ā˛ŋ➏ā˛ŋ.", "sharing_sidebar_description": "ā˛¸āŗˆā˛Ąāŗâ€Œā˛Ŧā˛žā˛°āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛šā˛‚ā˛šā˛ŋ➕⺆➗⺆ ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏ā˛ŋ", "shift_to_permanent_delete": "ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋ➏➞⺁ ⇧ ā˛’ā˛¤āŗā˛¤ā˛ŋ➰ā˛ŋ", + "show_and_hide_people": "ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ➤⺋➰ā˛ŋ➏ā˛ŋ ā˛Žā˛¤āŗā˛¤āŗ ā˛Žā˛°āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "show_in_timeline_setting_description": "➈ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛Ÿāŗˆā˛Žāŗâ€Œā˛˛āŗˆā˛¨āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ➤⺋➰ā˛ŋ➏ā˛ŋ", + "show_or_hide_info": "ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➤⺋➰ā˛ŋ➏ā˛ŋ ➅ā˛Ĩā˛ĩā˛ž ā˛Žā˛°āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "show_supporter_badge_description": "ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➗➰ ā˛Ŧāŗā˛¯ā˛žā˛Ąāŗā˛œāŗ ➤⺋➰ā˛ŋ➏ā˛ŋ", + "sidebar_display_description": "ā˛¸āŗˆā˛Ąāŗâ€Œā˛Ŧā˛žā˛°āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛Ŗāŗ†ā˛—āŗ† ➞ā˛ŋā˛‚ā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛Ļā˛°āŗā˛ļā˛ŋ➏ā˛ŋ", "slideshow_repeat_description": "ā˛¸āŗā˛˛āŗˆā˛Ąāŗâ€Œā˛ļāŗ‹ ā˛•āŗŠā˛¨āŗ†ā˛—āŗŠā˛‚ā˛Ąā˛žā˛— ā˛†ā˛°ā˛‚ā˛­ā˛•āŗā˛•āŗ† ā˛šā˛ŋ➂➤ā˛ŋ➰⺁➗ā˛ŋ", + "sort_created": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ➰➚ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "sort_items": "ā˛ĩā˛¸āŗā˛¤āŗā˛—ā˛ŗ ā˛¸ā˛‚ā˛–āŗā˛¯āŗ†", + "sort_modified": "ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛Žā˛žā˛°āŗā˛Ēā˛Ąā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "sort_newest": "ā˛šāŗŠā˛¸ ā˛Ģāŗ‹ā˛Ÿāŗ‹", + "sort_oldest": "ā˛šā˛ŗāŗ†ā˛¯ ā˛Ģāŗ‹ā˛Ÿāŗ‹", + "sort_people_by_similarity": "ā˛šāŗ‹ā˛˛ā˛ŋ➕⺆➝ ā˛†ā˛§ā˛žā˛°ā˛Ļ ā˛Žāŗ‡ā˛˛āŗ† ā˛œā˛¨ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩā˛ŋā˛‚ā˛—ā˛Ąā˛ŋ➏ā˛ŋ", + "sort_recent": "ā˛¤āŗ€ā˛°ā˛ž ā˛‡ā˛¤āŗā˛¤āŗ€ā˛šā˛ŋ➍ ā˛Ģāŗ‹ā˛Ÿāŗ‹", + "sort_title": "ā˛ļāŗ€ā˛°āŗā˛ˇā˛ŋ➕⺆", + "stack": "ā˛¸āŗā˛Ÿā˛žā˛•āŗ", + "stack_duplicates": "ā˛¸āŗā˛Ÿā˛žā˛•āŗ ➍➕➞⺁➗➺⺁", "stack_select_one_photo": "ā˛¸āŗā˛Ÿāŗā˛¯ā˛žā˛•āŗâ€Œā˛—ā˛žā˛—ā˛ŋ ➒➂ā˛Ļ⺁ ā˛Žāŗā˛–āŗā˛¯ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "stack_selected_photos": "ā˛†ā˛¯āŗā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛œāŗ‹ā˛Ąā˛ŋ➏ā˛ŋ", + "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": "ā˛ļāŗ‡ā˛–ā˛°ā˛Ŗā˛ž ā˛•āŗ‹ā˛Ÿā˛ž", + "submit": "ā˛¸ā˛˛āŗā˛˛ā˛ŋ➏ā˛ŋ", + "success": "➝ā˛ļā˛¸āŗā˛¸āŗ", + "suggestions": "ā˛¸ā˛˛ā˛šāŗ†ā˛—ā˛ŗāŗ", + "sunrise_on_the_beach": "ā˛•ā˛Ąā˛˛ā˛¤āŗ€ā˛°ā˛Ļā˛˛āŗā˛˛ā˛ŋ ā˛¸āŗ‚ā˛°āŗā˛¯āŗ‹ā˛Ļ➝", + "support": "ā˛Ŧ⺆➂ā˛Ŧ➞", + "support_and_feedback": "ā˛Ŧ⺆➂ā˛Ŧ➞ ā˛Žā˛¤āŗā˛¤āŗ ā˛Ēāŗā˛°ā˛¤ā˛ŋā˛•āŗā˛°ā˛ŋ➝⺆", "support_third_party_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ā˛¸āŗā˛Ĩā˛žā˛Ēā˛¨āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ā˛Žāŗ‚ā˛°ā˛¨āŗ‡ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ➝ā˛ŋ➂ā˛Ļ ā˛Ēāŗā˛¯ā˛žā˛•āŗ‡ā˛œāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†. ➍⺀ā˛ĩ⺁ ➅➍⺁➭ā˛ĩā˛ŋ➏⺁ā˛ĩ ā˛¸ā˛Žā˛¸āŗā˛¯āŗ†ā˛—ā˛ŗāŗ ➆ ā˛Ēāŗā˛¯ā˛žā˛•āŗ‡ā˛œāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛‰ā˛‚ā˛Ÿā˛žā˛—ā˛ŋ➰ā˛Ŧā˛šāŗā˛Ļ⺁, ➆ā˛Ļāŗā˛Ļ➰ā˛ŋ➂ā˛Ļ ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ➕⺆➺➗ā˛ŋ➍ ➞ā˛ŋā˛‚ā˛•āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋā˛•āŗŠā˛‚ā˛Ąāŗ ā˛ŽāŗŠā˛Ļ➞ ➏➂ā˛Ļā˛°āŗā˛­ā˛Ļā˛˛āŗā˛˛ā˛ŋ ➅ā˛ĩā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ā˛¸ā˛Žā˛¸āŗā˛¯āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Žā˛¤āŗā˛¤ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ.", + "supporter": "ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➗", + "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_feature_description": "ā˛¤ā˛žā˛°āŗā˛•ā˛ŋ➕ ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ā˛ĩā˛ŋ➎➝➗➺ ā˛Žāŗ‚ā˛˛ā˛• ➗⺁➂ā˛Ē⺁ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ŧāŗā˛°āŗŒā˛¸āŗ ā˛Žā˛žā˛Ąāŗā˛ĩ⺁ā˛Ļ⺁", "tag_not_found_question": "ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ➏ā˛ŋā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛ā˛ĩāŗ‡? Create a new tag.", + "tag_people": "ā˛Ÿāŗā˛¯ā˛žā˛—āŗ ➜➍➰⺁", + "tags": "ā˛Ÿāŗā˛¯ā˛žā˛—āŗā˛—ā˛ŗāŗ", + "tap_to_run_job": "➕⺆➞➏ā˛ĩā˛¨āŗā˛¨āŗ ā˛šā˛˛ā˛žā˛¯ā˛ŋ➏➞⺁ ā˛Ÿāŗā˛¯ā˛žā˛Ēāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "template": "ā˛Ÿāŗ†ā˛‚ā˛Ēāŗā˛˛āŗ‡ā˛Ÿāŗ", + "text_recognition": "ā˛Ēā˛ āŗā˛¯ ➗⺁➰⺁➤ā˛ŋ➏⺁ā˛ĩā˛ŋ➕⺆", + "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": "ā˛Žāŗ‚ā˛°āŗ ā˛šā˛‚ā˛¤ā˛Ļ ā˛˛āŗ‹ā˛Ąā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛¸ā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋ", + "then": "➍➂➤➰", "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": "ā˛¸āŗ†ā˛Ÿāŗā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ÿā˛žā˛—ā˛˛āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "toggle_theme_description": "ā˛Ĩāŗ€ā˛Žāŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ÿā˛žā˛—ā˛˛āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "total": "ā˛’ā˛Ÿāŗā˛Ÿāŗ", + "total_usage": "ā˛’ā˛Ÿāŗā˛Ÿāŗ ā˛Ŧ➺➕⺆", + "trash": "➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤", + "trash_all": "ā˛Žā˛˛āŗā˛˛ā˛ž ➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤", + "trash_delete_asset": "➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ / ➅➺ā˛ŋ➏⺁ ā˛†ā˛¸āŗā˛¤ā˛ŋ", + "trash_emptied": "ā˛–ā˛žā˛˛ā˛ŋ ➕➏", "trash_no_results_message": "➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ā˛•āŗā˛•āŗ† ā˛ĩā˛°āŗā˛—ā˛žā˛¯ā˛ŋā˛¸ā˛˛ā˛žā˛Ļ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ ā˛‡ā˛˛āŗā˛˛ā˛ŋ ā˛•ā˛žā˛Ŗā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗāŗā˛¤āŗā˛¤ā˛ĩāŗ†.", + "trash_page_delete_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ‚ ➅➺ā˛ŋ➏ā˛ŋ", "trash_page_empty_trash_dialog_content": "➍ā˛ŋā˛Žāŗā˛Ž ➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛–ā˛žā˛˛ā˛ŋ ā˛Žā˛žā˛Ąā˛˛āŗ ➍⺀ā˛ĩ⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž? ➈ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛¨ā˛ŋ➂ā˛Ļ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "trash_page_info": "➅➍⺁ā˛Ēā˛¯āŗā˛•āŗā˛¤ā˛•āŗā˛•āŗ† ➏⺇➰ā˛ŋ➏ā˛ŋā˛Ļ ā˛ā˛Ÿā˛‚ā˛—ā˛ŗā˛¨āŗā˛¨āŗ {days} ā˛Ļā˛ŋ➍➗➺ ➍➂➤➰ ā˛ļā˛žā˛ļāŗā˛ĩ➤ā˛ĩā˛žā˛—ā˛ŋ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "trash_page_no_assets": "➕➏ā˛Ļ ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛‡ā˛˛āŗā˛˛", + "trash_page_restore_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ā˛Žā˛°āŗā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋ➏ā˛ŋ", + "trash_page_select_assets_btn": "ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋ", + "trigger": "ā˛Ÿāŗā˛°ā˛ŋā˛—āŗā˛—ā˛°āŗ", + "trigger_asset_uploaded": "ā˛†ā˛¸āŗā˛¤ā˛ŋ ➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "trigger_asset_uploaded_description": "ā˛šāŗŠā˛¸ ā˛¸āŗā˛ĩā˛¤āŗā˛¤ā˛¨āŗā˛¨āŗ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋā˛Ļā˛žā˛— ā˛Ÿāŗā˛°ā˛ŋā˛—ā˛°āŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", "trigger_description": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏⺁ā˛ĩ ➒➂ā˛Ļ⺁ ā˛˜ā˛Ÿā˛¨āŗ†", + "trigger_person_recognized": "ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ ➗⺁➰⺁➤ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", "trigger_person_recognized_description": "➒ā˛Ŧāŗā˛Ŧ ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ēā˛¤āŗā˛¤āŗ†ā˛šā˛šāŗā˛šā˛ŋā˛Ļā˛žā˛— ā˛Ēāŗā˛°ā˛šāŗ‹ā˛Ļā˛ŋā˛¸ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛Ļāŗ†", + "trigger_type": "ā˛Ÿāŗā˛°ā˛ŋā˛—āŗā˛—ā˛°āŗ ā˛Ēāŗā˛°ā˛•ā˛žā˛°", + "troubleshoot": "ā˛¤āŗŠā˛‚ā˛Ļ➰⺆", + "type": "➟⺈ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛ŋ", "unable_to_change_pin_code": "ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛Ŧā˛Ļā˛˛ā˛žā˛¯ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", "unable_to_check_version": "➅ā˛Ēāŗā˛˛ā˛ŋ➕⺇ā˛ļā˛¨āŗ ➅ā˛Ĩā˛ĩā˛ž ā˛¸ā˛°āŗā˛ĩā˛°āŗ ➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ē➰ā˛ŋā˛ļ⺀➞ā˛ŋ➏➞⺁ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", "unable_to_setup_pin_code": "ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛¸āŗ†ā˛Ÿā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛˛āŗā˛˛", + "unarchive": "ā˛…ā˛°ā˛žā˛œā˛•ā˛¤ā˛žā˛ĩā˛žā˛Ļā˛ŋ", + "unfavorite": "ā˛…ā˛šā˛ŋ➤➕➰", + "unhide_person": "ā˛¸ā˛šā˛žā˛¯ā˛• ā˛ĩāŗā˛¯ā˛•āŗā˛¤ā˛ŋ", + "unknown": "ā˛…ā˛œāŗā˛žā˛žā˛¤", + "unknown_country": "ā˛…ā˛œāŗā˛žā˛žā˛¤ ā˛Ļāŗ‡ā˛ļ", + "unknown_date": "ā˛…ā˛œāŗā˛žā˛žā˛¤ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•", + "unknown_year": "ā˛…ā˛œāŗā˛žā˛žā˛¤ ā˛ĩā˛°āŗā˛ˇ", + "unlimited": "➅➍ā˛ŋā˛¯ā˛Žā˛ŋ➤", + "unlink_motion_video": "ā˛šā˛˛ā˛¨āŗ†ā˛¯ ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ā˛ĩā˛¨āŗā˛¨āŗ ā˛…ā˛¨āŗā˛˛ā˛ŋā˛‚ā˛•āŗ ā˛Žā˛žā˛Ąā˛ŋ", + "unmute_memories": "ā˛…ā˛¨āŗā˛šā˛ŋ➤ ➍⺆➍ā˛Ē⺁➗➺⺁", + "unnamed_album": "ā˛šāŗ†ā˛¸ā˛°ā˛ŋ➏ā˛Ļ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ", + "unnamed_album_delete_confirmation": "➍⺀ā˛ĩ⺁ ➈ ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ā˛…ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "unnamed_share": "ā˛šāŗ†ā˛¸ā˛°ā˛ŋ➏ā˛Ļ ā˛Ēā˛žā˛˛āŗ", + "unsaved_change": "➉➺ā˛ŋ➏ā˛Ļ ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩ➪⺆", + "unselect_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ† ā˛Žā˛žā˛Ąā˛ŋ", + "unselect_all_duplicates": "ā˛Žā˛˛āŗā˛˛ā˛ž ā˛¨ā˛•ā˛˛āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛†ā˛¯āŗā˛•āŗ† ā˛Žā˛žā˛Ąā˛Ŧāŗ‡ā˛Ąā˛ŋ", + "unstack": "ā˛…ā˛¨āŗ-ā˛¸āŗā˛Ÿā˛žā˛•āŗ", + "unsupported_field_type": "ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➏ā˛Ļ ā˛•āŗā˛ˇāŗ‡ā˛¤āŗā˛° ā˛Ēāŗā˛°ā˛•ā˛žā˛°", "unsupported_file_type": "{file} ā˛Ģāŗˆā˛˛āŗ ā˛Ēāŗā˛°ā˛•ā˛žā˛°ā˛ĩ⺁ ā˛Ŧ⺆➂ā˛Ŧ➞ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋā˛˛āŗā˛˛ā˛Ļ {type} ā˛•ā˛žā˛°ā˛Ŗ ➅ā˛Ļā˛¨āŗā˛¨āŗ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ā˛¸ā˛žā˛§āŗā˛¯ā˛ĩā˛ŋā˛˛āŗā˛˛.", + "untagged": "ā˛…ā˛¨āŗā˛Ÿā˛žā˛—āŗā˛Ąāŗ", + "untitled_workflow": "ā˛ļāŗ€ā˛°āŗā˛ˇā˛ŋā˛•āŗ†ā˛°ā˛šā˛ŋ➤ ➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩ⺁", + "up_next": "ā˛Žāŗā˛‚ā˛Ļā˛ŋ➍ ➅ā˛Ēāŗ", "update_location_action_prompt": "{count} ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗ ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ➇ā˛Ļā˛°āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➍ā˛ĩ⺀➕➰ā˛ŋ➏ā˛ŋ:", + "updated_at": "➍ā˛ĩ⺀➕➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "updated_password": "ā˛Ēā˛žā˛¸āŗā˛ĩā˛°āŗā˛Ąāŗ ➍ā˛ĩ⺀➕➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "upload": "➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "upload_concurrency": "➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛•ā˛¨āŗā˛•āŗā˛¯āŗā˛°āŗ†ā˛¨āŗā˛¸ā˛ŋ", + "upload_details": "➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛ĩā˛ŋā˛ĩ➰➗➺⺁", "upload_dialog_info": "ā˛†ā˛¯āŗā˛•āŗ†ā˛Žā˛žā˛Ąā˛ŋā˛Ļ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗ(ā˛—ā˛ŗā˛¨āŗā˛¨āŗ) ā˛¸ā˛°āŗā˛ĩā˛°āŗâ€Œā˛—āŗ† ā˛Ŧāŗā˛¯ā˛žā˛•ā˛Ēāŗ ā˛Žā˛žā˛Ąā˛˛āŗ ➍⺀ā˛ĩ⺁ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "upload_dialog_title": "➅ā˛Ēāŗā˛˛āŗ‹ā˛Ąāŗ ā˛†ā˛¸āŗā˛¤ā˛ŋ", "upload_errors": "{count, plural, one {# ā˛Ļ⺋➎} other {# ā˛Ļ⺋➎➗➺⺁}} ā˛¨āŗŠā˛‚ā˛Ļā˛ŋ➗⺆ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Ēāŗ‚ā˛°āŗā˛Ŗā˛—āŗŠā˛‚ā˛Ąā˛ŋā˛Ļāŗ†, ā˛šāŗŠā˛¸ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ‹ā˛Ąā˛˛āŗ ā˛Ē⺁➟ā˛ĩā˛¨āŗā˛¨āŗ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ā˛Žā˛žā˛Ąā˛ŋ.", + "upload_finished": "➅ā˛Ēāŗā˛˛āŗ‹ā˛Ąāŗ ā˛Žāŗā˛—ā˛ŋā˛Ļā˛ŋā˛Ļāŗ†", + "upload_status_duplicates": "➍➕➞⺁", + "upload_status_errors": "ā˛Ļ⺋➎➗➺⺁", + "upload_status_uploaded": "➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "upload_success": "➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋā˛Ļāŗ†, ā˛šāŗŠā˛¸ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¨āŗ‹ā˛Ąā˛˛āŗ ā˛Ē⺁➟ā˛ĩā˛¨āŗā˛¨āŗ ➰ā˛ŋā˛Ģāŗā˛°āŗ†ā˛ļāŗ ā˛Žā˛žā˛Ąā˛ŋ.", + "upload_to_immich": "ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ({count}) ➗⺆ ➅ā˛Ēāŗâ€Œā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "uploading": "➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛†ā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", + "uploading_media": "ā˛Žā˛žā˛§āŗā˛¯ā˛Žā˛ĩā˛¨āŗā˛¨āŗ ➅ā˛Ēāŗ ā˛˛āŗ‹ā˛Ąāŗ ā˛Žā˛žā˛Ąā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", + "usage": "ā˛Ŧ➺➕⺆", + "use_biometric": "ā˛Ŧā˛¯āŗ‹ā˛Žāŗ†ā˛Ÿāŗā˛°ā˛ŋā˛•āŗ ā˛Ŧ➺➏ā˛ŋ", + "use_browser_locale": "ā˛Ŧāŗā˛°āŗŒā˛¸ā˛°āŗ ā˛˛āŗŠā˛•āŗ‡ā˛˛āŗ ā˛Ŧ➺➏ā˛ŋ", + "use_browser_locale_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ŧāŗā˛°āŗŒā˛¸ā˛°āŗ ā˛¸āŗā˛Ĩ➺ā˛ĩā˛¨āŗā˛¨āŗ ➆➧➰ā˛ŋ➏ā˛ŋ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛•ā˛—ā˛ŗāŗ, ā˛¸ā˛Žā˛¯ā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛¸ā˛‚ā˛–āŗā˛¯āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛Ģā˛žā˛°āŗā˛Žāŗā˛¯ā˛žā˛Ÿāŗ ā˛Žā˛žā˛Ąā˛ŋ", + "use_current_connection": "ā˛Ēāŗā˛°ā˛¸āŗā˛¤āŗā˛¤ ➏➂ā˛Ēā˛°āŗā˛•ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋ", "use_custom_date_range": "ā˛Ŧā˛Ļ➞ā˛ŋ➗⺆ ā˛•ā˛¸āŗā˛Ÿā˛Žāŗ ā˛Ļā˛ŋā˛¨ā˛žā˛‚ā˛• ā˛ļāŗā˛°āŗ‡ā˛Ŗā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛Ŧ➺➏ā˛ŋ", + "user": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°", "user_has_been_deleted": "➈ ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†.", + "user_id": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛° ID", + "user_pin_code_settings": "ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ", + "user_pin_code_settings_description": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛…ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", + "user_privacy": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ā˛—āŗŒā˛Ēāŗā˛¯ā˛¤āŗ†", + "user_purchase_settings": "➖➰⺀ā˛Ļā˛ŋ", + "user_purchase_settings_description": "➍ā˛ŋā˛Žāŗā˛Ž ➖➰⺀ā˛Ļā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏ā˛ŋ", + "user_usage_detail": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛° ā˛Ŧ➺➕⺆➝ ā˛ĩā˛ŋā˛ĩ➰", + "user_usage_stats": "ā˛–ā˛žā˛¤āŗ† ā˛Ŧ➺➕⺆➝ ➅➂➕ā˛ŋ➅➂ā˛ļ➗➺⺁", + "user_usage_stats_description": "ā˛–ā˛žā˛¤āŗ† ā˛Ŧ➺➕⺆➝ ➅➂➕ā˛ŋ➅➂ā˛ļā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "username": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛šāŗ†ā˛¸ā˛°āŗ", + "users": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°āŗ", + "utilities": "➉ā˛Ēā˛¯āŗā˛•āŗā˛¤ā˛¤āŗ†ā˛—ā˛ŗāŗ", + "validate": "ā˛ŽāŗŒā˛˛āŗā˛¯āŗ€ā˛•ā˛°ā˛ŋ➏ā˛ŋ", "validate_endpoint_error": "ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ ā˛Žā˛žā˛¨āŗā˛¯ā˛ĩā˛žā˛Ļ URL ā˛…ā˛¨āŗā˛¨āŗ ā˛¨ā˛Žāŗ‚ā˛Ļā˛ŋ➏ā˛ŋ", + "validation_error": "ā˛•āŗā˛°ā˛Žā˛Ŧā˛Ļāŗā˛§ ā˛Ļ⺋➎", + "variables": "ā˛…ā˛¸āŗā˛Ĩā˛ŋ➰➗➺⺁", + "version": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ", + "version_announcement_closing": "➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗā˛¨āŗ‡ā˛šā˛ŋ➤, ā˛…ā˛˛āŗ†ā˛•āŗā˛¸āŗ", "version_announcement_message": "ā˛¨ā˛Žā˛¸āŗā˛•ā˛žā˛°! ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗâ€Œā˛¨ ā˛šāŗŠā˛¸ ➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ā˛˛ā˛­āŗā˛¯ā˛ĩā˛ŋā˛Ļāŗ†. ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ➤ā˛Ēāŗā˛Ē⺁ ā˛¸ā˛‚ā˛°ā˛šā˛¨āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛¤ā˛Ąāŗ†ā˛—ā˛Ÿāŗā˛Ÿā˛˛āŗ ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗ†ā˛Ÿā˛Ēāŗ ➍ā˛ĩāŗ€ā˛•āŗƒā˛¤ā˛ĩā˛žā˛—ā˛ŋā˛Ļāŗ† ā˛Žā˛‚ā˛Ļ⺁ ā˛–ā˛šā˛ŋ➤ā˛Ēā˛Ąā˛ŋ➏ā˛ŋā˛•āŗŠā˛ŗāŗā˛ŗā˛˛āŗ, ā˛ĩā˛ŋā˛ļ⺇➎ā˛ĩā˛žā˛—ā˛ŋ ➍⺀ā˛ĩ⺁ ā˛ĩā˛žā˛šāŗâ€Œā˛Ÿā˛ĩā˛°āŗ ➅ā˛Ĩā˛ĩā˛ž ➍ā˛ŋā˛Žāŗā˛Ž ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ ➍ā˛ŋā˛Ļā˛°āŗā˛ļ➍ā˛ĩā˛¨āŗā˛¨āŗ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ➍ā˛ĩ⺀➕➰ā˛ŋ➏⺁ā˛ĩ⺁ā˛Ļā˛¨āŗā˛¨āŗ ➍ā˛ŋā˛°āŗā˛ĩā˛šā˛ŋ➏⺁ā˛ĩ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛•ā˛žā˛°āŗā˛¯ā˛ĩā˛ŋā˛§ā˛žā˛¨ā˛ĩā˛¨āŗā˛¨āŗ ā˛Ŧā˛ŗā˛¸āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗā˛Ļ➰⺆, ā˛Ļ➝ā˛ĩā˛ŋā˛Ÿāŗā˛Ÿāŗ release notes ➓ā˛Ļ➞⺁ ā˛¸āŗā˛ĩā˛˛āŗā˛Ē ā˛¸ā˛Žā˛¯ ➤⺆➗⺆ā˛Ļāŗā˛•āŗŠā˛ŗāŗā˛ŗā˛ŋ.", + "version_history": "➆ā˛ĩāŗƒā˛¤āŗā˛¤ā˛ŋ ➇➤ā˛ŋā˛šā˛žā˛¸", + "version_history_item": "{date} ➰➂ā˛Ļ⺁ {version} ā˛…ā˛¨āŗā˛¨āŗ ā˛¸āŗā˛Ĩā˛žā˛Ēā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "video": "ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊", "video_hover_setting": "ā˛šāŗ‹ā˛ĩā˛°āŗâ€Œā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗ ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛ŋ", "video_hover_setting_description": "ā˛ŽāŗŒā˛¸āŗ ā˛ā˛Ÿā˛‚ ā˛Žāŗ‡ā˛˛āŗ† ➏⺁➺ā˛ŋā˛Ļā˛žā˛Ąāŗā˛¤āŗā˛¤ā˛ŋ➰⺁ā˛ĩā˛žā˛— ā˛ĩāŗ€ā˛Ąā˛ŋ➝⺊ ā˛Ĩ➂ā˛Ŧāŗâ€Œā˛¨āŗ‡ā˛˛āŗ ā˛Ēāŗā˛˛āŗ‡ ā˛Žā˛žā˛Ąā˛ŋ. ➍ā˛ŋā˛ˇāŗā˛•āŗā˛°ā˛ŋā˛¯ā˛—āŗŠā˛ŗā˛ŋ➏ā˛ŋā˛Ļāŗā˛Ļ➰⺂ ā˛¸ā˛š, ā˛Ēāŗā˛˛āŗ‡ ā˛ā˛•ā˛žā˛¨āŗ ā˛Žāŗ‡ā˛˛āŗ† ➏⺁➺ā˛ŋā˛Ļā˛žā˛Ąāŗā˛ĩ ā˛Žāŗ‚ā˛˛ā˛• ā˛Ēāŗā˛˛āŗ‡ā˛Ŧāŗā˛¯ā˛žā˛•āŗ ā˛…ā˛¨āŗā˛¨āŗ ā˛Ēāŗā˛°ā˛žā˛°ā˛‚ā˛­ā˛ŋ➏ā˛Ŧā˛šāŗā˛Ļ⺁.", + "videos": "ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ", + "videos_only": "ā˛ĩāŗ€ā˛Ąā˛ŋā˛¯āŗŠā˛—ā˛ŗāŗ ā˛Žā˛žā˛¤āŗā˛°", + "view": "ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_album": "ā˛†ā˛˛āŗā˛Ŧā˛Žāŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_all": "ā˛Žā˛˛āŗā˛˛ā˛ĩā˛¨āŗā˛¨āŗ‚ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_all_users": "ā˛Žā˛˛āŗā˛˛ā˛ž ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_asset_owners": "ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛Žā˛žā˛˛āŗ€ā˛•ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_details": "ā˛ĩā˛ŋā˛ĩā˛°ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_in_timeline": "ā˛Ÿāŗˆā˛Žāŗ ā˛˛āŗˆā˛¨āŗ ā˛¨ā˛˛āŗā˛˛ā˛ŋ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_link": "➞ā˛ŋā˛‚ā˛•āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_links": "➞ā˛ŋā˛‚ā˛•āŗ ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_name": "ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_next_asset": "ā˛Žāŗā˛‚ā˛Ļā˛ŋ➍ ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_previous_asset": "ā˛šā˛ŋ➂ā˛Ļā˛ŋ➍ ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_qr_code": "ā˛•āŗā˛¯āŗ‚ā˛†ā˛°āŗ ā˛•āŗ‹ā˛Ąāŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_similar_photos": "➇ā˛Ļāŗ‡ ➰⺀➤ā˛ŋ➝ ā˛Ģāŗ‹ā˛Ÿāŗ‹ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_stack": "ā˛¸āŗā˛Ÿā˛žā˛•āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "view_user": "ā˛Ŧ➺➕⺆ā˛Ļā˛žā˛°ā˛°ā˛¨āŗā˛¨āŗ ā˛ĩāŗ€ā˛•āŗā˛ˇā˛ŋ➏ā˛ŋ", + "viewer_remove_from_stack": "ā˛¸āŗā˛Ÿā˛žā˛•āŗā˛¨ā˛ŋ➂ā˛Ļ ➤⺆➗⺆ā˛Ļāŗā˛šā˛žā˛•ā˛ŋ", + "viewer_stack_use_as_main_asset": "ā˛Žāŗā˛–āŗā˛¯ ā˛†ā˛¸āŗā˛¤ā˛ŋā˛¯ā˛žā˛—ā˛ŋ ā˛Ŧ➺➏ā˛ŋ", + "viewer_unstack": "ā˛…ā˛¨āŗ-ā˛¸āŗā˛Ÿā˛žā˛•āŗ", + "visibility": "ā˛—āŗ‹ā˛šā˛°ā˛¤āŗ†", + "visual": "ā˛ĩā˛ŋā˛ˇāŗā˛¯ā˛˛āŗ", + "visual_builder": "ā˛ĩā˛ŋā˛ˇāŗā˛¯ā˛˛āŗ ā˛Ŧā˛ŋā˛˛āŗā˛Ąā˛°āŗ", + "waiting": "ā˛•ā˛žā˛¯ā˛˛ā˛žā˛—āŗā˛¤āŗā˛¤ā˛ŋā˛Ļāŗ†", + "warning": "ā˛Žā˛šāŗā˛šā˛°ā˛ŋ➕⺆", + "week": "ā˛ĩā˛žā˛°", + "welcome": "ā˛¸āŗā˛ĩā˛žā˛—ā˛¤", + "welcome_to_immich": "ā˛¸āŗā˛ĩā˛žā˛—ā˛¤ ā˛‡ā˛Žāŗā˛Žā˛ŋā˛šāŗ", + "width": "➅➗➞", + "wifi_name": "ā˛ĩ⺈-ā˛Ģ⺈ ā˛šāŗ†ā˛¸ā˛°āŗ", "workflow_delete_prompt": "➈ ā˛ĩā˛°āŗā˛•āŗâ€Œā˛Ģāŗā˛˛āŗ‹ ā˛…ā˛¨āŗā˛¨āŗ ➅➺ā˛ŋ➏➞⺁ ➍⺀ā˛ĩ⺁ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "workflow_deleted": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩ⺁ ➅➺ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "workflow_description": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛ŋ➍ ā˛ĩā˛ŋā˛ĩ➰➪⺆", + "workflow_info": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛ŋ➍ ā˛Žā˛žā˛šā˛ŋ➤ā˛ŋ", + "workflow_json": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩ⺁ JSON", "workflow_json_help": "JSON ā˛¸āŗā˛ĩ➰⺂ā˛Ēā˛Ļā˛˛āŗā˛˛ā˛ŋ ➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛ŋ➍ ā˛¸ā˛‚ā˛°ā˛šā˛¨āŗ†ā˛¯ā˛¨āŗā˛¨āŗ ➏➂ā˛Ēā˛žā˛Ļā˛ŋ➏ā˛ŋ. ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩ➪⺆➗➺⺁ ā˛Ļ⺃ā˛ļāŗā˛¯ ā˛Ŧā˛ŋā˛˛āŗā˛Ąā˛°āŗâ€Œā˛—āŗ† ➏ā˛ŋā˛‚ā˛•āŗ ā˛†ā˛—āŗā˛¤āŗā˛¤ā˛ĩāŗ†.", + "workflow_name": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛ŋ➍ ā˛šāŗ†ā˛¸ā˛°āŗ", "workflow_navigation_prompt": "➍ā˛ŋā˛Žāŗā˛Ž ā˛Ŧā˛Ļā˛˛ā˛žā˛ĩā˛Ŗāŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➉➺ā˛ŋ➏ā˛Ļ⺆➝⺇ ➍⺀ā˛ĩ⺁ ā˛šāŗŠā˛°ā˛Ąā˛˛āŗ ā˛–ā˛šā˛ŋ➤ā˛ĩā˛žā˛—ā˛ŋ ā˛Ŧ➝➏⺁ā˛ĩā˛ŋā˛°ā˛ž?", + "workflow_summary": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛ŋ➍ ā˛¸ā˛žā˛°ā˛žā˛‚ā˛ļ", + "workflow_update_success": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛¨āŗā˛¨āŗ ➝ā˛ļā˛¸āŗā˛ĩā˛ŋā˛¯ā˛žā˛—ā˛ŋ ➍ā˛ĩ⺀➕➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "workflow_updated": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩā˛¨āŗā˛¨āŗ ➍ā˛ĩ⺀➕➰ā˛ŋā˛¸ā˛˛ā˛žā˛—ā˛ŋā˛Ļāŗ†", + "workflows": "➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩ⺁➗➺⺁", "workflows_help_text": "ā˛Ÿāŗā˛°ā˛ŋā˛—āŗā˛—ā˛°āŗâ€Œā˛—ā˛ŗāŗ ā˛Žā˛¤āŗā˛¤āŗ ā˛Ģā˛ŋā˛˛āŗā˛Ÿā˛°āŗâ€Œā˛—ā˛ŗ ā˛†ā˛§ā˛žā˛°ā˛Ļ ā˛Žāŗ‡ā˛˛āŗ† ➍ā˛ŋā˛Žāŗā˛Ž ā˛¸āŗā˛ĩā˛¤āŗā˛¤āŗā˛—ā˛ŗ ā˛Žāŗ‡ā˛˛ā˛ŋ➍ ā˛•āŗā˛°ā˛ŋā˛¯āŗ†ā˛—ā˛ŗā˛¨āŗā˛¨āŗ ➕⺆➞➏ā˛Ļ ā˛šā˛°ā˛ŋā˛ĩ⺁➗➺⺁ ā˛¸āŗā˛ĩā˛¯ā˛‚ā˛šā˛žā˛˛ā˛ŋā˛¤ā˛—āŗŠā˛ŗā˛ŋā˛¸āŗā˛¤āŗā˛¤ā˛ĩāŗ†", + "wrong_pin_code": "➤ā˛Ēāŗā˛Ēā˛žā˛Ļ ā˛Ēā˛ŋā˛¨āŗ ā˛•āŗ‹ā˛Ąāŗ", + "year": "ā˛ĩā˛°āŗā˛ˇ", + "yes": "ā˛šāŗŒā˛Ļ⺁", "you_dont_have_any_shared_links": "➍⺀ā˛ĩ⺁ ā˛¯ā˛žā˛ĩ⺁ā˛Ļāŗ‡ ā˛šā˛‚ā˛šā˛ŋā˛•āŗŠā˛‚ā˛Ą ➞ā˛ŋā˛‚ā˛•āŗâ€Œā˛—ā˛ŗā˛¨āŗā˛¨āŗ ā˛šāŗŠā˛‚ā˛Ļā˛ŋā˛˛āŗā˛˛", - "zero_to_clear_rating": "ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛°āŗ‡ā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ 0 ā˛’ā˛¤āŗā˛¤ā˛ŋ➰ā˛ŋ" + "your_wifi_name": "➍ā˛ŋā˛Žāŗā˛Ž ā˛ĩ⺈-ā˛Ģ⺈ ā˛šāŗ†ā˛¸ā˛°āŗ", + "zero_to_clear_rating": "ā˛†ā˛¸āŗā˛¤ā˛ŋ ā˛°āŗ‡ā˛Ÿā˛ŋā˛‚ā˛—āŗ ā˛…ā˛¨āŗā˛¨āŗ ➤⺆➰ā˛ĩāŗā˛—āŗŠā˛ŗā˛ŋ➏➞⺁ 0 ā˛’ā˛¤āŗā˛¤ā˛ŋ➰ā˛ŋ", + "zoom_image": "ā˛œāŗ‚ā˛Žāŗ ā˛‡ā˛Žāŗ‡ā˛œāŗ", + "zoom_to_bounds": "ā˛Žā˛Ąā˛ŋ➕➞⺁" } diff --git a/i18n/ko.json b/i18n/ko.json index 22d5d1b8a6..fff2c3d10a 100644 --- a/i18n/ko.json +++ b/i18n/ko.json @@ -441,7 +441,7 @@ "user_successfully_removed": "ė‚ŦėšŠėž {email}ë‹˜ė´ ė„ąęŗĩ렁ėœŧ로 ė‚­ė œë˜ė—ˆėŠĩ니다.", "users_page_description": "관ëĻŦėž ė‚ŦėšŠėž íŽ˜ė´ė§€", "version_check_enabled_description": "ë˛„ė „ í™•ė¸ í™œė„ąí™”", - "version_check_implications": "ėŖŧ揰렁ėœŧ로 Github뗐 ėš”ė˛­ė„ ëŗ´ë‚´ 냈 ë˛„ė „ė„ í™•ė¸í•Šë‹ˆë‹¤.", + "version_check_implications": "ėŖŧ揰렁ėœŧ로 {server}뗐 ėš”ė˛­ė„ ëŗ´ë‚´ 냈 ë˛„ė „ė„ í™•ė¸í•Šë‹ˆë‹¤.", "version_check_settings": "ë˛„ė „ í™•ė¸", "version_check_settings_description": "냈 ë˛„ė „ í™•ė¸ 및 ė•ŒëĻŧ 기ëŠĨė„ 관ëĻŦ합니다.", "video_conversion_job": "ë™ė˜ėƒ íŠ¸ëžœėŠ¤ėŊ”드", @@ -798,7 +798,7 @@ "command_palette_to_close": "ë‹Ģ기", "command_palette_to_navigate": "ë“¤ė–´ę°€ę¸°", "command_palette_to_select": "ė„ íƒí•˜ę¸°", - "command_palette_to_show_all": "다 ëŗ´ė—ŦėŖŧ기", + "command_palette_to_show_all": "ëĒ¨ë‘ ëŗ´ę¸°", "comment_deleted": "ëŒ“ę¸€ė´ ė‚­ė œë˜ė—ˆėŠĩ니다.", "comment_options": "댓글 ė˜ĩė…˜", "comments_and_likes": "댓글 및 ėĸ‹ė•„ėš”", @@ -849,9 +849,12 @@ "create_link_to_share": "ęŗĩ뜠 링íŦ ėƒė„ą", "create_link_to_share_description": "링íŦ가 ėžˆëŠ” ę˛Ŋ뚰 누ęĩŦ나 ė„ íƒí•œ ė‚Ŧė§„ė„ ëŗŧ 눘 ėžˆėŠĩ니다.", "create_new": "ėƒˆëĄœ 만들기", + "create_new_face": "냈 ė–ŧęĩ´ ėƒė„ą", "create_new_person": "ė¸ëŦŧ ėƒė„ą", "create_new_person_hint": "ė„ íƒí•œ 항ëĒŠė˜ ė¸ëŦŧė„ 냈 ė¸ëŦŧ로 ëŗ€ę˛Ŋ", "create_new_user": "냈 ė‚ŦėšŠėž ėƒė„ą", + "create_person": "ė¸ëŦŧ ėƒė„ą", + "create_person_subtitle": "ė„ íƒí•œ ė–ŧęĩ´ė— ė´ëĻ„ė„ ėļ”가해 ė‹ ęˇœ ė¸ëŦŧė„ ėƒė„ąí•˜ęŗ  태그 맀렕", "create_shared_album_page_share_add_assets": "항ëĒŠ ėļ”ę°€", "create_shared_album_page_share_select_photos": "ė‚Ŧė§„ ė„ íƒ", "create_shared_link": "ęŗĩ뜠 링íŦ ėƒė„ą", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "ęŗ ė •", "crop_aspect_ratio_free": "링렑 ėĄ°ė ˆ", "crop_aspect_ratio_original": "ė›ëŗ¸", + "crop_aspect_ratio_square": "ė •ė‚Ŧ각형", "curated_object_page_title": "ė‚ŦëŦŧ", "current_device": "현ėžŦ 기기", "current_pin_code": "현ėžŦ PIN ėŊ”드", @@ -880,7 +884,7 @@ "daily_title_text_date": "Mė›” dėŧ EEEE", "daily_title_text_date_year": "yyyy년 Mė›” dėŧ EEEE", "dark": "다íŦ", - "dark_theme": "다íŦ 테마 토글", + "dark_theme": "다íŦ 테마 ė „í™˜", "date": "ë‚ ė§œ", "date_after": "ë‹¤ėŒ ë‚ ė§œ ė´í›„", "date_and_time": "ë‚ ė§œ 및 ė‹œę°„", @@ -891,10 +895,8 @@ "day": "ėŧ", "days": "ėŧ", "deduplicate_all": "ëĒ¨ë‘ ė‚­ė œ", - "deduplication_criteria_1": "ė´ë¯¸ė§€ íŦ기 (ë°”ė´íŠ¸)", - "deduplication_criteria_2": "EXIF ė •ëŗ´ 항ëĒŠ 눘", - "deduplication_info": "ëš„ėŠˇí•œ 항ëĒŠ ė •ëŗ´", - "deduplication_info_description": "항ëĒŠė„ ėžë™ėœŧ로 미ëĻŦ ė„ íƒí•˜ęŗ , ëš„ėŠˇí•œ 항ëĒŠė„ ęĩŦëļ„í•  때 ë‹¤ėŒ ė •ëŗ´ëĨŧ ė°¸ęŗ í•Šë‹ˆë‹¤:", + "default_locale": "ę¸°ëŗ¸ 로ėŧ€ėŧ", + "default_locale_description": "브ëŧėš°ė € 로ėŧ€ėŧ 네렕뗐 따ëŧ ë‚ ė§œ 및 ėˆĢėž í˜•ė‹ė„ ė§€ė •í•Šë‹ˆë‹¤", "delete": "ė‚­ė œ", "delete_action_confirmation_message": "ė´ 항ëĒŠė„ ė‚­ė œí•˜ė‹œę˛ ėŠĩ니까? ė„œë˛„ė—ė„œëŠ” 항ëĒŠė„ íœ´ė§€í†ĩėœŧ로 ė´ë™ė‹œí‚¤ëŠ°, 로ėģŦė—ė„œë„ ė‚­ė œí•  ę˛ƒė¸ė§€ í™•ė¸ ëŠ”ė‹œė§€ę°€ í‘œė‹œëŠë‹ˆë‹¤.", "delete_action_prompt": "{count}氜 항ëĒŠ ė‚­ė œë¨", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "íŽ¸ė§‘ė´ ė ėšŠë˜ė—ˆėŠĩ니다.", "editor_flip_horizontal": "ėĸŒėš°ë°˜ė „", "editor_flip_vertical": "ėƒí•˜ë°˜ė „", + "editor_handle_corner": "{corner, select, top_left {ėĸŒėƒë‹¨} top_right {ėš°ėƒë‹¨} bottom_left {ėĸŒí•˜ë‹¨} bottom_right {ėš°í•˜ë‹¨} other {A}} ėŊ”너 핸들", + "editor_handle_edge": "{edge, select, top {ėœ„} bottom {ė•„ëž˜} left {ė™ŧėĒŊ} right {똤ëĨ¸ėĒŊ} other {An}} ëĒ¨ė„œëĻŦ 핸들", "editor_orientation": "ë°Ší–Ĩ", "editor_reset_all_changes": "íŽ¸ė§‘ë‚´ėšŠ ė´ˆę¸°í™”", "editor_rotate_left": "ë°˜ė‹œęŗ„ ë°Ší–Ĩėœŧ로 90° íšŒė „", @@ -1065,26 +1069,26 @@ "failed_to_load_assets": "항ëĒŠ 로드 ė‹¤íŒ¨", "failed_to_load_notifications": "ė•ŒëĻŧ 로드 ė‹¤íŒ¨", "failed_to_load_people": "ė¸ëŦŧ 로드 ė‹¤íŒ¨", - "failed_to_remove_product_key": "ė œí’ˆ 키 ė œęą°ė— ė‹¤íŒ¨", + "failed_to_remove_product_key": "ė œí’ˆ 키 ė œęą°ė— ė‹¤íŒ¨í–ˆėŠĩ니다.", "failed_to_reset_pin_code": "PIN ėŊ”드 ė´ˆę¸°í™” ė‹¤íŒ¨", - "failed_to_stack_assets": "항ëĒŠ ėŠ¤íƒė— ė‹¤íŒ¨", - "failed_to_unstack_assets": "항ëĒŠ ėŠ¤íƒ í’€ę¸°ė— ė‹¤íŒ¨", + "failed_to_stack_assets": "항ëĒŠ ėŠ¤íƒė— ė‹¤íŒ¨í–ˆėŠĩ니다.", + "failed_to_unstack_assets": "항ëĒŠ ėŠ¤íƒ í’€ę¸°ė— ė‹¤íŒ¨í–ˆėŠĩ니다.", "failed_to_update_notification_status": "ė•ŒëĻŧ ėƒíƒœ ė—…ë°ė´íŠ¸ ė‹¤íŒ¨", "incorrect_email_or_password": "ėž˜ëĒģ된 ė´ëŠ”ėŧ 또는 비밀번호", "library_folder_already_exists": "氀렏ė˜Ŧ ę˛Ŋ로가 ė´ë¯¸ ėĄ´ėžŦ합니다.", - "page_not_found": "íŽ˜ė´ė§€ëĨŧ ė°žė„ 눘 ė—†ėŒ :/", + "page_not_found": "íŽ˜ė´ė§€ëĨŧ ė°žė„ 눘 ė—†ėŒ", "paths_validation_failed": "{paths, plural, one {ę˛Ŋ로 #氜} other {ę˛Ŋ로 #氜}}가 ėœ íš¨ė„ą 검ė‚Ŧ뗐 ė‹¤íŒ¨í–ˆėŠĩ니다.", "profile_picture_transparent_pixels": "프로필 ė‚Ŧ맄뗐 íˆŦëĒ… í”Ŋė…€ė„ ė‚ŦėšŠí•  눘 ė—†ėŠĩ니다. ė‚Ŧė§„ė„ 확대하거나 ė´ë™í•˜ė„¸ėš”.", "quota_higher_than_disk_size": "í• ë‹šëŸ‰ė€ ë””ėŠ¤íŦ íŦę¸°ëŗ´ë‹¤ ėž‘ė•„ė•ŧ 합니다.", "something_went_wrong": "ëŦ¸ė œę°€ ë°œėƒí–ˆėŠĩ니다.", - "unable_to_add_album_users": "ė•¨ë˛”ė— ė‚ŦėšŠėžëĨŧ ėļ”가할 눘 ė—†ėŒ", - "unable_to_add_assets_to_shared_link": "항ëĒŠė„ ęŗĩ뜠 링íŦ뗐 ėļ”가할 눘 ė—†ėŒ", - "unable_to_add_comment": "ëŒ“ę¸€ė„ ėļ”가할 눘 ė—†ėŒ", - "unable_to_add_exclusion_pattern": "ė œė™¸ ęˇœėš™ė„ ėļ”가할 눘 ė—†ėŒ", - "unable_to_add_partners": "파트너ëĨŧ ėļ”가할 눘 ė—†ėŒ", - "unable_to_add_remove_archive": "{archived, select, true {ëŗ´ę´€í•¨ė—ė„œ 항ëĒŠė„ ė œęą°í• } other {ëŗ´ę´€í•¨ėœŧ로 항ëĒŠė„ ė´ë™í• }} 눘 ė—†ėŒ", - "unable_to_add_remove_favorites": "ėĻę˛¨ė°žę¸°ė— 항ëĒŠė„ {favorite, select, true {ėļ”ę°€} other {ė œęą°}}할 눘 ė—†ėŒ", - "unable_to_archive_unarchive": "항ëĒŠė„ {archived, select, true {ëŗ´ę´€} other {ëŗ´ę´€ í•´ė œ}}할 눘 ė—†ėŒ", + "unable_to_add_album_users": "ė•¨ë˛”ė— ė‚ŦėšŠėžëĨŧ ėļ”가할 눘 ė—†ėŠĩ니다.", + "unable_to_add_assets_to_shared_link": "항ëĒŠė„ ęŗĩ뜠 링íŦ뗐 ėļ”가할 눘 ė—†ėŠĩ니다.", + "unable_to_add_comment": "ëŒ“ę¸€ė„ ėļ”가할 눘 ė—†ėŠĩ니다.", + "unable_to_add_exclusion_pattern": "ė œė™¸ ęˇœėš™ė„ ėļ”가할 눘 ė—†ėŠĩ니다.", + "unable_to_add_partners": "파트너ëĨŧ ėļ”가할 눘 ė—†ėŠĩ니다.", + "unable_to_add_remove_archive": "{archived, select, true {ëŗ´ę´€í•¨ė—ė„œ 항ëĒŠė„ ė œęą°í• } other {ëŗ´ę´€í•¨ėœŧ로 항ëĒŠė„ ė´ë™í• }} 눘 ė—†ėŠĩ니다.", + "unable_to_add_remove_favorites": "ėĻę˛¨ė°žę¸°ė— 항ëĒŠė„ {favorite, select, true {ėļ”ę°€} other {ė œęą°}}할 눘 ė—†ėŠĩ니다", + "unable_to_archive_unarchive": "항ëĒŠė„ {archived, select, true {ëŗ´ę´€} other {ëŗ´ę´€ í•´ė œ}}할 눘 ė—†ėŠĩ니다", "unable_to_change_album_user_role": "ė•¨ë˛” ė‚ŦėšŠėžė˜ ė—­í• ė„ ëŗ€ę˛Ŋ할 눘 ė—†ėŠĩ니다.", "unable_to_change_date": "ë‚ ė§œëĨŧ ëŗ€ę˛Ŋ할 눘 ė—†ėŠĩ니다.", "unable_to_change_description": "네ëĒ…ė„ ëŗ€ę˛Ŋ할 눘 ė—†ėŠĩ니다.", @@ -1130,10 +1134,10 @@ "unable_to_remove_library": "ëŧė´ë¸ŒëŸŦëĻŦëĨŧ ė œęą°í•  눘 ė—†ėŠĩ니다.", "unable_to_remove_partner": "파트너ëĨŧ ė œęą°í•  눘 ė—†ėŠĩ니다.", "unable_to_remove_reaction": "ë°˜ė‘ė„ ė œęą°í•  눘 ė—†ėŠĩ니다.", - "unable_to_reset_password": "비밀번호ëĨŧ ė´ˆę¸°í™”í•  눘 ė—†ėŒ", + "unable_to_reset_password": "비밀번호ëĨŧ ė´ˆę¸°í™”í•  눘 ė—†ėŠĩ니다.", "unable_to_reset_pin_code": "PIN ėŊ”드ëĨŧ ė´ˆę¸°í™”í•  눘 ė—†ėŒ", "unable_to_resolve_duplicate": "ëš„ėŠˇí•œ 항ëĒŠė„ 래ëĻŦ할 눘 ė—†ėŒ", - "unable_to_restore_assets": "항ëĒŠė„ ëŗĩė›í•  눘 ė—†ėŒ", + "unable_to_restore_assets": "항ëĒŠė„ ëŗĩė›í•  눘 ė—†ėŠĩ니다.", "unable_to_restore_trash": "íœ´ė§€í†ĩė„ ëŗĩė›í•  눘 ė—†ėŠĩ니다.", "unable_to_restore_user": "ė‚ŦėšŠėžëĨŧ ëŗĩė›í•  눘 ė—†ėŠĩ니다.", "unable_to_save_album": "ė•¨ë˛”ė„ ė €ėžĨ할 눘 ė—†ėŠĩ니다.", @@ -1146,7 +1150,7 @@ "unable_to_scan_library": "ëŧė´ë¸ŒëŸŦëĻŦëĨŧ 늤ėē”í•  눘 ė—†ėŠĩ니다.", "unable_to_set_feature_photo": "대표 ė‚Ŧė§„ė„ ė„¤ė •í•  눘 ė—†ėŠĩ니다.", "unable_to_set_profile_picture": "프로필 ė‚Ŧė§„ė„ ė„¤ė •í•  눘 ė—†ėŠĩ니다.", - "unable_to_set_rating": "í‰ė ė„ ė •í•  눘 ė—†ėŒ", + "unable_to_set_rating": "ëŗ„ė ė„ ė§€ė •í•  눘 ė—†ėŠĩ니다.", "unable_to_submit_job": "ėž‘ė—…ė„ ėˆ˜í–‰í•  눘 ė—†ėŠĩ니다.", "unable_to_trash_asset": "íœ´ė§€í†ĩėœŧ로 ė´ë™í•  눘 ė—†ėŠĩ니다.", "unable_to_unlink_account": "ęŗ„ė • ė—°ę˛°ė„ í•´ė œí•  눘 ė—†ėŠĩ니다.", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "ė•¨ë˛”ëĒ…", "licenses": "ëŧė´ė„ ėŠ¤", "light": "ëŧė´íŠ¸", + "light_theme": "ëŧė´íŠ¸ 테마로 ė „í™˜", "like": "ėĸ‹ė•„ėš”", "like_deleted": "ėĸ‹ė•„ėš”ę°€ ė‚­ė œë˜ė—ˆėŠĩ니다.", "link_motion_video": "ëĒ¨ė…˜ ëš„ë””ė˜¤ 링íŦ", + "link_to_docs": "ėžė„¸í•œ ë‚´ėšŠė€ ëŦ¸ė„œëĨŧ ė°¸ėĄ°í•˜ė‹­ė‹œė˜¤.", "link_to_oauth": "OAuth뗐 뗰枰", "linked_oauth_account": "OAuth ęŗ„ė •ė´ ė—°ę˛°ë˜ė—ˆėŠĩ니다.", "list": "ëĒŠëĄ", @@ -1649,6 +1655,7 @@ "only_favorites": "ėĻę˛¨ė°žę¸°ë§Œ", "open": "뗴揰", "open_calendar": "ėē˜ëĻ°ë” 뗴揰", + "open_in_browser": "브ëŧėš°ė €ė—ė„œ 뗴揰", "open_in_map_view": "ė§€ë„ ëŗ´ę¸°ė—ė„œ 뗴揰", "open_in_openstreetmap": "OpenStreetMapė—ė„œ 뗴揰", "open_the_search_filters": "ę˛€ėƒ‰ 필터 뗴揰", @@ -1805,11 +1812,11 @@ "purchase_settings_server_activated": "ė„œë˛„ ė œí’ˆ 키는 관ëĻŦėžę°€ ė œė–´í•Šë‹ˆë‹¤.", "query_asset_id": "ėŋŧëĻŦ 항ëĒŠ ID", "queue_status": "렄랴 {total}, {count} 대기 뤑", - "rate_asset": "항ëĒŠ í‰ė ", + "rate_asset": "항ëĒŠ ëŗ„ė ", "rating": "ëŗ„ė ", - "rating_clear": "í‰ė  ė´ˆę¸°í™”", - "rating_count": "{count, plural, =0 {í‰ė  ė—†ėŒ} one {#렐} other {#렐}}", - "rating_description": "ėƒė„¸ ė •ëŗ´ íŒ¨ë„ė— EXIF 등급 태그 í‘œė‹œ", + "rating_clear": "ëŗ„ė  ė´ˆę¸°í™”", + "rating_count": "{count, plural, =0 {ëŗ„ė  ė—†ėŒ} one {#렐} other {#렐}}", + "rating_description": "ėƒė„¸ ė •ëŗ´ íŒ¨ë„ė— EXIF ëŗ„ė  태그 í‘œė‹œ", "reaction_options": "ë°˜ė‘ ė˜ĩė…˜", "read_changelog": "ëŗ€ę˛Ŋ ë‚´ė—­ ëŗ´ę¸°", "readonly_mode_disabled": "ėŊ기 ė „ėšŠ ëĒ¨ë“œ ëš„í™œė„ąí™”", @@ -1927,6 +1934,7 @@ "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": "ėš´ëŠ”ëŧ ëĒ¨ë¸ëĒ… ę˛€ėƒ‰...", @@ -1946,7 +1954,7 @@ "search_filter_media_type_title": "ë¯¸ë””ė–´ ėĸ…ëĨ˜ ė„ íƒ", "search_filter_ocr": "OCR ę˛€ėƒ‰", "search_filter_people_title": "ė¸ëŦŧ ė„ íƒ", - "search_filter_star_rating": "í‰ė ", + "search_filter_star_rating": "ëŗ„ė ", "search_filter_tags_title": "태그 ė„ íƒ", "search_for": "ę˛€ėƒ‰", "search_for_existing_person": "ėĄ´ėžŦ하는 ė¸ëŦŧ ę˛€ėƒ‰", @@ -1968,7 +1976,7 @@ "search_page_your_map": "ë‚˜ė˜ ė§€ë„", "search_people": "ė¸ëŦŧ ę˛€ėƒ‰", "search_places": "ėžĨė†Œ ę˛€ėƒ‰", - "search_rating": "등급ėœŧ로 ę˛€ėƒ‰...", + "search_rating": "ëŗ„ė ėœŧ로 ę˛€ėƒ‰...", "search_result_page_new_search_hint": "냈 ę˛€ėƒ‰", "search_settings": "네렕 ę˛€ėƒ‰", "search_state": "맀뗭 ę˛€ėƒ‰...", @@ -1990,6 +1998,7 @@ "select_all_in": "{group}ė˜ ëĒ¨ë“  항ëĒŠ ė„ íƒ", "select_avatar_color": "ė•„ë°”íƒ€ ėƒ‰ėƒ ė„ íƒ", "select_count": "{count, plural, one {# ė„ íƒė¤‘} other {# ė„ íƒė¤‘}}", + "select_cutoff_date": "ėœ ė§€ 기간 네렕", "select_face": "ė–ŧęĩ´ ė„ íƒ", "select_featured_photo": "대표 ė‚Ŧė§„ ė„ íƒ", "select_from_computer": "ėģ´í“¨í„°ė—ė„œ ė„ íƒ", @@ -2388,6 +2397,7 @@ "viewer_remove_from_stack": "ėŠ¤íƒė—ė„œ ė œęą°", "viewer_stack_use_as_main_asset": "대표 항ëĒŠėœŧ로 네렕", "viewer_unstack": "ėŠ¤íƒ 풀기", + "visibility": "í‘œė‹œ 네렕", "visibility_changed": "ė¸ëŦŧ {count, plural, one {#ëĒ…} other {#ëĒ…}}ė˜ í‘œė‹œ ė—Ŧëļ€ę°€ ëŗ€ę˛Ŋ됨", "visual": "비ėŖŧė–ŧ", "visual_builder": "비ėŖŧė–ŧ 빌더", @@ -2418,7 +2428,7 @@ "yes": "네", "you_dont_have_any_shared_links": "ęŗĩ뜠 링íŦ가 ė—†ėŠĩ니다.", "your_wifi_name": "Wi-Fi ë„¤íŠ¸ė›ŒíŦ ė´ëĻ„", - "zero_to_clear_rating": "0ė„ 눌ëŸŦ 항ëĒŠ í‰ė  ė´ˆę¸°í™”", + "zero_to_clear_rating": "0ė„ 눌ëŸŦ 항ëĒŠ ëŗ„ė  ė´ˆę¸°í™”", "zoom_image": "ė´ë¯¸ė§€ 확대", "zoom_to_bounds": "í™”ëŠ´ė— 맞ėļ° í™•ëŒ€" } diff --git a/i18n/lt.json b/i18n/lt.json index 5675673317..b686e2526d 100644 --- a/i18n/lt.json +++ b/i18n/lt.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Naudotojas {email} sėkmingai paÅĄalintas.", "users_page_description": "AdministratoriÅŗ vartotojÅŗ puslapis", "version_check_enabled_description": "ÄŽgalinti versijÅŗ tikrinimą", - "version_check_implications": "VersijÅŗ tikrinimas reikalauja periodiÅĄkos komunikacijos su github.com", + "version_check_implications": "VersijÅŗ tikrinimas reikalauja periodiÅĄkos komunikacijos su {server}", "version_check_settings": "Versijos tikrinimas", "version_check_settings_description": "ÄŽjungti/iÅĄjungti naujos versijos praneÅĄimus", "video_conversion_job": "Vaizdo įraÅĄÅŗ konvertavimas", @@ -849,9 +849,12 @@ "create_link_to_share": "Sukurti bendrinimo nuorodą", "create_link_to_share_description": "Leisti bet kam su nuoroda matyti paÅžymėtą(-as) nuotrauką(-as)", "create_new": "SUKURTI NAUJĄ", + "create_new_face": "Sukurti naują veidą", "create_new_person": "Sukurti naują ÅžmogÅŗ", "create_new_person_hint": "Priskirti pasirinktus elementus naujam Åžmogui", "create_new_user": "Sukurti naują varotoją", + "create_person": "Sukurti asmenį", + "create_person_subtitle": "Pridėkite vardą prie pasirinkto veido, kad sukurtumėte ir paÅžymėtumėte naują asmenį", "create_shared_album_page_share_add_assets": "PRIDĖTI ELEMENTŞ", "create_shared_album_page_share_select_photos": "PaÅžymėti nuotraukas", "create_shared_link": "Sukurti dalijimosi nuorodą", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "UÅžfiksuota", "crop_aspect_ratio_free": "Nefiksuota", "crop_aspect_ratio_original": "Originalus", + "crop_aspect_ratio_square": "Kvadratas", "curated_object_page_title": "Daiktai", "current_device": "Dabartinis įrenginys", "current_pin_code": "Dabartinis PIN kodas", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "Tamsi", - "dark_theme": "Perjungti tamsią temą", + "dark_theme": "Perjungti į tamsią temą", "date": "Data", "date_after": "Data po", "date_and_time": "Data ir laikas", @@ -891,10 +895,8 @@ "day": "Diena", "days": "DienÅŗ", "deduplicate_all": "Å alinti visus dublikatus", - "deduplication_criteria_1": "Failo dydis baitais", - "deduplication_criteria_2": "EXIF metaduomenÅŗ įraÅĄÅŗ skaičius", - "deduplication_info": "DublikatÅŗ ÅĄalinimo informacija", - "deduplication_info_description": "Automatinis elementÅŗ parinkimas ir masinis dublikatÅŗ ÅĄalinimas atliekamas atsiÅžvelgiant į:", + "default_locale": "Numatytoji Vietovė", + "default_locale_description": "Formatuoti datas ir skaičius pagal savo narÅĄyklės lokalę", "delete": "IÅĄtrinti", "delete_action_confirmation_message": "Ar tikrai norite iÅĄtrinti ÅĄÄ¯ elementą? Å is veiksmas perkels elementą į serverio ÅĄiukÅĄliadėŞę ir paklaus ar norite iÅĄtrinti vietiniame įrenginyje", "delete_action_prompt": "{count} iÅĄtrinta", @@ -970,7 +972,7 @@ "downloading_media": "Atsisiunčiama medija", "drop_files_to_upload": "UÅžkelkite failus bet kurioje vietoje kad įkeltumėte", "duplicates": "Dublikatai", - "duplicates_description": "Sutvarkykite kiekvieną elementÅŗ grupę nurodydami elementus, kurie yra dublikatai (jei tokiÅŗ yra)", + "duplicates_description": "Tvarkyti kiekvieną elementÅŗ grupę nurodant elementus, kurie yra dublikatai (jei tokiÅŗ yra).", "duration": "Trukmė", "edit": "Redaguoti", "edit_album": "Redaguoti albumą", @@ -1213,7 +1215,7 @@ "file_name_text": "Failo pavadinimas", "file_name_with_value": "Failo pavadinimas: {file_name}", "file_size": "Failo dydis", - "filename": "Failopavadinimas", + "filename": "Failo pavadinimas", "filetype": "Failo tipas", "filter": "Filtras", "filter_description": "TiksliniÅŗ elementÅŗ filtravimo sąlygos", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Albumo pavadinimas", "licenses": "Licencijos", "light": "Å viesi", - "like": "Kaip", - "like_deleted": "Kaip iÅĄtrintas", + "light_theme": "Perjungti į ÅĄviesią temą", + "like": "Patinka", + "like_deleted": "Patinka panaikintas", "link_motion_video": "Susieti judesio vaizdo įraÅĄÄ…", + "link_to_docs": "Daugiau informacijos rasite dokumentacijoje.", "link_to_oauth": "Susieti su OAuth", "linked_oauth_account": "Susieta OAuth paskyra", "list": "SąraÅĄas", @@ -1651,7 +1655,8 @@ "only_favorites": "Tik mėgstamiausi", "open": "Atverti", "open_calendar": "Atidaryti kalendoriÅŗ", - "open_in_map_view": "Atverti Åžemėlapio perÅžiÅĢroje", + "open_in_browser": "Atverti narÅĄyklėje", + "open_in_map_view": "Atverti Åžemėlapyje", "open_in_openstreetmap": "Atverti per OpenStreetMap", "open_the_search_filters": "Atidaryti paieÅĄkos filtrus", "options": "Pasirinktys", @@ -2212,6 +2217,7 @@ "tag": "ÅŊyma", "tag_assets": "PaÅžymėti", "tag_created": "Sukurta Åžyma: {tag}", + "tag_face": "PaÅžymėti veidą", "tag_feature_description": "PerÅžiÅĢrėkite nuotraukas ir vaizdo įraÅĄus sugrupuotus pagal suÅžymėtas temas", "tag_not_found_question": "Nerandate Åžymos? Sukurti naują Åžymą.", "tag_people": "PaÅžymėti ÅŊmones", @@ -2393,6 +2399,7 @@ "viewer_remove_from_stack": "PaÅĄalinti iÅĄ Grupės", "viewer_stack_use_as_main_asset": "Naudoti, kaip pagrindinį elementą", "viewer_unstack": "IÅĄgrupuoti", + "visibility": "Matomumas", "visibility_changed": "Matomumas pasikeitė {count, plural, one {# asmeniui} few {# asmenims} other {# asmenÅŗ}}", "visual": "IÅĄdėstymas", "visual_builder": "IÅĄdėstymo koreguotojas", diff --git a/i18n/lv.json b/i18n/lv.json index 59b5dea657..0c7776efe7 100644 --- a/i18n/lv.json +++ b/i18n/lv.json @@ -402,7 +402,7 @@ "user_settings": "Lietotāja iestatÄĢjumi", "user_settings_description": "Lietotāju iestatÄĢjumu pārvaldÄĢba", "version_check_enabled_description": "Ieslēgt versijas pārbaudi", - "version_check_implications": "Versiju pārbaudes funkcija ir atkarÄĢga no periodiskas saziņas ar github.com", + "version_check_implications": "Versiju pārbaudes funkcija ir atkarÄĢga no periodiskas saziņas ar {server}", "version_check_settings": "Versijas pārbaude", "version_check_settings_description": "Ieslēgt/izslēgt paziņojumus par jaunu versiju" }, @@ -713,9 +713,11 @@ "create_link": "Izveidot saiti", "create_link_to_share": "Izveidot kopÄĢgoÅĄanas saiti", "create_new": "IZVEIDOT JAUNU", + "create_new_face": "Izveidot jaunu seju", "create_new_person": "Izveidot jaunu personu", "create_new_person_hint": "PiesaistÄĢt izvēlētos failus jaunai personai", "create_new_user": "Izveidot jaunu lietotāju", + "create_person": "Izveidot personu", "create_shared_album_page_share_add_assets": "PIEVIENOT AKTÄĒVUS", "create_shared_album_page_share_select_photos": "Fotoattēlu Izvēle", "create_user": "Izveidot lietotāju", @@ -746,10 +748,6 @@ "day": "Diena", "days": "Dienas", "deduplicate_all": "Dedublicēt visus", - "deduplication_criteria_1": "Attēla izmēru baitos", - "deduplication_criteria_2": "EXIF datu skaitu", - "deduplication_info": "DeduplicÄ“ÅĄanas informācija", - "deduplication_info_description": "Lai automātiski atzÄĢmētu failus un masveidā noņemtu dublikātus, mēs skatāmies uz:", "delete": "Dzēst", "delete_album": "Dzēst albumu", "delete_dialog_alert": "Å ie vienumi tiks neatgriezeniski dzēsti no Immich un jÅĢsu ierÄĢces", @@ -883,6 +881,7 @@ "failed_to_update_notification_status": "Neizdevās mainÄĢt paziņojuma statusu", "incorrect_email_or_password": "Nepareizs e-pasts vai parole", "library_folder_already_exists": "Å is importa ceÄŧÅĄ jau pastāv.", + "page_not_found": "Lapa nav atrasta", "profile_picture_transparent_pixels": "Profila attēlos nevar bÅĢt caurspÄĢdÄĢgi pikseÄŧi. LÅĢdzu, palielini un/vai pārvieto attēlu.", "quota_higher_than_disk_size": "Tu esi iestatÄĢjis kvotu, kas pārsniedz diska izmēru", "something_went_wrong": "Kaut kas nogāja greizi", @@ -1299,6 +1298,7 @@ "only_favorites": "Tikai izlase", "open": "Atvērt", "open_calendar": "Atvērt kalendāru", + "open_in_browser": "Atvērt pārlÅĢkprogrammā", "open_in_map_view": "Atvērt kartes skatā", "open_in_openstreetmap": "Atvērt OpenStreetMap", "open_the_search_filters": "Atvērt meklÄ“ÅĄanas filtrus", @@ -1459,6 +1459,7 @@ "reset_people_visibility": "AtiestatÄĢt personu redzamÄĢbu", "reset_pin_code": "AtiestatÄĢt PIN kodu", "reset_sqlite": "AtiestatÄĢt SQLite datubāzi", + "reset_sqlite_clear_app_data": "NotÄĢrÄĢt datus", "reset_to_default": "AtiestatÄĢt noklusējuma iestatÄĢjumus", "resolve_duplicates": "Atrisināt dublÄ“ÅĄanās gadÄĢjumus", "resolved_all_duplicates": "Visi dublikāti ir atrisināti", @@ -1709,6 +1710,7 @@ "sync_local": "Sinhronizēt lokāli", "sync_status": "Sinhronizācijas statuss", "sync_status_subtitle": "SkatÄĢt un pārvaldÄĢt sinhronizācijas sistēmu", + "tag_face": "AtzÄĢmēt seju", "text_recognition": "Teksta atpazÄĢÅĄana", "theme": "Dizains", "theme_setting_asset_list_storage_indicator_title": "RādÄĢt krātuves indikatoru uz attēliem reÅžga skatā", @@ -1837,6 +1839,7 @@ "viewer_remove_from_stack": "Noņemt no Steka", "viewer_stack_use_as_main_asset": "Izmantot kā Galveno AktÄĢvu", "viewer_unstack": "At-Stekot", + "visibility": "RedzamÄĢba", "visual": "Vizuāli", "visual_builder": "Vizuālais veidotājs", "waiting": "Gaida", diff --git a/i18n/ml.json b/i18n/ml.json index f6d170623a..5b8a4ab7c4 100644 --- a/i18n/ml.json +++ b/i18n/ml.json @@ -420,7 +420,7 @@ "user_settings": "ā´‰ā´Ēā´¯āĩ‹ā´•āĩā´¤ā´žā´ĩā´ŋā´¨āĩā´ąāĩ† ā´•āĩā´°ā´Žāĩ€ā´•ā´°ā´Ŗā´™āĩā´™āĩž", "user_settings_description": "ā´‰ā´Ēā´¯āĩ‹ā´•āĩā´¤āĩƒ ā´•āĩā´°ā´Žāĩ€ā´•ā´°ā´Ŗā´™āĩā´™āĩž ā´•āĩˆā´•ā´žā´°āĩā´¯ā´‚ ⴚāĩ†ā´¯āĩā´¯āĩā´•", "version_check_enabled_description": "ā´Ēā´¤ā´ŋā´Ēāĩā´Ēāĩ ā´Ēā´°ā´ŋā´ļāĩ‹ā´§ā´¨ ā´Ēāĩā´°ā´ĩāĩŧā´¤āĩā´¤ā´¨ā´•āĩā´ˇā´Žā´Žā´žā´•āĩā´•āĩā´•", - "version_check_implications": "ā´Ēā´¤ā´ŋā´Ēāĩā´Ēāĩ ā´Ēā´°ā´ŋā´ļāĩ‹ā´§ā´¨ ā´Ģāĩ€ā´šāĩā´šāĩŧ github.com-ā´Žā´žā´¯ā´ŋ ⴆⴍāĩā´•ā´žā´˛ā´ŋā´• ā´†ā´ļā´¯ā´ĩā´ŋā´¨ā´ŋā´Žā´¯ā´¤āĩā´¤āĩ† ā´†ā´ļāĩā´°ā´¯ā´ŋⴚāĩā´šā´ŋā´°ā´ŋā´•āĩā´•āĩā´¨āĩā´¨āĩ", + "version_check_implications": "ā´Ēā´¤ā´ŋā´Ēāĩā´Ēāĩ ā´Ēā´°ā´ŋā´ļāĩ‹ā´§ā´¨ ā´Ģāĩ€ā´šāĩā´šāĩŧ {server}-ā´Žā´žā´¯ā´ŋ ⴆⴍāĩā´•ā´žā´˛ā´ŋā´• ā´†ā´ļā´¯ā´ĩā´ŋā´¨ā´ŋā´Žā´¯ā´¤āĩā´¤āĩ† ā´†ā´ļāĩā´°ā´¯ā´ŋⴚāĩā´šā´ŋā´°ā´ŋā´•āĩā´•āĩā´¨āĩā´¨āĩ", "version_check_settings": "ā´Ēā´¤ā´ŋā´Ēāĩā´Ēāĩ ā´Ēā´°ā´ŋā´ļāĩ‹ā´§ā´¨", "version_check_settings_description": "ā´Ēāĩā´¤ā´ŋā´¯ ā´Ēā´¤ā´ŋā´Ēāĩā´Ēā´ŋā´¨āĩā´ąāĩ† ā´…ā´ąā´ŋā´¯ā´ŋā´Ēāĩā´Ēāĩ ā´Ēāĩā´°ā´ĩāĩŧā´¤āĩā´¤ā´¨ā´•āĩā´ˇā´Žā´Žā´žā´•āĩā´•āĩā´•/ā´Ēāĩā´°ā´ĩāĩŧā´¤āĩā´¤ā´¨ā´°ā´šā´ŋā´¤ā´Žā´žā´•āĩā´•āĩā´•", "video_conversion_job": "ā´ĩāĩ€ā´Ąā´ŋā´¯āĩ‹ā´•āĩž ⴟāĩā´°ā´žāĩģā´¸āĩâ€Œā´•āĩ‹ā´Ąāĩ ⴚāĩ†ā´¯āĩā´¯āĩā´•", @@ -822,10 +822,6 @@ "day": "ā´Ļā´ŋā´ĩⴏⴂ", "days": "ā´Ļā´ŋā´ĩⴏⴙāĩā´™āĩž", "deduplicate_all": "ā´Žā´˛āĩā´˛ā´ž ā´Ąāĩā´¯āĩ‚ā´Ēāĩā´˛ā´ŋā´•āĩā´•āĩ‡ā´ąāĩā´ąāĩā´•ā´ŗāĩā´‚ ā´’ā´´ā´ŋā´ĩā´žā´•āĩā´•āĩā´•", - "deduplication_criteria_1": "ⴚā´ŋā´¤āĩā´°ā´¤āĩā´¤ā´ŋā´¨āĩā´ąāĩ† ā´ĩā´˛āĩā´Ēāĩā´Ēā´‚ (ā´Ŧāĩˆā´ąāĩā´ąāĩā´•ā´ŗā´ŋāĩŊ)", - "deduplication_criteria_2": "EXIF ā´Ąā´žā´ąāĩā´ąā´¯āĩā´Ÿāĩ† ā´Žā´Ŗāĩā´Ŗā´‚", - "deduplication_info": "ā´Ąāĩā´¯āĩ‚ā´Ēāĩā´˛ā´ŋā´•āĩā´•āĩ‡ā´ˇāĩģ ā´’ā´´ā´ŋā´ĩā´žā´•āĩā´•āĩŊ ā´ĩā´ŋā´ĩā´°ā´‚", - "deduplication_info_description": "ā´…ā´¸ā´ąāĩā´ąāĩā´•āĩž ā´¯ā´žā´¨āĩā´¤āĩā´°ā´ŋā´•ā´Žā´žā´¯ā´ŋ ā´Žāĩāĩģā´•āĩ‚ā´Ÿāĩā´Ÿā´ŋ ā´¤ā´ŋā´°ā´žāĩā´žāĩ†ā´Ÿāĩā´•āĩā´•āĩā´¨āĩā´¨ā´¤ā´ŋā´¨āĩā´‚ ā´Ąāĩā´¯āĩ‚ā´Ēāĩā´˛ā´ŋā´•āĩā´•āĩ‡ā´ąāĩā´ąāĩā´•āĩž ā´Ŧāĩžā´•āĩā´•ā´žā´¯ā´ŋ ā´¨āĩ€ā´•āĩā´•ā´‚ ⴚāĩ†ā´¯āĩā´¯āĩā´¨āĩā´¨ā´¤ā´ŋā´¨āĩā´‚, ā´žā´™āĩā´™āĩž ā´‡ā´ĩ ā´Ēā´°ā´ŋā´—ā´Ŗā´ŋā´•āĩā´•āĩā´¨āĩā´¨āĩ:", "delete": "ⴇⴞāĩā´˛ā´žā´¤ā´žā´•āĩā´•āĩā´•", "delete_action_confirmation_message": "ⴈ ā´…ā´¸ā´ąāĩā´ąāĩ ⴇⴞāĩā´˛ā´žā´¤ā´žā´•āĩā´•ā´Ŗā´Žāĩ†ā´¨āĩā´¨āĩ ā´¨ā´ŋā´™āĩā´™āĩžā´•āĩā´•āĩ ā´‰ā´ąā´Ēāĩā´Ēā´žā´Ŗāĩ‹? ⴈ ā´Ēāĩā´°ā´ĩāĩŧā´¤āĩā´¤ā´¨ā´‚ ā´…ā´¸ā´ąāĩā´ąā´ŋā´¨āĩ† ā´¸āĩ†āĩŧā´ĩā´ąā´ŋā´¨āĩā´ąāĩ† ⴟāĩā´°ā´žā´ˇā´ŋā´˛āĩ‡ā´•āĩā´•āĩ ā´Žā´žā´ąāĩā´ąāĩā´‚, ā´•āĩ‚ā´Ÿā´žā´¤āĩ† ⴇⴤāĩ ā´Ēāĩā´°ā´žā´Ļāĩ‡ā´ļā´ŋā´•ā´Žā´žā´¯ā´ŋ ⴇⴞāĩā´˛ā´žā´¤ā´žā´•āĩā´•ā´Ŗāĩ‹ ā´Žā´¨āĩā´¨āĩ ⴚāĩ‹ā´Ļā´ŋā´•āĩā´•āĩā´•ā´¯āĩā´‚ ⴚāĩ†ā´¯āĩā´¯āĩā´‚", "delete_action_prompt": "{count} ā´Žā´Ŗāĩā´Ŗā´‚ ⴇⴞāĩā´˛ā´žā´¤ā´žā´•āĩā´•ā´ŋ", diff --git a/i18n/mr.json b/i18n/mr.json index cbeac5131f..8b6244b94e 100644 --- a/i18n/mr.json +++ b/i18n/mr.json @@ -408,7 +408,7 @@ "user_settings": "ā¤ĩā¤žā¤Ē⤰⤕⤰āĨā¤¤ā¤ž ⤏āĨ‡ā¤Ÿā¤ŋ⤂⤗āĨā¤œ", "user_settings_description": "ā¤ĩā¤žā¤Ē⤰⤕⤰āĨā¤¤ā¤ž ⤏āĨ‡ā¤Ÿā¤ŋ⤂⤗āĨā¤œ ā¤ĩāĨā¤¯ā¤ĩ⤏āĨā¤Ĩā¤žā¤Ēā¤ŋ⤤ ā¤•ā¤°ā¤ž", "version_check_enabled_description": "⤆ā¤ĩāĨƒā¤¤āĨā¤¤āĨ€ ⤤ā¤Ēā¤žā¤¸ā¤ŖāĨ€ ⤏⤕āĨā¤ˇā¤Ž ā¤•ā¤°ā¤ž", - "version_check_implications": "⤆ā¤ĩāĨƒā¤¤āĨā¤¤āĨ€ ⤤ā¤Ēā¤žā¤¸ā¤ŖāĨ€ ā¤ĩāĨˆā¤ļā¤ŋ⤎āĨā¤ŸāĨā¤¯ GitHub.com ⤏āĨ‹ā¤Ŧ⤤ ⤆ā¤ĩ⤰āĨā¤¤āĨ€ ⤏⤂ā¤ĩā¤žā¤Ļā¤žā¤ĩ⤰ ⤅ā¤ĩ⤞⤂ā¤ŦāĨ‚⤍ ā¤†ā¤šāĨ‡", + "version_check_implications": "⤆ā¤ĩāĨƒā¤¤āĨā¤¤āĨ€ ⤤ā¤Ēā¤žā¤¸ā¤ŖāĨ€ ā¤ĩāĨˆā¤ļā¤ŋ⤎āĨā¤ŸāĨā¤¯ {server} ⤏āĨ‹ā¤Ŧ⤤ ⤆ā¤ĩ⤰āĨā¤¤āĨ€ ⤏⤂ā¤ĩā¤žā¤Ļā¤žā¤ĩ⤰ ⤅ā¤ĩ⤞⤂ā¤ŦāĨ‚⤍ ā¤†ā¤šāĨ‡", "version_check_settings": "⤆ā¤ĩāĨƒā¤¤āĨā¤¤āĨ€ ⤤ā¤Ēā¤žā¤¸ā¤ŖāĨ€", "version_check_settings_description": "⤍ā¤ĩāĨ€ā¤¨ ⤆ā¤ĩāĨƒā¤¤āĨā¤¤āĨ€ ⤏āĨ‚ā¤šā¤¨ā¤ž ⤏⤕āĨā¤ˇā¤Ž/⤅⤕āĨā¤ˇā¤Ž ā¤•ā¤°ā¤ž", "video_conversion_job": "ā¤ĩāĨā¤šā¤ŋā¤Ąā¤ŋ⤓ ⤟āĨā¤°ā¤žā¤¨āĨā¤¸ā¤•āĨ‹ā¤Ą ā¤•ā¤°ā¤ž", @@ -810,10 +810,6 @@ "day": "ā¤Ļā¤ŋā¤ĩ⤏", "days": "⤅⤍āĨ‡ā¤• ā¤Ļā¤ŋā¤ĩ⤏", "deduplicate_all": "⤏⤰āĨā¤ĩ ā¤ĄāĨā¤ĒāĨā¤˛ā¤ŋ⤕āĨ‡ā¤Ÿ ā¤•ā¤žā¤ĸā¤ž", - "deduplication_criteria_1": "ā¤ĒāĨā¤°ā¤¤ā¤ŋā¤ŽāĨ‡ā¤šā¤ž ā¤†ā¤•ā¤žā¤° (ā¤Ŧā¤žā¤‡ā¤ŸāĨā¤¸)", - "deduplication_criteria_2": "EXIF ā¤ĄāĨ‡ā¤Ÿā¤ž ā¤ĒāĨā¤°ā¤Žā¤žā¤Ŗ", - "deduplication_info": "ā¤ĄāĨā¤ĒāĨā¤˛ā¤ŋ⤕āĨ‡ā¤Ÿ ⤍ā¤ŋā¤ĩā¤žā¤°ā¤Ŗ ā¤Žā¤žā¤šā¤ŋ⤤āĨ€", - "deduplication_info_description": "ā¤ĄāĨā¤ĒāĨā¤˛ā¤ŋ⤕āĨ‡ā¤Ÿ ⤏āĨā¤ĩā¤¯ā¤‚ā¤šā¤˛ā¤ŋ⤤ā¤Ē⤪āĨ‡ ⤍ā¤ŋā¤ĩā¤ĄāĨ‚⤍ ā¤•ā¤žā¤ĸ⤪āĨā¤¯ā¤žā¤¸ā¤žā¤ āĨ€ ā¤–ā¤žā¤˛āĨ€ā¤˛ ⤍ā¤ŋ⤕⤎ ā¤ĩā¤žā¤Ē⤰⤞āĨ‡ ā¤œā¤žā¤¤ā¤žā¤¤:", "delete": "ā¤šā¤Ÿā¤ĩā¤ž", "delete_action_confirmation_message": "⤤āĨā¤ŽāĨā¤šā¤žā¤˛ā¤ž ā¤šāĨ€ ā¤Ģā¤žā¤ˆā¤˛ ā¤šā¤Ÿā¤ĩā¤žā¤¯ā¤šāĨ€ ā¤†ā¤šāĨ‡ ā¤•ā¤ž? ā¤šāĨ€ ⤕āĨā¤°ā¤ŋā¤¯ā¤ž ⤏⤰āĨā¤ĩāĨā¤šā¤°ā¤šāĨā¤¯ā¤ž ⤟āĨā¤°āĨ…ā¤ļā¤Žā¤§āĨā¤¯āĨ‡ ā¤šā¤˛ā¤ĩāĨ‡ā¤˛ ⤆⤪ā¤ŋ ⤏āĨā¤Ĩā¤žā¤¨ā¤ŋ⤕ā¤Ē⤪āĨ‡ ā¤šā¤Ÿā¤ĩā¤žā¤¯ā¤šāĨ‡ ā¤•ā¤ž ⤤āĨ‡ ā¤ĩā¤ŋā¤šā¤žā¤°āĨ‡ā¤˛", "delete_action_prompt": "{count} ā¤šā¤Ÿā¤ĩ⤞āĨ‡", diff --git a/i18n/ms.json b/i18n/ms.json index 0c1ae6c156..5459b78450 100644 --- a/i18n/ms.json +++ b/i18n/ms.json @@ -5,6 +5,7 @@ "acknowledge": "Akui", "action": "Tindakan", "action_common_update": "Kemaskini", + "action_description": "Satu set tindakan untuk dilakukan atas aset yang ditapis", "actions": "Tindakan", "active": "Aktif", "active_count": "Aktif: {count}", @@ -16,6 +17,7 @@ "add_a_name": "Tambah nama", "add_a_title": "Tambah tajuk", "add_action": "Tambah Tindakan", + "add_assets": "Tambah aset", "add_birthday": "Tambah hari jadi", "add_endpoint": "Tambah titik akhir", "add_exclusion_pattern": "Tambahkan corak pengecualian", @@ -393,7 +395,7 @@ "user_settings": "Tetapan Pengguna", "user_settings_description": "Urus tetapan pengguna", "version_check_enabled_description": "Dayakan semakan versi", - "version_check_implications": "Ciri semakan versi bergantung kepada komunikasi berkala dengan github.com", + "version_check_implications": "Ciri semakan versi bergantung kepada komunikasi berkala dengan {server}", "version_check_settings": "Semakan Versi", "version_check_settings_description": "Dayakan/nyahdayakan notifikasi versi baharu", "video_conversion_job": "Transkod video", @@ -433,10 +435,6 @@ "album_user_left": "Kiri {album}", "album_user_removed": "{user} telah dibuang", "album_with_link_access": "Benarkan sesiapa yang mempunyai pautan melihat foto dan individu dalam album ini.", - "deduplication_criteria_1": "Saiz imej dalam bait", - "deduplication_criteria_2": "Kiraan data EXIF", - "deduplication_info": "Maklumat Pendeduplikasian", - "deduplication_info_description": "Untuk prapilih aset secara automatik dan mengalih keluar pendua secara pukal, kami melihat pada:", "delete": "Padam", "delete_album": "Padam album", "delete_api_key_prompt": "Adakah anda pasti mahu memadam kunci API ini?", diff --git a/i18n/nb_NO.json b/i18n/nb_NO.json index 4de7864811..1602707dd9 100644 --- a/i18n/nb_NO.json +++ b/i18n/nb_NO.json @@ -5,7 +5,7 @@ "acknowledge": "Bekreft", "action": "Handling", "action_common_update": "Oppdater", - "action_description": "Ett sett med handlinger som skal utføres pÃĨ de filtrerede objekter", + "action_description": "Ett sett handlinger som skal utføres pÃĨ de filtrerte mediefilene", "actions": "Handlinger", "active": "Aktiv", "active_count": "Aktiv: {count}", @@ -18,7 +18,7 @@ "add_a_title": "Legg til tittel", "add_action": "Legg til hendelse", "add_action_description": "Trykk for ÃĨ legge til en hendelse ÃĨ utføre", - "add_assets": "Legg til objekter", + "add_assets": "Legg til mediefiler", "add_birthday": "Legg til bursdag", "add_endpoint": "Legg til endepunkt", "add_exclusion_pattern": "Legg til ekskluderingsmønster", @@ -34,7 +34,7 @@ "add_to_album": "Legg til album", "add_to_album_bottom_sheet_added": "Lagt til i {album}", "add_to_album_bottom_sheet_already_exists": "Allerede i {album}", - "add_to_album_bottom_sheet_some_local_assets": "Noen lokale elementer kunne ikke legges til i albumet", + "add_to_album_bottom_sheet_some_local_assets": "Noen lokale filer kunne ikke legges til i albumet", "add_to_album_toggle": "Avhuking for {album}", "add_to_albums": "Legg til i album", "add_to_albums_count": "Legg til i album ({count})", @@ -50,8 +50,8 @@ "add_exclusion_pattern_description": "Legg til ekskluderingsmønstre. Globbing med *, ** og ? støttes. For ÃĨ ignorere alle filer i en hvilken som helst mappe som heter \"Raw\", bruk \"**/Raw/**\". For ÃĨ ignorere alle filer som slutter pÃĨ \".tif\", bruk \"**/*.tif\". For ÃĨ ignorere en absolutt filplassering, bruk \"/filsti/til/ignorer/**\".", "admin_user": "Administrasjonsbruker", "asset_offline_description": "Dette eksterne bibliotekselementet finnes ikke lenger pÃĨ disk og har blitt flyttet til papirkurven. Hvis filen ble flyttet innad i biblioteket, se etter det tilsvarende elementet i tidslinjen din. For ÃĨ gjenopprette elementet, vennligst sørg for at filstien under er tilgjengelig for Immich og skann biblioteket.", - "authentication_settings": "Godkjenninger", - "authentication_settings_description": "Administrer passord, OAuth, og andre innstillinger for autentisering", + "authentication_settings": "Godkjenings Instillinger", + "authentication_settings_description": "Administrer passord, OAuth, og andre innstillinger for autentiserings Instilinger", "authentication_settings_disable_all": "Er du sikker pÃĨ at du ønsker ÃĨ deaktivere alle innloggingsmetoder? Innlogging vil bli fullstendig deaktivert.", "authentication_settings_reenable": "For ÃĨ aktivere pÃĨ nytt, bruk en Server Command.", "background_task_job": "Bakgrunnsjobber", @@ -81,7 +81,7 @@ "cron_expression_description": "Still inn skanneintervallet med cron-formatet. For mer informasjon henvises til f.eks. Crontab Guru", "cron_expression_presets": "ForhÃĨndsinnstillinger for Cron-uttrykk", "disable_login": "Deaktiver innlogging", - "duplicate_detection_job_description": "Kjør maskinlÃĻring pÃĨ filer for ÃĨ oppdage lignende bilder. Krever bruk av Smart Search", + "duplicate_detection_job_description": "Kjør maskinlÃĻring pÃĨ filer for ÃĨ oppdage lignende bilder. Krever bruk av Smart Søk", "exclusion_pattern_description": "Ekskluderingsmønstre lar deg ignorere filer og mapper nÃĨr du skanner biblioteket ditt. Dette er nyttig hvis du har mapper som inneholder filer du ikke vil importere, for eksempel RAW-filer.", "export_config_as_json_description": "Last ned nÃĨvÃĻrende systemkonfigurasjon som en JSON fil", "external_libraries_page_description": "Administrering for eksterne bibliotek", @@ -441,7 +441,7 @@ "user_successfully_removed": "Bruker {email} har blitt fjernet.", "users_page_description": "Administrer brukere", "version_check_enabled_description": "Aktiver periodiske forespørsler til GitHub for ÃĨ sjekke etter nye utgivelser", - "version_check_implications": "Versjonssjekkfunksjonen baserer seg pÃĨ periodisk kommunikasjon med github.com", + "version_check_implications": "Versjonssjekkfunksjonen baserer seg pÃĨ periodisk kommunikasjon med {server}", "version_check_settings": "Versjonssjekk", "version_check_settings_description": "Aktiver/deaktiver varsel om ny versjon", "video_conversion_job": "Transkod videoer", @@ -849,9 +849,12 @@ "create_link_to_share": "Opprett delelink", "create_link_to_share_description": "La alle med lenken se de(t) valgte bildet/bildene", "create_new": "LAG NY", + "create_new_face": "Opprett nytt ansikt", "create_new_person": "Opprett ny person", "create_new_person_hint": "Tildel valgte eiendeler til en ny person", "create_new_user": "Opprett ny bruker", + "create_person": "Opprett person", + "create_person_subtitle": "Gi det valgte ansiktet et navn for ÃĨ opprette og tagge den nye personen", "create_shared_album_page_share_add_assets": "LEGG TIL OBJEKTER", "create_shared_album_page_share_select_photos": "Velg bilder", "create_shared_link": "Opprett delt lenke", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fikset", "crop_aspect_ratio_free": "Lagret", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Firkant", "curated_object_page_title": "Ting", "current_device": "NÃĨvÃĻrende enhet", "current_pin_code": "NÃĨvÃĻrende PIN kode", @@ -880,7 +884,7 @@ "daily_title_text_date": "E MMM. dd", "daily_title_text_date_year": "E MMM. dddd, yyyy", "dark": "Mørk", - "dark_theme": "Aktiver mørk-modus", + "dark_theme": "Skift til mørkt tema", "date": "Dato", "date_after": "Dato etter", "date_and_time": "Dato og tid", @@ -891,12 +895,10 @@ "day": "Dag", "days": "Dager", "deduplicate_all": "De-dupliser alle", - "deduplication_criteria_1": "Bilde størrelse i bytes", - "deduplication_criteria_2": "Antall av EXIF data", - "deduplication_info": "Dedupliseringsinformasjon", - "deduplication_info_description": "For ÃĨ automatisk forhÃĨndsvelge eiendeler og fjerne duplikater samtidig, ser vi pÃĨ:", + "default_locale": "StandardsprÃĨk", + "default_locale_description": "Formater datoer og tall basert pÃĨ din nettlesers sprÃĨkinnstillinger", "delete": "Slett", - "delete_action_confirmation_message": "Vil du virkelig slette dette elementet? Dette vil flytte elementet til papirkurvn og vil gi deg beskjed om du vil slette det lokalt", + "delete_action_confirmation_message": "Vil du virkelig slette dette elementet? Dette vil flytte elementet til papirkurven og vil gi deg beskjed om du vil slette det lokalt", "delete_action_prompt": "{count} slettet", "delete_album": "Slett album", "delete_api_key_prompt": "Vil du virkelig slette denne API-nøkkelen?", @@ -970,7 +972,7 @@ "downloading_media": "Laster ned media", "drop_files_to_upload": "Slipp filer hvor som helst for ÃĨ laste opp", "duplicates": "Duplikater", - "duplicates_description": "Løs hver gruppe ved ÃĨ angi hvilke, hvis noen, er duplikater", + "duplicates_description": "Løs hver gruppe ved ÃĨ angi hvilke, hvis noen, er duplikater.", "duration": "Varighet", "edit": "Rediger", "edit_album": "Rediger album", @@ -1007,8 +1009,8 @@ "editor_edits_applied_success": "Lagring av endringer vellykket", "editor_flip_horizontal": "Roter horisontalt", "editor_flip_vertical": "Roter vertikalt", - "editor_handle_corner": "{corner, select, top_left {Øvre venstre} top_right {Øvre høyre} bottom_left {Nedre venstre} bottom_right {Nedre høyre} other {A}} hjørnehÃĨndtak", - "editor_handle_edge": "{edge, select, top {Øvre} bottom {Nedre} left {Venstre} right {Høyre} other {Et}} kanthÃĨndtak", + "editor_handle_corner": "{corner, select, top_left {Øverst venstre} top_right {Øverst høyre} bottom_left {Nederst venstre} bottom_right {Nederst høyre} other {A}} hjørnehÃĨndtak", + "editor_handle_edge": "{edge, select, top {Øverst} bottom {Nederst} left {Venstre} right {Høyre} other {Et}} kanthÃĨndtak", "editor_orientation": "Orientering", "editor_reset_all_changes": "Tilbakestill endringer", "editor_rotate_left": "Roter 90° mot klokken", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Albumtittel", "licenses": "Lisenser", "light": "Lys", + "light_theme": "Skift til lyst tema", "like": "Lik", "like_deleted": "Som slettede", "link_motion_video": "Koble bevegelsesvideo", + "link_to_docs": "For mer informasjon, se dokumentasjonen.", "link_to_oauth": "Lenke til OAuth", "linked_oauth_account": "Lenket til OAuth-konto", "list": "Liste", @@ -1651,6 +1655,7 @@ "only_favorites": "Bare favoritter", "open": "Åpne", "open_calendar": "Åpne kalender", + "open_in_browser": "Åpne i nettleser", "open_in_map_view": "Åpne i kartvisning", "open_in_openstreetmap": "Åpne i OpenStreetMap", "open_the_search_filters": "Åpne søkefiltrene", @@ -1719,9 +1724,9 @@ "permission_onboarding_permission_limited": "Begrenset tilgang. For ÃĨ la Immich sikkerhetskopiere og hÃĨndtere galleriet, tillatt bilde- og video-tilgang i Innstillinger.", "permission_onboarding_request": "Immich trenger tilgang til ÃĨ se dine bilder og videoer.", "person": "Person", - "person_age_months": "{months, plural, one {# month} other {# months}} gammel", - "person_age_year_months": "1 ÃĨr, {months, plural, one {# month} other {# months}} gammel", - "person_age_years": "{years, plural, other {# years}} gammel", + "person_age_months": "{months, plural, one {# mÃĨned} other {# mÃĨneder}} gammel", + "person_age_year_months": "1 ÃĨr, {months, plural, one {# mÃĨned} other {# mÃĨneder}} gammel", + "person_age_years": "{years, plural, other {# ÃĨr}} gammel", "person_birthdate": "Født den {date}", "person_hidden": "{name}{hidden, select, true { (skjult)} other {}}", "person_recognized": "Person gjenkjent", @@ -2212,6 +2217,7 @@ "tag": "Tagg", "tag_assets": "Merk ressurser", "tag_created": "Lag merke: {tag}", + "tag_face": "Tagg ansikt", "tag_feature_description": "Bla gjennom bilder og videoer gruppert etter logiske merke-emner", "tag_not_found_question": "Finner du ikke en merke? Opprett en nytt merke.", "tag_people": "Tag personer", @@ -2393,6 +2399,7 @@ "viewer_remove_from_stack": "Fjern fra stabling", "viewer_stack_use_as_main_asset": "Bruk som hovedelement", "viewer_unstack": "avstable", + "visibility": "Synlighet", "visibility_changed": "Synlighet endret for {count, plural, one {# person} other {# people}}", "visual": "Visuell", "visual_builder": "Visuell oppbygging", diff --git a/i18n/nl.json b/i18n/nl.json index 89daa4bee5..c584fc4b86 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -349,7 +349,7 @@ "template_email_update_album": "Update in album sjabloon", "template_email_welcome": "Welkomstmail sjabloon", "template_settings": "Melding sjablonen", - "template_settings_description": "Beheer aangepast sjablonen voor meldingen", + "template_settings_description": "Beheer aangepaste sjablonen voor meldingen", "theme_custom_css_settings": "Aangepaste CSS", "theme_custom_css_settings_description": "Met Cascading Style Sheets kan het ontwerp van Immich worden aangepast.", "theme_settings": "Thema-instellingen", @@ -441,7 +441,7 @@ "user_successfully_removed": "Gebruiker {email} is succesvol verwÄŗderd.", "users_page_description": "Gebruikers­pagina voor administrators", "version_check_enabled_description": "Versiecontrole inschakelen", - "version_check_implications": "De versiecontrole is afhankelijk van periodieke communicatie met github.com", + "version_check_implications": "De versiecontrole is afhankelijk van periodieke communicatie met {server}", "version_check_settings": "Versiecontrole", "version_check_settings_description": "Melding voor een nieuwe versie in-/uitschakelen", "video_conversion_job": "Transcodeer video's", @@ -544,7 +544,7 @@ "appears_in": "Komt voor in", "apply_count": "Toepassen ({count, number})", "archive": "Archief", - "archive_action_prompt": "{count} item(s) toegevoegd aan het archief", + "archive_action_prompt": "{count, plural, one {# item} other {# items}} toegevoegd aan het archief", "archive_or_unarchive_photo": "Foto archiveren of uit het archief halen", "archive_page_no_archived_assets": "Geen gearchiveerde items gevonden", "archive_page_title": "Archief ({count})", @@ -593,20 +593,20 @@ "assets_cannot_be_added_to_album_count": "{count, plural, one {# item} other {# items}} konden niet aan album toegevoegd worden", "assets_cannot_be_added_to_albums": "{count, plural, one {Item kan} other {Items kunnen}} niet toegevoegd worden aan de albums", "assets_count": "{count, plural, one {# item} other {# items}}", - "assets_deleted_permanently": "{count} item(s) permanent verwijderd", - "assets_deleted_permanently_from_server": "{count} item(s) permanent verwijderd van de Immich server", + "assets_deleted_permanently": "{count, plural, one {# item} other {# items}} permanent verwijderd", + "assets_deleted_permanently_from_server": "{count, plural, one {# item} other {# items}} permanent verwijderd van de Immich server", "assets_downloaded_failed": "{count, plural, one {# bestand gedownload - {error} bestand mislukt} other {# bestanden gedownload - {error} bestanden mislukt}}", "assets_downloaded_successfully": "{count, plural, one {# bestand succesvol gedownload} other {# bestanden succesvol gedownload}}", "assets_moved_to_trash_count": "{count, plural, one {# item} other {# items}} verplaatst naar prullenbak", "assets_permanently_deleted_count": "{count, plural, one {# item} other {# items}} permanent verwijderd", "assets_removed_count": "{count, plural, one {# item} other {# items}} verwijderd", - "assets_removed_permanently_from_device": "{count} item(s) permanent verwijderd van je apparaat", + "assets_removed_permanently_from_device": "{count, plural, one {# item} other {# items}} permanent verwijderd van je apparaat", "assets_restore_confirmation": "Weet je zeker dat je alle verwijderde items wilt herstellen? Je kunt deze actie niet ongedaan maken! Offline items kunnen op deze manier niet worden hersteld.", "assets_restored_count": "{count, plural, one {# item} other {# items}} hersteld", - "assets_restored_successfully": "{count} item(s) succesvol hersteld", - "assets_trashed": "{count} item(s) naar de prullenbak verplaatst", + "assets_restored_successfully": "{count, plural, one {# item} other {# items}} succesvol hersteld", + "assets_trashed": "{count, plural, one {# item} other {# items}} naar de prullenbak verplaatst", "assets_trashed_count": "{count, plural, one {# item} other {# items}} naar prullenbak verplaatst", - "assets_trashed_from_server": "{count} item(s) naar de prullenbak verplaatst op de Immich server", + "assets_trashed_from_server": "{count, plural, one {# item} other {# items}} naar de prullenbak verplaatst op de Immich server", "assets_were_part_of_album_count": "{count, plural, one {Item was} other {Items waren}} al onderdeel van het album", "assets_were_part_of_albums_count": "{count, plural, one {Item is} other {Items zijn}} al onderdeel van de albums", "authorized_devices": "Geautoriseerde apparaten", @@ -849,9 +849,12 @@ "create_link_to_share": "Gedeelde link maken", "create_link_to_share_description": "Laat iedereen met de link de geselecteerde foto(s) zien", "create_new": "MAAK NIEUW", + "create_new_face": "Nieuw gezicht aanmaken", "create_new_person": "Nieuwe persoon aanmaken", "create_new_person_hint": "Geselecteerde items toewijzen aan een nieuwe persoon", "create_new_user": "Nieuwe gebruiker aanmaken", + "create_person": "Persoon aanmaken", + "create_person_subtitle": "Voeg een naam toe aan het geselecteerde gezicht om de nieuwe persoon aan te maken en te taggen", "create_shared_album_page_share_add_assets": "ITEMS TOEVOEGEN", "create_shared_album_page_share_select_photos": "Selecteer foto's", "create_shared_link": "Gedeelde link maken", @@ -866,21 +869,22 @@ "crop_aspect_ratio_fixed": "Vast", "crop_aspect_ratio_free": "Vrij", "crop_aspect_ratio_original": "Origineel", + "crop_aspect_ratio_square": "Vierkant", "curated_object_page_title": "Dingen", "current_device": "Huidig apparaat", "current_pin_code": "Huidige pincode", "current_server_address": "Huidig serveradres", "custom_date": "Aangepaste datum", "custom_locale": "Aangepaste landinstelling", - "custom_locale_description": "Formatteer datums, tijden en getallen op basis van de geselecteerde taal en de regio", + "custom_locale_description": "Formatteer datums, tijden, en getallen op basis van de geselecteerde taal en regio", "custom_url": "Aangepaste URL", "cutoff_date_description": "Bewaar foto's van de laatsteâ€Ļ", "cutoff_day": "{count, plural, one {dag} other {dagen}}", - "cutoff_year": "{count, plural, one {jaar} other {jaar}}", + "cutoff_year": "{count, plural, one {jaar} other {jaren}}", "daily_title_text_date": "E dd MMM", "daily_title_text_date_year": "E dd MMM yyyy", "dark": "Donker", - "dark_theme": "Donker thema in- of uitschakelen", + "dark_theme": "Wissel naar donker thema", "date": "Datum", "date_after": "Datum na", "date_and_time": "Datum en tijd", @@ -891,13 +895,11 @@ "day": "Dag", "days": "Dagen", "deduplicate_all": "Alles dedupliceren", - "deduplication_criteria_1": "Grootte van afbeelding in bytes", - "deduplication_criteria_2": "Aantal EXIF data", - "deduplication_info": "Deduplicatie-info", - "deduplication_info_description": "Om automatisch items te preselecteren en duplicaten te verwijderen in bulk, kijken we naar:", + "default_locale": "Standaard landinstelling", + "default_locale_description": "Formatteer datums en getallen op basis van de taalinstellingen van je browser", "delete": "Verwijderen", "delete_action_confirmation_message": "Weet je zeker dat je dit item wilt verwijderen? Deze actie zorgt ervoor dat het item naar de prullenbak van de server wordt verplaatst en je wordt gevraagd of je deze ook lokaal wilt verwijderen", - "delete_action_prompt": "{count} item(s) verwijderd", + "delete_action_prompt": "{count} verwijderd", "delete_album": "Album verwijderen", "delete_api_key_prompt": "Weet je zeker dat je deze API-sleutel wilt verwijderen?", "delete_dialog_alert": "Deze items zullen permanent verwijderd worden van Immich en je apparaat", @@ -911,12 +913,12 @@ "delete_key": "Verwijder key", "delete_library": "Verwijder bibliotheek", "delete_link": "Verwijder link", - "delete_local_action_prompt": "{count} item(s) lokaal verwijderd", + "delete_local_action_prompt": "{count} lokaal verwijderd", "delete_local_dialog_ok_backed_up_only": "Verwijder alleen met back-up", "delete_local_dialog_ok_force": "Toch verwijderen", "delete_others": "Andere verwijderen", "delete_permanently": "Permanent verwijderen", - "delete_permanently_action_prompt": "{count} item(s) permanent verwijderd", + "delete_permanently_action_prompt": "{count} permanent verwijderd", "delete_shared_link": "Verwijder gedeelde link", "delete_shared_link_dialog_title": "Verwijder gedeelde link", "delete_tag": "Tag verwijderen", @@ -946,7 +948,7 @@ "documentation": "Documentatie", "done": "Klaar", "download": "Downloaden", - "download_action_prompt": "{count} item(s) aan het downloaden", + "download_action_prompt": "{count, plural, one {# item} other {# items}} aan het downloaden", "download_canceled": "Download geannuleerd", "download_complete": "Download voltooid", "download_enqueue": "Download in wachtrij", @@ -970,7 +972,7 @@ "downloading_media": "Media aan het downloaden", "drop_files_to_upload": "Zet bestanden ergens neer om ze te uploaden", "duplicates": "Duplicaten", - "duplicates_description": "Kies voor iedere groep welke, indien aanwezig, duplicaten zijn", + "duplicates_description": "Kies voor iedere groep welke, indien aanwezig, duplicaten zijn.", "duration": "Tijdsduur", "edit": "Bewerken", "edit_album": "Album bewerken", @@ -978,7 +980,7 @@ "edit_birthday": "Wijzig verjaardag", "edit_date": "Datum bewerken", "edit_date_and_time": "Datum en tijd bewerken", - "edit_date_and_time_action_prompt": "Datum en tijd bijgewerkt van {count} item(s)", + "edit_date_and_time_action_prompt": "Datum en tijd bijgewerkt van {count, plural, one {# item} other {# items}}", "edit_date_and_time_by_offset": "Wijzigen datum door verschuiving", "edit_date_and_time_by_offset_interval": "Nieuw datuminterval: {from}-{to}", "edit_description": "Beschrijving bewerken", @@ -988,7 +990,7 @@ "edit_key": "Key bewerken", "edit_link": "Link bewerken", "edit_location": "Locatie bewerken", - "edit_location_action_prompt": "Locatie bijgewerkt van {count} item(s)", + "edit_location_action_prompt": "Locatie bijgewerkt van {count, plural, one {# item} other {# items}}", "edit_location_dialog_title": "Locatie", "edit_name": "Naam bewerken", "edit_people": "Mensen bewerken", @@ -1201,7 +1203,7 @@ "failed_to_load_assets": "Kan items niet laden", "failed_to_load_folder": "Laden van map mislukt", "favorite": "Favoriet", - "favorite_action_prompt": "{count} item(s) toegevoegd aan je favorieten", + "favorite_action_prompt": "{count, plural, one {# item} other {# items}} toegevoegd aan je favorieten", "favorite_or_unfavorite_photo": "Foto markeren als of verwijderen uit favorieten", "favorites": "Favorieten", "favorites_page_no_favorites": "Geen favoriete items gevonden", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Albumtitel", "licenses": "Licenties", "light": "Licht", + "light_theme": "Wissel naar licht thema", "like": "Vind ik leuk", "like_deleted": "Like verwijderd", "link_motion_video": "Koppel bewegende video", + "link_to_docs": "Raadpleeg voor meer informatie de documentatie.", "link_to_oauth": "Koppel OAuth", "linked_oauth_account": "Gekoppeld OAuth account", "list": "Lijst", @@ -1547,7 +1551,7 @@ "move_off_locked_folder": "Verplaats uit vergrendelde map", "move_to": "Verplaatsen naar", "move_to_device_trash": "Naar prullenbak van apparaat", - "move_to_lock_folder_action_prompt": "{count} item(s) toegevoegd aan de vergrendelde map", + "move_to_lock_folder_action_prompt": "{count, plural, one {# item} other {# items}} 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", "move_up": "Naar boven verplaatsen", @@ -1850,9 +1854,9 @@ "remove_custom_date_range": "Aangepast datumbereik verwijderen", "remove_deleted_assets": "Verwijder offline bestanden", "remove_from_album": "Verwijderen uit album", - "remove_from_album_action_prompt": "{count} item(s) verwijderd uit het album", + "remove_from_album_action_prompt": "{count, plural, one {# item} other {# items}} verwijderd uit het album", "remove_from_favorites": "Verwijderen uit favorieten", - "remove_from_lock_folder_action_prompt": "{count} item(s) verwijderd uit de vergrendelde map", + "remove_from_lock_folder_action_prompt": "{count, plural, one {# item} other {# items}} verwijderd uit de vergrendelde map", "remove_from_locked_folder": "Verwijder uit de vergrendelde map", "remove_from_locked_folder_confirmation": "Weet je zeker dat je deze foto's en video's uit de vergrendelde map wilt verplaatsen? Ze zijn dan weer zichtbaar in je bibliotheek.", "remove_from_shared_link": "Verwijderen uit gedeelde link", @@ -1895,7 +1899,7 @@ "resolved_all_duplicates": "Alle duplicaten opgelost", "restore": "Herstellen", "restore_all": "Herstel alle", - "restore_trash_action_prompt": "{count} item(s) teruggehaald uit de prullenbak", + "restore_trash_action_prompt": "{count, plural, one {# item} other {# items}} teruggehaald uit de prullenbak", "restore_user": "Gebruiker herstellen", "restored_asset": "Item hersteld", "resume": "Hervatten", @@ -2063,9 +2067,9 @@ "settings_saved": "Instellingen opgeslagen", "setup_pin_code": "Stel een pincode in", "share": "Delen", - "share_action_prompt": "{count} item(s) gedeeld", + "share_action_prompt": "{count, plural, one {# item} other {# items}} gedeeld", "share_add_photos": "Foto's toevoegen", - "share_assets_selected": "{count} item(s) geselecteerd", + "share_assets_selected": "{count, plural, one {# item} other {# items}} geselecteerd", "share_dialog_preparing": "Voorbereiden...", "share_link": "Link delen", "shared": "Gedeeld", @@ -2173,7 +2177,7 @@ "sort_title": "Titel", "source": "Bron", "stack": "Stapel", - "stack_action_prompt": "{count} item(s) gestapeld", + "stack_action_prompt": "{count} items gestapeld", "stack_duplicates": "Stapel duplicaten", "stack_select_one_photo": "Selecteer ÊÊn primaire foto voor de stapel", "stack_selected_photos": "Geselecteerde foto's stapelen", @@ -2213,6 +2217,7 @@ "tag": "Tag", "tag_assets": "Items taggen", "tag_created": "Tag aangemaakt: {tag}", + "tag_face": "Gezicht labelen", "tag_feature_description": "Bladeren door foto's en video's gegroepeerd op tags", "tag_not_found_question": "Kun je een tag niet vinden? Maak een nieuwe tag.", "tag_people": "Mensen taggen", @@ -2259,7 +2264,7 @@ "total": "Totaal", "total_usage": "Totaal gebruik", "trash": "Prullenbak", - "trash_action_prompt": "{count} item(s) verplaatst naar de prullenbak", + "trash_action_prompt": "{count, plural, one {# item} other {# items}} verplaatst naar de prullenbak", "trash_all": "Verplaats alle naar prullenbak", "trash_count": "{count, number} naar prullenbak", "trash_delete_asset": "Items naar prullenbak verplaatsen of verwijderen", @@ -2309,7 +2314,7 @@ "unselect_all_duplicates": "Deselecteer alle duplicaten", "unselect_all_in": "Deselecteer alles in {group}", "unstack": "Ontstapelen", - "unstack_action_prompt": "{count} item(s) ontstapeld", + "unstack_action_prompt": "{count} items ontstapeld", "unstacked_assets_count": "{count, plural, one {# item} other {# items}} ontstapeld", "unsupported_field_type": "Veldtype niet ondersteund", "unsupported_file_type": "Bestand {file} kan niet worden geÃŧpload omdat het bestandstype {type} niet wordt ondersteund.", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Verwijder van stapel", "viewer_stack_use_as_main_asset": "Zet bovenaan de stapel", "viewer_unstack": "Ontstapel", + "visibility": "Zichtbaarheid", "visibility_changed": "Zichtbaarheid gewijzigd voor {count, plural, one {# persoon} other {# mensen}}", "visual": "Visueel", "visual_builder": "Visuele bouwer", diff --git a/i18n/nn.json b/i18n/nn.json index cbf81e4807..7a0471c574 100644 --- a/i18n/nn.json +++ b/i18n/nn.json @@ -37,8 +37,10 @@ "add_to_album_bottom_sheet_some_local_assets": "Somme lokale eigedelar kunne ikkje leggjast til i 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 i delt album", "add_url": "Legg til URL", + "add_workflow_step": "Legg til steg i arbeidsflyt", "added_to_archive": "Lagt til i arkiv", "added_to_favorites": "Lagt til i favorittar", "added_to_favorites_count": "La til {count, number} i favorittar", @@ -71,6 +73,7 @@ "confirm_reprocess_all_faces": "Er du sikker pÃĨ at du vil behandle alle ansikt pÃĨ nytt? Det vil Ã˛g fjerne namngjevne personar.", "confirm_user_password_reset": "Er du sikker at du vil tilbakestille passordet til {user}?", "confirm_user_pin_code_reset": "Er du sikker pÃĨ at du vil tilbakestille {user} sin PIN-kode?", + "copy_config_to_clipboard_description": "Kopier systemkonfigurasjonen som eit JSON-objekt til utklippstavla", "create_job": "Lag jobb", "cron_expression": "Cron uttrykk", "cron_expression_description": "Set inn skanningsintervall med cron-formatet. For meir informasjon sjÃĨ t.d. Crontab Guru", @@ -78,6 +81,7 @@ "disable_login": "Deaktiver innlogging", "duplicate_detection_job_description": "Kjør maskinlÃĻring pÃĨ filer for ÃĨ oppdage liknande bilete. Krev bruk av Smart Search", "exclusion_pattern_description": "Utelatingsmønster let deg utelate filer og mapper nÃĨr du skannar biblioteket ditt. Det er nyttig om du har mapper som inneheld filer du ikkje ynskjer ÃĨ importere, til dømes RAW-filer.", + "export_config_as_json_description": "Last ned nÃĨverande systemkonfigurasjon som ei JSON-fil", "face_detection": "Ansiktssøk", "face_detection_description": "Finn ansikt i bilete ved hjelp av maskinlÃĻring. For videoar vert berre miniatyrbilete bruka. \"Alle\" søkjer (opp att) gjennom alle bilete. \"Tilbakestill\" fjernar all gjeldande ansiktsdata. \"Manglande\" legg filer som ikkje vert behandla til i køa for ansiktssøk. Oppdaga ansikt vert lagt i køa for ansiktsattkjenning, og kopla til eksisterande eller nye personar.", "facial_recognition_job_description": "Koplar attkjende ansikt til personar. Det skjer fyrst nÃĨr anskiktssøkjet er ferdig. \"Tilbakestill\" fjernar alle koplingar til personar, og tilbakestiller ansiktsgrupper. \"Manglande\" legg ansikt som ikkje er oppkopla til i køa.", @@ -105,6 +109,7 @@ "image_thumbnail_description": "Lite miniatyrbilete med fjerna metadata, brukt nÃĨr ein ser pÃĨ grupper av bilete som hovudtidslinja", "image_thumbnail_quality_description": "Kvalitet pÃĨ miniatyrbilete frÃĨ 1-100. Høgare er betre, men gjev større filstorleik, og kan senkje appresposen.", "image_thumbnail_title": "Innstillingar for miniatyrbilete", + "import_config_from_json_description": "Importer systemkonfigurasjon ved ÃĨ laste opp ei JSON konfigurasjonsfil", "job_concurrency": "{job} samstundes utføring", "job_created": "Jobb laga", "job_not_concurrency_safe": "Kan ikke trygt utføre jobben samstundes.", @@ -112,22 +117,30 @@ "job_settings_description": "Handsam samstundes utføring av jobber", "jobs_delayed": "{jobCount, plural, other {# forsinka}}", "jobs_failed": "{jobCount, plural, other {# mislykkast}}", + "jobs_over_time": "Jobbar over tid", "library_created": "Opprett bibliotek: {library}", "library_deleted": "Bibliotek sletta", + "library_details": "Bibliotekdetaljar", + "library_folder_description": "Vel ei mappe ÃĨ importere. Denne mappa, inkludert undermappar, vil bli skanna for biletar og videoar.", + "library_remove_exclusion_pattern_prompt": "Er du sikker pÃĨ at du vil fjerne dette unntaksmønsteret?", "library_scanning": "Regelbunden skanning", "library_scanning_description": "Sett opp regelbunden skanning av biblioteket", "library_scanning_enable_description": "Aktiver regelbunden skanning av biblioteket", "library_settings": "Eksternt Bibliotek", "library_settings_description": "Handsam eksterne biblioteksinnstillingar", "library_tasks_description": "Utfør bibliotekstoppgÃĨver", + "library_updated": "Oppdatert bibliotek", "library_watching_enable_description": "Sjekk eksterne bibliotek for forandringar", "library_watching_settings": "BiblioteksovervÃĨking (EKSPERIMENTELL)", "library_watching_settings_description": "Sjekk automatisk for forandringar", "logging_enable_description": "Aktiver loggføring", "logging_level_description": "NÃĨr aktivert, kva loggnivÃĨ ÃĨ bruke.", "logging_settings": "Logging", + "machine_learning_availability_checks": "Tilgjengelegheitssjekkar", "machine_learning_availability_checks_description": "Automatiser oppdaging og prioritet av tilgjengelege maskinlÃĻrings-serverar", + "machine_learning_availability_checks_enabled": "SlÃĨ pÃĨ tilgjengelegheitssjekkar", "machine_learning_availability_checks_interval": "Sjekk intervall", + "machine_learning_availability_checks_timeout": "Tidsavbrot pÃĨ forespørsel", "machine_learning_availability_checks_timeout_description": "Utløpstid i millisekund for tilgjengelegheitssjekk", "machine_learning_clip_model": "CLIP modell", "machine_learning_clip_model_description": "Namnet pÃĨ ein CLIP modell finst her. Merk at du mÃĨ køyre 'Smart Søk'-jobben pÃĨ nytt for alle bilete etter du har forandra modell.", @@ -151,6 +164,11 @@ "machine_learning_min_detection_score_description": "Minimum tillitspoeng for at eit ansikt skal bli oppdaga, pÃĨ ein skala frÃĨ 0 til 1. LÃĨgare verdiar vil oppdage fleire ansikt, men kan føre til feilaktige treff.", "machine_learning_min_recognized_faces": "Minimum gjenkjende ansikt", "machine_learning_min_recognized_faces_description": "Minste tal pÃĨ gjenkjende fjes for ÃĨ opprette ein person. Aukar ein dette, vert ansiktsgjenkjenninga meir presis, pÃĨ bekostning av auka sjanse for at ansikt ikkje vert tileigna ein person.", + "machine_learning_ocr": "OCR", + "machine_learning_ocr_description": "Bruk maskinlÃĻring for ÃĨ gjenkjenne tekst i bilete", + "machine_learning_ocr_enabled": "SlÃĨ pÃĨ OCR", + "machine_learning_ocr_max_resolution": "Maksimal oppløysing", + "machine_learning_ocr_model": "OCR-modell", "machine_learning_settings": "Innstillingar for maskinlÃĻring", "machine_learning_settings_description": "Administrer maskinlÃĻringsfunksjonar og innstillingar", "machine_learning_smart_search": "Smart Søk", diff --git a/i18n/package.json b/i18n/package.json index a654f8715f..2b9548ed8b 100644 --- a/i18n/package.json +++ b/i18n/package.json @@ -1,6 +1,6 @@ { "name": "immich-i18n", - "version": "2.6.2", + "version": "2.7.5", "private": true, "scripts": { "format": "prettier --cache --check .", diff --git a/i18n/pl.json b/i18n/pl.json index d123d17077..98cd5296bc 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -91,7 +91,7 @@ "failed_job_command": "Polecenie {command} nie powiodło się dla zadania: {job}", "force_delete_user_warning": "UWAGA: UÅŧytkownik i wszystkie zasoby uÅŧytkownika zostaną natychmiast trwale usunięte. Nie moÅŧna tego cofnąć, a plikÃŗw nie będzie moÅŧna przywrÃŗcić.", "image_format": "Format", - "image_format_description": "UÅŧycie formatu WebP skutkuje utworzeniem plikÃŗw o rozmiarze mniejszym niÅŧ w przypadku JPEG ale jego kodowanie trwa dłuÅŧej.", + "image_format_description": "Format WebP generuje mniejsze pliki niÅŧ JPEG, ale ich kodowanie trwa dłuÅŧej.", "image_fullsize_description": "Pełnowymiarowy obraz z usuniętymi metadanymi, uÅŧywany przy powiększeniu", "image_fullsize_enabled": "Włącz generowanie obrazÃŗw o pełnym wymiarze", "image_fullsize_enabled_description": "Generuje pełnowymiarowe obrazy dla formatÃŗw nieprzyjaznych stronom internetowym. Gdy opcja „Preferuj osadzony podgląd” jest włączona, osadzone podglądy są uÅŧywane bezpośrednio bez konwersji. Nie wpływa na formaty przyjazne stronom internetowym, takie jak JPEG.", @@ -138,7 +138,7 @@ "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", + "library_watching_settings_description": "Automatycznie poszukuj zmian w plikach", "logging_enable_description": "Uruchom zapisywanie logÃŗw", "logging_level_description": "Kiedy włączone, jakiego poziomu uÅŧyć.", "logging_settings": "Rejestrowanie logÃŗw", @@ -441,7 +441,7 @@ "user_successfully_removed": "UÅŧytkownik {email} został pomyślnie usunięty.", "users_page_description": "Strona administracyjna do zarządzania uÅŧytkownikami", "version_check_enabled_description": "Włącz sprawdzanie wersji", - "version_check_implications": "Funkcja sprawdzania wersji opiera się na okresowej komunikacji z github.com", + "version_check_implications": "Funkcja sprawdzania wersji opiera się na okresowej komunikacji z {server}", "version_check_settings": "Sprawdzenie Wersji", "version_check_settings_description": "Włącz/wyłącz powiadomienia o nowej wersji", "video_conversion_job": "Transkodowanie wideo", @@ -849,9 +849,12 @@ "create_link_to_share": "UtwÃŗrz link do udostępnienia", "create_link_to_share_description": "PozwÃŗl kaÅŧdemu z dostępem do linku zobaczyć wybrane zdjęcie/zdjęcia", "create_new": "UTWÓRZ NOWY", + "create_new_face": "UtwÃŗrz nową twarz", "create_new_person": "StwÃŗrz nową osobę", "create_new_person_hint": "Przypisz wybrane zasoby do nowej osoby", "create_new_user": "StwÃŗrz nowego uÅŧytkownika", + "create_person": "UtwÃŗrz osobę", + "create_person_subtitle": "Dodaj nazwę do wybranej twarzy aby utworzyć i oznaczyć nową osobę", "create_shared_album_page_share_add_assets": "DODAJ ZASOBY", "create_shared_album_page_share_select_photos": "Zaznacz Zdjęcia", "create_shared_link": "UtwÃŗrz link udostępniający", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Stałe", "crop_aspect_ratio_free": "Dowolne", "crop_aspect_ratio_original": "Oryginalne", + "crop_aspect_ratio_square": "Kwadrat", "curated_object_page_title": "Rzeczy", "current_device": "Obecne urządzenie", "current_pin_code": "Aktualny kod PIN", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Ciemny", - "dark_theme": "Przełącz ciemny motyw", + "dark_theme": "Przełącz na ciemny motyw", "date": "Data", "date_after": "Data po", "date_and_time": "Data i godzina", @@ -891,10 +895,8 @@ "day": "Dzień", "days": "Dni", "deduplicate_all": "Usuń duplikaty", - "deduplication_criteria_1": "Rozmiar obrazu w bajtach", - "deduplication_criteria_2": "Ilość plikÃŗw EXIF", - "deduplication_info": "Stan duplikatÃŗw", - "deduplication_info_description": "Aby zakwalifikować elementy jako duplikaty do masowego usunięcia, sprawdzane jest:", + "default_locale": "Domyślne ustawienia regionalne", + "default_locale_description": "Formatuj daty i liczby zgodnie z ustawieniami regionalnymi przeglądarki", "delete": "Usuń", "delete_action_confirmation_message": "Jesteś pewien, Åŧe chcesz usunąć ten zasÃŗb? Ta czynność przeniesie zasÃŗb do kosza na serwerze i wyświetli komunikat z pytaniem, czy chcesz go usunąć lokalnie", "delete_action_prompt": "{count} usuniętych", @@ -970,7 +972,7 @@ "downloading_media": "Pobieranie multimediÃŗw", "drop_files_to_upload": "Upuść pliki w dowolnym miejscu, aby je przesłać", "duplicates": "Duplikaty", - "duplicates_description": "Rozstrzygnij kaÅŧdą grupę, określając, ktÃŗre zasoby są duplikatami, jeÅŧeli są duplikatami", + "duplicates_description": "Rozstrzygnij kaÅŧdą grupę, określając, ktÃŗre zasoby są duplikatami, jeÅŧeli są duplikatami.", "duration": "Czas trwania", "edit": "Edytuj", "edit_album": "Edytuj album", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Zmiany zostały pomyślnie zastosowane", "editor_flip_horizontal": "OdwrÃŗÄ‡ poziomo", "editor_flip_vertical": "OdwrÃŗÄ‡ pionowo", + "editor_handle_corner": "{corner, select, top_left {GÃŗrny lewy} top_right {GÃŗrny prawy} bottom_left {Dolny lewy} bottom_right {Dolny prawy} other {Jakiś}} uchwyt naroÅŧny", + "editor_handle_edge": "{edge, select, top {GÃŗrny} bottom {Dolny} left {Lewy} right {Prawy} other {Jakiś}} uchwyt krawędziowy", "editor_orientation": "Orientacja", "editor_reset_all_changes": "Zresetuj zmiany", "editor_rotate_left": "ObrÃŗÄ‡ o 90° przeciwnie do ruchu wskazÃŗwek zegara", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Tytuł albumu", "licenses": "Licencje", "light": "Jasny", + "light_theme": "Przełącz na jasny motyw", "like": "Polub", "like_deleted": "Polubienie usunięte", "link_motion_video": "Podłącz ruchome wideo", + "link_to_docs": "Więcej informacji znajdziesz w dokumentacji.", "link_to_oauth": "Połącz z OAuth", "linked_oauth_account": "Połączone konto OAuth", "list": "Lista", @@ -1567,7 +1573,7 @@ "network_requirements_updated": "Zmieniono wymagania sieciowe, resetowanie kolejki kopii zapasowych", "networking_settings": "Sieć", "networking_subtitle": "Zarządzaj ustawieniami punktu końcowego serwera", - "never": "nigdy", + "never": "Nigdy", "new_album": "Nowy album", "new_api_key": "Nowy Klucz API", "new_date_range": "Nowy zakres dat", @@ -2211,18 +2217,19 @@ "tag": "Etykieta", "tag_assets": "Ustaw etykiety zasobÃŗw", "tag_created": "Stworzono etykietę: {tag}", + "tag_face": "Oznacz twarz", "tag_feature_description": "Przeglądanie zdjęć i filmÃŗw pogrupowanych według logicznych etykiet wskazujących temat", "tag_not_found_question": "Nie moÅŧesz znaleÅēć etykiety? UtwÃŗrz ją tutaj", "tag_people": "Dodaj etykiety osÃŗb", "tag_updated": "Uaktualniono etykietę: {tag}", "tagged_assets": "Przypisano etykietę {count, plural, one {# zasobowi} other {# zasobom}}", "tags": "Etykiety", - "tap_to_run_job": "Uruchom zadanie", + "tap_to_run_job": "Naciśnij, Åŧeby uruchomić zadanie", "template": "Szablon", "text_recognition": "Rozpoznawanie tekstu", "theme": "Motyw", "theme_selection": "WybÃŗr motywu", - "theme_selection_description": "Automatycznie zmień motyw na jasny lub ciemny zaleÅŧnie od ustawień przeglądarki", + "theme_selection_description": "Automatycznie zmień motyw na jasny lub ciemny zaleÅŧnie od ustawień systemu", "theme_setting_asset_list_storage_indicator_title": "PokaÅŧ wskaÅēnik przechowywania na kafelkach zasobÃŗw", "theme_setting_asset_list_tiles_per_row_title": "Liczba zasobÃŗw w wierszu ({count})", "theme_setting_colorful_interface_subtitle": "Zastosuj kolor podstawowy do powierzchni tła.", @@ -2392,6 +2399,7 @@ "viewer_remove_from_stack": "Usuń ze stosu", "viewer_stack_use_as_main_asset": "UÅŧyj jako gÅ‚Ãŗwnego zasobu", "viewer_unstack": "Rozdziel stos", + "visibility": "Widoczność", "visibility_changed": "Zmieniono widoczność dla {count, plural, one {# osoby} other {# osÃŗb}}", "visual": "Wizualny", "visual_builder": "Edytor wizualny", diff --git a/i18n/pt.json b/i18n/pt.json index e4822f12ff..7511ed58a5 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -441,7 +441,7 @@ "user_successfully_removed": "O utilizador {email} foi removido com sucesso.", "users_page_description": "PÃĄgina de administador de utilizadores", "version_check_enabled_description": "Ativa verificaÃ§ÃŖo de novas versÃĩes", - "version_check_implications": "A funcionalidade de verificaÃ§ÃŖo da versÃŖo necessita de comunicaÃ§ÃŖo periÃŗdica com o github.com", + "version_check_implications": "A funcionalidade de verificaÃ§ÃŖo da versÃŖo necessita de comunicaÃ§ÃŖo periÃŗdica com o {server}", "version_check_settings": "VerificaÃ§ÃŖo de versÃŖo", "version_check_settings_description": "Ativar/desativar a notificaÃ§ÃŖo de nova versÃŖo", "video_conversion_job": "Transcodificar vídeos", @@ -849,9 +849,12 @@ "create_link_to_share": "Criar link para partilhar", "create_link_to_share_description": "Permitir a visualizaÃ§ÃŖo desta(s) imagem(s) a qualquer pessoa com o link", "create_new": "CRIAR NOVO", + "create_new_face": "Criar novo rosto", "create_new_person": "Criar nova pessoa", "create_new_person_hint": "Associe os ficheiros a uma nova pessoa", "create_new_user": "Criar novo utilizador", + "create_person": "Criar pessoa", + "create_person_subtitle": "Adicione um nome ao rosto selecionado para criar e etiquetar a nova pessoa", "create_shared_album_page_share_add_assets": "ADICIONAR FICHEIROS", "create_shared_album_page_share_select_photos": "Selecionar Fotos", "create_shared_link": "Criar link partilhado", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixo", "crop_aspect_ratio_free": "Livre", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Quadrado", "curated_object_page_title": "Objetos", "current_device": "Dispositivo atual", "current_pin_code": "CÃŗdigo PIN atual", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Escuro", - "dark_theme": "Alternar tema escuro", + "dark_theme": "Alterar para o tema escuro", "date": "Data", "date_after": "Data apÃŗs", "date_and_time": "Data e Hora", @@ -891,10 +895,8 @@ "day": "Dia", "days": "Dias", "deduplicate_all": "Remover todos os duplicados", - "deduplication_criteria_1": "Tamanho da imagem em bytes", - "deduplication_criteria_2": "Quantidade de dados EXIF", - "deduplication_info": "InformaçÃĩes sobre remoÃ§ÃŖo de duplicados", - "deduplication_info_description": "Para selecionar automaticamente itens e remover duplicados em massa, iremos ver o seguinte:", + "default_locale": "LocalizaÃ§ÃŖo PadrÃŖo", + "default_locale_description": "Formatar datas e nÃēmeros baseados na definiÃ§ÃŖo de localizaÃ§ÃŖo do navegador", "delete": "Eliminar", "delete_action_confirmation_message": "Tem a certeza de que quer eliminar este ficheiro? EstÃĄ aÃ§ÃŖo irÃĄ mover o ficheiro para a reciclagem do servidor e perguntar se quer apagÃĄ-lo localmente", "delete_action_prompt": "{count} eliminados", @@ -970,7 +972,7 @@ "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", + "duplicates_description": "Marca cada grupo ao indicar quais ficheiros, se algum, sÃŖo duplicados.", "duration": "DuraÃ§ÃŖo", "edit": "Editar", "edit_album": "Editar ÃĄlbum", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Título do ÃĄlbum", "licenses": "Licenças", "light": "Claro", + "light_theme": "Alterar para o tema claro", "like": "Gosto", "like_deleted": "Gosto removido", "link_motion_video": "Relacionar video animado", + "link_to_docs": "Para mais informaçÃĩes, veja a documentaÃ§ÃŖo.", "link_to_oauth": "Link do OAuth", "linked_oauth_account": "Conta OAuth Associada", "list": "Lista", @@ -1651,6 +1655,7 @@ "only_favorites": "Apenas favoritos", "open": "Abrir", "open_calendar": "Abrir calendÃĄrio", + "open_in_browser": "Abrir no navegador", "open_in_map_view": "Abrir na visualizaÃ§ÃŖo de mapa", "open_in_openstreetmap": "Abrir no OpenStreetMap", "open_the_search_filters": "Abrir os filtros de pesquisa", @@ -2212,6 +2217,7 @@ "tag": "Etiqueta", "tag_assets": "Etiquetar ficheiros", "tag_created": "Criada a etiqueta {tag}", + "tag_face": "Etiquetar rosto", "tag_feature_description": "A mostrar fotos e videos agrupados por tÃŗpicos lÃŗgicos de etiquetas", "tag_not_found_question": "NÃŖo consegue encontrar a etiqueta? Crie uma nova etiqueta.", "tag_people": "Etiquetar Pessoas", @@ -2393,6 +2399,7 @@ "viewer_remove_from_stack": "Remover da pilha", "viewer_stack_use_as_main_asset": "Usar como foto principal", "viewer_unstack": "Desempilhar", + "visibility": "Visibilidade", "visibility_changed": "Visibilidade alterada para {count, plural, one {# pessoa} other {# pessoas}}", "visual": "Visual", "visual_builder": "Construtor visual", diff --git a/i18n/pt_BR.json b/i18n/pt_BR.json index b35fa25b4b..20d376289f 100644 --- a/i18n/pt_BR.json +++ b/i18n/pt_BR.json @@ -441,7 +441,7 @@ "user_successfully_removed": "UsuÃĄrio {email} foi removido com sucesso.", "users_page_description": "PÃĄgina de usuÃĄrios Admin", "version_check_enabled_description": "Ativa a verificaÃ§ÃŖo de versÃŖo", - "version_check_implications": "A verificaÃ§ÃŖo de versÃŖo depende de uma comunicaÃ§ÃŖo periÃŗdica com github.com", + "version_check_implications": "A verificaÃ§ÃŖo de versÃŖo depende de uma comunicaÃ§ÃŖo periÃŗdica com {server}", "version_check_settings": "VerificaÃ§ÃŖo de versÃŖo", "version_check_settings_description": "Ativar/desativar a notificaÃ§ÃŖo de nova versÃŖo", "video_conversion_job": "Transcodificar vídeos", @@ -866,6 +866,7 @@ "crop_aspect_ratio_fixed": "Fixo", "crop_aspect_ratio_free": "Livre", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Quadrado", "curated_object_page_title": "Objetos", "current_device": "Dispositivo atual", "current_pin_code": "CÃŗdigo PIN atual", @@ -891,10 +892,7 @@ "day": "Dia", "days": "Dias", "deduplicate_all": "Limpar todas Duplicidades", - "deduplication_criteria_1": "Tamanho do arquivo em bytes", - "deduplication_criteria_2": "Quantidade de dados EXIF", - "deduplication_info": "InformaçÃĩes", - "deduplication_info_description": "Ao selecionar os arquivos que serÃŖo marcados para remoÃ§ÃŖo por duplicidade, serÃĄ considerado os parÃĸmetros:", + "default_locale": "Local padrÃŖo", "delete": "Excluir", "delete_action_confirmation_message": "Tem certeza? O arquivo serÃĄ enviado para a lixeira do servidor, depois vocÃĒ poderÃĄ confirmar se deseja tambÊm deletar do seu dispositivo local", "delete_action_prompt": "{count} deletados", @@ -1387,9 +1385,11 @@ "library_page_sort_title": "Título do ÃĄlbum", "licenses": "Licenças", "light": "Claro", + "light_theme": "Mudar para tema claro", "like": "Curtir", "like_deleted": "Curtida excluída", "link_motion_video": "Relacionar video animado", + "link_to_docs": "Para mais informaçÃĩes, veja", "link_to_oauth": "Link do OAuth", "linked_oauth_account": "Conta OAuth Vinculada", "list": "Lista", @@ -2394,6 +2394,7 @@ "viewer_remove_from_stack": "Remover do grupo", "viewer_stack_use_as_main_asset": "Usar como foto principal", "viewer_unstack": "Desagrupar", + "visibility": "Visibilidade", "visibility_changed": "A visibilidade de {count, plural, one {# pessoa foi alterada} other {# pessoas foram alteradas}}", "visual": "Visual", "visual_builder": "Construtor visual", diff --git a/i18n/ro.json b/i18n/ro.json index 9e097b4d20..a4f7e94eaa 100644 --- a/i18n/ro.json +++ b/i18n/ro.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Utilizatorul {email} a fost șters cu succes.", "users_page_description": "Pagina utilizatorilor administratori", "version_check_enabled_description": "Activează verificarea versiunii", - "version_check_implications": "Funcția de verificare a versiunii se bazează pe comunicarea periodică cu github.com", + "version_check_implications": "Funcția de verificare a versiunii se bazează pe comunicarea periodică cu {server}", "version_check_settings": "Verificare versiune", "version_check_settings_description": "ActiveazĮŽ/dezactiveazĮŽ notificarea unei noi versiuni", "video_conversion_job": "Transcodați videoclipuri", @@ -866,6 +866,7 @@ "crop_aspect_ratio_fixed": "Reparat", "crop_aspect_ratio_free": "Liber", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Pătrat", "curated_object_page_title": "Obiecte", "current_device": "Dispozitiv curent", "current_pin_code": "Codul PIN actual", @@ -880,7 +881,7 @@ "daily_title_text_date": "E, LLL zz", "daily_title_text_date_year": "E, LLL zz, aaaa", "dark": "Întunecat", - "dark_theme": "Comută tema ÃŽntunecată", + "dark_theme": "Comută la tema ÃŽntunecată", "date": "Dată", "date_after": "După data", "date_and_time": "Dată și oră", @@ -891,10 +892,8 @@ "day": "Zi", "days": "Zile", "deduplicate_all": "Deduplicați Toate", - "deduplication_criteria_1": "Marimea imagini ÃŽn octeți", - "deduplication_criteria_2": "Numărul de date EXIF", - "deduplication_info": "Informați despre deduplicare", - "deduplication_info_description": "Ca să preselecționăm activele și să scoatem duplicatele ÃŽn vrac , ne uităm la:", + "default_locale": "Localizare implicită", + "default_locale_description": "Formatează datele și numerele ÃŽn funcție de localizarea browser-ului", "delete": "Ștergere", "delete_action_confirmation_message": "Sigur vrei să ștergi acest element? Această acțiune va muta elementul ÃŽn coșul de gunoi al serverului și te va ÃŽntreba dacă vrei să-l ștergi local", "delete_action_prompt": "{count} șterse", @@ -970,7 +969,7 @@ "downloading_media": "Se descarcă fișierele media", "drop_files_to_upload": "Trageți fișierele aici pentru a le ÃŽncărca", "duplicates": "Duplicate", - "duplicates_description": "Rezolvați fiecare grup indicÃĸnd care sunt duplicate, dacă există", + "duplicates_description": "Rezolvați fiecare grup indicÃĸnd care sunt duplicate, dacă există.", "duration": "Durată", "edit": "Editare", "edit_album": "Editare album", diff --git a/i18n/ru.json b/i18n/ru.json index d1958d76e6..799861ebc2 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -441,7 +441,7 @@ "user_successfully_removed": "ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ {email} ҃ҁĐŋĐĩ҈ĐŊĐž ŅƒĐ´Đ°ĐģĐĩĐŊ.", "users_page_description": "ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧи ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹", "version_check_enabled_description": "ВĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ ĐŊаĐģĐ¸Ņ‡Đ¸Ņ ĐŊĐžĐ˛Ņ‹Ņ… вĐĩŅ€ŅĐ¸Đš", - "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи вĐĩŅ€ŅĐ¸Đ¸ ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐĩҁĐēи ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ Đē ŅĐ°ĐšŅ‚Ņƒ github.com", + "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи вĐĩŅ€ŅĐ¸Đ¸ ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐĩҁĐēи ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ Đē ŅĐ°ĐšŅ‚Ņƒ {server}", "version_check_settings": "ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа вĐĩŅ€ŅĐ¸Đ¸", "version_check_settings_description": "ВĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ/ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊиĐĩ Đž ĐŊОвОК вĐĩŅ€ŅĐ¸Đ¸", "video_conversion_job": "ПĐĩŅ€ĐĩĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ видĐĩĐž", @@ -849,9 +849,12 @@ "create_link_to_share": "ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ҁҁҋĐģĐē҃ ĐžĐąŅ‰ĐĩĐŗĐž Đ´ĐžŅŅ‚ŅƒĐŋа", "create_link_to_share_description": "Đ Đ°ĐˇŅ€ĐĩŅˆĐ¸Ņ‚ŅŒ Đ˛ŅĐĩĐŧ, ҃ ĐēĐžĐŗĐž ĐĩŅŅ‚ŅŒ ҁҁҋĐģĐēа, ĐŋŅ€ĐžŅĐŧĐ°Ņ‚Ņ€Đ¸Đ˛Đ°Ņ‚ŅŒ Đ˛Ņ‹ĐąŅ€Đ°ĐŊĐŊŅ‹Đĩ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Đ¸", "create_new": "СОЗДАĐĸĐŦ НОВĐĢЙ", + "create_new_face": "ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŊОвОĐĩ ĐģĐ¸Ņ†Đž", "create_new_person": "Đ”ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŊĐžĐ˛ĐžĐŗĐž ҇ĐĩĐģОвĐĩĐēа", "create_new_person_hint": "НазĐŊĐ°Ņ‡Đ¸Ņ‚ŅŒ Đ˛Ņ‹ĐąŅ€Đ°ĐŊĐŊŅ‹Đĩ ĐžĐąŅŠĐĩĐē҂ҋ ĐŊа ĐŊĐžĐ˛ĐžĐŗĐž ҇ĐĩĐģОвĐĩĐēа", "create_new_user": "ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŊĐžĐ˛ĐžĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ", + "create_person": "ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ҇ĐĩĐģОвĐĩĐēа", + "create_person_subtitle": "ĐŖĐēаĐļĐ¸Ņ‚Đĩ иĐŧŅ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ҇ĐĩĐģОвĐĩĐēа", "create_shared_album_page_share_add_assets": "ДОБАВИĐĸĐŦ ОБĐĒЕКĐĸĐĢ", "create_shared_album_page_share_select_photos": "Đ’Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Đ¸", "create_shared_link": "ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐžĐąŅ‰ŅƒŅŽ ҁҁҋĐģĐē҃", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "ФиĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš", "crop_aspect_ratio_free": "ХвОйОдĐŊĐž", "crop_aspect_ratio_original": "ĐžŅ€Đ¸ĐŗĐ¸ĐŊаĐģ", + "crop_aspect_ratio_square": "ĐšĐ˛Đ°Đ´Ņ€Đ°Ņ‚", "curated_object_page_title": "ĐŸŅ€ĐĩĐ´ĐŧĐĩ҂ҋ", "current_device": "ĐĸĐĩĐēŅƒŅ‰ĐĩĐĩ ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đž", "current_pin_code": "ĐĸĐĩĐēŅƒŅ‰Đ¸Đš PIN-ĐēОд", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "ĐĸŅ‘ĐŧĐŊĐ°Ņ", - "dark_theme": "ВĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ/Đ˛Ņ‹ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ҂ґĐŧĐŊŅƒŅŽ Ņ‚ĐĩĐŧ҃", + "dark_theme": "ПĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа ҂ґĐŧĐŊŅƒŅŽ Ņ‚ĐĩĐŧ҃", "date": "Đ”Đ°Ņ‚Đ°", "date_after": "Đ”Đ°Ņ‚Đ° ĐŋĐžŅĐģĐĩ", "date_and_time": "Đ”Đ°Ņ‚Đ° и Đ˛Ņ€ĐĩĐŧŅ", @@ -891,10 +895,8 @@ "day": "ДĐĩĐŊҌ", "days": "ДĐŊи", "deduplicate_all": "ĐŖĐąŅ€Đ°Ņ‚ŅŒ Đ˛ŅĐĩ Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Ņ‹", - "deduplication_criteria_1": "РаСĐŧĐĩŅ€ Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐ¸Ņ в ĐąĐ°ĐšŅ‚Đ°Ņ…", - "deduplication_criteria_2": "КоĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž EXIF даĐŊĐŊҋ҅", - "deduplication_info": "ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Đž Đ´ĐĩĐ´ŅƒĐŋĐģиĐēĐ°Ņ†Đ¸Đ¸", - "deduplication_info_description": "ДĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž Đ˛Ņ‹ĐąĐžŅ€Đ° ĐģŅƒŅ‡ŅˆĐ¸Ņ… ĐžĐąŅŠĐĩĐēŅ‚ĐžĐ˛ ҁҀĐĩди Đ´ŅƒĐąĐģиĐēĐ°Ņ‚ĐžĐ˛ аĐŊаĐģĐ¸ĐˇĐ¸Ņ€ŅƒĐĩŅ‚ŅŅ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ:", + "default_locale": "ЛоĐēаĐģҌ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ", + "default_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Đ´Đ°Ņ‚ и Ņ‡Đ¸ŅĐĩĐģ в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ҁ ŅĐˇŅ‹ĐēĐžĐ˛Ņ‹Đŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи Đ˛Đ°ŅˆĐĩĐŗĐž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°", "delete": "ĐŖĐ´Đ°ĐģĐ¸Ņ‚ŅŒ", "delete_action_confirmation_message": "Đ’Ņ‹ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐžĐąŅŠĐĩĐēŅ‚? Đ­Ņ‚Đž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đĩ ĐŋĐĩŅ€ĐĩĐŧĐĩŅŅ‚Đ¸Ņ‚ ĐžĐąŅŠĐĩĐēŅ‚ в ĐēĐžŅ€ĐˇĐ¸ĐŊ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и ĐŋĐžĐŋŅ€ĐžĐąŅƒĐĩŅ‚ ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ ĐĩĐŗĐž ĐģĐžĐēаĐģҌĐŊĐž.", "delete_action_prompt": "ĐžĐąŅŠĐĩĐē҂ҋ ŅƒĐ´Đ°ĐģĐĩĐŊŅ‹ ({count} ŅˆŅ‚.)", @@ -970,7 +972,7 @@ "downloading_media": "Đ—Đ°ĐŗŅ€ŅƒĐˇĐēа ĐŧĐĩдиа", "drop_files_to_upload": "ПĐĩŅ€ĐĩĐŊĐĩŅĐ¸Ņ‚Đĩ Ņ„Đ°ĐšĐģŅ‹ в ĐģŅŽĐąĐžĐĩ ĐŧĐĩŅŅ‚Đž Đ´ĐģŅ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи", "duplicates": "Đ”ŅƒĐąĐģиĐēĐ°Ņ‚Ņ‹", - "duplicates_description": "ĐŸŅ€ĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐŊаКдĐĩĐŊĐŊŅ‹Đĩ Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Ņ‹ и в ĐēаĐļдОК ĐŗŅ€ŅƒĐŋĐŋĐĩ ҃ĐēаĐļĐ¸Ņ‚Đĩ, ĐēаĐēиĐĩ ĐžĐąŅŠĐĩĐē҂ҋ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ, а ĐēаĐēиĐĩ ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ", + "duplicates_description": "ĐŸŅ€ĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐŊаКдĐĩĐŊĐŊŅ‹Đĩ Đ´ŅƒĐąĐģиĐēĐ°Ņ‚Ņ‹ и в ĐēаĐļдОК ĐŗŅ€ŅƒĐŋĐŋĐĩ ҃ĐēаĐļĐ¸Ņ‚Đĩ, ĐēаĐēиĐĩ ĐžĐąŅŠĐĩĐē҂ҋ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ, а ĐēаĐēиĐĩ ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ.", "duration": "ĐŸŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ", "edit": "ИСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ", "edit_album": "ИСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "НазваĐŊиĐĩ аĐģŅŒĐąĐžĐŧа", "licenses": "Đ›Đ¸Ņ†ĐĩĐŊСии", "light": "ХвĐĩŅ‚ĐģĐ°Ņ", + "light_theme": "ПĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа ŅĐ˛ĐĩŅ‚ĐģŅƒŅŽ Ņ‚ĐĩĐŧ҃", "like": "ĐŅ€Đ°Đ˛Đ¸Ņ‚ŅŅ", "like_deleted": "ЛайĐē ŅƒĐ´Đ°ĐģĐĩĐŊ", "link_motion_video": "ĐĄŅŅ‹ĐģĐēа ĐŊа двиĐļŅƒŅ‰ĐĩĐĩŅŅ видĐĩĐž", + "link_to_docs": "ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Đ´ĐžŅŅ‚ŅƒĐŋĐŊа в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸.", "link_to_oauth": "ĐŸŅ€Đ¸ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ Đē OAuth", "linked_oauth_account": "ĐŸŅ€Đ¸ŅĐžĐĩдиĐŊŅ‘ĐŊĐŊŅ‹Đš аĐēĐēĐ°ŅƒĐŊŅ‚ OAuth", "list": "ĐĄĐŋĐ¸ŅĐžĐē", @@ -1915,7 +1919,7 @@ "saved_settings": "ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи ŅĐžŅ…Ņ€Đ°ĐŊĐĩĐŊŅ‹", "say_something": "НаĐŋĐ¸ŅˆĐ¸Ņ‚Đĩ Ņ‡Ņ‚Đž-ĐŊĐ¸ĐąŅƒĐ´ŅŒ", "scaffold_body_error_occurred": "ВозĐŊиĐēĐģа ĐžŅˆĐ¸ĐąĐēа", - "scaffold_body_error_unrecoverable": "ĐŸŅ€ĐžĐ¸ĐˇĐžŅˆĐģа ĐŊĐĩŅƒŅŅ‚Ņ€Đ°ĐŊиĐŧĐ°Ņ ĐžŅˆĐ¸ĐąĐēа. ПоĐļаĐģŅƒĐšŅŅ‚Đ°, ŅĐžĐžĐąŅ‰Đ¸Ņ‚Đĩ Ой ĐžŅˆĐ¸ĐąĐēĐĩ в Discord иĐģи ĐŊа GitHub, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŧĐžĐŗĐģи ĐŋĐžĐŧĐžŅ‡ŅŒ. Đ•ŅĐģи ŅĐžĐ˛ĐĩŅ‚ŅƒŅŽŅ‚, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ.", + "scaffold_body_error_unrecoverable": "ĐŸŅ€ĐžĐ¸ĐˇĐžŅˆĐģа ĐŊĐĩŅƒŅŅ‚Ņ€Đ°ĐŊиĐŧĐ°Ņ ĐžŅˆĐ¸ĐąĐēа. ПоĐļаĐģŅƒĐšŅŅ‚Đ°, ŅĐžĐžĐąŅ‰Đ¸Ņ‚Đĩ Ой ŅŅ‚ĐžĐš ĐžŅˆĐ¸ĐąĐēĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧ в Discord иĐģи ĐŊа GitHub. В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ ĐŧĐžĐļĐŊĐž ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ.", "scan": "ĐŸĐžĐ¸ŅĐē", "scan_all_libraries": "ĐĄĐēаĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи", "scan_library": "ĐĄĐēаĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ", @@ -2213,6 +2217,7 @@ "tag": "ĐĸĐĩĐŗ", "tag_assets": "Đ”ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ‚ĐĩĐŗĐ¸", "tag_created": "ĐĸĐĩĐŗ {tag} ŅĐžĐˇĐ´Đ°ĐŊ", + "tag_face": "ĐžŅ‚ĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ ҇ĐĩĐģОвĐĩĐēа", "tag_feature_description": "ĐŸŅ€ĐžŅĐŧĐžŅ‚Ņ€ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Đš и видĐĩĐž, ŅĐŗŅ€ŅƒĐŋĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐŋĐž Ņ‚ĐĩĐŗĐ°Đŧ", "tag_not_found_question": "НĐĩ ŅƒĐ´Đ°ĐĩŅ‚ŅŅ ĐŊĐ°ĐšŅ‚Đ¸ Ņ‚ĐĩĐŗ? ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŊĐžĐ˛Ņ‹Đš Ņ‚ĐĩĐŗ.", "tag_people": "ĐžŅ‚ĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ ҇ĐĩĐģОвĐĩĐēа", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "ĐŖĐąŅ€Đ°Ņ‚ŅŒ иС ĐŗŅ€ŅƒĐŋĐŋŅ‹", "viewer_stack_use_as_main_asset": "Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ°", "viewer_unstack": "Đ Đ°ĐˇĐŗŅ€ŅƒĐŋĐŋĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ", + "visibility": "ВидиĐŧĐžŅŅ‚ŅŒ", "visibility_changed": "ИСĐŧĐĩĐŊĐĩĐŊа видиĐŧĐžŅŅ‚ŅŒ ҃ {count, plural, one {# ҇ĐĩĐģОвĐĩĐēа} other {# ҇ĐĩĐģОвĐĩĐē}}", "visual": "Đ’Đ¸ĐˇŅƒĐ°ĐģҌĐŊŅ‹Đš", "visual_builder": "Đ’Đ¸ĐˇŅƒĐ°ĐģҌĐŊŅ‹Đš ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ‚ĐžŅ€", diff --git a/i18n/sk.json b/i18n/sk.json index 6235815c2b..d18c2fc23b 100644 --- a/i18n/sk.json +++ b/i18n/sk.json @@ -441,7 +441,7 @@ "user_successfully_removed": "PouŞívateÄž {email} bol ÃēspeÅĄne odstrÃĄnenÃŊ.", "users_page_description": "StrÃĄnka pouŞívateÄžov pre sprÃĄvcu", "version_check_enabled_description": "PovoliÅĨ kontrolu verzie", - "version_check_implications": "Funkcia kontroly verzie sa spolieha na pravidelnÃē komunikÃĄciu s github.com", + "version_check_implications": "Funkcia kontroly verzie sa spolieha na pravidelnÃē komunikÃĄciu s {server}", "version_check_settings": "Kontrola verzie", "version_check_settings_description": "PovoliÅĨ/zakÃĄzaÅĨ upozornenia na novÃē verziu", "video_conversion_job": "PrekÃŗdovaÅĨ videÃĄ", @@ -849,9 +849,12 @@ "create_link_to_share": "VytvoriÅĨ odkaz na zdieÄžanie", "create_link_to_share_description": "UmoÅžniÅĨ kaÅždÊmu, kto mÃĄ odkaz, zobraziÅĨ vybranÊ fotografie", "create_new": "VYTVORIŤ NOVÉ", + "create_new_face": "VytvoriÅĨ novÃē tvÃĄr", "create_new_person": "VytvoriÅĨ novÃē osobu", "create_new_person_hint": "PriradiÅĨ vybranÊ poloÅžky novej osobe", "create_new_user": "Vytvorenie novÊho pouŞívateÄža", + "create_person": "VytvoriÅĨ osobu", + "create_person_subtitle": "Pridajte meno k vybranej tvÃĄri, aby ste vytvorili a označili novÃē osobu", "create_shared_album_page_share_add_assets": "PRIDAŤ POLOÅŊKY", "create_shared_album_page_share_select_photos": "VybraÅĨ fotografie", "create_shared_link": "VytvoriÅĨ zdieÄžanÃŊ odkaz", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "PevnÃŊ pomer", "crop_aspect_ratio_free": "VoÄžnÃŊ", "crop_aspect_ratio_original": "OriginÃĄlny", + "crop_aspect_ratio_square": "Å tvorec", "curated_object_page_title": "Veci", "current_device": "SÃēčasnÊ zariadenie", "current_pin_code": "AktuÃĄlny PIN kÃŗd", @@ -880,7 +884,7 @@ "daily_title_text_date": "EEEE, d. MMMM", "daily_title_text_date_year": "EEEE, d. MMMM y", "dark": "TmavÃĄ", - "dark_theme": "PrepnÃēÅĨ tmavÃē tÊmu", + "dark_theme": "PrepnÃēÅĨ na tmavÃē tÊmu", "date": "DÃĄtum", "date_after": "DÃĄtum po", "date_and_time": "DÃĄtum a Čas", @@ -891,10 +895,8 @@ "day": "Deň", "days": "Dní", "deduplicate_all": "DeduplikovaÅĨ vÅĄetko", - "deduplication_criteria_1": "VeÄžkosÅĨ obrÃĄzku v bajtoch", - "deduplication_criteria_2": "Počet EXIF Ãēdajov", - "deduplication_info": "Info o deduplikÃĄcii", - "deduplication_info_description": "Na automatickÃŊ predvÃŊber poloÅžiek a hromadnÊ odstrÃĄnenie duplicít, sa pozerÃĄme do:", + "default_locale": "PredvolenÃŊ jazyk", + "default_locale_description": "FormÃĄtovaÅĨ dÃĄtumy a čísla podÄža jazyka vÃĄÅĄho prehliadača", "delete": "VymazaÅĨ", "delete_action_confirmation_message": "Naozaj chcete tÃēto poloÅžku odstrÃĄniÅĨ? TÃĄto akcia presunie poloÅžku do koÅĄa na serveri a zobrazí sa otÃĄzka, či ju chcete odstrÃĄniÅĨ aj lokÃĄlne", "delete_action_prompt": "{count} vymazanÃŊch", @@ -970,7 +972,7 @@ "downloading_media": "SÅĨahovanie mÊdií", "drop_files_to_upload": "Umiestnite sÃēbory kamkoÄžvek na nahratie", "duplicates": "DuplikÃĄty", - "duplicates_description": "VysporiadaÅĨ sa s kaÅždou skupinou tak, Åže sa duplicitnÊ označia ako duplicitnÊ", + "duplicates_description": "VyrieÅĄiÅĨ jednotlivÊ skupiny tak, Åže sa označia tie, ktorÊ z nich sÃē duplicitnÊ, ak nejakÊ sÃē.", "duration": "Trvanie", "edit": "UpraviÅĨ", "edit_album": "UpraviÅĨ album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "PodÄža nÃĄzvu albumu", "licenses": "Licencie", "light": "SvetlÃĄ", + "light_theme": "PrepnÃēÅĨ na svetlÃē tÊmu", "like": "PÃĄÄi sa mi", "like_deleted": "Like odstrÃĄnenÃŊ", "link_motion_video": "PripojiÅĨ pohyblivÊ video", + "link_to_docs": "ĎalÅĄie informÃĄcie nÃĄjdete v dokumentÃĄcii.", "link_to_oauth": "PrepojiÅĨ s OAuth", "linked_oauth_account": "PripojenÃŊ OAuth Ãēčet", "list": "Zoznam", @@ -2213,6 +2217,7 @@ "tag": "Å títok", "tag_assets": "PridaÅĨ ÅĄtítky", "tag_created": "VytvorenÃŊ ÅĄtítok: {tag}", + "tag_face": "OznačiÅĨ tvÃĄr", "tag_feature_description": "Prehliadanie fotiek a videÃĄ zoskupenÃŊch podÄža tematickÃŊch ÅĄtítkov", "tag_not_found_question": "Neviete nÃĄjsÅĨ ÅĄtítok? Vytvorte novÃŊ ÅĄtítok.", "tag_people": "OznačiÅĨ Äžudí", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "OdstrÃĄniÅĨ zo zoskupenia", "viewer_stack_use_as_main_asset": "PouÅžiÅĨ ako hlavnÃē fotku", "viewer_unstack": "ZruÅĄiÅĨ zoskupenie", + "visibility": "ViditeÄžnosÅĨ", "visibility_changed": "ViditeÄžnosÅĨ zmenenÃĄ pre {count, plural, one {# osobu} few {# osoby} other {# osôb}}", "visual": "VizuÃĄlny", "visual_builder": "VizuÃĄlny nÃĄstroj na tvorbu", diff --git a/i18n/sl.json b/i18n/sl.json index ce24a71fd3..fa6e04201e 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Uporabnik {email} je bil uspeÅĄno odstranjen.", "users_page_description": "Stran skrbniÅĄkih uporabnikov", "version_check_enabled_description": "Omogoči preverjanje različice", - "version_check_implications": "Funkcija preverjanja različic se opira na občasno komunikacijo z github.com", + "version_check_implications": "Funkcija preverjanja različic se opira na občasno komunikacijo z {server}", "version_check_settings": "Preverjanje različice", "version_check_settings_description": "Omogoči/onemogoči obvestilo o novi različici", "video_conversion_job": "Prekodiranje videoposnetkov", @@ -849,9 +849,12 @@ "create_link_to_share": "Ustvari povezavo za skupno rabo", "create_link_to_share_description": "Omogoči vsem s povezavo ogled izbranih fotografij", "create_new": "USTVARI NOVEGA", + "create_new_face": "Ustvari nov obraz", "create_new_person": "Ustvari novo osebo", "create_new_person_hint": "Dodeli izbrana sredstva novi osebi", "create_new_user": "Ustvari novega uporabnika", + "create_person": "Ustvari osebo", + "create_person_subtitle": "Dodajte ime izbranemu obrazu, da ustvarite in označite novo osebo", "create_shared_album_page_share_add_assets": "DODAJ SREDSTVA", "create_shared_album_page_share_select_photos": "Izberi fotografije", "create_shared_link": "Ustvari deljeno povezavo", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fiksno", "crop_aspect_ratio_free": "Poljubno", "crop_aspect_ratio_original": "Izvirno", + "crop_aspect_ratio_square": "Kvadrat", "curated_object_page_title": "Stvari", "current_device": "Trenutna naprava", "current_pin_code": "Trenutna PIN koda", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "Temno", - "dark_theme": "Preklopi temno temo", + "dark_theme": "Preklopi na temno temo", "date": "Datum", "date_after": "Datum po", "date_and_time": "Datum in ura", @@ -891,10 +895,8 @@ "day": "Dan", "days": "Dnevi", "deduplicate_all": "Odstrani vse podvojene", - "deduplication_criteria_1": "Velikost slike v bajtih", - "deduplication_criteria_2": "Å tevilo podatkov EXIF", - "deduplication_info": "Informacije o zaznavanju dvojnikov", - "deduplication_info_description": "Za samodejno vnaprejÅĄnjo izbiro sredstev in mnoÅžično odstranjevanje dvojnikov si ogledamo:", + "default_locale": "Privzete jezikovne nastavitve", + "default_locale_description": "Oblikujte datume in ÅĄtevilke glede na jezikovne nastavitve brskalnika", "delete": "IzbriÅĄi", "delete_action_confirmation_message": "Ali ste prepričani, da Åželite izbrisati to sredstvo? S tem dejanjem boste sredstvo premaknili v koÅĄ na streÅžniku in vas pozvali, ali ga Åželite izbrisati lokalno", "delete_action_prompt": "izbrisano {count}", @@ -970,7 +972,7 @@ "downloading_media": "PrenaÅĄanje medijev", "drop_files_to_upload": "Spustite datoteke kamor koli, da jih naloÅžite", "duplicates": "Dvojniki", - "duplicates_description": "RazreÅĄite vsako skupino tako, da navedete, kateri so dvojniki, če obstajajo", + "duplicates_description": "Vsako skupino razreÅĄite tako, da navedete, kateri so, če sploh, dvojniki.", "duration": "Trajanje", "edit": "Uredi", "edit_album": "Uredi album", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "Naslov albuma", "licenses": "Licence", "light": "Svetlo", + "light_theme": "Preklopi na svetlo temo", "like": "VÅĄeč mi je", "like_deleted": "VÅĄeček izbrisan", "link_motion_video": "Povezava videa gibanja", + "link_to_docs": "Za več informacij glejte dokumentacijo.", "link_to_oauth": "Povezava do OAuth", "linked_oauth_account": "Povezan račun OAuth", "list": "Seznam", @@ -2213,6 +2217,7 @@ "tag": "Oznaka", "tag_assets": "Označi sredstva", "tag_created": "Ustvarjena oznaka: {tag}", + "tag_face": "Označi obraz", "tag_feature_description": "Brskanje po fotografijah in videoposnetkih, razvrÅĄÄenih po temah logičnih oznak", "tag_not_found_question": "Ne najdete oznake? Ustvarite novo oznako.", "tag_people": "Označi osebe", @@ -2394,6 +2399,7 @@ "viewer_remove_from_stack": "Odstrani iz sklada", "viewer_stack_use_as_main_asset": "Uporabi kot glavno sredstvo", "viewer_unstack": "Razkladi", + "visibility": "Vidljivost", "visibility_changed": "Vidnost spremenjena za {count, plural, one {# osebo} two {# osebi} few {# osebe} other {# oseb}}", "visual": "Vizualno", "visual_builder": "Vizualni graditelj", diff --git a/i18n/sr_Cyrl.json b/i18n/sr_Cyrl.json index 00fc4b3087..1472b111a4 100644 --- a/i18n/sr_Cyrl.json +++ b/i18n/sr_Cyrl.json @@ -370,7 +370,7 @@ "user_settings": "ПодĐĩŅˆĐ°Đ˛Đ°ŅšĐ° ĐēĐžŅ€Đ¸ŅĐŊиĐēа", "user_settings_description": "ĐŖĐŋŅ€Đ°Đ˛Ņ™Đ°Ņ˜Ņ‚Đĩ ĐēĐžŅ€Đ¸ŅĐŊĐ¸Ņ‡ĐēиĐŧ ĐŋОдĐĩŅˆĐ°Đ˛Đ°ŅšĐ¸Đŧа", "version_check_enabled_description": "ОĐŧĐžĐŗŅƒŅ›Đ¸ ĐŋŅ€ĐžĐ˛ĐĩŅ€Ņƒ ĐŊĐžĐ˛Đ¸Ņ… Đ¸ĐˇĐ´Đ°ŅšĐ°", - "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° ĐŋŅ€ĐžĐ˛ĐĩŅ€Đĩ вĐĩŅ€ĐˇĐ¸Ņ˜Đĩ ҁĐĩ ĐžŅĐģĐ°ŅšĐ° ĐŊа ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐŊ҃ ĐēĐžĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Ņ˜Ņƒ ŅĐ° ĐŗĐ¸Ņ‚Ņ…ŅƒĐą.Ņ†ĐžĐŧ", + "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° ĐŋŅ€ĐžĐ˛ĐĩŅ€Đĩ вĐĩŅ€ĐˇĐ¸Ņ˜Đĩ ҁĐĩ ĐžŅĐģĐ°ŅšĐ° ĐŊа ĐŋĐĩŅ€Đ¸ĐžĐ´Đ¸Ņ‡ĐŊ҃ ĐēĐžĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Ņ˜Ņƒ ŅĐ° {server}", "version_check_settings": "ĐŸŅ€ĐžĐ˛ĐĩŅ€Đ° вĐĩŅ€ĐˇĐ¸Ņ˜Đĩ", "version_check_settings_description": "ОĐŧĐžĐŗŅƒŅ›Đ¸/ĐžĐŊĐĩĐŧĐžĐŗŅƒŅ›Đ¸ ОйавĐĩŅˆŅ‚ĐĩҚĐĩ Đž ĐŊĐžĐ˛ĐžŅ˜ вĐĩŅ€ĐˇĐ¸Ņ˜Đ¸", "video_conversion_job": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´Đ¸Ņ€Đ°ŅšĐĩ видĐĩĐž СаĐŋĐ¸ŅĐ°", @@ -733,10 +733,6 @@ "day": "ДаĐŊ", "days": "ДаĐŊи", "deduplicate_all": "ДĐĩ-Đ´ŅƒĐŋĐģĐ¸Ņ†Đ¸Ņ€Đ°Ņ˜ ŅĐ˛Đĩ", - "deduplication_criteria_1": "ВĐĩĐģĐ¸Ņ‡Đ¸ĐŊа ҁĐģиĐēĐĩ ҃ ĐąĐ°Ņ˜Ņ‚ĐžĐ˛Đ¸Đŧа", - "deduplication_criteria_2": "Đ‘Ņ€ĐžŅ˜ EXIF ĐŋĐžĐ´Đ°Ņ‚Đ°Đēа", - "deduplication_info": "ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ˜Đĩ Đž Đ´ĐĩĐ´ŅƒĐŋĐģиĐēĐ°Ņ†Đ¸Ņ˜Đ¸", - "deduplication_info_description": "Да ĐąĐ¸ŅĐŧĐž Đ°ŅƒŅ‚ĐžĐŧĐ°Ņ‚ŅĐēи ҃ĐŊаĐŋŅ€ĐĩĐ´ ĐžĐ´Đ°ĐąŅ€Đ°Đģи Đ´Đ°Ņ‚ĐžŅ‚ĐĩĐēĐĩ и ҃ĐēĐģĐžĐŊиĐģи Đ´ŅƒĐŋĐģиĐēĐ°Ņ‚Đĩ ĐŗŅ€ŅƒĐŋĐŊĐž, ĐŗĐģĐĩдаĐŧĐž:", "delete": "ĐžĐąŅ€Đ¸ŅˆĐ¸", "delete_album": "ĐžĐąŅ€Đ¸ŅˆĐ¸ аĐģĐąŅƒĐŧ", "delete_api_key_prompt": "Да Đģи ҁ҂Đĩ ŅĐ¸ĐŗŅƒŅ€ĐŊи да ĐļĐĩĐģĐ¸Ņ‚Đĩ да Đ¸ĐˇĐąŅ€Đ¸ŅˆĐĩŅ‚Đĩ ĐžĐ˛Đ°Ņ˜ АПИ ĐēŅ™ŅƒŅ‡ (ĐēĐĩy)?", diff --git a/i18n/sr_Latn.json b/i18n/sr_Latn.json index d09e1a1abf..b7f71ba4b8 100644 --- a/i18n/sr_Latn.json +++ b/i18n/sr_Latn.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Korisnik {email} je uspeÅĄno uklonjen.", "users_page_description": "Stranica administratorskih korisnika", "version_check_enabled_description": "Omogucˁite proveru novih izdanja", - "version_check_implications": "Funkcija provere verzije se oslanja na periodičnu komunikaciju sa github.com", + "version_check_implications": "Funkcija provere verzije se oslanja na periodičnu komunikaciju sa {server}", "version_check_settings": "Provera verzije", "version_check_settings_description": "Omogucˁite/onemogucˁite obaveÅĄtenje o novoj verziji", "video_conversion_job": "Transkodiranje video zapisa", @@ -879,10 +879,6 @@ "day": "Dan", "days": "Dani", "deduplicate_all": "De-dupliciraj sve", - "deduplication_criteria_1": "Veličina slike u bajtovima", - "deduplication_criteria_2": "Broj EXIF podataka", - "deduplication_info": "Informacije o deduplikaciji", - "deduplication_info_description": "Da bismo automatski unapred odabrali datoteke i uklonili duplikate grupno, gledamo:", "delete": "ObriÅĄi", "delete_action_confirmation_message": "Da li sigurno ÅželiÅĄ da obriÅĄeÅĄ ovu stvar? Ova akcija će pomeriti stvar u serversku kantu i ponuditi da li ÅželiÅĄ da je obriÅĄeÅĄ i lokalno", "delete_action_prompt": "{count} obrisano", diff --git a/i18n/sv.json b/i18n/sv.json index 82c2398b02..a9c63cc836 100644 --- a/i18n/sv.json +++ b/i18n/sv.json @@ -425,10 +425,10 @@ "unlink_all_oauth_accounts_description": "Kom ihÃĨg att ta bort länken till alla OAuth-konton innan du migrerar till en ny leverantÃļr.", "unlink_all_oauth_accounts_prompt": "Är du säker pÃĨ att du vill ta bort länken till alla OAuth-konton? Detta ÃĨterställer OAuth-ID:t fÃļr varje användare och kan inte ÃĨngras.", "user_cleanup_job": "Användarrensning", - "user_delete_delay": "{user} 's konto och objekt kommer att schemaläggas fÃļr permanent radering om {delay, plural, one {# day} other {# days}}.", + "user_delete_delay": "{user}s konto och resurser kommer att schemaläggas fÃļr permanent radering om {delay, plural, one {# dag} other {# dagar}}.", "user_delete_delay_settings": "BorttagningsfÃļrdrÃļjning", "user_delete_delay_settings_description": "Antal dagar efter borttagning fÃļr att permanent radera en användares konto och objekt. Arbetet med borttagning av användare kÃļrs vid midnatt fÃļr att sÃļka efter användare som är redo fÃļr radering. Ändringar av denna inställning kommer att utvärderas vid nästa kÃļrning.", - "user_delete_immediately": "{user} konto och objekt kommer att stÃĨ i kÃļ fÃļr permanent radering.", + "user_delete_immediately": "{user}s konto och resurser kommer att stÃĨ i kÃļ fÃļr omedelbar permanent radering.", "user_delete_immediately_checkbox": "KÃļa användare och objekt fÃļr omedelbar radering", "user_details": "Användardetaljer", "user_management": "Användarhantering", @@ -441,7 +441,7 @@ "user_successfully_removed": "Användaren {email} har tagits bort.", "users_page_description": "AdministratÃļrsanvändare", "version_check_enabled_description": "Aktivera versionskontroll", - "version_check_implications": "Funktionen fÃļr versionskontroll är beroende av periodisk kommunikation med github.com", + "version_check_implications": "Funktionen fÃļr versionskontroll är beroende av periodisk kommunikation med {server}", "version_check_settings": "Versionskontroll", "version_check_settings_description": "Aktivera/inaktivera notis om ny version", "video_conversion_job": "Omkoda videor", @@ -558,16 +558,16 @@ "asset_action_delete_err_read_only": "Kan inte ta bort skrivskyddade objekt, hoppar Ãļver", "asset_action_share_err_offline": "Kan inte hämta offline-objekt, hoppar Ãļver", "asset_added_to_album": "Lades till i album", - "asset_adding_to_album": "Lägger till i album...â€Ļ", + "asset_adding_to_album": "Lägger till i albumâ€Ļ", "asset_created": "Objekt skapad", "asset_description_updated": "Objektbeskrivning har uppdaterats", "asset_filename_is_offline": "Objektet {filename} är offline", "asset_has_unassigned_faces": "Objektet har otilldelade ansikten", - "asset_hashing": "Hashing...â€Ļ", + "asset_hashing": "Hashningâ€Ļ", "asset_list_group_by_sub_title": "Gruppera pÃĨ", "asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout", "asset_list_layout_settings_group_automatically": "Automatiskt", - "asset_list_layout_settings_group_by": "Gruppera bilder efter", + "asset_list_layout_settings_group_by": "Gruppera resurser efter", "asset_list_layout_settings_group_by_month_day": "MÃĨnad + dag", "asset_list_layout_sub_title": "Layout", "asset_list_settings_subtitle": "Layoutinställningar fÃļr bildrutnät", @@ -583,32 +583,32 @@ "asset_trashed": "Objekt kasserat", "asset_troubleshoot": "FelsÃļkning av objekt", "asset_uploaded": "Uppladdad", - "asset_uploading": "Laddar upp...â€Ļ", - "asset_viewer_settings_subtitle": "Hantera inställningar fÃļr gallerivisare", + "asset_uploading": "Laddar uppâ€Ļ", + "asset_viewer_settings_subtitle": "Hantera inställningar fÃļr gallerivisning", "asset_viewer_settings_title": "Objektvisare", "assets": "Objekt", - "assets_added_count": "La till {count, plural, one {# asset} other {# assets}}", - "assets_added_to_album_count": "Lade till {count, plural, one {# asset} other {# assets}} i albumet", - "assets_added_to_albums_count": "Lade till {assetTotal, plural, one {# asset} other {# assets}} till {albumTotal, plural, one {# album} other {# albums}}", - "assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} kan inte läggas till i albumet", - "assets_cannot_be_added_to_albums": "{count, plural, one {Asset} other {Assets}} kan inte läggas till i nÃĨgot av albumen", + "assets_added_count": "Lade till {count, plural, one {# resurs} other {# resurser}}", + "assets_added_to_album_count": "Lade till {count, plural, one {# resurs} other {# resurser}} i albumet", + "assets_added_to_albums_count": "Lade till {assetTotal, plural, one {# resurs} other {# resurser}} till {albumTotal, plural, one {# album} other {# album}}", + "assets_cannot_be_added_to_album_count": "{count, plural, one {Resurs} other {Resurser}} kan inte läggas till i albumet", + "assets_cannot_be_added_to_albums": "{count, plural, one {Resurs} other {Resurser}} kan inte läggas till i nÃĨgot av albumen", "assets_count": "{count, plural, one {# objekt} other {# objekt}}", - "assets_deleted_permanently": "{count} objekt har tagits bort permanent", - "assets_deleted_permanently_from_server": "{count} objekt har tagits bort permanent frÃĨn Immich-servern", - "assets_downloaded_failed": "{count, plural, one {Nedladdad # fil - {error} fil misslyckades} other {Nedladdade # filer - {error} filer misslyckades}}", - "assets_downloaded_successfully": "{count, plural, one {Nedladdade # fil framgÃĨngsrikt} other {Nedladdade # filer framgÃĨngsrikt}}", - "assets_moved_to_trash_count": "Flyttade {count, plural, one {# asset} other {# assets}} till papperskorgen", - "assets_permanently_deleted_count": "Raderad permanent {count, plural, one {# asset} other {# assets}}", - "assets_removed_count": "Tog bort {count, plural, one {# asset} other {# assets}}", - "assets_removed_permanently_from_device": "{count} objekt har raderats permanent frÃĨn din enhet", - "assets_restore_confirmation": "Är du säker pÃĨ att du vill ÃĨterställa alla dina papperskorgen? Du kan inte ÃĨngra den här ÃĨtgärden! Observera att offlineobjekt inte kan ÃĨterställas pÃĨ detta sätt.", - "assets_restored_count": "Återställd {count, plural, one {# asset} other {# assets}}", - "assets_restored_successfully": "{count} objekt har ÃĨterställts", - "assets_trashed": "{count} objekt raderade", - "assets_trashed_count": "Till Papperskorgen {count, plural, one {# asset} other {# assets}}", + "assets_deleted_permanently": "{count, plural, one {# resurs} other {# resurser}} har raderats permanent", + "assets_deleted_permanently_from_server": "{count, plural, one {# resurs} other {# resurser}} har permanent raderats frÃĨn Immich-servern", + "assets_downloaded_failed": "{count, plural, one {Nerladdning av # fil - {error} fil misslyckades} other {Nerladdning av # filer - {error} filer misslyckades}}", + "assets_downloaded_successfully": "{count, plural, one {# fil framgÃĨngsrikt nerladdad} other {# filer framgÃĨngsrikt nerladdade}}", + "assets_moved_to_trash_count": "Flyttade {count, plural, one {# resurs} other {# resurser}} till papperskorgen", + "assets_permanently_deleted_count": "{count, plural, one {# resurs} other {# resurser}} permanent raderade", + "assets_removed_count": "Tog bort {count, plural, one {# resurs} other {# resurser}}", + "assets_removed_permanently_from_device": "{count, plural, one {# resurs} other {# resurser}} har raderats permanent frÃĨn din enhet", + "assets_restore_confirmation": "Är du säker pÃĨ att du vill ÃĨterställa alla dina slängda resurser? Du kan inte ÃĨngra den här ÃĨtgärden! Observera att offlineresurser inte kan ÃĨterställas pÃĨ detta sätt.", + "assets_restored_count": "Återställde {count, plural, one {# resurs} other {# resurser}}", + "assets_restored_successfully": "{count, plural, one {# resurs} other {# resurser}} har framgÃĨngsrikt ÃĨterställts", + "assets_trashed": "{count, plural, one {# resurs} other {# resurser}} {count, plural, one {flyttad} other {flyttade}} till papperskorgen", + "assets_trashed_count": "{count, plural, one {# resurs} other {# resurser}} {count, plural, one {flyttad} other {flyttade}} till papperskorgen", "assets_trashed_from_server": "{count} objekt raderade frÃĨn Immich-servern", - "assets_were_part_of_album_count": "{count, plural, one {Asset was} other {Asset were}} är redan en del av albumet", - "assets_were_part_of_albums_count": "{count, plural, one {Asset was} other {Asset were}} redan del av albumen", + "assets_were_part_of_album_count": "{count, plural, one {Resursen} other {Resurserna}} tillhÃļr redan albumet", + "assets_were_part_of_albums_count": "{count, plural, one {Resursen} other {Resurserna}} tillhÃļr redan albumen", "authorized_devices": "Auktoriserade enheter", "automatic_endpoint_switching_subtitle": "Anslut lokalt via det angivna Wi-Fi-nätverket när det är tillgängligt och använd alternativa anslutningar pÃĨ andra platser", "automatic_endpoint_switching_title": "Automatisk URL-växling", @@ -622,14 +622,14 @@ "backup": "Säkerhetskopiera", "backup_album_selection_page_albums_device": "Album pÃĨ enhet ({count})", "backup_album_selection_page_albums_tap": "Tryck en gÃĨng fÃļr att inkludera, tryck tvÃĨ gÃĨnger fÃļr att exkludera", - "backup_album_selection_page_assets_scatter": "Objekt kan vara utspridda Ãļver flera album. DärfÃļr kan album inkluderas eller exkluderas under säkerhetskopieringsprocessen.", + "backup_album_selection_page_assets_scatter": "Resurser kan vara utspridda Ãļver flera album. DärfÃļr kan album inkluderas eller exkluderas under säkerhetskopieringsprocessen.", "backup_album_selection_page_select_albums": "Välj album", "backup_album_selection_page_selection_info": "Info om valda objekt", - "backup_album_selection_page_total_assets": "Antal unika objekt", + "backup_album_selection_page_total_assets": "Antal unika resurser", "backup_albums_sync": "Backup-albumsynkronisering", "backup_all": "Allt", - "backup_background_service_backup_failed_message": "Säkerhetskopiering av foton och videor misslyckades. FÃļrsÃļker igenâ€Ļ", - "backup_background_service_complete_notification": "Säkerhetskopiering av objekt klar", + "backup_background_service_backup_failed_message": "Säkerhetskopiering av resurser misslyckades. FÃļrsÃļker igenâ€Ļ", + "backup_background_service_complete_notification": "Säkerhetskopiering av resurser slutfÃļrt", "backup_background_service_connection_failed_message": "Anslutning till servern misslyckades. FÃļrsÃļker igenâ€Ļ", "backup_background_service_current_upload_notification": "Laddar upp {filename}", "backup_background_service_default_notification": "SÃļker efter nya objektâ€Ļ", @@ -678,7 +678,7 @@ "backup_controller_page_uploading_file_info": "Laddar upp filinformation", "backup_err_only_album": "Kan inte ta bort det enda albumet", "backup_error_sync_failed": "Synkroniseringen misslyckades. Det gÃĨr inte att bearbeta säkerhetskopian.", - "backup_info_card_assets": "objekt", + "backup_info_card_assets": "resurser", "backup_manual_cancelled": "Avbrutet", "backup_manual_in_progress": "Uppladdning pÃĨgÃĨr redan. FÃļrsÃļk igen om en liten stund", "backup_manual_success": "Klart", @@ -700,8 +700,8 @@ "build": "Bygge", "build_image": "Byggfil", "bulk_delete_duplicates_confirmation": "Är du säker pÃĨ att du vill massradera {count, plural, one {# dublettobjekt} other {# dublettobjekt}}? Detta kommer att behÃĨlla det stÃļrsta objektet i varje grupp och permanent radera alla andra dubbletter. Du kan inte ÃĨngra den här ÃĨtgärden!", - "bulk_keep_duplicates_confirmation": "Är du säker pÃĨ att du vill behÃĨlla {count, plural, one {# duplicate asset} other {# duplicate assets}}? Detta kommer att lÃļsa alla dubbletter av grupper utan att ta bort nÃĨgonting.", - "bulk_trash_duplicates_confirmation": "Är du säker pÃĨ att du vill skicka {count, plural, one {# dublettobjekt} other {# dublettobjekt}} till papperskorgen? Detta kommer att behÃĨlla det stÃļrsta objektet i varje grupp och alla andra dubbletter kasseras.", + "bulk_keep_duplicates_confirmation": "Är du säker pÃĨ att du vill behÃĨlla {count, plural, one {# dublett} other {# dubletter}}? Detta kommer att lÃļsa alla grupper av dubbletter utan att ta bort nÃĨgonting.", + "bulk_trash_duplicates_confirmation": "Är du säker pÃĨ att du vill skicka {count, plural, one {# dublett} other {# dubletter}} till papperskorgen? Detta kommer att behÃĨlla det stÃļrsta objektet i varje grupp och alla andra dubbletter kasseras.", "buy": "KÃļp Immich", "cache_settings_clear_cache_button": "Rensa cacheminnet", "cache_settings_clear_cache_button_title": "Rensar appens cacheminne. Detta kommer att avsevärt pÃĨverka appens prestanda tills cachen har byggts om.", @@ -752,22 +752,22 @@ "changed_visibility_successfully": "Synligheten har ändrats", "charging": "Laddar", "charging_requirement_mobile_backup": "Bakgrundssäkerhetskopiering kräver att enheten laddas", - "check_corrupt_asset_backup": "Kontrollera om det finns korrupta säkerhetskopior av objekt", + "check_corrupt_asset_backup": "Kontrollera om det finns korrupta resursbackuper", "check_corrupt_asset_backup_button": "Kontrollera", - "check_corrupt_asset_backup_description": "KÃļr kontrollen endast Ãļver Wi-Fi och när alla objekt har säkerhetskopierats. Det kan ta nÃĨgra minuter.", + "check_corrupt_asset_backup_description": "KÃļr kontrollen endast Ãļver Wi-Fi och när alla resurser har säkerhetskopierats. Det kan ta nÃĨgra minuter.", "check_logs": "Kontrollera loggar", "checksum": "Checksumma", "choose_matching_people_to_merge": "Välj matchande personer att slÃĨ samman", "city": "Stad", - "cleanup_confirm_description": "Immich hittade {count} material (skapade fÃļre {date} som säkerhetskopierats säkert till servern. Ta bort de lokala kopiorna frÃĨn den här enheten?", + "cleanup_confirm_description": "Immich hittade {count} resurser (skapade fÃļre {date}) som säkerhetskopierats säkert till servern. Ta bort de lokala kopiorna frÃĨn den här enheten?", "cleanup_confirm_prompt_title": "Ta bort frÃĨn den här enheten?", - "cleanup_deleted_assets": "Flyttade {count} material till enhetens papperskorg", + "cleanup_deleted_assets": "Flyttade {count, plural, one {# resurs} other {# resurser}} till enhetens papperskorg", "cleanup_deleting": "Flyttar till papperskorg...", - "cleanup_found_assets": "Hittade {count} säkerhetskopierade material", + "cleanup_found_assets": "Hittade {count} {count, plural, one {säkerhetskopierad resurs} other {säkerhetskopierade resurser}}", "cleanup_found_assets_with_size": "Hittade {count} säkerhetskopierade objekt ({size})", "cleanup_icloud_shared_albums_excluded": "iCloud delade album exkluderas frÃĨn skanningen", - "cleanup_no_assets_found": "Inga objekt hittades som matchar kriterierna ovan. FrigÃļr utrymme kan bara ta bort objekt som har säkerhetskopierats till servern", - "cleanup_preview_title": "Material att ta bort {count}", + "cleanup_no_assets_found": "Inga objekt hittades som matchar kriterierna ovan. FrigÃļr Utrymme kan bara ta bort objekt som har säkerhetskopierats till servern", + "cleanup_preview_title": "Resurser att ta bort ({count})", "cleanup_step3_description": "Skanna efter säkerhetskopierade objekt som matchar ditt datum och behÃĨll inställningarna.", "cleanup_step4_summary": "{count} objekt (skapade fÃļre {date}) att tas bort frÃĨn din lokala enhet. Foton kommer att fÃļrbli tillgängliga frÃĨn Immich-appen.", "cleanup_trash_hint": "FÃļr att helt frigÃļra lagringsutrymme, Ãļppna systemgalleriappen och tÃļm papperskorgen", @@ -807,7 +807,7 @@ "completed": "Klar", "confirm": "Bekräfta", "confirm_admin_password": "Bekräfta administratÃļrslÃļsenord", - "confirm_delete_face": "Är du säker pÃĨ att du vill ta bort {name}'s ansikte frÃĨn objektet?", + "confirm_delete_face": "Är du säker pÃĨ att du vill ta bort {name}s ansikte frÃĨn objektet?", "confirm_delete_shared_link": "Är du säker pÃĨ att du vill ta bort den här delade länken?", "confirm_keep_this_delete_others": "Alla objekt fÃļrutom den här tas bort frÃĨn hÃļgen. Är du säker pÃĨ att du vill fortsätta?", "confirm_new_pin_code": "Bekräfta ny PIN-kod", @@ -849,9 +849,12 @@ "create_link_to_share": "Skapa länk att dela", "create_link_to_share_description": "LÃĨt alla med länken se de valda fotona", "create_new": "SKAPA NY", + "create_new_face": "Skapa nytt ansikte", "create_new_person": "Skapa ny person", "create_new_person_hint": "Tilldela valda objekt till en ny person", "create_new_user": "Skapa en ny användare", + "create_person": "Skapa person", + "create_person_subtitle": "Lägg till ett namn till det valda ansiktet fÃļr att skapa och tagga den nya personen", "create_shared_album_page_share_add_assets": "LÄGG TILL OBJEKT", "create_shared_album_page_share_select_photos": "Välj bilder", "create_shared_link": "Skapa delad länk", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Fixat", "crop_aspect_ratio_free": "Fritt", "crop_aspect_ratio_original": "Original", + "crop_aspect_ratio_square": "Kvadrat", "curated_object_page_title": "Objekt", "current_device": "Aktuell enhet", "current_pin_code": "Nuvarande PIN-kod", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "MÃļrk", - "dark_theme": "Växla mÃļrkt tema", + "dark_theme": "Växla till mÃļrkt tema", "date": "Datum", "date_after": "Datum efter", "date_and_time": "Datum och Tid", @@ -891,10 +895,8 @@ "day": "Dag", "days": "Dagar", "deduplicate_all": "Deduplicera alla", - "deduplication_criteria_1": "Bildstorlek i bytes", - "deduplication_criteria_2": "Räkning av EXIF-data", - "deduplication_info": "Dedupliceringsinformation", - "deduplication_info_description": "FÃļr att automatiskt välja filer och ta bort dubletter i bulk analyserar vi:", + "default_locale": "StandardsprÃĨk", + "default_locale_description": "Formatera datum och siffror baserat pÃĨ din webbläsares sprÃĨkinställningar", "delete": "Radera", "delete_action_confirmation_message": "Är du säker pÃĨ att du vill ta bort det här objektet? Den här ÃĨtgärden flyttar objektet till serverns papperskorg och frÃĨgar om du vill ta bort den lokalt", "delete_action_prompt": "{count} raderade", @@ -923,7 +925,7 @@ "delete_tag_confirmation_prompt": "Är du säker pÃĨ att du vill ta bort {tagName}-taggen?", "delete_user": "Ta bort användare", "deleted_shared_link": "Ta bort delad länk", - "deletes_missing_assets": "Tar bort objekt som saknas frÃĨn disken", + "deletes_missing_assets": "Tar bort objekt som saknas pÃĨ disken", "description": "Beskrivning", "description_input_hint_text": "Lägg till beskrivning...", "description_input_submit_error": "Fel vid uppdatering av beskrivning, se loggen fÃļr fler detaljer", @@ -959,18 +961,18 @@ "download_original": "Ladda ner ursprunglig fil", "download_paused": "Nedladdning pausad", "download_settings": "Ladda ner", - "download_settings_description": "Hantera inställningar relaterade till nedladdning av objekt", + "download_settings_description": "Hantera inställningar relaterade till nedladdning av resurser", "download_started": "Nedladdning pÃĨbÃļrjad", "download_sucess": "Nedladdning lyckades", "download_sucess_android": "Media har laddats ner till DCIM/Immich", "download_waiting_to_retry": "Väntar pÃĨ omfÃļrsÃļk", "downloading": "Laddar ner", - "downloading_asset_filename": "Laddar ned objekt {filename}", + "downloading_asset_filename": "Laddar ner objekt {filename}", "downloading_from_icloud": "Laddar ner frÃĨn iCloud", "downloading_media": "Laddar ner media", "drop_files_to_upload": "Släpp filer var som helst fÃļr att ladda upp", "duplicates": "Dubletter", - "duplicates_description": "LÃļs varje grupp genom att ange vilka, om nÃĨgra, är dubbletter", + "duplicates_description": "LÃļs varje grupp genom att ange vilka, om nÃĨgra, är dubbletter.", "duration": "Varaktighet", "edit": "Redigera", "edit_album": "Redigera album", @@ -1007,6 +1009,8 @@ "editor_edits_applied_success": "Redigeringarna har tillämpats framgÃĨngsrikt", "editor_flip_horizontal": "Vänd horisontellt", "editor_flip_vertical": "Vänd vertikalt", + "editor_handle_corner": "{corner, select, top_left {Övre vänstra} top_right {Övre hÃļgra} bottom_left {Nedre vänstra} bottom_right {Nedre hÃļgra} other {A}} hÃļrn handtag", + "editor_handle_edge": "{edge, select, top {Övre} bottom {Nedre} left {Vänster} right {HÃļger} other {En}} hÃļrnhandtag", "editor_orientation": "Orientering", "editor_reset_all_changes": "Återställ ändringar", "editor_rotate_left": "Rotera 90° moturs", @@ -1042,8 +1046,8 @@ "cannot_navigate_previous_asset": "Det gÃĨr inte att navigera till fÃļregÃĨende objekt", "cant_apply_changes": "Det gÃĨr inte att tillämpa ändringar", "cant_change_activity": "Kan inte {enabled, select, true {avaktivera} other {aktivera}} aktivitet", - "cant_change_asset_favorite": "Det gÃĨr inte att byta favorit mot objekt", - "cant_change_metadata_assets_count": "Det gÃĨr inte att ändra metadata fÃļr {count, plural, one {# asset} other {# assets}}", + "cant_change_asset_favorite": "Det gÃĨr inte att byta favorit fÃļr objekt", + "cant_change_metadata_assets_count": "Det gÃĨr inte att ändra metadata fÃļr {count, plural, one {# resurs} other {# resurser}}", "cant_get_faces": "Kan inte fÃĨ ansikten", "cant_get_number_of_comments": "Kan inte fÃĨ antal kommentarer", "cant_search_people": "Kan inte sÃļka efter personer", @@ -1060,7 +1064,7 @@ "failed_to_create_shared_link": "Det gick inte att skapa delad länk", "failed_to_edit_shared_link": "Det gick inte att redigera delad länk", "failed_to_get_people": "Det gick inte att hämta personer", - "failed_to_keep_this_delete_others": "Misslyckades att behÃĨlla detta objekt radera Ãļvriga objekt", + "failed_to_keep_this_delete_others": "Misslyckades att behÃĨlla detta objekt och radera Ãļvriga objekt", "failed_to_load_asset": "Det gick inte att ladda objekt", "failed_to_load_assets": "Det gick inte att ladda objekten", "failed_to_load_notifications": "Misslyckades med att ladda notifikationer", @@ -1273,17 +1277,17 @@ "hide_schema": "GÃļm schema", "hide_text_recognition": "DÃļlj textigenkänning", "hide_unnamed_people": "GÃļm personer utan namn", - "home_page_add_to_album_conflicts": "Lade till {added} foton och videor i albumet {album}. {failed} foton och videor finns redan i albumet.", + "home_page_add_to_album_conflicts": "Lade till {added} resurser i albumet {album}. {failed} resurser finns redan i albumet.", "home_page_add_to_album_err_local": "Kan inte lägga till lokala objekt till album ännu, hoppar Ãļver", - "home_page_add_to_album_success": "Lade till {added} foton och videor i albumet {album}.", + "home_page_add_to_album_success": "Lade till {added} resurser i albumet {album}.", "home_page_album_err_partner": "Kan inte lägga till partner-objekt till album ännu, hoppar Ãļver", "home_page_archive_err_local": "Kan inte arkivera lokala objekt ännu, hoppar Ãļver", "home_page_archive_err_partner": "Kan inte arkivera partner-objekt, hoppar Ãļver", "home_page_building_timeline": "Bygger tidslinjen", "home_page_delete_err_partner": "Kan inte ta bort partner-objekt, hoppar Ãļver", "home_page_delete_remote_err_local": "Lokala objekt i urvalet fÃļr att ta bort frÃĨn servern, hoppar Ãļver", - "home_page_favorite_err_local": "Kan inte favorisera lokala objekt ännu, hoppar Ãļver", - "home_page_favorite_err_partner": "Kan inte favorisera partner-objekt ännu, hoppar Ãļver", + "home_page_favorite_err_local": "Kan inte favoritmarkera lokala objekt ännu, hoppar Ãļver", + "home_page_favorite_err_partner": "Kan inte favoritmarkera partner-objekt ännu, hoppar Ãļver", "home_page_first_time_notice": "Om det här är fÃļrsta gÃĨngen du använder appen, välj ett eller flera backup-album sÃĨ att tidslinjen kan fyllas med foton och videor frÃĨn albumen", "home_page_locked_error_local": "Kan inte flytta lokala resurser till lÃĨst mapp, hoppar Ãļver", "home_page_locked_error_partner": "Kan inte flytta partnerresurser till lÃĨst mapp, hoppar Ãļver", @@ -1321,7 +1325,7 @@ "in_year_selector": "In", "include_archived": "Inkludera arkiverade", "include_shared_albums": "Inkludera delade album", - "include_shared_partner_assets": "Inkludera delade partners objekt", + "include_shared_partner_assets": "Inkludera partnerdelade resurser", "individual_share": "Enskild delning", "individual_shares": "Individuella delningar", "info": "Information", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "Albumtitel", "licenses": "Licenser", "light": "Ljus", + "light_theme": "Ändra till ljust tema", "like": "Gilla", "like_deleted": "Gilla borttagen", "link_motion_video": "Länka rÃļrlig video", + "link_to_docs": "FÃļr mer information, se dokumentationen.", "link_to_oauth": "Länk till OAuth", "linked_oauth_account": "Länkat OAuth konto", "list": "Lista", @@ -2211,6 +2217,7 @@ "tag": "Tagg", "tag_assets": "Tagga objekt", "tag_created": "Skapade tagg: {tag}", + "tag_face": "Tagga ansikte", "tag_feature_description": "Bläddra bland foton och videor grupperade efter logiska taggar", "tag_not_found_question": "Kan du inte hitta en tagg? Skapa en ny tagg.", "tag_people": "Tagga Personer", @@ -2392,6 +2399,7 @@ "viewer_remove_from_stack": "Ta bort frÃĨn Stapeln", "viewer_stack_use_as_main_asset": "Använd som Huvudobjekt", "viewer_unstack": "Stapla Av", + "visibility": "Synlighet", "visibility_changed": "Synlighet ändrad fÃļr {count, plural, one {# person} other {# personer}}", "visual": "Visuellt", "visual_builder": "Visuell byggare", diff --git a/i18n/ta.json b/i18n/ta.json index f33c148fd5..482be2e993 100644 --- a/i18n/ta.json +++ b/i18n/ta.json @@ -61,8 +61,8 @@ "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-āŽ āŽ¤āŽ°āŽĩ❁ āŽ¨āŽ•āŽ˛ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁ āŽŽāŽŸā¯āŽĒā¯āŽĒāŽ¤ā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ¤āŽ•āŽĩāŽ˛ā¯āŽ•ā¯āŽ•ā¯, āŽ¤āŽ¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽ†āŽĩāŽŖāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", + "backup_onboarding_description": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¤āŽ°āŽĩ❈āŽĒā¯ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽĒā¯āŽĒāŽ¤āŽąā¯āŽ•āŽžāŽ• āŽ’āŽ°ā¯ 3-2-1 āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽĒāŽ°āŽŋāŽ¨ā¯āŽ¤ā¯āŽ°ā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽŽā¯āŽ´ā¯āŽŽā¯ˆāŽ¯āŽžāŽŠ āŽ•āŽžāŽĒā¯āŽĒ❁ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽĒā¯āŽĒ❁ āŽ¤ā¯€āŽ°ā¯āŽĩāŽŋāŽąā¯āŽ•āŽžāŽ•, āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŋāŽ¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯/āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ Immich āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ• āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯.", + "backup_onboarding_footer": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯-āŽ āŽ¤āŽ°āŽĩ❁ āŽ¨āŽ•āŽ˛ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁ āŽŽāŽŸā¯āŽĒā¯āŽĒāŽ¤ā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ¤āŽ•āŽĩāŽ˛ā¯āŽ•ā¯āŽ•ā¯, āŽ¤āŽ¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽ†āŽĩāŽŖāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", "backup_onboarding_parts_title": "3-2-1 āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯āŽŋāŽ˛ā¯ āŽĒāŽŋāŽŠā¯āŽĩāŽ°ā¯āŽĩāŽŠ āŽ…āŽŸāŽ™ā¯āŽ•ā¯āŽŽā¯:", "backup_onboarding_title": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ•āŽŗā¯", "backup_settings": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗ āŽ¤āŽŋāŽŖāŽŋāŽĒā¯āŽĒ❁ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", @@ -104,6 +104,8 @@ "image_preview_description": "āŽ…āŽ•āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽŽā¯†āŽŸā¯āŽŸāŽžāŽŸā¯‡āŽŸā¯āŽŸāŽžāŽĩā¯āŽŸāŽŠā¯ āŽ¨āŽŸā¯āŽ¤ā¯āŽ¤āŽ° āŽ…āŽŗāŽĩāŽŋāŽ˛āŽžāŽŠ āŽĒāŽŸāŽŽā¯, āŽ’āŽąā¯āŽąā¯ˆ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ‡āŽ¯āŽ¨ā¯āŽ¤āŽŋāŽ° āŽ•āŽąā¯āŽąāŽ˛ā¯āŽ•ā¯āŽ•āŽžāŽ•āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯", "image_preview_quality_description": "1-100 āŽŽā¯āŽ¤āŽ˛ā¯ āŽ¤āŽ°āŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯āŽŠā¯āŽŠā¯‹āŽŸā¯āŽŸāŽŽāŽŋāŽŸā¯āŽ™ā¯āŽ•āŽŗā¯. āŽ‰āŽ¯āŽ°ā¯āŽ¨ā¯āŽ¤āŽ¤ā¯ āŽšāŽŋāŽąāŽ¨ā¯āŽ¤āŽ¤ā¯, āŽ†āŽŠāŽžāŽ˛ā¯ āŽĒā¯†āŽ°āŽŋāŽ¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ āŽŽāŽąā¯āŽŽā¯ŠāŽ´āŽŋāŽ¯ā¯ˆāŽ•ā¯ āŽ•ā¯āŽąā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯. āŽ•ā¯āŽąā¯ˆāŽ¨ā¯āŽ¤ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒ❈ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒāŽ¤ā¯ āŽ‡āŽ¯āŽ¨ā¯āŽ¤āŽŋāŽ° āŽ•āŽąā¯āŽąāŽ˛ā¯ āŽ¤āŽ°āŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ¤āŽŋāŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯.", "image_preview_title": "āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ āŽŽā¯āŽŠā¯āŽŠā¯‹āŽŸā¯āŽŸāŽŽā¯", + "image_progressive": "āŽŽā¯āŽąā¯āŽĒā¯‹āŽ•ā¯āŽ•āŽžāŽŠāŽ¤ā¯", + "image_progressive_description": "āŽĒāŽŸāŽŋāŽĒā¯āŽĒāŽŸāŽŋāŽ¯āŽžāŽ• āŽāŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽ•āŽžāŽŸā¯āŽšāŽŋāŽ•ā¯āŽ•ā¯ JPEG āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒāŽŸāŽŋāŽĒā¯āŽĒāŽŸāŽŋāŽ¯āŽžāŽ• āŽ•ā¯āŽąāŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯. āŽ‡āŽ¤ā¯ WebP āŽĒāŽŸāŽ™ā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽŽāŽ¨ā¯āŽ¤ āŽĩāŽŋāŽŗā¯ˆāŽĩā¯ˆāŽ¯ā¯āŽŽā¯ āŽāŽąā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽžāŽ¤ā¯.", "image_quality": "āŽ¤āŽ°āŽŽā¯", "image_resolution": "āŽĒāŽ•ā¯āŽ¤ā¯āŽ¤āŽ˛ā¯", "image_resolution_description": "āŽ…āŽ¤āŽŋāŽ• āŽ¤ā¯€āŽ°ā¯āŽŽāŽžāŽŠāŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽ¤āŽŋāŽ• āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯ā¯āŽŽā¯, āŽ†āŽŠāŽžāŽ˛ā¯ āŽ•ā¯āŽąāŽŋāŽ¯āŽžāŽ•ā¯āŽ• āŽ…āŽ¤āŽŋāŽ• āŽ¨ā¯‡āŽ°āŽŽā¯ āŽŽāŽŸā¯āŽ•ā¯āŽ•ā¯āŽŽā¯, āŽĒā¯†āŽ°āŽŋāŽ¯ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽ…āŽŗāŽĩā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸāŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ āŽŽāŽąā¯āŽŽā¯ŠāŽ´āŽŋāŽ¯ā¯ˆāŽ•ā¯ āŽ•ā¯āŽąā¯ˆāŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯.", @@ -189,10 +191,20 @@ "machine_learning_smart_search_enabled_description": "āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯, āŽ¸ā¯āŽŽāŽžāŽ°ā¯āŽŸā¯ āŽ¤ā¯‡āŽŸāŽ˛ā¯āŽ•ā¯āŽ•āŽžāŽ• āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸāŽžāŽ¤ā¯.", "machine_learning_url_description": "āŽ‡āŽ¯āŽ¨ā¯āŽ¤āŽŋāŽ° āŽ•āŽąā¯āŽąāŽ˛ā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽŽā¯āŽ•āŽĩāŽ°āŽŋ. āŽ’āŽŠā¯āŽąā¯āŽ•ā¯āŽ•ā¯ āŽŽā¯‡āŽąā¯āŽĒāŽŸā¯āŽŸ āŽŽā¯āŽ•āŽĩāŽ°āŽŋ āŽĩāŽ´āŽ™ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯, āŽ’āŽĩā¯āŽĩā¯ŠāŽ°ā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽŽā¯āŽŽā¯ āŽ’āŽĩā¯āŽĩā¯ŠāŽŠā¯āŽąāŽžāŽ• āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽĒāŽ¤āŽŋāŽ˛āŽŗāŽŋāŽ•ā¯āŽ•ā¯āŽŽā¯ āŽĩāŽ°ā¯ˆ, āŽŽā¯āŽ¤āŽ˛āŽŋāŽ˛ā¯ āŽ‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•āŽŸā¯ˆāŽšāŽŋ āŽĩāŽ°ā¯ˆ āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯. āŽĒāŽ¤āŽŋāŽ˛āŽŗāŽŋāŽ•ā¯āŽ•āŽžāŽ¤ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ†āŽŠā¯āŽ˛ā¯ˆāŽŠāŽŋāŽ˛ā¯ āŽĩāŽ°ā¯āŽŽā¯ āŽĩāŽ°ā¯ˆ āŽ¤āŽąā¯āŽ•āŽžāŽ˛āŽŋāŽ•āŽŽāŽžāŽ•āŽĒā¯ āŽĒā¯āŽąāŽ•ā¯āŽ•āŽŖāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", "maintenance_delete_backup": "āŽ•āŽžāŽĒā¯āŽĒā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "maintenance_delete_backup_description": "āŽ‡āŽ¨ā¯āŽ¤āŽ•ā¯ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽŽā¯€āŽŗāŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽŽāŽ˛ā¯ āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", + "maintenance_delete_error": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", + "maintenance_restore_backup": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆ", + "maintenance_restore_backup_description": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽ¤ā¯āŽŸā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯. āŽ¤ā¯ŠāŽŸāŽ°ā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽŽā¯āŽŠā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", + "maintenance_restore_backup_different_version": "āŽ‡āŽ¨ā¯āŽ¤ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯āŽšāŽŋāŽŠā¯ āŽĩā¯‡āŽąā¯āŽĒāŽŸā¯āŽŸ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒā¯ˆāŽ•ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯!", + "maintenance_restore_backup_unknown_version": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤ā¯€āŽ°ā¯āŽŽāŽžāŽŠāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", + "maintenance_restore_database_backup": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "maintenance_restore_database_backup_description": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽ•ā¯‹āŽĒā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋ āŽŽā¯āŽ¨ā¯āŽ¤ā¯ˆāŽ¯ āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗ āŽ¨āŽŋāŽ˛ā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¤āŽŋāŽ°ā¯āŽŽā¯āŽĒāŽĩā¯āŽŽā¯", "maintenance_settings": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁", "maintenance_settings_description": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯āŽšā¯ˆ āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽŽā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽĩā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", - "maintenance_start": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ•ā¯", + "maintenance_start": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽŽā¯āŽąā¯ˆāŽ•ā¯āŽ•ā¯ āŽŽāŽžāŽąāŽĩā¯āŽŽā¯", "maintenance_start_error": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", + "maintenance_upload_backup": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗ āŽ•āŽžāŽĒā¯āŽĒ❁ āŽ•ā¯‹āŽĒā¯āŽĒ❈ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĩā¯āŽŽā¯", + "maintenance_upload_backup_error": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ, āŽ‡āŽ¤ā¯ .sql/.sql.gz āŽ•ā¯‹āŽĒā¯āŽĒāŽžāŽ•ā¯āŽŽāŽž?", "manage_concurrency": "āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩ❈ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "manage_concurrency_description": "āŽĩā¯‡āŽ˛ā¯ˆ āŽ’āŽ°ā¯āŽ™ā¯āŽ•āŽŋāŽŖā¯ˆāŽĩ❈ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ• āŽĩā¯‡āŽ˛ā¯ˆāŽ•āŽŗā¯ āŽĒāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯āŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛āŽĩā¯āŽŽā¯", "manage_log_settings": "āŽĒāŽ¤āŽŋāŽĩ❁ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -206,7 +218,7 @@ "map_reverse_geocoding": "āŽĒ❁āŽĩāŽŋ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ¤ā¯€āŽ°ā¯āŽŽāŽžāŽŠāŽŋāŽ¤ā¯āŽ¤āŽ˛ā¯", "map_reverse_geocoding_enable_description": "āŽĒ❁āŽĩāŽŋāŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸ āŽ¤ā¯€āŽ°ā¯āŽŽāŽžāŽŠāŽ¤ā¯āŽ¤ā¯ˆ āŽšā¯†āŽ¯āŽ˛ā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "map_reverse_geocoding_settings": "āŽĒ❁āŽĩāŽŋāŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ¤ā¯€āŽ°ā¯āŽŽāŽžāŽŠāŽŋāŽ¤ā¯āŽ¤āŽ˛ā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", - "map_settings": "āŽŽā¯‡āŽĒā¯ & āŽœāŽŋāŽĒāŽŋāŽŽāŽ¸ā¯ (GPS) āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", + "map_settings": "āŽĩāŽ°ā¯ˆāŽĒāŽŸāŽŽā¯", "map_settings_description": "āŽŽā¯‡āŽĒā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "map_style_description": "style.json āŽŽā¯‡āŽĒā¯ āŽ¤ā¯€āŽŽā¯āŽ•ā¯āŽ•āŽžāŽŠ URL", "memory_cleanup_job": "āŽ¨āŽŋāŽŠā¯ˆāŽĩāŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽšā¯āŽ¤ā¯āŽ¤āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¤āŽ˛ā¯", @@ -260,7 +272,7 @@ "oauth_auto_register": "āŽ¤āŽžāŽŠāŽŋāŽ¯āŽ™ā¯āŽ•ā¯ āŽĒāŽ¤āŽŋāŽĩ❁", "oauth_auto_register_description": "OAuth āŽ‰āŽŸāŽŠā¯ āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽ¨ā¯āŽ¤ āŽĒāŽŋāŽąāŽ•ā¯ āŽ¤āŽžāŽŠāŽžāŽ•āŽĩ❇ āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", "oauth_button_text": "āŽĒāŽŸā¯āŽŸāŽŠā¯ āŽ‰āŽ°ā¯ˆ", - "oauth_client_secret_description": "āŽ…āŽĩāŽšāŽŋāŽ¯āŽŽā¯, OAuth āŽĩāŽ´āŽ™ā¯āŽ•ā¯āŽ¨āŽ°āŽžāŽ˛ā¯ PKCE (āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯āŽĒā¯ āŽĒāŽ°āŽŋāŽŽāŽžāŽąā¯āŽąāŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•āŽžāŽŠ āŽ†āŽ¤āŽžāŽ° āŽĩāŽŋāŽšā¯ˆ) āŽ†āŽ¤āŽ°āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽĩāŽŋāŽŸā¯āŽŸāŽžāŽ˛ā¯", + "oauth_client_secret_description": "āŽ°āŽ•āŽšāŽŋāŽ¯ āŽĩāŽžāŽŸāŽŋāŽ•ā¯āŽ•ā¯ˆāŽ¯āŽžāŽŗāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽ¤ā¯ āŽ¤ā¯‡āŽĩ❈, āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒā¯ŠāŽ¤ā¯ āŽ•āŽŋāŽŗā¯ˆāŽ¯āŽŖā¯āŽŸāŽŋāŽąā¯āŽ•ā¯ PKCE (āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ āŽĒāŽ°āŽŋāŽŽāŽžāŽąā¯āŽąāŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•āŽžāŽŠ āŽ†āŽ¤āŽžāŽ° āŽĩāŽŋāŽšā¯ˆ) āŽ†āŽ¤āŽ°āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽĩāŽŋāŽŸā¯āŽŸāŽžāŽ˛ā¯.", "oauth_enable_description": "OAuth āŽŽā¯‚āŽ˛āŽŽā¯ āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽ•", "oauth_mobile_redirect_uri": "āŽŽā¯ŠāŽĒā¯ˆāŽ˛ā¯ āŽĩāŽ´āŽŋāŽŽāŽžāŽąā¯āŽąā¯ URI", "oauth_mobile_redirect_uri_override": "āŽŽā¯ŠāŽĒā¯ˆāŽ˛ā¯ āŽĩāŽ´āŽŋāŽŽāŽžāŽąā¯āŽąā¯ URI āŽŽā¯‡āŽ˛ā¯†āŽ´ā¯āŽ¤ā¯āŽ¤āŽ˛ā¯", @@ -269,7 +281,7 @@ "oauth_role_claim_description": "āŽ‡āŽ¨ā¯āŽ¤āŽ•ā¯ āŽ•ā¯‹āŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆāŽ¯āŽŋāŽŠā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ¤āŽžāŽŠāŽžāŽ•āŽĩ❇ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋ āŽ…āŽŖā¯āŽ•āŽ˛ā¯ˆ āŽĩāŽ´āŽ™ā¯āŽ•āŽĩā¯āŽŽā¯. āŽ•ā¯‹āŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆāŽ¯āŽŋāŽ˛ā¯ 'āŽĒāŽ¯āŽŠāŽ°ā¯' āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ 'āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋ' āŽ‡āŽ°ā¯āŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯.", "oauth_settings": "āŽ“āŽ†āŽ¤ā¯", "oauth_settings_description": "OAuth āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽĩ❁ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", - "oauth_settings_more_details": "āŽ‡āŽ¨ā¯āŽ¤ āŽ…āŽŽā¯āŽšāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯, āŽŸāŽžāŽ•ā¯āŽ¸ā¯ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", + "oauth_settings_more_details": "āŽ‡āŽ¨ā¯āŽ¤ āŽ¨āŽąā¯āŽĒāŽŖā¯āŽĒ❈āŽĒā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯, āŽ†āŽĩāŽŖāŽ™ā¯āŽ•āŽŗā¯ˆ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯.", "oauth_storage_label_claim": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽ˛ā¯‡āŽĒāŽŋāŽŗā¯ āŽ‰āŽ°āŽŋāŽŽā¯ˆāŽ•ā¯‹āŽ°āŽ˛ā¯", "oauth_storage_label_claim_description": "āŽĒāŽ¯āŽŠāŽ°āŽŋāŽŠā¯ āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽ˛ā¯‡āŽĒāŽŋāŽŗā¯ˆ āŽ‡āŽ¨ā¯āŽ¤ āŽ‰āŽ°āŽŋāŽŽā¯ˆāŽ•ā¯‹āŽ°āŽ˛āŽŋāŽŠā¯ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯āŽ•ā¯āŽ•ā¯ āŽ¤āŽžāŽŠāŽžāŽ• āŽ…āŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", "oauth_storage_quota_claim": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽ’āŽ¤ā¯āŽ•ā¯āŽ•ā¯€āŽŸā¯ āŽ‰āŽ°āŽŋāŽŽā¯ˆāŽ•ā¯‹āŽ°āŽ˛ā¯", @@ -285,10 +297,13 @@ "paths_validated_successfully": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽĒāŽžāŽ¤ā¯ˆāŽ•āŽŗā¯āŽŽā¯ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ", "person_cleanup_job": "āŽ¨āŽĒāŽ°ā¯ āŽ¤ā¯‚āŽ¯ā¯āŽŽā¯ˆāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ¤āŽ˛ā¯", "queue_details": "āŽĩāŽ°āŽŋāŽšā¯ˆ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯", + "queues": "āŽĩā¯‡āŽ˛ā¯ˆ āŽĩāŽ°āŽŋāŽšā¯ˆāŽ•āŽŗā¯", + "queues_page_description": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋ āŽĩā¯‡āŽ˛ā¯ˆ āŽĩāŽ°āŽŋāŽšā¯ˆāŽ•āŽŗā¯ āŽĒāŽ•ā¯āŽ•āŽŽā¯", "quota_size_gib": "āŽ’āŽ¤ā¯āŽ•ā¯āŽ•ā¯€āŽŸā¯ āŽ…āŽŗāŽĩ❁ (GiB)", "refreshing_all_libraries": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ¨ā¯‚āŽ˛āŽ•āŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "registration": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ• āŽĒāŽ¤āŽŋāŽĩ❁", "registration_description": "āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŖāŽŋāŽŠāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽŽā¯āŽ¤āŽ˛ā¯ āŽĒāŽ¯āŽŠāŽ°āŽžāŽ• āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽ¤āŽžāŽ˛ā¯, āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋāŽ¯āŽžāŽ• āŽ¨āŽŋāŽ¯āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽĩā¯€āŽ°ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽĒā¯ āŽĒāŽŖāŽŋāŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯āŽĒā¯ āŽĒā¯ŠāŽąā¯āŽĒā¯āŽĒāŽžāŽĩā¯€āŽ°ā¯āŽ•āŽŗā¯, āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ‰āŽ™ā¯āŽ•āŽŗāŽžāŽ˛ā¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽĩāŽžāŽ°ā¯āŽ•āŽŗā¯.", + "remove_failed_jobs": "āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋāŽ¯ā¯āŽąā¯āŽą āŽĩā¯‡āŽ˛ā¯ˆāŽ•āŽŗā¯ˆ āŽ…āŽ•āŽąā¯āŽąāŽĩā¯āŽŽā¯", "require_password_change_on_login": "āŽŽā¯āŽ¤āŽ˛ā¯ āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽĩāŽŋāŽ˛ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽŽāŽžāŽąā¯āŽą āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯", "reset_settings_to_default": "āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ‡āŽ¯āŽ˛ā¯āŽĒā¯āŽ¨āŽŋāŽ˛ā¯ˆāŽ•ā¯āŽ•ā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "reset_settings_to_recent_saved": "āŽ…āŽŖā¯āŽŽā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -296,7 +311,7 @@ "search_jobs": "āŽĩā¯‡āŽ˛ā¯ˆāŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯â€Ļ", "send_welcome_email": "āŽĩāŽ°āŽĩā¯‡āŽąā¯āŽĒ❁ āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯ˆ āŽ…āŽŠā¯āŽĒā¯āŽĒāŽĩā¯āŽŽā¯", "server_external_domain_settings": "āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒā¯āŽą āŽ•āŽŗāŽŽā¯", - "server_external_domain_settings_description": "HTTP (āŽ•āŽŗā¯) āŽ‰āŽŸā¯āŽĒāŽŸ āŽĒā¯ŠāŽ¤ā¯ āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•āŽžāŽŠ āŽŸā¯ŠāŽŽā¯ˆāŽŠā¯: //", + "server_external_domain_settings_description": "āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒā¯āŽą āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽŸā¯ŠāŽŽā¯ˆāŽŠā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯", "server_public_users": "āŽĒā¯ŠāŽ¤ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯", "server_public_users_description": "āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯ˆāŽšā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯āŽŽā¯ (āŽĒā¯†āŽ¯āŽ°ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯) āŽĒāŽŸā¯āŽŸāŽŋāŽ¯āŽ˛āŽŋāŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗāŽŠ. āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯, āŽĒāŽ¯āŽŠāŽ°ā¯ āŽĒāŽŸā¯āŽŸāŽŋāŽ¯āŽ˛ā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ• āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯.", "server_settings": "āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ• āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", @@ -318,8 +333,8 @@ "storage_template_migration_description": "āŽāŽąā¯āŽ•āŽŠāŽĩ❇ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŋāŽ¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ˆāŽ¯ {template} āŽāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "storage_template_migration_info": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽĩāŽžāŽ°ā¯āŽĒā¯āŽĒā¯āŽ°ā¯ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ¨ā¯€āŽŸā¯āŽŸāŽŋāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽšāŽŋāŽąāŽŋāŽ¯ āŽŽāŽ´ā¯āŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽŽāŽžāŽąā¯āŽąā¯āŽŽā¯. āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯ āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤ā¯āŽŽā¯. āŽŽā¯āŽŠā¯āŽĒ❁ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŋāŽ¯ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯āŽŸā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤, {job} āŽ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", "storage_template_migration_job": "āŽ¸ā¯āŽŸā¯‹āŽ°ā¯‡āŽœā¯ āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯ āŽ‡āŽŸāŽŽā¯āŽĒā¯†āŽ¯āŽ°ā¯āŽĩ❁ āŽĩā¯‡āŽ˛ā¯ˆ", - "storage_template_more_details": "āŽ‡āŽ¨ā¯āŽ¤ āŽ…āŽŽā¯āŽšāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯, Storage Template āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ…āŽ¤āŽŠā¯ āŽ¤āŽžāŽ•ā¯āŽ•āŽ™ā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", - "storage_template_onboarding_description_v2": "āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯, āŽ‡āŽ¨ā¯āŽ¤ āŽ…āŽŽā¯āŽšāŽŽā¯ āŽĒāŽ¯āŽŠāŽ°ā¯ āŽĩāŽ°ā¯ˆāŽ¯āŽąā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯āŽŸāŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¤āŽžāŽŠāŽžāŽ• āŽ’āŽ´ā¯āŽ™ā¯āŽ•āŽŽā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯. āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ¤āŽ•āŽĩāŽ˛ā¯āŽ•ā¯āŽ•ā¯, āŽ†āŽĩāŽŖāŽ™ā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", + "storage_template_more_details": "āŽ‡āŽ¨ā¯āŽ¤ āŽ¨āŽąā¯āŽĒāŽŖā¯āŽĒ❈āŽĒā¯ āŽĒāŽąā¯āŽąāŽŋāŽ¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯, Storage Template āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ…āŽ¤āŽŠā¯ āŽ¤āŽžāŽ•ā¯āŽ•āŽ™ā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "storage_template_onboarding_description_v2": "āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯, āŽ‡āŽ¨ā¯āŽ¤ āŽ¨āŽąā¯āŽĒāŽŖā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠāŽ°ā¯ āŽĩāŽ°ā¯ˆāŽ¯āŽąā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯āŽŸāŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤āŽžāŽŠāŽžāŽ• āŽ’āŽ´ā¯āŽ™ā¯āŽ•āŽŽā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯. āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ¤āŽ•āŽĩāŽ˛ā¯āŽ•ā¯āŽ•ā¯, āŽ†āŽĩāŽŖāŽ™ā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽžāŽ°ā¯.", "storage_template_path_length": "āŽ¤ā¯‹āŽ°āŽžāŽ¯āŽŽāŽžāŽŠ āŽĒāŽžāŽ¤ā¯ˆ āŽ¨ā¯€āŽŗ āŽĩāŽ°āŽŽā¯āŽĒ❁: {length, number}/{limit, number}", "storage_template_settings": "āŽ¸ā¯āŽŸā¯‹āŽ°ā¯‡āŽœā¯ āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯", "storage_template_settings_description": "āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽĒā¯†āŽ¯āŽ°ā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -336,7 +351,7 @@ "template_settings": "āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒ❁ āŽĩāŽžāŽ°ā¯āŽĒā¯āŽĒā¯āŽ°ā¯āŽ•ā¯āŽ•āŽŗā¯", "template_settings_description": "āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽĩāŽžāŽ°ā¯āŽĒā¯āŽĒā¯āŽ°ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "theme_custom_css_settings": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ CSS", - "theme_custom_css_settings_description": "CSS āŽ…āŽŽā¯āŽšāŽŽā¯ Immich āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽĒā¯āŽĒ❈ āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠāŽžāŽ•ā¯āŽ• āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯.", + "theme_custom_css_settings_description": "āŽ…āŽŸā¯āŽ•ā¯āŽ•ā¯ āŽ¨āŽŸā¯ˆ āŽ¤āŽžāŽŗā¯āŽ•āŽŗā¯ āŽ¨āŽąā¯āŽĒāŽŖā¯āŽĒ❈āŽĒā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽĒā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠāŽžāŽ•ā¯āŽ• āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯.", "theme_settings": "āŽ¤ā¯€āŽŽā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", "theme_settings_description": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽĩāŽ˛ā¯ˆ āŽ‡āŽŸā¯ˆāŽŽā¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠāŽžāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "thumbnail_generation_job": "āŽšāŽŋāŽąā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -396,7 +411,7 @@ "transcoding_tone_mapping": "āŽ¤ā¯ŠāŽŠāŽŋ-āŽŽā¯‡āŽĒā¯āŽĒāŽŋāŽ™ā¯", "transcoding_tone_mapping_description": "āŽŽāŽšā¯.āŽŸāŽŋ.āŽ†āŽ°āŽžāŽ• āŽŽāŽžāŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽŽāŽšā¯.āŽŸāŽŋ.āŽ†āŽ°ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ¤ā¯‹āŽąā¯āŽąāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽ•ā¯āŽ• āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽ•āŽŗā¯. āŽ’āŽĩā¯āŽĩā¯ŠāŽ°ā¯ āŽĩāŽ´āŽŋāŽŽā¯āŽąā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩāŽŖā¯āŽŖāŽŽā¯, āŽĩāŽŋāŽĩāŽ°āŽŽā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĒāŽŋāŽ°āŽ•āŽžāŽšāŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽĩ❆āŽĩā¯āŽĩā¯‡āŽąā¯ āŽĒāŽ°āŽŋāŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽ…āŽĒāŽŋāŽŗā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽ•ā¯āŽ•āŽŋāŽąāŽžāŽ°ā¯, āŽŽā¯ŠāŽĒāŽŋāŽ¯āŽšā¯ āŽ¨āŽŋāŽąāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽ•ā¯āŽ•āŽŋāŽąāŽžāŽ°ā¯, āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ°ā¯†āŽ¯ā¯āŽŠā¯āŽ†āŽ°ā¯āŽŸā¯ āŽĒāŽŋāŽ°āŽ•āŽžāŽšāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽ•ā¯āŽ•āŽŋāŽąāŽžāŽ°ā¯.", "transcoding_transcode_policy": "āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯ āŽ•ā¯ŠāŽŗā¯āŽ•ā¯ˆ", - "transcoding_transcode_policy_description": "āŽ’āŽ°ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽŽāŽĒā¯āŽĒā¯‹āŽ¤ā¯ āŽŽāŽžāŽąā¯āŽąāŽĒā¯āŽĒāŽŸ āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯ āŽŽāŽŠā¯āŽĒāŽ¤āŽąā¯āŽ•āŽžāŽŠ āŽ•ā¯ŠāŽŗā¯āŽ•ā¯ˆ. āŽŽāŽšā¯.āŽŸāŽŋ.āŽ†āŽ°ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽĒā¯āŽĒā¯‹āŽ¤ā¯āŽŽā¯ āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ (āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸāŽŋāŽ™ā¯ āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯ āŽ¤āŽĩāŽŋāŽ°).", + "transcoding_transcode_policy_description": "āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽŽāŽĒā¯āŽĒā¯‹āŽ¤ā¯ āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸ āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯ āŽŽāŽŠā¯āŽĒāŽ¤āŽąā¯āŽ•āŽžāŽŠ āŽ•ā¯ŠāŽŗā¯āŽ•ā¯ˆ. HDR āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽŽāŽąā¯āŽąā¯āŽŽā¯ YUV 4:2:0 āŽ¤āŽĩāŽŋāŽ° āŽĩā¯‡āŽąā¯ āŽĒāŽŸāŽĒā¯āŽĒā¯āŽŗā¯āŽŗāŽŋ āŽĩāŽŸāŽŋāŽĩāŽ¤ā¯āŽ¤ā¯āŽŸāŽŠā¯ āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽĒā¯āŽĒā¯ŠāŽ´ā¯āŽ¤ā¯āŽŽā¯ āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ (āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸāŽŋāŽ™ā¯ āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯ āŽ¤āŽĩāŽŋāŽ°).", "transcoding_two_pass_encoding": "āŽ‡āŽ°āŽŖā¯āŽŸā¯-āŽĒāŽžāŽšā¯ āŽ•ā¯āŽąāŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽŽā¯", "transcoding_two_pass_encoding_setting_description": "āŽšāŽŋāŽąāŽ¨ā¯āŽ¤ āŽ•ā¯āŽąāŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ• āŽ‡āŽ°āŽŖā¯āŽŸā¯ āŽĒāŽžāŽšā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯. āŽŽā¯‡āŽ•ā¯āŽšā¯ āŽĒāŽŋāŽŸā¯āŽ°ā¯‡āŽŸā¯ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ (H.264 āŽŽāŽąā¯āŽąā¯āŽŽā¯ HEVC āŽ‰āŽŸāŽŠā¯ āŽĩā¯‡āŽ˛ā¯ˆ āŽšā¯†āŽ¯ā¯āŽ¯ āŽ‡āŽ¤ā¯ āŽ¤ā¯‡āŽĩ❈āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯), āŽ‡āŽ¨ā¯āŽ¤ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆ āŽ…āŽ¤āŽŋāŽ•āŽĒāŽŸā¯āŽš āŽĒāŽŋāŽŸā¯āŽ°ā¯‡āŽŸā¯āŽŸā¯ˆ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽžāŽ•āŽ•ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸ āŽĒāŽŋāŽŸā¯āŽ°ā¯‡āŽŸā¯ āŽĩāŽ°āŽŽā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽąāŽ¤ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ CRF āŽ āŽĒā¯āŽąāŽ•ā¯āŽ•āŽŖāŽŋāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. VP9 āŽāŽĒā¯ āŽĒā¯ŠāŽąā¯āŽ¤ā¯āŽ¤āŽĩāŽ°ā¯ˆ, āŽ…āŽ¤āŽŋāŽ•āŽĒāŽŸā¯āŽš āŽĒāŽŋāŽŸā¯āŽ°ā¯‡āŽŸā¯ āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯ CRF āŽāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽ˛āŽžāŽŽā¯.", "transcoding_video_codec": "āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽ•ā¯‹āŽŸā¯†āŽ•ā¯", @@ -413,7 +428,7 @@ "user_delete_delay": "{user}āŽ‡āŽŠā¯ āŽ•āŽŖāŽ•ā¯āŽ•ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ {delay, plural, one {# āŽ¨āŽžāŽŗā¯} other {# āŽ¨āŽžāŽŗā¯āŽ•āŽŗā¯}}āŽ‡āŽ˛ā¯ āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ° āŽ¨ā¯€āŽ•ā¯āŽ•āŽ¤ā¯ āŽ¤āŽŋāŽŸā¯āŽŸāŽŽāŽŋāŽŸāŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", "user_delete_delay_settings": "āŽ¤āŽžāŽŽāŽ¤āŽ¤ā¯āŽ¤ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ•ā¯", "user_delete_delay_settings_description": "āŽŽāŽŖā¯ of days after āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽŽā¯ āŽĒā¯†āŽąā¯āŽ¨āŽ°ā¯ permanently āŽ¨ā¯€āŽ•ā¯āŽ•ā¯ a user's account and assets. āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽ¤āŽ¯āŽžāŽ°āŽžāŽ• āŽ‡āŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯ āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯ˆāŽšā¯ āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ• āŽĒāŽ¯āŽŠāŽ°ā¯ āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽ¤āŽ˛ā¯ āŽĩā¯‡āŽ˛ā¯ˆ āŽ¨āŽŗā¯āŽŗāŽŋāŽ°āŽĩāŽŋāŽ˛ā¯ āŽ‡āŽ¯āŽ™ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽ‡āŽ¨ā¯āŽ¤ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒāŽŋāŽ˛ā¯ āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽŸā¯āŽ¤ā¯āŽ¤ āŽŽāŽ°āŽŖāŽ¤āŽŖā¯āŽŸāŽŠā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", - "user_delete_immediately": " {user} āŽ‡āŽŠā¯ āŽ•āŽŖāŽ•ā¯āŽ•ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ° āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽ¤āŽ˛ā¯āŽ•ā¯āŽ•āŽžāŽ• āŽĩāŽ°āŽŋāŽšā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ¨āŽŋāŽąā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽ‰āŽŸāŽŠāŽŸāŽŋāŽ¯āŽžāŽ• .", + "user_delete_immediately": "{user} āŽ‡āŽŠā¯ āŽ•āŽŖāŽ•ā¯āŽ•ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ° āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽ¤āŽ˛ā¯āŽ•ā¯āŽ•āŽžāŽ• āŽĩāŽ°āŽŋāŽšā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ¨āŽŋāŽąā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽ‰āŽŸāŽŠāŽŸāŽŋāŽ¯āŽžāŽ•.", "user_delete_immediately_checkbox": "āŽ‰āŽŸāŽŠāŽŸāŽŋāŽ¯āŽžāŽ• āŽ¨ā¯€āŽ•ā¯āŽ• āŽĒāŽ¯āŽŠāŽ°ā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯", "user_details": "āŽĒāŽ¯āŽŠāŽ°ā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯", "user_management": "āŽĒāŽ¯āŽŠāŽ°ā¯ āŽŽā¯‡āŽ˛āŽžāŽŖā¯āŽŽā¯ˆ", @@ -426,7 +441,7 @@ "user_successfully_removed": "āŽĒāŽ¯āŽŠāŽ°ā¯ {email} āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽ…āŽ•āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯.", "users_page_description": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ• āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯ āŽĒāŽ•ā¯āŽ•āŽŽā¯", "version_check_enabled_description": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽĒā¯āŽĒ❁ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", - "version_check_implications": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽĒā¯āŽĒ❁ āŽ…āŽŽā¯āŽšāŽŽā¯ github .com āŽ‰āŽŸāŽŠāŽžāŽŠ āŽ…āŽĩā¯āŽĩāŽĒā¯āŽĒā¯‹āŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ°ā¯āŽĒā¯āŽ•ā¯ŠāŽŗā¯āŽĩāŽ¤ā¯ˆ āŽ¨āŽŽā¯āŽĒāŽŋāŽ¯ā¯āŽŗā¯āŽŗāŽ¤ā¯", + "version_check_implications": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽĒā¯āŽĒ❁ āŽ…āŽŽā¯āŽšāŽŽā¯ {server} āŽ‰āŽŸāŽŠāŽžāŽŠ āŽ…āŽĩā¯āŽĩāŽĒā¯āŽĒā¯‹āŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ°ā¯āŽĒā¯āŽ•ā¯ŠāŽŗā¯āŽĩāŽ¤ā¯ˆ āŽ¨āŽŽā¯āŽĒāŽŋāŽ¯ā¯āŽŗā¯āŽŗāŽ¤ā¯", "version_check_settings": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽšā¯‹āŽ¤āŽŠā¯ˆ", "version_check_settings_description": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒ❈ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯/āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "video_conversion_job": "āŽŸāŽŋāŽ°āŽžāŽŠā¯āŽšā¯āŽ•ā¯‹āŽŸā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯", @@ -436,6 +451,9 @@ "admin_password": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯", "administration": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŽā¯", "advanced": "āŽŽā¯‡āŽŽā¯āŽĒāŽŸā¯āŽŸ", + "advanced_settings_clear_image_cache": "āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ¤āŽąā¯āŽ•āŽžāŽ˛āŽŋāŽ• āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒ❈ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "advanced_settings_clear_image_cache_error": "āŽĒāŽŸāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ¤āŽąā¯āŽ•āŽžāŽ˛āŽŋāŽ• āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒ❈ āŽ…āŽ´āŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "advanced_settings_clear_image_cache_success": "{size} āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "advanced_settings_enable_alternate_media_filter_subtitle": "āŽŽāŽžāŽąā¯āŽąā¯ āŽ…āŽŗāŽĩā¯āŽ•ā¯‹āŽ˛ā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩāŽŋāŽŠā¯ āŽĒā¯‹āŽ¤ā¯ āŽŽā¯€āŽŸāŽŋāŽ¯āŽžāŽĩ❈ āŽĩāŽŸāŽŋāŽ•āŽŸā¯āŽŸ āŽ‡āŽ¨ā¯āŽ¤ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯. āŽŽāŽ˛ā¯āŽ˛āŽž āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ†āŽĒā¯āŽ¸ā¯ āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽĩāŽ¤āŽŋāŽ˛ā¯ āŽšāŽŋāŽ•ā¯āŽ•āŽ˛ā¯āŽ•āŽŗā¯ āŽ‡āŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ‡āŽ¤ā¯ˆ āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", "advanced_settings_enable_alternate_media_filter_title": "[āŽĒāŽ°āŽŋāŽšā¯‹āŽ¤āŽŠā¯ˆāŽ•ā¯āŽ•ā¯ āŽ‰āŽŸā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯] āŽŽāŽžāŽąā¯āŽąā¯ āŽšāŽžāŽ¤āŽŠ āŽ†āŽ˛ā¯āŽĒ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩ❁ āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "advanced_settings_log_level_title": "āŽĒāŽ¤āŽŋāŽĩ❁ āŽ¨āŽŋāŽ˛ā¯ˆ: {level}", @@ -472,10 +490,12 @@ "album_remove_user": "āŽĒāŽ¯āŽŠāŽ°ā¯ˆ āŽ…āŽ•āŽąā¯āŽąāŽĩāŽž?", "album_remove_user_confirmation": "{user} āŽ āŽ…āŽ•āŽąā¯āŽą āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", "album_search_not_found": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¤ā¯‡āŽŸāŽ˛ā¯āŽŸāŽŠā¯ āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", + "album_selected": "āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "album_share_no_users": "āŽ‡āŽ¨ā¯āŽ¤ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆ āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽ˛ā¯āŽ˛āŽž āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯āŽŽā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸāŽ¤āŽžāŽ•āŽ¤ā¯ āŽ¤ā¯†āŽ°āŽŋāŽ•āŽŋāŽąāŽ¤ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗāŽŋāŽŸāŽŽā¯ āŽŽāŽ¨ā¯āŽ¤ āŽĒāŽ¯āŽŠāŽ°ā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ.", "album_summary": "āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽšā¯āŽ°ā¯āŽ•ā¯āŽ•āŽŽā¯", "album_updated": "āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "album_updated_setting_description": "āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĒā¯āŽ¤āŽŋāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽ‡āŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯ āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒ❈āŽĒā¯ āŽĒā¯†āŽąā¯āŽ™ā¯āŽ•āŽŗā¯", + "album_upload_assets": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŖāŽŋāŽŠāŽŋāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŋ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "album_user_left": "āŽ‡āŽŸāŽ¤ā¯ {album}", "album_user_removed": "āŽ…āŽ•āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯ {user}", "album_viewer_appbar_delete_confirm": "āŽ‡āŽ¨ā¯āŽ¤ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŖāŽ•ā¯āŽ•āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ¨ā¯€āŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", @@ -493,9 +513,11 @@ "albums_default_sort_order_description": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽ†āŽ°āŽŽā¯āŽĒ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĩāŽ°āŽŋāŽšā¯ˆāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽ˛ā¯ āŽĩāŽ°āŽŋāŽšā¯ˆ.", "albums_feature_description": "āŽĒāŽŋāŽą āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•ā¯ŠāŽŗā¯āŽŗāŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ¤ā¯ŠāŽ•ā¯āŽĒā¯āŽĒā¯āŽ•āŽŗā¯.", "albums_on_device_count": "āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ ({count})", + "albums_selected": "{count, plural, one {# āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯} other {# āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ}}", "all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯āŽŽā¯", "all_albums": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯āŽŽā¯", "all_people": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽŽāŽ•ā¯āŽ•āŽŗā¯āŽŽā¯", + "all_photos": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽŽā¯", "all_videos": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯āŽŽā¯", "allow_dark_mode": "āŽ‡āŽ°ā¯āŽŖā¯āŽŸ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆ āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "allow_edits": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ˆ āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -503,6 +525,9 @@ "allow_public_user_to_upload": "āŽĒā¯ŠāŽ¤ā¯ āŽĒāŽ¯āŽŠāŽ°ā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "allowed": "āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ¤ā¯āŽ¤", "alt_text_qr_code": "QR āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯ āŽĒāŽŸāŽŽā¯", + "always_keep": "āŽŽāŽĒā¯āŽĒā¯‹āŽ¤ā¯āŽŽā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "always_keep_photos_hint": "āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗ āŽŽāŽ˛ā¯āŽ˛āŽžāŽĒā¯ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•ā¯āŽ™ā¯āŽ•āŽŗā¯.", + "always_keep_videos_hint": "āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽŽāŽ˛ā¯āŽ˛āŽž āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•ā¯āŽŽā¯.", "anti_clockwise": "āŽ•āŽŸāŽŋāŽ•āŽžāŽ° āŽŽāŽ¤āŽŋāŽ°ā¯āŽĒā¯āŽĒ❁", "api_key": "āŽĒāŽ¨āŽŋāŽ‡ āŽĩāŽŋāŽšā¯ˆ", "api_key_description": "āŽ‡āŽ¨ā¯āŽ¤ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽ’āŽ°ā¯ āŽŽā¯āŽąā¯ˆ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ•āŽžāŽŖā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯. āŽšāŽžāŽŗāŽ°āŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯‚āŽŸā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽŽā¯āŽŠā¯ āŽ…āŽ¤ā¯ˆ āŽ¨āŽ•āŽ˛ā¯†āŽŸā¯āŽ•ā¯āŽ• āŽŽāŽąāŽ•ā¯āŽ•āŽžāŽ¤ā¯€āŽ°ā¯āŽ•āŽŗā¯.", @@ -529,10 +554,12 @@ "archived_count": "{count, plural, other {āŽ•āŽžāŽĒā¯āŽĒāŽ•āŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯ #}}", "are_these_the_same_person": "āŽ‡āŽĩāŽ°ā¯āŽ•āŽŗā¯ āŽ’āŽ°ā¯‡ āŽ¨āŽĒāŽ°āŽž?", "are_you_sure_to_do_this": "āŽ‡āŽ¤ā¯ˆ āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽšā¯†āŽ¯ā¯āŽ¯ āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", + "array_field_not_fully_supported": "āŽĩāŽ°āŽŋāŽšā¯ˆ āŽĒā¯āŽ˛āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ•ā¯ˆāŽŽā¯āŽąā¯ˆāŽ¯āŽžāŽ• āŽšāŽžāŽ¤ā¯ŠāŽĒā¯ŠāŽ•ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽŽā¯ āŽ¤ā¯‡āŽĩ❈", "asset_action_delete_err_read_only": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ (āŽ•āŽŗā¯ˆ) āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽĒāŽŸāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", "asset_action_share_err_offline": "āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒāŽŋāŽ˛ā¯āŽ˛āŽžāŽ¤ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ (āŽ•āŽŗā¯ˆ) āŽĒā¯†āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯, āŽ¤āŽĩāŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "asset_added_to_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "asset_adding_to_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", + "asset_created": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "asset_description_updated": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĩāŽŋāŽŗāŽ•ā¯āŽ•āŽŽā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗāŽ¤ā¯", "asset_filename_is_offline": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ {filename} āŽ†āŽƒāŽĒā¯āŽ˛ā¯ˆāŽŠāŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽ¤ā¯", "asset_has_unassigned_faces": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ’āŽ¤ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤ āŽŽā¯āŽ•āŽ™ā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸā¯āŽŗā¯āŽŗāŽ¤ā¯", @@ -545,6 +572,9 @@ "asset_list_layout_sub_title": "āŽŽāŽŠā¯ˆāŽ¯āŽŽā¯ˆāŽĩ❁", "asset_list_settings_subtitle": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸ āŽ•āŽŸā¯āŽŸāŽŽā¯ āŽ¤āŽŗāŽĩāŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", "asset_list_settings_title": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸ āŽ•āŽŸā¯āŽŸāŽŽā¯", + "asset_not_found_on_device_android": "āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", + "asset_not_found_on_device_ios": "āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ. āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ iCloud āŽāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗā¯ āŽŽāŽŠāŽŋāŽ˛ā¯, iCloud āŽ‡āŽ˛ā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗ āŽŽā¯‹āŽšāŽŽāŽžāŽŠ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽ•āŽžāŽ°āŽŖāŽŽāŽžāŽ• āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŖā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽŽāŽ˛ā¯ āŽĒā¯‹āŽ•āŽ˛āŽžāŽŽā¯", + "asset_not_found_on_icloud": "iCloud āŽ‡āŽ˛ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ. iCloud āŽ‡āŽ˛ā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗ āŽŽā¯‹āŽšāŽŽāŽžāŽŠ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽ•āŽžāŽ°āŽŖāŽŽāŽžāŽ• āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ…āŽŖā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤āŽ¤āŽžāŽ• āŽ‡āŽ°ā¯āŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯", "asset_offline": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ†āŽƒāŽĒā¯āŽ˛ā¯ˆāŽŠāŽŋāŽ˛ā¯", "asset_offline_description": "āŽ‡āŽ¨ā¯āŽ¤ āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒā¯āŽą āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ‡āŽŠāŽŋ āŽĩāŽŸā¯āŽŸāŽŋāŽ˛ā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ. āŽ‰āŽ¤āŽĩāŽŋāŽ•ā¯āŽ•ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋāŽ¯ā¯ˆ āŽ¤ā¯ŠāŽŸāŽ°ā¯āŽĒ❁ āŽ•ā¯ŠāŽŗā¯āŽŗāŽĩā¯āŽŽā¯.", "asset_restored_successfully": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -596,7 +626,7 @@ "backup_album_selection_page_select_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "backup_album_selection_page_selection_info": "āŽ¤ā¯‡āŽ°ā¯āŽĩ❁ āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ", "backup_album_selection_page_total_assets": "āŽŽā¯ŠāŽ¤ā¯āŽ¤ āŽ¤āŽŠāŽŋāŽ¤ā¯āŽ¤ā¯āŽĩāŽŽāŽžāŽŠ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯", - "backup_albums_sync": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩ❁", + "backup_albums_sync": "āŽ•āŽžāŽĒā¯āŽĒ❁ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩ❁", "backup_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯āŽŽā¯", "backup_background_service_backup_failed_message": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽ¤ā¯ āŽ¤āŽĩāŽąāŽŋāŽĩāŽŋāŽŸā¯āŽŸāŽ¤ā¯. āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽĒā¯āŽĒāŽ¤ā¯â€Ļ", "backup_background_service_complete_notification": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽā¯āŽŸāŽŋāŽ¨ā¯āŽ¤āŽ¤ā¯", @@ -657,6 +687,7 @@ "backup_options_page_title": "āŽ•āŽžāŽĒā¯āŽĒ❁ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯", "backup_setting_subtitle": "āŽĒāŽŋāŽŠā¯āŽŠāŽŖāŽŋ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽā¯āŽŠā¯āŽĒā¯āŽą āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "backup_settings_subtitle": "āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "backup_upload_details_page_more_details": "āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ¤āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", "backward": "āŽĒāŽŋāŽŠā¯āŽŠā¯‹āŽ•ā¯āŽ•ā¯", "biometric_auth_enabled": "āŽĒāŽ¯ā¯‹āŽŽā¯†āŽŸā¯āŽ°āŽŋāŽ•ā¯ āŽāŽąā¯āŽĒ❁ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "biometric_locked_out": "āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽĒāŽ¯ā¯‹āŽŽā¯†āŽŸā¯āŽ°āŽŋāŽ•ā¯ āŽ…āŽ™ā¯āŽ•ā¯€āŽ•āŽžāŽ°āŽ¤ā¯āŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĒā¯‚āŽŸā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗā¯", @@ -715,6 +746,8 @@ "change_password_form_password_mismatch": "āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽąā¯āŽ•āŽŗā¯ āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "change_password_form_reenter_new_password": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ‰āŽŗā¯āŽŗāŽŋāŽŸāŽĩā¯āŽŽā¯", "change_pin_code": "āŽŽā¯āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽĩā¯āŽŽā¯", + "change_trigger": "āŽ¤ā¯‚āŽŖā¯āŽŸā¯āŽ¤āŽ˛ā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽĩā¯āŽŽā¯", + "change_trigger_prompt": "āŽ¤ā¯‚āŽŖā¯āŽŸā¯āŽ¤āŽ˛ā¯ˆ āŽ¨āŽŋāŽšā¯āŽšāŽ¯āŽŽāŽžāŽ• āŽŽāŽžāŽąā¯āŽą āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž? āŽ‡āŽ¤ā¯ āŽāŽąā¯āŽ•āŽŠāŽĩ❇ āŽ‰āŽŗā¯āŽŗ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽšā¯†āŽ¯āŽ˛ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ…āŽ•āŽąā¯āŽąā¯āŽŽā¯.", "change_your_password": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽĩā¯āŽŽā¯", "changed_visibility_successfully": "āŽ¤ā¯†āŽ°āŽŋāŽĩā¯āŽ¨āŽŋāŽ˛ā¯ˆ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽŽāŽžāŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "charging": "āŽšāŽžāŽ°ā¯āŽšāŽŋāŽ™ā¯", @@ -723,8 +756,21 @@ "check_corrupt_asset_backup_button": "āŽ•āŽžāŽšā¯‹āŽ˛ā¯ˆ āŽšā¯†āŽ¯ā¯āŽ¯ā¯āŽ™ā¯āŽ•āŽŗā¯", "check_corrupt_asset_backup_description": "āŽ‡āŽ¨ā¯āŽ¤ āŽ•āŽžāŽšā¯‹āŽ˛ā¯ˆāŽ¯ā¯ˆ āŽĩā¯ˆāŽƒāŽĒ❈ āŽŽā¯€āŽ¤ā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯, āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯āŽŽā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽĩā¯āŽŸāŽŠā¯. āŽšā¯†āŽ¯āŽ˛ā¯āŽŽā¯āŽąā¯ˆ āŽšāŽŋāŽ˛ āŽ¨āŽŋāŽŽāŽŋāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽ†āŽ•āŽ˛āŽžāŽŽā¯.", "check_logs": "āŽĒāŽ¤āŽŋāŽĩā¯āŽ•āŽŗā¯ˆ āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "checksum": "āŽšā¯†āŽ•ā¯āŽšāŽŽā¯", "choose_matching_people_to_merge": "āŽ’āŽŠā¯āŽąāŽŋāŽŖā¯ˆāŽ•ā¯āŽ• āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽ¨āŽĒāŽ°ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ•", "city": "āŽ¨āŽ•āŽ°āŽŽā¯", + "cleanup_confirm_description": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ {count} āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ ({date} āŽ•ā¯āŽ•ā¯ āŽŽā¯āŽŠā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯) āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽĒā¯āŽĒāŽžāŽ• āŽšāŽ°ā¯āŽĩāŽ°āŽŋāŽ˛ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽŗā¯āŽŗāŽžāŽ°ā¯. āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ‰āŽŗā¯āŽŗāŽ• āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯ˆ āŽ…āŽ•āŽąā¯āŽąāŽĩāŽž?", + "cleanup_confirm_prompt_title": "āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ…āŽ•āŽąā¯āŽąāŽĩāŽž?", + "cleanup_deleted_assets": "{count} āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ", + "cleanup_deleting": "āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ•āŽŋāŽąāŽ¤ā¯...", + "cleanup_found_assets": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯ {count} āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ", + "cleanup_found_assets_with_size": "{count} āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯ ({size}) āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ", + "cleanup_icloud_shared_albums_excluded": "iCloud āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽĩāŽ°ā¯āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽĩāŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĩāŽŋāŽ˛āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗāŽŠ", + "cleanup_no_assets_found": "āŽŽā¯‡āŽ˛ā¯‡ āŽ‰āŽŗā¯āŽŗ āŽ…āŽŗāŽĩā¯āŽ•ā¯‹āŽ˛ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯ āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ. āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽŋāŽŠāŽžāŽ˛ā¯, āŽšāŽ°ā¯āŽĩāŽ°āŽŋāŽ˛ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ…āŽ•āŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯ā¯āŽŽā¯", + "cleanup_preview_title": "āŽ…āŽ•āŽąā¯āŽą āŽĩā¯‡āŽŖā¯āŽŸāŽŋāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ ({count})", + "cleanup_step3_description": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¤ā¯‡āŽ¤āŽŋāŽ¯ā¯āŽŸāŽŠā¯ āŽĒā¯ŠāŽ°ā¯āŽ¨ā¯āŽ¤āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽĩāŽ°ā¯āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯.", + "cleanup_step4_summary": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‰āŽŗā¯āŽŗāŽ• āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ…āŽ•āŽąā¯āŽą {count} āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ ({date}āŽ•ā¯āŽ•ā¯ āŽŽā¯āŽŠā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯). āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸāŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ…āŽŖā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯ā¯āŽŽā¯.", + "cleanup_trash_hint": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯āŽ´ā¯āŽŽā¯ˆāŽ¯āŽžāŽ• āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽ•ā¯āŽ•, āŽšāŽŋāŽšā¯āŽŸāŽŽā¯ āŽ•ā¯‡āŽ˛āŽ°āŽŋ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽąāŽ¨ā¯āŽ¤ā¯ āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ¯ā¯ˆ āŽĩā¯†āŽąā¯āŽŽā¯ˆ āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", "clear": "āŽ¤ā¯†āŽŗāŽŋāŽĩāŽžāŽŠ", "clear_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "clear_all_recent_searches": "āŽ…āŽŖā¯āŽŽā¯ˆāŽ•ā¯ āŽ•āŽžāŽ˛ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ¤ā¯‡āŽŸāŽ˛ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -736,6 +782,8 @@ "client_cert_import": "āŽ‡āŽąāŽ•ā¯āŽ•ā¯āŽŽāŽ¤āŽŋ", "client_cert_import_success_msg": "āŽ•āŽŋāŽŗā¯ˆāŽ¯āŽŠā¯āŽŸā¯ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ āŽ‡āŽąāŽ•ā¯āŽ•ā¯āŽŽāŽ¤āŽŋ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯", "client_cert_invalid_msg": "āŽ¤āŽĩāŽąāŽžāŽŠ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ¤āŽĩāŽąāŽžāŽŠ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯", + "client_cert_password_message": "āŽ‡āŽ¨ā¯āŽ¤ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯āŽ•ā¯āŽ•āŽžāŽŠ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽ‰āŽŗā¯āŽŗāŽŋāŽŸāŽĩā¯āŽŽā¯", + "client_cert_password_title": "āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯", "client_cert_remove_msg": "āŽ•āŽŋāŽŗā¯ˆāŽ¯āŽŠā¯āŽŸā¯ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ āŽ…āŽ•āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "client_cert_subtitle": "PKCS12 (.p12, .pfx) āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽĒā¯āŽĒ❈ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽ†āŽ¤āŽ°āŽŋāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽŽā¯āŽŠā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ āŽ‡āŽąāŽ•ā¯āŽ•ā¯āŽŽāŽ¤āŽŋ/āŽ…āŽ•āŽąā¯āŽąā¯āŽ¤āŽ˛ā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯", "client_cert_title": "SSL āŽ•āŽŋāŽŗā¯ˆāŽ¯āŽŠā¯āŽŸā¯ āŽšāŽžāŽŠā¯āŽąāŽŋāŽ¤āŽ´ā¯ [āŽĒāŽ°āŽŋāŽšā¯‹āŽ¤āŽŠā¯ˆ]", @@ -746,6 +794,11 @@ "color": "āŽ¨āŽŋāŽąāŽŽā¯", "color_theme": "āŽĩāŽŖā¯āŽŖ āŽ•āŽ°ā¯āŽĒā¯āŽĒā¯ŠāŽ°ā¯āŽŗā¯", "command": "āŽ•āŽŸā¯āŽŸāŽŗā¯ˆ", + "command_palette_prompt": "āŽĒāŽ•ā¯āŽ•āŽ™ā¯āŽ•āŽŗā¯, āŽšā¯†āŽ¯āŽ˛ā¯āŽ•āŽŗā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ•āŽŸā¯āŽŸāŽŗā¯ˆāŽ•āŽŗā¯ˆ āŽĩāŽŋāŽ°ā¯ˆāŽĩāŽžāŽ•āŽ•ā¯ āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽ¯āŽĩā¯āŽŽā¯", + "command_palette_to_close": "āŽŽā¯‚āŽŸā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯", + "command_palette_to_navigate": "āŽ¨ā¯āŽ´ā¯ˆāŽ¯", + "command_palette_to_select": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•", + "command_palette_to_show_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ•āŽžāŽŸā¯āŽŸ", "comment_deleted": "āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯ āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "comment_options": "āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯", "comments_and_likes": "āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯", @@ -790,6 +843,7 @@ "create_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "create_album_page_untitled": "āŽ¤āŽ˛ā¯ˆāŽĒā¯āŽĒāŽŋāŽŸāŽĒā¯āŽĒāŽŸāŽžāŽ¤", "create_api_key": "āŽĒāŽ¨āŽŋāŽ‡ āŽĩāŽŋāŽšā¯ˆāŽ¯ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "create_first_workflow": "āŽŽā¯āŽ¤āŽ˛ā¯ āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "create_library": "āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "create_link": "āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒ❈ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "create_link_to_share": "āŽĒāŽ•āŽŋāŽ°ā¯āŽĩā¯āŽ•ā¯āŽ•ā¯ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒ❈ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -804,17 +858,25 @@ "create_tag": "āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "create_tag_description": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯. āŽ‰āŽŗā¯āŽŗāŽŽā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽąā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯, āŽŽā¯āŽŠā¯āŽŠā¯‹āŽ•ā¯āŽ•āŽŋ āŽšā¯āŽ˛āŽžāŽšā¯āŽ•āŽŗā¯ āŽ‰āŽŸā¯āŽĒāŽŸ āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛āŽŋāŽŠā¯ āŽŽā¯āŽ´ā¯ āŽĒāŽžāŽ¤ā¯ˆāŽ¯ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ‰āŽŗā¯āŽŗāŽŋāŽŸāŽĩā¯āŽŽā¯.", "create_user": "āŽĒāŽ¯āŽŠāŽ°ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯", + "create_workflow": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "created": "āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "created_at": "āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "creating_linked_albums": "āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽ¤āŽ˛ā¯ ...", "crop": "āŽĒāŽ¯āŽŋāŽ°ā¯", + "crop_aspect_ratio_fixed": "āŽšāŽ°āŽŋ āŽšā¯†āŽ¯ā¯āŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "crop_aspect_ratio_free": "āŽ‡āŽ˛āŽĩāŽšāŽŽā¯", + "crop_aspect_ratio_original": "āŽ…āŽšāŽ˛ā¯", "curated_object_page_title": "āŽĩāŽŋāŽšāŽ¯āŽ™ā¯āŽ•āŽŗā¯", "current_device": "āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ˆāŽ¯ āŽšāŽžāŽ¤āŽŠāŽŽā¯", "current_pin_code": "āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ˆāŽ¯ āŽŽā¯āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯", "current_server_address": "āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ˆāŽ¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ• āŽŽā¯āŽ•āŽĩāŽ°āŽŋ", - "custom_locale": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽ‡āŽŸāŽŽā¯", - "custom_locale_description": "āŽŽā¯ŠāŽ´āŽŋ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĒāŽŋāŽ°āŽžāŽ¨ā¯āŽ¤āŽŋāŽ¯āŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽ¤ā¯‡āŽ¤āŽŋāŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽāŽŖā¯āŽ•āŽŗā¯", + "custom_date": "āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒ āŽ¤ā¯‡āŽ¤āŽŋ", + "custom_locale": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽŽā¯ŠāŽ´āŽŋ", + "custom_locale_description": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽŽā¯ŠāŽ´āŽŋ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĒāŽŋāŽ°āŽžāŽ¨ā¯āŽ¤āŽŋāŽ¯āŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ¤ā¯‡āŽ¤āŽŋāŽ•āŽŗā¯, āŽ¨ā¯‡āŽ°āŽŽā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽāŽŖā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "custom_url": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽŽā¯āŽ•āŽĩāŽ°āŽŋ", + "cutoff_date_description": "āŽ•āŽŸā¯ˆāŽšāŽŋ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯â€Ļ", + "cutoff_day": "{count, plural, one {āŽ¨āŽžāŽŗā¯} other {āŽ¨āŽžāŽŗā¯āŽ•āŽŗā¯}}", + "cutoff_year": "{count, plural, one {āŽ†āŽŖā¯āŽŸā¯} other {āŽ†āŽŖā¯āŽŸā¯āŽ•āŽŗā¯}}", "daily_title_text_date": "E, mmm dd", "daily_title_text_date_year": "E, mmm dd, yyyy", "dark": "āŽ‡āŽ°ā¯āŽŖā¯āŽŸ", @@ -829,10 +891,6 @@ "day": "āŽ¨āŽžāŽŗā¯", "days": "āŽ¨āŽžāŽŸā¯āŽ•āŽŗā¯", "deduplicate_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ•āŽ´āŽŋāŽ¤ā¯āŽ¤āŽ˛ā¯", - "deduplication_criteria_1": "āŽĒā¯ˆāŽŸā¯āŽŸā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽĒāŽŸ āŽ…āŽŗāŽĩ❁", - "deduplication_criteria_2": "EXIF āŽ¤āŽ°āŽĩāŽŋāŽŠā¯ āŽŽāŽŖā¯āŽŖāŽŋāŽ•ā¯āŽ•ā¯ˆ", - "deduplication_info": "āŽ•āŽ´āŽŋāŽ¤ā¯āŽ¤āŽ˛ā¯ āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ", - "deduplication_info_description": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ¤āŽžāŽŠāŽžāŽ• āŽŽā¯āŽŠā¯āŽŠā¯†āŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛āŽĩā¯āŽŽā¯, āŽŽā¯ŠāŽ¤ā¯āŽ¤āŽŽāŽžāŽ• āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯ˆ āŽ…āŽ•āŽąā¯āŽąāŽĩā¯āŽŽā¯, āŽ¨āŽžāŽ™ā¯āŽ•āŽŗā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąā¯‹āŽŽā¯:", "delete": "āŽ¨ā¯€āŽ•ā¯āŽ•ā¯", "delete_action_confirmation_message": "āŽ‡āŽ¨ā¯āŽ¤ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž? āŽ‡āŽ¨ā¯āŽ¤ āŽ¨āŽŸāŽĩāŽŸāŽŋāŽ•ā¯āŽ•ā¯ˆ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯āŽŽā¯, āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽ¤ā¯ˆ āŽ‰āŽŗā¯āŽ¨āŽžāŽŸā¯āŽŸāŽŋāŽ˛ā¯ āŽ¨ā¯€āŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒāŽŋāŽŠāŽžāŽ˛ā¯ āŽ•ā¯‡āŽŸā¯āŽ•ā¯āŽŽā¯", "delete_action_prompt": "{count} āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -868,6 +926,7 @@ "deselect_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤ā¯‡āŽ°ā¯āŽĩ❁ āŽšā¯†āŽ¯ā¯āŽ¯ā¯āŽ™ā¯āŽ•āŽŗā¯", "details": "āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯", "direction": "āŽ¤āŽŋāŽšā¯ˆ", + "disable": "āŽŽā¯āŽŸāŽ•ā¯āŽ•ā¯", "disabled": "āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "disallow_edits": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ˆ āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "discord": "āŽŽā¯āŽ°āŽŖā¯āŽĒāŽžāŽŸā¯", @@ -893,6 +952,7 @@ "download_include_embedded_motion_videos": "āŽ‰āŽŸā¯āŽĒā¯ŠāŽ¤āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯", "download_include_embedded_motion_videos_description": "āŽŽā¯‹āŽšāŽŠā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽ‰āŽŸā¯āŽĒā¯ŠāŽ¤āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ¤āŽŠāŽŋ āŽ•ā¯‹āŽĒā¯āŽĒāŽžāŽ• āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "download_notfound": "āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "download_original": "āŽ…āŽšāŽ˛ā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•", "download_paused": "āŽ‡āŽŸā¯ˆāŽ¨āŽŋāŽąā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "download_settings": "āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•āŽŽā¯", "download_settings_description": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•āŽŽā¯ āŽ¤ā¯ŠāŽŸāŽ°ā¯āŽĒāŽžāŽŠ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -902,6 +962,7 @@ "download_waiting_to_retry": "āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽ•ā¯āŽ• āŽ•āŽžāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "downloading": "āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "downloading_asset_filename": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•āŽŽā¯ {filename}", + "downloading_from_icloud": "iCloud āŽ‡āŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "downloading_media": "āŽŠāŽŸāŽ•āŽ™ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "drop_files_to_upload": "āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽŽāŽ™ā¯āŽ•ā¯āŽŽā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽĩāŽŋāŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", "duplicates": "āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯", @@ -930,9 +991,24 @@ "edit_tag": "āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤ā¯", "edit_title": "āŽ¤āŽ˛ā¯ˆāŽĒā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤ā¯", "edit_user": "āŽĒāŽ¯āŽŠāŽ°ā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤ā¯", + "edit_workflow": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "editor": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽŋ", "editor_close_without_save_prompt": "āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤ā¯", "editor_close_without_save_title": "āŽŽā¯‚āŽŸā¯ āŽ†āŽšāŽŋāŽ°āŽŋāŽ¯āŽ°ā¯?", + "editor_confirm_reset_all_changes": "āŽŽāŽ˛ā¯āŽ˛āŽž āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", + "editor_discard_edits_confirm": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°āŽžāŽ•āŽ°āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "editor_discard_edits_prompt": "āŽ‰āŽ™ā¯āŽ•āŽŗāŽŋāŽŸāŽŽā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ āŽ‰āŽŗā¯āŽŗāŽŠ. āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ¨āŽŋāŽšā¯āŽšāŽ¯āŽŽāŽžāŽ• āŽ…āŽĩāŽąā¯āŽąā¯ˆ āŽ¨āŽŋāŽ°āŽžāŽ•āŽ°āŽŋāŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", + "editor_discard_edits_title": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°āŽžāŽ•āŽ°āŽŋāŽ•ā¯āŽ•āŽĩāŽž?", + "editor_edits_applied_error": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋ", + "editor_edits_applied_success": "āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ•āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ", + "editor_flip_horizontal": "āŽ•āŽŋāŽŸā¯ˆāŽŽāŽŸā¯āŽŸāŽŽāŽžāŽ• āŽĒā¯āŽ°āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", + "editor_flip_vertical": "āŽšā¯†āŽ™ā¯āŽ•ā¯āŽ¤ā¯āŽ¤āŽžāŽ• āŽĒā¯āŽ°āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", + "editor_handle_corner": "{corner, select, top_left {āŽŽā¯‡āŽ˛ā¯-āŽ‡āŽŸāŽ¤ā¯} top_right {āŽŽā¯‡āŽ˛ā¯-āŽĩāŽ˛āŽ¤ā¯} bottom_left {āŽ•ā¯€āŽ´ā¯-āŽ‡āŽŸāŽ¤ā¯} bottom_right {āŽ•ā¯€āŽ´ā¯-āŽĩāŽ˛āŽ¤ā¯} other {āŽ’āŽ°ā¯}} āŽŽā¯‚āŽ˛ā¯ˆ āŽ•ā¯ˆāŽĒā¯āŽĒāŽŋāŽŸāŽŋ", + "editor_handle_edge": "{edge, select, top {āŽŽā¯‡āŽ˛ā¯‡} bottom {āŽ•ā¯€āŽ´ā¯‡} left {āŽ‡āŽŸāŽ¤ā¯} right {āŽĩāŽ˛āŽ¤ā¯} other {āŽ’āŽ°ā¯}} āŽĩāŽŋāŽŗāŽŋāŽŽā¯āŽĒ❁ āŽ•ā¯ˆāŽĒā¯āŽĒāŽŋāŽŸāŽŋ", + "editor_orientation": "āŽ¨ā¯‹āŽ•ā¯āŽ•ā¯āŽ¨āŽŋāŽ˛ā¯ˆ", + "editor_reset_all_changes": "āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "editor_rotate_left": "āŽŽāŽ¤āŽŋāŽ°ā¯†āŽ¤āŽŋāŽ°ā¯ āŽ¤āŽŋāŽšā¯ˆāŽ¯āŽŋāŽ˛ā¯ 90° āŽšā¯āŽ´āŽąā¯āŽąā¯", + "editor_rotate_right": "āŽ•āŽŸāŽŋāŽ•āŽžāŽ° āŽ¤āŽŋāŽšā¯ˆāŽ¯āŽŋāŽ˛ā¯ 90° āŽšā¯āŽ´āŽąā¯āŽąā¯", "email": "āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯", "email_notifications": "āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯ āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", "empty_folder": "āŽ‡āŽ¨ā¯āŽ¤ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ• āŽ‰āŽŗā¯āŽŗāŽ¤ā¯", @@ -951,11 +1027,14 @@ "error_change_sort_album": "āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽĩāŽ°āŽŋāŽšā¯ˆ āŽĩāŽ°āŽŋāŽšā¯ˆāŽ¯ā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽ¤ā¯ āŽ¤āŽĩāŽąāŽŋāŽĩāŽŋāŽŸā¯āŽŸāŽ¤ā¯", "error_delete_face": "āŽšā¯ŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽŽā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "error_getting_places": "āŽ‡āŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯†āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", + "error_loading_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽāŽąā¯āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "error_loading_image": "āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽāŽąā¯āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "error_loading_partners": "āŽ•ā¯‚āŽŸā¯āŽŸāŽžāŽŗāŽ°ā¯āŽ•āŽŗā¯ˆ āŽāŽąā¯āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ: {error}", + "error_retrieving_asset_information": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ¤āŽ•āŽĩāŽ˛ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽĒā¯āŽĒāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "error_saving_image": "āŽĒāŽŋāŽ´ā¯ˆ: {error}", "error_tag_face_bounding_box": "āŽŽā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ•ā¯āŽąāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯ āŽĒāŽŋāŽ´ā¯ˆ - āŽŽāŽ˛ā¯āŽ˛ā¯ˆ āŽĒā¯†āŽŸā¯āŽŸāŽŋ āŽ†āŽ¯āŽ¤ā¯āŽ¤ā¯ŠāŽ˛ā¯ˆāŽĩā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯†āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", "error_title": "āŽĒāŽŋāŽ´ā¯ˆ - āŽāŽ¤ā¯‹ āŽ¤āŽĩāŽąā¯ āŽ¨āŽŸāŽ¨ā¯āŽ¤āŽ¤ā¯", + "error_while_navigating": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "errors": { "cannot_navigate_next_asset": "āŽ…āŽŸā¯āŽ¤ā¯āŽ¤ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", "cannot_navigate_previous_asset": "āŽŽā¯āŽ¨ā¯āŽ¤ā¯ˆāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", @@ -991,6 +1070,7 @@ "failed_to_update_notification_status": "āŽ…āŽąāŽŋāŽĩāŽŋāŽĒā¯āŽĒ❁ āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯ā¯ˆāŽĒā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽ¤ā¯ āŽ¤āŽĩāŽąāŽŋāŽĩāŽŋāŽŸā¯āŽŸāŽ¤ā¯", "incorrect_email_or_password": "āŽ¤āŽĩāŽąāŽžāŽŠ āŽŽāŽŋāŽŠā¯āŽŠāŽžā¯āŽšāŽ˛ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯", "library_folder_already_exists": "āŽ‡āŽ¨ā¯āŽ¤ āŽ‡āŽąāŽ•ā¯āŽ•ā¯āŽŽāŽ¤āŽŋ āŽĒāŽžāŽ¤ā¯ˆ āŽāŽąā¯āŽ•āŽŠāŽĩ❇ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸāŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽ¤ā¯.", + "page_not_found": "āŽĒāŽ•ā¯āŽ•āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "paths_validation_failed": "āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋāŽ¯ā¯āŽąā¯āŽą āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽĒā¯āŽĒ❁ {paths, plural, one {# āŽĒāŽžāŽ¤ā¯ˆ} other {# āŽĒāŽžāŽ¤ā¯ˆāŽ•āŽŗā¯}}", "profile_picture_transparent_pixels": "āŽšā¯āŽ¯āŽĩāŽŋāŽĩāŽ°āŽĒā¯ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽžāŽŠ āŽĒāŽŸāŽĒā¯āŽĒā¯āŽŗā¯āŽŗāŽŋāŽ•āŽŗā¯ āŽ‡āŽ°ā¯āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯. āŽ¤āŽ¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽĒā¯†āŽ°āŽŋāŽ¤āŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯/āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯.", "quota_higher_than_disk_size": "āŽĩāŽŸā¯āŽŸā¯ āŽ…āŽŗāŽĩ❈ āŽĩāŽŋāŽŸ āŽ…āŽ¤āŽŋāŽ•āŽŽāŽžāŽ• āŽ’āŽ¤ā¯āŽ•ā¯āŽ•ā¯€āŽŸā¯āŽŸā¯ˆ āŽ…āŽŽā¯ˆāŽ¤ā¯āŽ¤ā¯āŽŗā¯āŽŗā¯€āŽ°ā¯āŽ•āŽŗā¯", @@ -1012,7 +1092,8 @@ "unable_to_change_visibility": "{count, plural, one {# āŽ¨āŽĒāŽ°ā¯} other {# āŽĒā¯‡āŽ°ā¯}}āŽ•ā¯āŽ•āŽžāŽŠ āŽ¤ā¯†āŽ°āŽŋāŽĩā¯āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯ā¯ˆ āŽŽāŽžāŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_complete_oauth_login": "OAuth āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽĩ❈ āŽŽā¯āŽŸāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_connect": "āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", - "unable_to_copy_to_clipboard": "āŽ‡āŽŸā¯ˆāŽ¨āŽŋāŽ˛ā¯ˆāŽĒā¯āŽĒāŽ˛āŽ•ā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ˛ā¯†āŽŸā¯āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯, āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ HTTPS āŽŽā¯‚āŽ˛āŽŽā¯ āŽĒāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŖā¯āŽ•ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗā¯ āŽŽāŽŠā¯āŽĒāŽ¤ā¯ˆ āŽ‰āŽąā¯āŽ¤āŽŋāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽ•ā¯ āŽ•ā¯ŠāŽŗā¯āŽŗā¯āŽ™ā¯āŽ•āŽŗā¯", + "unable_to_copy_to_clipboard": "āŽ‡āŽŸā¯ˆāŽ¨āŽŋāŽ˛ā¯ˆāŽĒā¯āŽĒāŽ˛āŽ•ā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ˛ā¯†āŽŸā¯āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯, āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ‰āŽ‰āŽĒāŽ¨ā¯†āŽĒ āŽŽā¯‚āŽ˛āŽŽā¯ āŽĒāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŖā¯āŽ•ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗā¯ āŽŽāŽŠā¯āŽĒāŽ¤ā¯ˆ āŽ‰āŽąā¯āŽ¤āŽŋāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽ•ā¯ āŽ•ā¯ŠāŽŗā¯āŽŗā¯āŽ™ā¯āŽ•āŽŗā¯", + "unable_to_create": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_create_admin_account": "āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ• āŽ•āŽŖāŽ•ā¯āŽ•ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_create_api_key": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¨āŽŋāŽ‡ āŽĩāŽŋāŽšā¯ˆāŽ¯ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_create_library": "āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", @@ -1023,6 +1104,7 @@ "unable_to_delete_exclusion_pattern": "āŽĩāŽŋāŽ˛āŽ•ā¯āŽ•ā¯ āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_delete_shared_link": "āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒ❈ āŽ¨ā¯€āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_delete_user": "āŽĒāŽ¯āŽŠāŽ°ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "unable_to_delete_workflow": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_download_files": "āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_edit_exclusion_pattern": "āŽĩāŽŋāŽ˛āŽ•ā¯āŽ•ā¯ āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤ āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_empty_trash": "āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•āŽŗā¯ˆ āŽĩā¯†āŽąā¯āŽąā¯ āŽšā¯†āŽ¯ā¯āŽ¯ āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", @@ -1062,6 +1144,7 @@ "unable_to_scan_library": "āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽšā¯āŽ•ā¯‡āŽŠā¯ āŽšā¯†āŽ¯ā¯āŽ¯ āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_set_feature_photo": "āŽ…āŽŽā¯āŽš āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_set_profile_picture": "āŽšā¯āŽ¯āŽĩāŽŋāŽĩāŽ°āŽĒā¯ āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "unable_to_set_rating": "āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯āŽŸā¯ˆ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_submit_job": "āŽĩā¯‡āŽ˛ā¯ˆāŽ¯ā¯ˆāŽšā¯ āŽšāŽŽāŽ°ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_trash_asset": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽ•ā¯āŽĒā¯āŽĒ❈ āŽšā¯†āŽ¯ā¯āŽ¯ āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_unlink_account": "āŽ•āŽŖāŽ•ā¯āŽ•ā¯ˆ āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", @@ -1073,8 +1156,10 @@ "unable_to_update_settings": "āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_update_timeline_display_status": "āŽ•āŽžāŽ˛āŽĩāŽ°āŽŋāŽšā¯ˆ āŽ•āŽžāŽŸā¯āŽšāŽŋ āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯ā¯ˆ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_update_user": "āŽĒāŽ¯āŽŠāŽ°ā¯ˆāŽĒā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "unable_to_update_workflow": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unable_to_upload_file": "āŽ•ā¯‹āŽĒā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ" }, + "errors_text": "āŽĒāŽŋāŽ´ā¯ˆāŽ•āŽŗā¯", "exclusion_pattern": "āŽĩāŽŋāŽ˛āŽ•ā¯āŽ•ā¯ āŽŽā¯āŽąā¯ˆ", "exif": "āŽŽāŽ•ā¯āŽ¸āŽŋāŽƒāŽĒā¯", "exif_bottom_sheet_description": "āŽĩāŽŋāŽŗāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆāŽšā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯ ...", @@ -1085,6 +1170,7 @@ "exif_bottom_sheet_people": "āŽŽāŽ•ā¯āŽ•āŽŗā¯", "exif_bottom_sheet_person_add_person": "āŽĒā¯†āŽ¯āŽ°ā¯ˆāŽšā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "exit_slideshow": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹āŽĩāŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯‡āŽąāŽĩā¯āŽŽā¯", + "expand": "āŽĩāŽŋāŽ°āŽŋāŽĩāŽžāŽ•ā¯āŽ•ā¯", "expand_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩāŽŋāŽ°āŽŋāŽĩāŽžāŽ•ā¯āŽ•ā¯āŽ™ā¯āŽ•āŽŗā¯", "experimental_settings_new_asset_list_subtitle": "āŽĩā¯‡āŽ˛ā¯ˆ āŽŽā¯āŽŠā¯āŽŠā¯‡āŽąā¯āŽąāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽ¤ā¯", "experimental_settings_new_asset_list_title": "āŽšā¯‹āŽ¤āŽŠā¯ˆ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸ āŽ•āŽŸā¯āŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1106,6 +1192,7 @@ "external_network_sheet_info": "āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽŽāŽžāŽŠ āŽĩā¯ˆāŽƒāŽĒ❈ āŽ¨ā¯†āŽŸā¯āŽĩā¯ŠāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽ˛ā¯ āŽ‡āŽ˛ā¯āŽ˛āŽžāŽ¤āŽĒā¯‹āŽ¤ā¯, āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤ā¯āŽŸāŽŠā¯ āŽ•ā¯€āŽ´ā¯‡ āŽ‰āŽŗā¯āŽŗ āŽŽā¯āŽ•āŽĩāŽ°āŽŋ āŽ•āŽŗāŽŋāŽŠā¯ āŽŽā¯āŽ¤āŽ˛ā¯ āŽĩāŽ´āŽŋāŽ¯āŽžāŽ• āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯, āŽ‡āŽ¤ā¯ āŽŽā¯‡āŽ˛ā¯‡ āŽ‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•ā¯€āŽ´ā¯‡ āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "face_unassigned": "āŽ’āŽ¤ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤āŽ¤ā¯", "failed": "āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋāŽ¯ā¯āŽąā¯āŽąāŽ¤ā¯", + "failed_count": "āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋ: {count}", "failed_to_authenticate": "āŽ…āŽ™ā¯āŽ•ā¯€āŽ•āŽ°āŽŋāŽ•ā¯āŽ•āŽ¤ā¯ āŽ¤āŽĩāŽąāŽŋāŽĩāŽŋāŽŸā¯āŽŸāŽ¤ā¯", "failed_to_load_assets": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽāŽąā¯āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋ", "failed_to_load_folder": "āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ¯ā¯ˆ āŽāŽąā¯āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋ", @@ -1119,12 +1206,17 @@ "features_in_development": "āŽĩāŽŗāŽ°ā¯āŽšā¯āŽšāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽ¨āŽąā¯āŽĒā¯ŠāŽ°ā¯āŽ¤ā¯āŽ¤āŽ™ā¯āŽ•āŽŗā¯", "features_setting_description": "āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ āŽ…āŽŽā¯āŽšāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "file_name_or_extension": "āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽĒā¯†āŽ¯āŽ°ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ¨ā¯€āŽŸā¯āŽŸāŽŋāŽĒā¯āŽĒ❁", + "file_name_text": "āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽĒā¯†āŽ¯āŽ°ā¯", + "file_name_with_value": "āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽĒā¯†āŽ¯āŽ°ā¯: {file_name}", "file_size": "āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽ…āŽŗāŽĩ❁", "filename": "āŽ•ā¯‹āŽĒā¯āŽĒ❁āŽĒā¯āŽĒā¯†āŽ¯āŽ°ā¯", "filetype": "āŽĒā¯ˆāŽ˛ā¯āŽŸā¯ˆāŽĒā¯", "filter": "āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽŋ", + "filter_description": "āŽ‡āŽ˛āŽ•ā¯āŽ•ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽ•āŽŸā¯āŽŸā¯āŽĩāŽ¤āŽąā¯āŽ•āŽžāŽŠ āŽ¨āŽŋāŽĒāŽ¨ā¯āŽ¤āŽŠā¯ˆāŽ•āŽŗā¯", "filter_people": "āŽŽāŽ•ā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽ•āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", "filter_places": "āŽ‡āŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽ•āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", + "filter_tags": "āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽąā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽ•āŽŸā¯āŽŸāŽŋ", + "filters": "āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯āŽ•āŽŗā¯", "find_them_fast": "āŽ¤ā¯‡āŽŸāŽ˛ā¯āŽŸāŽŠā¯ āŽĒā¯†āŽ¯āŽ°āŽžāŽ˛ā¯ āŽĩā¯‡āŽ•āŽŽāŽžāŽ• āŽ…āŽĩāŽąā¯āŽąā¯ˆāŽ•ā¯ āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽ¯āŽĩā¯āŽŽā¯", "first": "āŽŽā¯āŽ¤āŽ˛ā¯", "fix_incorrect_match": "āŽ¤āŽĩāŽąāŽžāŽŠ āŽĒā¯‹āŽŸā¯āŽŸāŽŋāŽ¯ā¯ˆ āŽšāŽ°āŽŋāŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", @@ -1134,12 +1226,16 @@ "folders_feature_description": "āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽŽā¯āŽąā¯ˆāŽŽā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•āŽžāŽŠ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆ āŽ•āŽžāŽŸā¯āŽšāŽŋāŽ¯ā¯ˆ āŽ‰āŽ˛āŽžāŽĩā¯āŽ¤āŽ˛ā¯", "forgot_pin_code_question": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯āŽŗā¯ āŽŽāŽąāŽ¨ā¯āŽ¤ā¯āŽĩāŽŋāŽŸā¯āŽŸā¯€āŽ°ā¯āŽ•āŽŗāŽž?", "forward": "āŽŽā¯āŽŠā¯āŽŠā¯‹āŽ•ā¯āŽ•āŽŋ", + "free_up_space": "āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽĩāŽŋāŽŸā¯āŽĩāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "free_up_space_description": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•, āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯. āŽšāŽ°ā¯āŽĩāŽ°āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ•āŽŗā¯ āŽĒāŽžāŽ¤ā¯āŽ•āŽžāŽĒā¯āŽĒāŽžāŽ• āŽ‡āŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯.", + "free_up_space_settings_subtitle": "āŽšāŽžāŽ¤āŽŠ āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "full_path": "āŽŽā¯āŽ´ā¯ āŽĒāŽžāŽ¤ā¯ˆ: {path}", "gcast_enabled": "āŽ•ā¯‚āŽ•āŽŋāŽŗā¯ āŽ¨āŽŸāŽŋāŽ•āŽ°ā¯āŽ•āŽŗā¯", "gcast_enabled_description": "āŽ‡āŽ¨ā¯āŽ¤ āŽ¨āŽąā¯āŽĒā¯ŠāŽ°ā¯āŽ¤ā¯āŽ¤āŽŽā¯ āŽĩā¯‡āŽ˛ā¯ˆ āŽšā¯†āŽ¯ā¯āŽĩāŽ¤āŽąā¯āŽ•āŽžāŽ• Google āŽ‡āŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒā¯āŽą āŽĩāŽŗāŽ™ā¯āŽ•āŽŗā¯ˆ āŽāŽąā¯āŽąā¯āŽ•āŽŋāŽąāŽ¤ā¯.", "general": "āŽĒā¯†āŽžāŽ¤ā¯", "geolocation_instruction_location": "āŽ…āŽ¤āŽŠā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ āŽšāŽŋ.āŽĒāŽŋ.āŽŽāŽšā¯ āŽ†āŽ¯āŽ¤ā¯āŽ¤ā¯ŠāŽ˛ā¯ˆāŽĩā¯āŽ•āŽŗā¯āŽŸāŽŠā¯ āŽ’āŽ°ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽšā¯ŠāŽŸā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ¯ā¯āŽ• āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĩāŽ°ā¯ˆāŽĒāŽŸāŽ¤ā¯āŽ¤āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ¨ā¯‡āŽ°āŽŸāŽŋāŽ¯āŽžāŽ• āŽ’āŽ°ā¯ āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "get_help": "āŽ‰āŽ¤āŽĩāŽŋ āŽĒā¯†āŽąā¯", + "get_people_error": "āŽŽāŽ•ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯†āŽąā¯āŽĩāŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "get_wifiname_error": "āŽĩā¯ˆāŽƒāŽĒ❈ āŽĒā¯†āŽ¯āŽ°ā¯ˆāŽĒā¯ āŽĒā¯†āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ. āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ¤ā¯‡āŽĩā¯ˆāŽ¯āŽžāŽŠ āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•āŽŗā¯ˆ āŽĩāŽ´āŽ™ā¯āŽ•āŽŋāŽ¯ā¯āŽŗā¯āŽŗā¯€āŽ°ā¯āŽ•āŽŗā¯ āŽŽāŽŠā¯āŽĒāŽ¤ā¯ˆ āŽ‰āŽąā¯āŽ¤āŽŋāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽ•ā¯ āŽ•ā¯ŠāŽŗā¯āŽŗā¯āŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯ˆāŽƒāŽĒ❈ āŽ¨ā¯†āŽŸā¯āŽĩā¯ŠāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŸāŽŠā¯ āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗā¯€āŽ°ā¯āŽ•āŽŗā¯", "getting_started": "āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ•ā¯āŽ¤āŽ˛ā¯", "go_back": "āŽ¤āŽŋāŽ°ā¯āŽŽā¯āŽĒāŽŋāŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽ™ā¯āŽ•āŽŗā¯", @@ -1165,12 +1261,14 @@ "header_settings_header_name_input": "āŽ¤āŽ˛ā¯ˆāŽĒā¯āŽĒ❁ āŽĒā¯†āŽ¯āŽ°ā¯", "header_settings_header_value_input": "āŽ¤āŽ˛ā¯ˆāŽĒā¯āŽĒ❁ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒ❁", "headers_settings_tile_title": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽĒāŽ¤āŽŋāŽ˛āŽžāŽŗā¯ āŽ¤āŽ˛ā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", + "height": "āŽ‰āŽ¯āŽ°āŽŽā¯", "hi_user": "āŽ†āŽ¯ā¯ {name} ({email})", "hide_all_people": "āŽŽāŽ˛ā¯āŽ˛āŽž āŽŽāŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽŽāŽąā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "hide_gallery": "āŽ•ā¯‡āŽ˛āŽ°āŽŋāŽ¯ā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "hide_named_person": "āŽ¨āŽĒāŽ°ā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ• {name}", "hide_password": "āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "hide_person": "āŽ¨āŽĒāŽ°ā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ•", + "hide_schema": "āŽ¤āŽŋāŽŸā¯āŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽŽāŽąā¯ˆ", "hide_text_recognition": "āŽ‰āŽ°ā¯ˆ āŽ…āŽ™ā¯āŽ•ā¯€āŽ•āŽžāŽ°āŽ¤ā¯āŽ¤ā¯ˆ āŽŽāŽąā¯ˆ", "hide_unnamed_people": "āŽĒā¯†āŽ¯āŽ°āŽŋāŽŸāŽĒā¯āŽĒāŽŸāŽžāŽ¤āŽĩāŽ°ā¯āŽ•āŽŗā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "home_page_add_to_album_conflicts": "{album} āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ {added} āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠ. {failed} āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽāŽąā¯āŽ•āŽŠāŽĩ❇ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽŠ.", @@ -1194,8 +1292,8 @@ "hours": "āŽŽāŽŖāŽŋ", "id": "āŽāŽŸāŽŋ", "idle": "āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯āŽŋāŽ•ā¯āŽ•āŽŽā¯", - "ignore_icloud_photos": "ICloud āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒā¯āŽąāŽ•ā¯āŽ•āŽŖāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", - "ignore_icloud_photos_description": "ICloud āŽ‡āŽ˛ā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯āŽĒāŽŸāŽžāŽ¤ā¯", + "ignore_icloud_photos": "āŽāŽŽā¯āŽ•āŽŋāŽ˛ā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯āŽąāŽ•ā¯āŽ•āŽŖāŽŋ", + "ignore_icloud_photos_description": "āŽāŽŽā¯āŽ•āŽŋāŽ˛ā¯ āŽ‡āŽ˛ā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯āŽĒāŽŸāŽžāŽ¤ā¯", "image": "āŽĒāŽŸāŽŽā¯", "image_alt_text_date": "{isVideo, select, true {āŽ•āŽžāŽŖā¯ŠāŽŗāŽŋ} other {āŽĒāŽŸāŽŽā¯}} {date} āŽ…āŽŠā¯āŽąā¯ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "image_alt_text_date_1_person": "{isVideo, select, true {āŽ•āŽžāŽŖā¯ŠāŽŗāŽŋ} other {āŽĒāŽŸāŽŽā¯}} {person1} āŽ‰āŽŸāŽŠā¯ {date} āŽ…āŽŠā¯āŽąā¯ āŽŽāŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -1243,9 +1341,18 @@ "ios_debug_info_processing_ran_at": "āŽšā¯†āŽ¯āŽ˛āŽžāŽ•ā¯āŽ•āŽŽā¯ {dateTime}", "items_count": "{count, plural, one {# āŽ‰āŽ°ā¯āŽĒā¯āŽĒāŽŸāŽŋ} other {# āŽ‰āŽ°ā¯āŽĒā¯āŽĒāŽŸāŽŋāŽ•āŽŗā¯}}", "jobs": "āŽĩā¯‡āŽ˛ā¯ˆāŽ•āŽŗā¯", + "json_editor": "āŽšāŽžāŽ¤ā¯ŠāŽĒā¯ŠāŽ•ā¯ āŽ†āŽšāŽŋāŽ°āŽŋāŽ¯āŽ°ā¯", + "json_error": "āŽšāŽžāŽ¤ā¯ŠāŽĒā¯ŠāŽ•ā¯ āŽĒāŽŋāŽ´ā¯ˆ", "keep": "āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "keep_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "keep_albums_count": "{count} {count, plural, one {āŽ¤ā¯ŠāŽ•ā¯āŽĒā¯āŽĒ❁} other {āŽ¤ā¯ŠāŽ•ā¯āŽĒā¯āŽĒā¯āŽ•āŽŗā¯}} āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯", "keep_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "keep_description": "āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽ˛āŽŋāŽ¯āŽžāŽ•ā¯āŽ•ā¯āŽŽā¯ āŽĒā¯‹āŽ¤ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽŽāŽŠā¯āŽŠ āŽ‡āŽ°ā¯āŽ•ā¯āŽ• āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯ āŽŽāŽŠā¯āŽĒāŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯.", + "keep_favorites": "āŽĒāŽŋāŽŸāŽŋāŽ¤ā¯āŽ¤āŽĩā¯ˆāŽ•āŽŗā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "keep_on_device": "āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", + "keep_on_device_hint": "āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ• āŽĩā¯‡āŽŖā¯āŽŸāŽŋāŽ¯ āŽĒā¯ŠāŽ°ā¯āŽŸā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "keep_this_delete_others": "āŽ‡āŽ¤ā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯, āŽŽāŽąā¯āŽąāŽĩāŽ°ā¯āŽ•āŽŗā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ•ā¯", + "keeping": "āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽ˛ā¯: {items}", "kept_this_deleted_others": "āŽ‡āŽ¨ā¯āŽ¤āŽšā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽĩā¯ˆāŽ¤ā¯āŽ¤ā¯, {count, plural, one {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯} other {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯}} āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "keyboard_shortcuts": "āŽĩāŽŋāŽšā¯ˆāŽĒā¯āŽĒāŽ˛āŽ•ā¯ˆ āŽ•ā¯āŽąā¯āŽ•ā¯āŽ•ā¯āŽĩāŽ´āŽŋāŽ•āŽŗā¯", "language": "āŽŽā¯ŠāŽ´āŽŋ", @@ -1287,6 +1394,7 @@ "local": "āŽ‰āŽŗā¯āŽŗāŽ•", "local_asset_cast_failed": "āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯āŽĒāŽŸāŽžāŽ¤ āŽ’āŽ°ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŠā¯āŽĒā¯āŽĒ āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "local_assets": "āŽ‰āŽŗā¯āŽŗāŽ• āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯", + "local_id": "āŽ‰āŽŗā¯āŽŗāŽ• āŽ…āŽŸā¯ˆāŽ¯āŽžāŽŗāŽŽā¯", "local_media_summary": "āŽ‰āŽŗā¯āŽŗāŽ• āŽŠāŽŸāŽ• āŽšā¯āŽ°ā¯āŽ•ā¯āŽ•āŽŽā¯", "local_network": "āŽ‰āŽŗā¯āŽŗāŽ• āŽĒāŽŋāŽŖā¯ˆāŽ¯āŽŽā¯", "local_network_sheet_info": "āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒāŽŋāŽŸā¯āŽŸ āŽĩā¯ˆāŽƒāŽĒ❈ āŽ¨ā¯†āŽŸā¯āŽĩā¯ŠāŽ°ā¯āŽ•ā¯āŽ•ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽŽā¯ āŽĒā¯‹āŽ¤ā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯ āŽ‡āŽ¨ā¯āŽ¤ āŽŽā¯āŽ•āŽĩāŽ°āŽŋ āŽŽā¯‚āŽ˛āŽŽā¯ āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤ā¯āŽŸāŽŠā¯ āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯", @@ -1338,10 +1446,28 @@ "loop_videos_description": "āŽĩāŽŋāŽ°āŽŋāŽĩāŽžāŽŠ āŽĒāŽžāŽ°ā¯āŽĩā¯ˆāŽ¯āŽžāŽŗāŽ°āŽŋāŽ˛ā¯ āŽ’āŽ°ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽĩ❈ āŽ¤āŽžāŽŠāŽžāŽ• āŽĩāŽŗā¯ˆāŽ¯āŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯.", "main_branch_warning": "āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ’āŽ°ā¯ āŽŽā¯‡āŽŽā¯āŽĒāŽžāŽŸā¯āŽŸā¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗā¯; āŽĩā¯†āŽŗāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ āŽ¨āŽžāŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŸā¯āŽŽā¯ˆāŽ¯āŽžāŽ• āŽĒāŽ°āŽŋāŽ¨ā¯āŽ¤ā¯āŽ°ā¯ˆāŽ•ā¯āŽ•āŽŋāŽąā¯‹āŽŽā¯!", "main_menu": "āŽĒāŽŸā¯āŽŸāŽŋāŽ¯āŽ˛ā¯ āŽĩāŽŋāŽŗā¯ˆāŽ¯āŽžāŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", + "maintenance_action_restore": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "maintenance_description": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽĩā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸā¯āŽŗā¯āŽŗāŽ¤ā¯.", "maintenance_end": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽĒāŽ¯āŽŠā¯āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆ āŽŽā¯āŽŸāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "maintenance_end_error": "āŽĒāŽ°āŽžāŽŽāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆ āŽŽā¯āŽŸāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", "maintenance_logged_in_as": "āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ {user} āŽ†āŽ• āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽ¨ā¯āŽ¤ā¯āŽŗā¯āŽŗā¯€āŽ°ā¯āŽ•āŽŗā¯", + "maintenance_restore_from_backup": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆ", + "maintenance_restore_library": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "maintenance_restore_library_confirm": "āŽ‡āŽ¤ā¯ āŽšāŽ°āŽŋāŽ¯āŽžāŽ•āŽ¤ā¯ āŽ¤ā¯‹āŽŠā¯āŽąāŽŋāŽŠāŽžāŽ˛ā¯, āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽĒā¯āŽĒāŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ°āŽĩā¯āŽŽā¯!", + "maintenance_restore_library_description": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", + "maintenance_restore_library_folder_has_files": "{folder}āŽ˛ā¯ {count} āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆ(āŽ•āŽŗā¯) āŽ‰āŽŗā¯āŽŗāŽ¤ā¯", + "maintenance_restore_library_folder_no_files": "{folder} āŽ‡āŽ˛ā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ!", + "maintenance_restore_library_folder_pass": "āŽĒāŽŸāŽŋāŽ•ā¯āŽ•āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽāŽ´ā¯āŽ¤āŽ•ā¯āŽ•ā¯‚āŽŸāŽŋāŽ¯", + "maintenance_restore_library_folder_read_fail": "āŽĒāŽŸāŽŋāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", + "maintenance_restore_library_folder_write_fail": "āŽŽāŽ´ā¯āŽ¤ āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", + "maintenance_restore_library_hint_missing_files": "āŽŽā¯āŽ•ā¯āŽ•āŽŋāŽ¯āŽŽāŽžāŽŠ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽžāŽŖāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "maintenance_restore_library_hint_regenerate_later": "āŽ‡āŽĩāŽąā¯āŽąā¯ˆ āŽĒāŽŋāŽŠā¯āŽŠāŽ°ā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯", + "maintenance_restore_library_hint_storage_template_missing_files": "āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒāŽ• āŽŸā¯†āŽŽā¯āŽĒā¯āŽŗā¯‡āŽŸā¯āŽŸā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž? āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽ•āŽžāŽŖāŽžāŽŽāŽ˛ā¯ āŽ‡āŽ°ā¯āŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯", + "maintenance_restore_library_loading": "āŽ’āŽ°ā¯āŽŽā¯ˆāŽĒā¯āŽĒāŽžāŽŸā¯ āŽ•āŽžāŽšā¯‹āŽ˛ā¯ˆāŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŠāŽ°āŽŋāŽšā¯āŽŸāŽŋāŽ•ā¯āŽšā¯ āŽāŽąā¯āŽąā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", + "maintenance_task_backup": "āŽāŽąā¯āŽ•āŽŠāŽĩ❇ āŽ‰āŽŗā¯āŽŗ āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", + "maintenance_task_migrations": "āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗ āŽ¨āŽ•āŽ°ā¯āŽĩā¯āŽ•āŽŗā¯ˆ āŽ‡āŽ¯āŽ•ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", + "maintenance_task_restore": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋāŽ¯ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", + "maintenance_task_rollback": "āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽĒā¯āŽĒ❁ āŽ¤ā¯‹āŽ˛ā¯āŽĩāŽŋāŽ¯āŽŸā¯ˆāŽ¨ā¯āŽ¤āŽ¤ā¯, āŽĒā¯āŽŗā¯āŽŗāŽŋāŽ¯ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸā¯†āŽŸā¯āŽ•ā¯āŽ• āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ‰āŽ°ā¯āŽŸā¯āŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯â€Ļ", "maintenance_title": "āŽ¤āŽąā¯āŽ•āŽžāŽ˛āŽŋāŽ•āŽŽāŽžāŽ• āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "make": "āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯", "manage_geolocation": "āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1403,6 +1529,8 @@ "minimize": "āŽ•ā¯āŽąā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "minute": "āŽ¨āŽŋāŽŽāŽŋāŽŸāŽ™ā¯āŽ•āŽŗā¯", "minutes": "āŽ¨āŽŋāŽŽāŽŋāŽŸāŽ™ā¯āŽ•āŽŗā¯", + "mirror_horizontal": "āŽ•āŽŋāŽŸā¯ˆāŽŽāŽŸā¯āŽŸ", + "mirror_vertical": "āŽšā¯†āŽ™ā¯āŽ•ā¯āŽ¤ā¯āŽ¤ā¯", "missing": "āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", "mobile_app": "āŽŽā¯ŠāŽĒā¯ˆāŽ˛ā¯ āŽ†āŽĒā¯", "mobile_app_download_onboarding_note": "āŽĒāŽŋāŽŠā¯āŽĩāŽ°ā¯āŽŽā¯ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋ āŽ¤ā¯āŽŖā¯ˆ āŽŽā¯ŠāŽĒā¯ˆāŽ˛ā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ˆāŽĒā¯ āŽĒāŽ¤āŽŋāŽĩāŽŋāŽąāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1411,11 +1539,14 @@ "monthly_title_text_date_format": "Mmmm āŽ’āŽ¯ā¯", "more": "āŽŽā¯‡āŽ˛ā¯āŽŽā¯", "move": "āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", + "move_down": "āŽ•ā¯€āŽ´ā¯‡ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "move_off_locked_folder": "āŽĒā¯‚āŽŸā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯‡āŽąāŽĩā¯āŽŽā¯", "move_to": "āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯", + "move_to_device_trash": "āŽšāŽžāŽ¤āŽŠāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "move_to_lock_folder_action_prompt": "āŽĒā¯‚āŽŸā¯āŽŸāŽŋāŽ¯ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛ā¯ {count} āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "move_to_locked_folder": "āŽĒā¯‚āŽŸā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽ™ā¯āŽ•āŽŗā¯", "move_to_locked_folder_confirmation": "āŽ‡āŽ¨ā¯āŽ¤ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗāŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯āŽŽā¯ āŽ…āŽ•āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŽā¯, āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽĒā¯‚āŽŸā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯ā¯āŽŽā¯", + "move_up": "āŽŽā¯‡āŽ˛ā¯‡ āŽšā¯†āŽ˛ā¯āŽ˛āŽĩā¯āŽŽā¯", "moved_to_archive": "{count, plural, one {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯} other {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯}} āŽ•āŽžāŽĒā¯āŽĒāŽ•āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "moved_to_library": "{count, plural, one {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯} other {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯}} āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "moved_to_trash": "āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ•ā¯āŽ•ā¯ āŽ¨āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -1425,6 +1556,7 @@ "my_albums": "āŽŽāŽŠāŽ¤ā¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯", "name": "āŽĒā¯†āŽ¯āŽ°ā¯", "name_or_nickname": "āŽĒā¯†āŽ¯āŽ°ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒā¯āŽŠā¯ˆāŽĒā¯āŽĒā¯†āŽ¯āŽ°ā¯", + "name_required": "āŽĒā¯†āŽ¯āŽ°ā¯ āŽ¤ā¯‡āŽĩ❈", "navigate": "āŽĩāŽ´āŽŋāŽšā¯†āŽ˛ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "navigate_to_time": "āŽ¨ā¯‡āŽ°āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽšā¯†āŽ˛ā¯āŽ˛āŽĩā¯āŽŽā¯", "network_requirement_photos_upload": "āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽ˛āŽžāŽ°ā¯ āŽ¤āŽ°āŽĩ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", @@ -1449,20 +1581,24 @@ "next": "āŽ…āŽŸā¯āŽ¤ā¯āŽ¤āŽ¤ā¯", "next_memory": "āŽ…āŽŸā¯āŽ¤ā¯āŽ¤ āŽ¨āŽŋāŽŠā¯ˆāŽĩāŽ•āŽŽā¯", "no": "āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", + "no_actions_added": "āŽ‡āŽŠā¯āŽŠā¯āŽŽā¯ āŽšā¯†āŽ¯āŽ˛ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "no_albums_found": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", "no_albums_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ’āŽ´ā¯āŽ™ā¯āŽ•āŽŽā¯ˆāŽ•ā¯āŽ• āŽ’āŽ°ā¯ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "no_albums_with_name_yet": "āŽ‡āŽ¨ā¯āŽ¤ āŽĒā¯†āŽ¯āŽ°ā¯āŽŸāŽŠā¯ āŽ‡āŽŠā¯āŽŠā¯āŽŽā¯ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ āŽŽāŽŠā¯āŽąā¯ āŽ¤ā¯†āŽ°āŽŋāŽ•āŽŋāŽąāŽ¤ā¯.", "no_albums_yet": "āŽ‰āŽ™ā¯āŽ•āŽŗāŽŋāŽŸāŽŽā¯ āŽ‡āŽ¤ā¯āŽĩāŽ°ā¯ˆ āŽŽāŽ¨ā¯āŽ¤ āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ āŽŽāŽŠā¯āŽąā¯ āŽ¤ā¯†āŽ°āŽŋāŽ•āŽŋāŽąāŽ¤ā¯.", "no_archived_assets_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽšāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽ‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ…āŽĩāŽąā¯āŽąā¯ˆ āŽŽāŽąā¯ˆāŽ•ā¯āŽ• āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ•āŽžāŽĒā¯āŽĒāŽ•āŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", - "no_assets_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯āŽ¤āŽ˛ā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽšā¯ŠāŽŸā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ¯ā¯āŽ•", + "no_assets_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯āŽ¤āŽ˛ā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽšā¯ŠāŽŸā¯āŽ•ā¯āŽ•ā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", "no_assets_to_show": "āŽ•āŽžāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", "no_cast_devices_found": "āŽ¨āŽŸāŽŋāŽ•āŽ°ā¯āŽ•āŽŗā¯ āŽšāŽžāŽ¤āŽŠāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "no_checksum_local": "āŽšā¯†āŽ•ā¯āŽšāŽŽā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ - āŽ‰āŽŗā¯āŽŗāŽ• āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒā¯†āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", "no_checksum_remote": "āŽšā¯†āŽ•ā¯āŽšāŽŽā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ - āŽ¤ā¯ŠāŽ˛ā¯ˆ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĒā¯†āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯", + "no_configuration_needed": "āŽ•āŽŸā¯āŽŸāŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽ¤ā¯‡āŽĩā¯ˆāŽ¯āŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "no_devices": "āŽ…āŽ™ā¯āŽ•ā¯€āŽ•āŽ°āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšāŽžāŽ¤āŽŠāŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", "no_duplicates_found": "āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", - "no_exif_info_available": "EXIF āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", + "no_exif_info_available": "exif āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "no_explore_results_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¤ā¯ŠāŽ•ā¯āŽĒā¯āŽĒ❈ āŽ†āŽ°āŽžāŽ¯ āŽ•ā¯‚āŽŸā¯āŽ¤āŽ˛ā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĩā¯āŽŽā¯.", "no_favorites_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽšāŽŋāŽąāŽ¨ā¯āŽ¤ āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽĩāŽŋāŽ°ā¯ˆāŽĩāŽžāŽ•āŽ•ā¯ āŽ•āŽŖā¯āŽŸā¯āŽĒāŽŋāŽŸāŽŋāŽ•ā¯āŽ• āŽĒāŽŋāŽŸāŽŋāŽ¤ā¯āŽ¤āŽĩā¯ˆāŽ•āŽŗā¯ˆāŽšā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "no_filters_added": "āŽ‡āŽ¤ā¯āŽĩāŽ°ā¯ˆ āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽšā¯‡āŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "no_libraries_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•āŽžāŽŖ āŽĩā¯†āŽŗāŽŋāŽĒā¯āŽĒā¯āŽą āŽ¨ā¯‚āŽ˛āŽ•āŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "no_local_assets_found": "āŽ‡āŽ¨ā¯āŽ¤ āŽšā¯†āŽ•ā¯āŽšāŽŽā¯ āŽŽā¯‚āŽ˛āŽŽā¯ āŽ‰āŽŗā¯āŽŗāŽ• āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "no_location_set": "āŽ‡āŽŸāŽŽā¯ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", @@ -1476,6 +1612,7 @@ "no_results_description": "āŽ’āŽ°ā¯ āŽ’āŽ¤ā¯āŽ¤ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒā¯ŠāŽ¤ā¯āŽĩāŽžāŽŠ āŽŽā¯āŽ•ā¯āŽ•āŽŋāŽ¯ āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆ āŽŽā¯āŽ¯āŽąā¯āŽšāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "no_shared_albums_message": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¨ā¯†āŽŸā¯āŽĩā¯ŠāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽĩāŽ°ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•ā¯ŠāŽŗā¯āŽŗ āŽ’āŽ°ā¯ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "no_uploads_in_progress": "āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯āŽŠā¯āŽŠā¯‡āŽąā¯āŽąāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", + "none": "āŽŽāŽ¤ā¯āŽĩā¯āŽŽāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "not_allowed": "āŽ…āŽŠā¯āŽŽāŽ¤āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "not_available": "āŽ‡āŽ¤āŽąā¯āŽ•āŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "not_in_any_album": "āŽŽāŽ¨ā¯āŽ¤ āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", @@ -1509,6 +1646,8 @@ "online": "āŽ†āŽŠā¯āŽ˛ā¯ˆāŽŠāŽŋāŽ˛ā¯", "only_favorites": "āŽĒāŽŋāŽŸāŽŋāŽ¤ā¯āŽ¤āŽĩ❈ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡", "open": "āŽ¤āŽŋāŽą", + "open_calendar": "āŽ•āŽžāŽ˛ā¯†āŽŖā¯āŽŸāŽ°ā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽąāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "open_in_browser": "āŽ‰āŽ˛āŽžāŽĩāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽ¤āŽŋāŽą", "open_in_map_view": "āŽĩāŽ°ā¯ˆāŽĒāŽŸāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽšāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽ¤āŽŋāŽąāŽ¨ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯", "open_in_openstreetmap": "OpenStreetMap āŽ‡āŽ˛ā¯ āŽ¤āŽŋāŽąāŽ¨ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯", "open_the_search_filters": "āŽ¤ā¯‡āŽŸāŽ˛ā¯ āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽąāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1557,6 +1696,7 @@ "people": "āŽŽāŽ•ā¯āŽ•āŽŗā¯", "people_edits_count": "{count, plural, one {# āŽ¨āŽĒāŽ°ā¯} other {# āŽĒā¯‡āŽ°ā¯}} āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "people_feature_description": "āŽŽāŽ•ā¯āŽ•āŽŗā¯ āŽ¤ā¯ŠāŽ•ā¯āŽ¤ā¯āŽ¤ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ‰āŽ˛āŽžāŽĩā¯āŽ¤āŽ˛ā¯", + "people_selected": "{count, plural, one {# āŽ¨āŽĒāŽ°ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ°ā¯} other {# āŽĒā¯‡āŽ°ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŠāŽ°ā¯}}", "people_sidebar_description": "āŽĒāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ¯āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗāŽĩāŽ°ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯ āŽ’āŽ°ā¯ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯ˆāŽ•ā¯ āŽ•āŽžāŽŖā¯āŽĒāŽŋ", "permanent_deletion_warning": "āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ° āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽ¤āŽ˛ā¯ āŽŽāŽšā¯āŽšāŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆ", "permanent_deletion_warning_setting_description": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ°āŽŽāŽžāŽ• āŽ¨ā¯€āŽ•ā¯āŽ•ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽ’āŽ°ā¯ āŽŽāŽšā¯āŽšāŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆāŽ¯ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", @@ -1581,11 +1721,14 @@ "person_age_years": "{years, plural, other {# āŽ†āŽŖā¯āŽŸā¯āŽ•āŽŗā¯}} āŽĒāŽ´ā¯ˆāŽ¯āŽ¤ā¯", "person_birthdate": "{date} āŽ‡āŽ˛ā¯ āŽĒāŽŋāŽąāŽ¨ā¯āŽ¤āŽžāŽ°ā¯", "person_hidden": "{name}{hidden, select, true { (āŽŽāŽąā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ)} other {}}", + "person_recognized": "āŽ…āŽŸā¯ˆāŽ¯āŽžāŽŗāŽŽā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ¨āŽĒāŽ°ā¯", + "person_selected": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ¨āŽĒāŽ°ā¯", "photo_shared_all_users": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆ āŽŽāŽ˛ā¯āŽ˛āŽž āŽĒāŽ¯āŽŠāŽ°ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯āŽŽā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸāŽ¤āŽžāŽ•āŽ¤ā¯ āŽ¤ā¯†āŽ°āŽŋāŽ•āŽŋāŽąāŽ¤ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽĒāŽ•āŽŋāŽ°ā¯āŽĩāŽ¤āŽąā¯āŽ•ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗāŽŋāŽŸāŽŽā¯ āŽŽāŽ¨ā¯āŽ¤ āŽĒāŽ¯āŽŠāŽ°ā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ.", "photos": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯", "photos_and_videos": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ & āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯", "photos_count": "{count, plural, one {{count, number} āŽĒāŽŸāŽŽā¯} other {{count, number} āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯}}", "photos_from_previous_years": "āŽŽā¯āŽ¨ā¯āŽ¤ā¯ˆāŽ¯ āŽ†āŽŖā¯āŽŸā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯", + "photos_only": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡", "pick_a_location": "āŽ’āŽ°ā¯ āŽ‡āŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", "pick_custom_range": "āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽĩāŽ°āŽŽā¯āŽĒ❁", "pick_date_range": "āŽ¤ā¯‡āŽ¤āŽŋ āŽĩāŽ°āŽŽā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1661,9 +1804,10 @@ "purchase_settings_server_activated": "āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ• āŽ¤āŽ¯āŽžāŽ°āŽŋāŽĒā¯āŽĒ❁ āŽĩāŽŋāŽšā¯ˆ āŽ¨āŽŋāŽ°ā¯āŽĩāŽžāŽ•āŽŋāŽ¯āŽžāŽ˛ā¯ āŽ¨āŽŋāŽ°ā¯āŽĩāŽ•āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯", "query_asset_id": "āŽĩāŽŋāŽŠāŽĩāŽ˛ā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽ…āŽŸā¯ˆāŽ¯āŽžāŽŗāŽŽā¯", "queue_status": "āŽĩāŽ°āŽŋāŽšā¯ˆ {count}/{total}", + "rate_asset": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒ❁", "rating": "āŽ¨āŽŸā¯āŽšāŽ¤ā¯āŽ¤āŽŋāŽ° āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯", "rating_clear": "āŽ¤ā¯†āŽŗāŽŋāŽĩāŽžāŽŠ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯", - "rating_count": "{count, plural, one {# āŽĩāŽŋāŽŖā¯āŽŽā¯€āŽŠā¯} other {# āŽĩāŽŋāŽŖā¯āŽŽā¯€āŽŠā¯āŽ•āŽŗā¯}}", + "rating_count": "{count, plural, =0 {āŽŽāŽ¤āŽŋāŽĒāŽŋāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ} one {# āŽĩāŽŋāŽŖā¯āŽŽā¯€āŽŠā¯} other {# āŽĩāŽŋāŽŖā¯āŽŽā¯€āŽŠā¯āŽ•āŽŗā¯}}", "rating_description": "āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ āŽ•ā¯āŽ´ā¯āŽĩāŽŋāŽ˛ā¯ EXIF āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯āŽŸā¯ˆāŽ•ā¯ āŽ•āŽžāŽŖā¯āŽĒāŽŋ", "reaction_options": "āŽŽāŽ¤āŽŋāŽ°ā¯āŽĩāŽŋāŽŠā¯ˆ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯", "read_changelog": "āŽšā¯‡āŽžā¯āŽšā¯āŽ˛āŽžāŽ•ā¯ āŽĒāŽŸāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1736,7 +1880,10 @@ "reset_pin_code_success": "āŽŽā¯āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ˆ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "reset_pin_code_with_password": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯ āŽŽā¯‚āŽ˛āŽŽā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽŽā¯āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ˆ āŽŽāŽĒā¯āŽĒā¯‹āŽ¤ā¯āŽŽā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯", "reset_sqlite": "SQLite āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", - "reset_sqlite_confirmation": "SQLITE āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤ā¯ˆ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž? āŽ¤āŽ°āŽĩ❈ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽ•ā¯āŽ• āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯‡āŽąāŽŋ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽ¯ āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯", + "reset_sqlite_clear_app_data": "āŽ¤āŽ°āŽĩ❈ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "reset_sqlite_confirmation": "āŽ†āŽĒā¯āŽšā¯ āŽ¤āŽ°āŽĩ❈ āŽ¨āŽŋāŽšā¯āŽšāŽ¯āŽŽāŽžāŽ• āŽ…āŽ´āŽŋāŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž? āŽ‡āŽ¤ā¯ āŽŽāŽ˛ā¯āŽ˛āŽž āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¨ā¯€āŽ•ā¯āŽ•āŽŋāŽĩāŽŋāŽŸā¯āŽŸā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ˆ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯‡āŽąā¯āŽąā¯āŽŽā¯.", + "reset_sqlite_confirmation_note": "āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒ❁: āŽ¨ā¯€āŽ•ā¯āŽ•āŽŋāŽ¯ āŽĒāŽŋāŽąāŽ•ā¯, āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ˆ āŽŽāŽąā¯āŽ¤ā¯ŠāŽŸāŽ•ā¯āŽ•āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¯ āŽĩā¯‡āŽŖā¯āŽŸā¯āŽŽā¯.", + "reset_sqlite_done": "āŽ†āŽĒā¯āŽšā¯ āŽ¤āŽ°āŽĩ❁ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯. āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯āŽšā¯ˆ āŽŽāŽąā¯āŽ¤ā¯ŠāŽŸāŽ•ā¯āŽ•āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ‰āŽŗā¯āŽ¨ā¯āŽ´ā¯ˆāŽ¯āŽĩā¯āŽŽā¯.", "reset_sqlite_success": "SQLITE āŽ¤āŽ°āŽĩā¯āŽ¤ā¯āŽ¤āŽŗāŽ¤ā¯āŽ¤ā¯ˆ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "reset_to_default": "āŽ‡āŽ¯āŽ˛ā¯āŽĒā¯āŽ¨āŽŋāŽ˛ā¯ˆāŽ•ā¯āŽ•ā¯ āŽŽā¯€āŽŸā¯āŽŸāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "resolution": "āŽ¤ā¯†āŽŗāŽŋāŽĩā¯āŽ¤ā¯āŽ¤āŽŋāŽąāŽŠā¯", @@ -1764,9 +1911,12 @@ "saved_settings": "āŽšā¯‡āŽŽāŽŋāŽ¤ā¯āŽ¤ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", "say_something": "āŽāŽ¤āŽžāŽĩāŽ¤ā¯ āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯āŽ™ā¯āŽ•āŽŗā¯", "scaffold_body_error_occurred": "āŽĒāŽŋāŽ´ā¯ˆ āŽāŽąā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "scaffold_body_error_unrecoverable": "āŽŽā¯€āŽŸā¯āŽ• āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ āŽĒāŽŋāŽ´ā¯ˆ āŽāŽąā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯. āŽŸāŽŋāŽšā¯āŽ•āŽžāŽ°ā¯āŽŸā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ•āŽŋāŽŸā¯āŽ…āŽĒā¯āŽĒāŽŋāŽ˛ā¯ āŽĒāŽŋāŽ´ā¯ˆ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ…āŽŸā¯āŽ•ā¯āŽ•ā¯ āŽŸā¯āŽ°ā¯‡āŽšā¯ˆāŽĒā¯ āŽĒāŽ•āŽŋāŽ°āŽĩā¯āŽŽā¯, āŽ…āŽ¤āŽŠāŽžāŽ˛ā¯ āŽ¨āŽžāŽ™ā¯āŽ•āŽŗā¯ āŽ‰āŽ¤āŽĩ āŽŽā¯āŽŸāŽŋāŽ¯ā¯āŽŽā¯. āŽ…āŽąāŽŋāŽĩā¯āŽąā¯āŽ¤ā¯āŽ¤āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯, āŽ•ā¯€āŽ´ā¯‡ āŽ‰āŽŗā¯āŽŗ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯āŽ¤ā¯ āŽ¤āŽ°āŽĩ❈ āŽ…āŽ´āŽŋāŽ•ā¯āŽ•āŽ˛āŽžāŽŽā¯.", + "scan": "āŽĩāŽ°ā¯āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", "scan_all_libraries": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ¨ā¯‚āŽ˛āŽ•āŽ™ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽšā¯āŽ•ā¯‡āŽŠā¯ āŽšā¯†āŽ¯ā¯āŽ¯ā¯āŽ™ā¯āŽ•āŽŗā¯", "scan_library": "āŽšā¯āŽ•ā¯‡āŽŠā¯", "scan_settings": "āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆ āŽšā¯āŽ•ā¯‡āŽŠā¯ āŽšā¯†āŽ¯ā¯āŽ¯ā¯āŽ™ā¯āŽ•āŽŗā¯", + "scanning": "āŽĩāŽ°ā¯āŽŸā¯ āŽšā¯†āŽ¯ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "scanning_for_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽšā¯āŽ•ā¯‡āŽŠāŽŋāŽ™ā¯ ...", "search": "āŽ¤ā¯‡āŽŸāŽ˛ā¯", "search_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", @@ -1796,6 +1946,8 @@ "search_filter_media_type_title": "āŽŽā¯€āŽŸāŽŋāŽ¯āŽž āŽĩāŽ•ā¯ˆāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "search_filter_ocr": "āŽ“āŽšāŽŋāŽ†āŽ°ā¯ āŽŽā¯‚āŽ˛āŽŽā¯ āŽ¤ā¯‡āŽŸā¯", "search_filter_people_title": "āŽŽāŽ•ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "search_filter_star_rating": "āŽ¨āŽŸā¯āŽšāŽ¤ā¯āŽ¤āŽŋāŽ° āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯", + "search_filter_tags_title": "āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽąā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "search_for": "āŽ¤ā¯‡āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", "search_for_existing_person": "āŽ‡āŽ°ā¯āŽ•ā¯āŽ•ā¯āŽŽā¯ āŽ¨āŽĒāŽ°ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽŸā¯āŽ™ā¯āŽ•āŽŗā¯", "search_no_more_result": "āŽŽā¯‡āŽ˛ā¯āŽŽā¯ āŽŽā¯āŽŸāŽŋāŽĩā¯āŽ•āŽŗā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", @@ -1830,17 +1982,23 @@ "second": "āŽ‡āŽ°āŽŖā¯āŽŸāŽžāŽĩāŽ¤ā¯", "see_all_people": "āŽŽāŽ˛ā¯āŽ˛āŽž āŽŽāŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒāŽžāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯", "select": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯", + "select_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_album_cover": "āŽ†āŽ˛ā¯āŽĒāŽŽā¯ āŽ…āŽŸā¯āŽŸā¯ˆāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "select_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤ā¯†āŽ°āŽŋāŽĩā¯āŽšā¯†āŽ¯ā¯", "select_all_duplicates": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ āŽ¨āŽ•āŽ˛ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_all_in": "{group} āŽ‡āŽ˛ā¯ āŽ‰āŽŗā¯āŽŗ āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_avatar_color": "āŽ…āŽĩāŽ¤āŽžāŽ°ā¯ āŽ¨āŽŋāŽąāŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "select_count": "{count, plural, one {āŽ¤ā¯‡āŽ°ā¯āŽĩ❁ #} other {āŽ¤ā¯‡āŽ°ā¯āŽĩā¯āŽ•āŽŗā¯ #}}", + "select_cutoff_date": "āŽĩā¯†āŽŸā¯āŽŸā¯ āŽ¤ā¯‡āŽ¤āŽŋāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_face": "āŽŽā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_featured_photo": "āŽĒāŽŋāŽ°āŽ¤ā¯āŽ¯ā¯‡āŽ• āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_from_computer": "āŽ•āŽŖāŽŋāŽŠāŽŋāŽ¯āŽŋāŽ˛āŽŋāŽ°ā¯āŽ¨ā¯āŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_keep_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽĩā¯ˆāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽŠā¯āŽĒāŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_library_owner": "āŽ¨ā¯‚āŽ˛āŽ• āŽ‰āŽ°āŽŋāŽŽā¯ˆāŽ¯āŽžāŽŗāŽ°ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_new_face": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽŽā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "select_people": "āŽ¨āŽĒāŽ°ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "select_person": "āŽ¨āŽĒāŽ°ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_person_to_tag": "āŽ•ā¯āŽąāŽŋāŽ•ā¯āŽ• āŽ’āŽ°ā¯ āŽ¨āŽĒāŽ°ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_photos": "āŽĒā¯āŽ•ā¯ˆāŽĒā¯āŽĒāŽŸāŽ™ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "select_trash_all": "āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤ā¯ŠāŽŸā¯āŽŸāŽŋāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -1869,6 +2027,9 @@ "set_profile_picture": "āŽšā¯āŽ¯āŽĩāŽŋāŽĩāŽ°āŽĒā¯ āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "set_slideshow_to_fullscreen": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹āŽĩ❈ āŽŽā¯āŽ´ā¯āŽŽā¯ˆāŽ•ā¯āŽ•ā¯ āŽ…āŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "set_stack_primary_asset": "āŽŽā¯āŽ¤āŽŠā¯āŽŽā¯ˆ āŽšā¯ŠāŽ¤ā¯āŽ¤āŽžāŽ• āŽ…āŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "setting_image_navigation_enable_subtitle": "āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽŋāŽ°ā¯āŽ¨ā¯āŽ¤āŽžāŽ˛ā¯, āŽ¤āŽŋāŽ°ā¯ˆāŽ¯āŽŋāŽŠā¯ āŽ‡āŽŸāŽ¤ā¯āŽĒā¯āŽąāŽŽā¯/āŽĩāŽ˛āŽ¤ā¯āŽĒā¯āŽąāŽŽā¯ āŽ‰āŽŗā¯āŽŗ āŽ•āŽžāŽ˛ā¯āŽĒāŽ•ā¯āŽ¤āŽŋāŽ¯ā¯ˆāŽ¤ā¯ āŽ¤āŽŸā¯āŽŸā¯āŽĩāŽ¤āŽŠā¯ āŽŽā¯‚āŽ˛āŽŽā¯ āŽŽā¯āŽ¨ā¯āŽ¤ā¯ˆāŽ¯/āŽ…āŽŸā¯āŽ¤ā¯āŽ¤ āŽĒāŽŸāŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯āŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛āŽ˛āŽžāŽŽā¯.", + "setting_image_navigation_enable_title": "āŽĩāŽ´āŽŋāŽšā¯†āŽ˛ā¯āŽ¤ā¯āŽ¤ āŽ¤āŽŸā¯āŽŸāŽĩā¯āŽŽā¯", + "setting_image_navigation_title": "āŽĒāŽŸ āŽĩāŽ´āŽŋāŽšā¯†āŽ˛ā¯āŽ¤ā¯āŽ¤āŽ˛ā¯", "setting_image_viewer_help": "āŽĩāŽŋāŽĩāŽ°āŽŽā¯ āŽĒāŽžāŽ°ā¯āŽĩā¯ˆāŽ¯āŽžāŽŗāŽ°ā¯ āŽŽā¯āŽ¤āŽ˛āŽŋāŽ˛ā¯ āŽšāŽŋāŽąāŽŋāŽ¯ āŽšāŽŋāŽąā¯ āŽ‰āŽ°ā¯āŽĩāŽ¤ā¯āŽ¤ā¯ˆ āŽāŽąā¯āŽąā¯āŽ•āŽŋāŽąāŽžāŽ°ā¯, āŽĒāŽŋāŽŠā¯āŽŠāŽ°ā¯ āŽ¨āŽŸā¯āŽ¤ā¯āŽ¤āŽ° āŽ…āŽŗāŽĩāŽŋāŽ˛āŽžāŽŠ āŽŽā¯āŽŠā¯āŽŠā¯‹āŽŸā¯āŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽāŽąā¯āŽąā¯āŽ•āŽŋāŽąāŽžāŽ°ā¯ (āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯), āŽ‡āŽąā¯āŽ¤āŽŋāŽ¯āŽžāŽ• āŽ…āŽšāŽ˛ā¯ˆ āŽāŽąā¯āŽąā¯āŽ•āŽŋāŽąāŽ¤ā¯ (āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯).", "setting_image_viewer_original_subtitle": "āŽ…āŽšāŽ˛ā¯ āŽŽā¯āŽ´ā¯ āŽ¤ā¯†āŽŗāŽŋāŽĩā¯āŽ¤ā¯āŽ¤āŽŋāŽąāŽŠā¯ āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽāŽąā¯āŽąāŽĩā¯āŽŽā¯ (āŽĒā¯†āŽ°āŽŋāŽ¯āŽ¤ā¯!). āŽ¤āŽ°āŽĩ❁ āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸā¯ˆāŽ•ā¯ āŽ•ā¯āŽąā¯ˆāŽ•ā¯āŽ• āŽŽā¯āŽŸāŽ•ā¯āŽ•ā¯ (āŽĒāŽŋāŽŖā¯ˆāŽ¯āŽŽā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽšāŽžāŽ¤āŽŠ āŽ¤āŽąā¯āŽ•āŽžāŽ˛āŽŋāŽ• āŽšā¯‡āŽŽāŽŋāŽĒā¯āŽĒ❁ āŽ‡āŽ°āŽŖā¯āŽŸā¯āŽŽā¯).", "setting_image_viewer_original_title": "āŽ…āŽšāŽ˛ā¯ āŽĒāŽŸāŽ¤ā¯āŽ¤ā¯ˆ āŽāŽąā¯āŽąāŽĩā¯āŽŽā¯", @@ -1976,6 +2137,7 @@ "show_password": "āŽ•āŽŸāŽĩā¯āŽšā¯āŽšā¯ŠāŽ˛ā¯āŽ˛ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", "show_person_options": "āŽ¨āŽĒāŽ°ā¯ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", "show_progress_bar": "āŽŽā¯āŽŠā¯āŽŠā¯‡āŽąā¯āŽąāŽĒā¯ āŽĒāŽŸā¯āŽŸāŽŋāŽ¯ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", + "show_schema": "āŽ¤āŽŋāŽŸā¯āŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", "show_search_options": "āŽ¤ā¯‡āŽŸāŽ˛ā¯ āŽĩāŽŋāŽ°ā¯āŽĒā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", "show_shared_links": "āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", "show_slideshow_transition": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹ āŽŽāŽžāŽąā¯āŽąāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŸā¯āŽŸā¯", @@ -1993,6 +2155,8 @@ "skip_to_folders": "āŽ•ā¯‹āŽĒā¯āŽĒā¯āŽąā¯ˆāŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯āŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽ™ā¯āŽ•āŽŗā¯", "skip_to_tags": "āŽ•ā¯āŽąāŽŋāŽšā¯āŽšā¯ŠāŽąā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤āŽĩāŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "slideshow": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹", + "slideshow_repeat": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹āŽĩ❈ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽšā¯†āŽ¯ā¯āŽ¯āŽĩā¯āŽŽā¯", + "slideshow_repeat_description": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹ āŽŽā¯āŽŸāŽŋāŽĩāŽŸā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒā¯‹āŽ¤ā¯ āŽŽā¯€āŽŖā¯āŽŸā¯āŽŽā¯ āŽ¤ā¯ŠāŽŸāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯āŽšā¯ āŽšā¯†āŽ˛ā¯āŽ˛āŽĩā¯āŽŽā¯", "slideshow_settings": "āŽšā¯āŽ˛ā¯ˆāŽŸā¯āŽšā¯‹ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯", "sort_albums_by": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽĩāŽ°āŽŋāŽšā¯ˆāŽĒā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ™ā¯āŽ•āŽŗā¯ ...", "sort_created": "āŽ¤ā¯‡āŽ¤āŽŋ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -2032,6 +2196,7 @@ "support": "āŽ‰āŽ¤āŽĩāŽŋ", "support_and_feedback": "āŽ‰āŽ¤āŽĩāŽŋ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯", "support_third_party_description": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽ¨āŽŋāŽąā¯āŽĩāŽ˛ā¯ āŽŽā¯‚āŽŠā¯āŽąāŽžāŽŽā¯ āŽ¤āŽ°āŽĒā¯āŽĒāŽŋāŽŠāŽ°āŽžāŽ˛ā¯ āŽ¤ā¯ŠāŽ•ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯. āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽŠā¯āŽĒāŽĩāŽŋāŽ•ā¯āŽ•ā¯āŽŽā¯ āŽšāŽŋāŽ•ā¯āŽ•āŽ˛ā¯āŽ•āŽŗā¯ āŽ…āŽ¨ā¯āŽ¤ āŽ¤ā¯ŠāŽ•ā¯āŽĒā¯āŽĒāŽžāŽ˛ā¯ āŽāŽąā¯āŽĒāŽŸāŽ˛āŽžāŽŽā¯, āŽŽāŽŠāŽĩ❇ āŽ•ā¯€āŽ´ā¯‡āŽ¯ā¯āŽŗā¯āŽŗ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋ āŽŽā¯āŽ¤āŽ˛ā¯ āŽšāŽ¨ā¯āŽ¤āŽ°ā¯āŽĒā¯āŽĒāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽ…āŽĩāŽ°ā¯āŽ•āŽŗā¯āŽŸāŽŠā¯ āŽšāŽŋāŽ•ā¯āŽ•āŽ˛ā¯āŽ•āŽŗā¯ˆ āŽŽāŽ´ā¯āŽĒā¯āŽĒā¯āŽ™ā¯āŽ•āŽŗā¯.", + "supporter": "āŽ†āŽ¤āŽ°āŽĩāŽžāŽŗāŽ°ā¯", "swap_merge_direction": "āŽ’āŽŠā¯āŽąāŽŋāŽŖā¯ˆāŽ•ā¯āŽ•ā¯āŽŽā¯ āŽ¤āŽŋāŽšā¯ˆāŽ¯ā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽĩā¯āŽŽā¯", "sync": "āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽĩ❁", "sync_albums": "āŽ†āŽ˛ā¯āŽĒāŽ™ā¯āŽ•āŽŗā¯ˆ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -2069,6 +2234,7 @@ "theme_setting_theme_subtitle": "āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽŸāŽŋāŽŠā¯ āŽ•āŽ°ā¯āŽĒā¯āŽĒā¯ŠāŽ°ā¯āŽŗā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ•", "theme_setting_three_stage_loading_subtitle": "āŽŽā¯‚āŽŠā¯āŽąā¯-āŽ¨āŽŋāŽ˛ā¯ˆ āŽāŽąā¯āŽąā¯āŽ¤āŽ˛ā¯ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽŋāŽŠāŽžāŽ˛ā¯ āŽāŽąā¯āŽąā¯āŽ¤āŽ˛ā¯ āŽšā¯†āŽ¯āŽ˛ā¯āŽ¤āŽŋāŽąāŽŠā¯ˆ āŽ…āŽ¤āŽŋāŽ•āŽ°āŽŋāŽ•ā¯āŽ•āŽ•ā¯āŽ•ā¯‚āŽŸā¯āŽŽā¯, āŽ†āŽŠāŽžāŽ˛ā¯ āŽ•āŽŖāŽŋāŽšāŽŽāŽžāŽ• āŽŽāŽŋāŽ•ā¯ˆ āŽĒāŽŋāŽŖā¯ˆāŽ¯āŽšā¯ āŽšā¯āŽŽā¯ˆāŽ¯ā¯ˆ āŽāŽąā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽąāŽ¤ā¯", "theme_setting_three_stage_loading_title": "āŽŽā¯‚āŽŠā¯āŽąā¯-āŽ¨āŽŋāŽ˛ā¯ˆ āŽāŽąā¯āŽąā¯āŽ¤āŽ˛ā¯ˆ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", + "then": "āŽĒāŽŋāŽąāŽ•ā¯", "they_will_be_merged_together": "āŽ…āŽĩāŽ°ā¯āŽ•āŽŗā¯ āŽ’āŽŠā¯āŽąāŽžāŽ• āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽĩāŽžāŽ°ā¯āŽ•āŽŗā¯", "third_party_resources": "āŽŽā¯‚āŽŠā¯āŽąāŽžāŽŽā¯ āŽ¤āŽ°āŽĒā¯āŽĒ❁ āŽĩāŽŗāŽ™ā¯āŽ•āŽŗā¯", "time": "āŽ¨ā¯‡āŽ°āŽŽā¯", @@ -2103,6 +2269,13 @@ "trash_page_select_assets_btn": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¤ā¯ āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "trash_page_title": "({count})", "trashed_items_will_be_permanently_deleted_after": "āŽ•ā¯āŽĒā¯āŽĒā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ‰āŽŗā¯āŽŗ āŽ‰āŽ°ā¯āŽĒā¯āŽĒāŽŸāŽŋāŽ•āŽŗā¯ {days, plural, one {# āŽ¨āŽžāŽŗā¯āŽ•ā¯āŽ•ā¯} other {# āŽ¨āŽžāŽŸā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯}}āŽĒāŽŋāŽąāŽ•ā¯ āŽ¨āŽŋāŽ°āŽ¨ā¯āŽ¤āŽ°āŽŽāŽžāŽ• āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", + "trigger": "āŽ¤ā¯‚āŽŖā¯āŽŸā¯āŽ¤āŽ˛ā¯", + "trigger_asset_uploaded": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "trigger_asset_uploaded_description": "āŽĒā¯āŽ¤āŽŋāŽ¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŽā¯ āŽĒā¯‹āŽ¤ā¯ āŽ¤ā¯‚āŽŖā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "trigger_description": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ•ā¯āŽŽā¯ āŽ’āŽ°ā¯ āŽ¨āŽŋāŽ•āŽ´ā¯āŽĩ❁", + "trigger_person_recognized": "āŽ…āŽŸā¯ˆāŽ¯āŽžāŽŗāŽŽā¯ āŽ•āŽžāŽŖāŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ¨āŽĒāŽ°ā¯", + "trigger_person_recognized_description": "āŽ’āŽ°ā¯ āŽ¨āŽĒāŽ°ā¯ āŽ•āŽŖā¯āŽŸāŽąāŽŋāŽ¯āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯ āŽ¤ā¯‚āŽŖā¯āŽŸāŽĒā¯āŽĒāŽŸā¯āŽ•āŽŋāŽąāŽ¤ā¯", + "trigger_type": "āŽ¤ā¯‚āŽŖā¯āŽŸā¯āŽ¤āŽ˛ā¯ āŽĩāŽ•ā¯ˆ", "troubleshoot": "āŽšāŽ°āŽŋāŽšā¯†āŽ¯ā¯āŽ¤āŽ˛ā¯", "type": "āŽĩāŽ•ā¯ˆ", "unable_to_change_pin_code": "āŽŽā¯āŽŗā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯ˆ āŽŽāŽžāŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", @@ -2117,6 +2290,7 @@ "unhide_person": "āŽ…āŽ°ā¯āŽĩāŽ°ā¯āŽĒā¯āŽĒāŽžāŽŠ āŽ¨āŽĒāŽ°ā¯", "unknown": "āŽ¤ā¯†āŽ°āŽŋāŽ¯āŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ", "unknown_country": "āŽ¤ā¯†āŽ°āŽŋāŽ¯āŽžāŽ¤ āŽ¨āŽžāŽŸā¯", + "unknown_date": "āŽ¤ā¯†āŽ°āŽŋāŽ¯āŽžāŽ¤ āŽ¤ā¯‡āŽ¤āŽŋ", "unknown_year": "āŽ¤ā¯†āŽ°āŽŋāŽ¯āŽžāŽ¤ āŽ†āŽŖā¯āŽŸā¯", "unlimited": "āŽĩāŽ°āŽŽā¯āŽĒāŽąā¯āŽąāŽ¤ā¯", "unlink_motion_video": "āŽ‡āŽ¯āŽ•ā¯āŽ• āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽĩ❈ āŽ‡āŽŖā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", @@ -2133,7 +2307,10 @@ "unstack": "āŽ…āŽŠā¯-āŽšā¯āŽŸāŽžāŽ•ā¯", "unstack_action_prompt": "{count} āŽ¤āŽŸā¯ˆāŽ¯āŽŋāŽŠā¯āŽąāŽŋ", "unstacked_assets_count": "āŽ…āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤ {count, plural, one {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯} other {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯}}", + "unsupported_field_type": "āŽ†āŽ¤āŽ°āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤ āŽĒā¯āŽ˛ āŽĩāŽ•ā¯ˆ", + "unsupported_file_type": "āŽ•ā¯‹āŽĒā¯āŽĒ❈ {file} āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽŽā¯āŽŸāŽŋāŽ¯āŽžāŽ¤ā¯, āŽāŽŠā¯†āŽŠāŽŋāŽ˛ā¯ āŽ…āŽ¤āŽŠā¯ āŽ•ā¯‹āŽĒā¯āŽĒ❁ āŽĩāŽ•ā¯ˆ {type} āŽ†āŽ¤āŽ°āŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽĩāŽŋāŽ˛ā¯āŽ˛ā¯ˆ.", "untagged": "āŽ…āŽĩāŽŋāŽ´ā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸāŽžāŽ¤āŽ¤ā¯", + "untitled_workflow": "āŽĒā¯†āŽ¯āŽ°āŽŋāŽŸāŽĒā¯āŽĒāŽŸāŽžāŽ¤ āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁", "up_next": "āŽ…āŽŸā¯āŽ¤ā¯āŽ¤ā¯", "update_location_action_prompt": "{count} āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯:", "updated_at": "āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", @@ -2143,6 +2320,7 @@ "upload_details": "āŽĩāŽŋāŽĩāŽ°āŽ™ā¯āŽ•āŽŗā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĩā¯āŽŽā¯", "upload_dialog_info": "āŽ¤ā¯‡āŽ°ā¯āŽ¨ā¯āŽ¤ā¯†āŽŸā¯āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ (āŽ•āŽŗā¯ˆ) āŽšā¯‡āŽĩā¯ˆāŽ¯āŽ•āŽ¤ā¯āŽ¤āŽŋāŽąā¯āŽ•ā¯ āŽ•āŽžāŽĒā¯āŽĒ❁āŽĒā¯ āŽĒāŽŋāŽ°āŽ¤āŽŋ āŽŽāŽŸā¯āŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", "upload_dialog_title": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ˆ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĩā¯āŽŽā¯", + "upload_error_with_count": "{count, plural, one {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•ā¯} other {# āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯āŽ•ā¯āŽ•ā¯}} āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽĒā¯ āŽĒāŽŋāŽ´ā¯ˆ", "upload_errors": "{count, plural, one {# āŽĒāŽŋāŽ´ā¯ˆ} other {# āŽĒāŽŋāŽ´ā¯ˆāŽ•āŽŗā¯}}āŽŽā¯‚āŽ˛āŽŽā¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŽā¯ āŽŽā¯āŽŸāŽŋāŽ¨ā¯āŽ¤āŽ¤ā¯, āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽą āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗā¯ˆāŽĒā¯ āŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĒā¯ āŽĒāŽ•ā¯āŽ•āŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯.", "upload_finished": "āŽĒāŽ¤āŽŋāŽĩā¯‡āŽąā¯āŽąāŽŽā¯ āŽŽā¯āŽŸāŽŋāŽ¨ā¯āŽ¤āŽ¤ā¯", "upload_progress": "āŽŽā¯€āŽ¤āŽŽā¯āŽŗā¯āŽŗ {remaining, number} - āŽšā¯†āŽ¯āŽ˛āŽžāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯ {processed, number}/{total, number}", @@ -2157,6 +2335,8 @@ "url": "āŽŽā¯āŽ•āŽĩāŽ°āŽŋ", "usage": "āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯", "use_biometric": "āŽĒāŽ¯ā¯‹āŽŽā¯†āŽŸā¯āŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", + "use_browser_locale": "āŽ‰āŽ˛āŽžāŽĩāŽŋāŽ¯āŽŋāŽŠā¯ āŽŽā¯ŠāŽ´āŽŋāŽ¯ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", + "use_browser_locale_description": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‰āŽ˛āŽžāŽĩāŽŋāŽ¯āŽŋāŽŠā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽŋāŽŸāŽ¤ā¯āŽ¤āŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ¤ā¯‡āŽ¤āŽŋāŽ•āŽŗā¯, āŽ¨ā¯‡āŽ°āŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽŽāŽŖā¯āŽ•āŽŗā¯ˆ āŽĩāŽŸāŽŋāŽĩāŽŽā¯ˆāŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "use_current_connection": "āŽ¤āŽąā¯āŽĒā¯‹āŽ¤ā¯ˆāŽ¯ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "use_custom_date_range": "āŽ…āŽ¤āŽąā¯āŽ•ā¯ āŽĒāŽ¤āŽŋāŽ˛āŽžāŽ• āŽ¤āŽŠāŽŋāŽĒā¯āŽĒāŽ¯āŽŠā¯ āŽ¤ā¯‡āŽ¤āŽŋ āŽĩāŽ°āŽŽā¯āŽĒ❈āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "user": "āŽĒāŽ¯āŽŠāŽ°ā¯", @@ -2178,10 +2358,11 @@ "utilities": "āŽĒāŽ¯āŽŠā¯āŽĒāŽžāŽŸā¯āŽ•āŽŗā¯", "validate": "āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯", "validate_endpoint_error": "āŽ¤āŽ¯āŽĩā¯āŽšā¯†āŽ¯ā¯āŽ¤ā¯ āŽ’āŽ°ā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽĒāŽŸāŽŋāŽ¯āŽžāŽ•ā¯āŽŽā¯ URL āŽ āŽ‰āŽŗā¯āŽŗāŽŋāŽŸāŽĩā¯āŽŽā¯", + "validation_error": "āŽšāŽ°āŽŋāŽĒāŽžāŽ°ā¯āŽĒā¯āŽĒ❁ āŽĒāŽŋāŽ´ā¯ˆ", "variables": "āŽŽāŽžāŽąāŽŋāŽ•āŽŗā¯", "version": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁", "version_announcement_closing": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ¨āŽŖā¯āŽĒāŽ°ā¯, āŽ…āŽ˛ā¯†āŽ•ā¯āŽšā¯", - "version_announcement_message": "āŽĩāŽŖāŽ•ā¯āŽ•āŽŽā¯! āŽ‡āŽŽā¯āŽŽāŽŋāŽ¯āŽŋāŽŠā¯ āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽŽāŽ¨ā¯āŽ¤āŽĩā¯ŠāŽ°ā¯ āŽ¤āŽĩāŽąāŽžāŽŠ āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤āŽŸā¯āŽ•ā¯āŽ• āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ¤ā¯āŽ¤ āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽ¤ā¯ˆ āŽ‰āŽąā¯āŽ¤āŽŋāŽšā¯†āŽ¯ā¯āŽ¯ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯āŽ•ā¯ āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽŸāŽŋāŽ•ā¯āŽ• āŽšāŽŋāŽąāŽŋāŽ¤ā¯ āŽ¨ā¯‡āŽ°āŽŽā¯ āŽ’āŽ¤ā¯āŽ•ā¯āŽ•ā¯āŽ™ā¯āŽ•āŽŗā¯, āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒāŽžāŽ• āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽžāŽĩāŽąā¯āŽ•ā¯‹āŽĒā¯āŽ°āŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽŠāŽžāŽ˛ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽ¨āŽŋāŽ•āŽ´ā¯āŽĩ❈ āŽ¤āŽžāŽŠāŽžāŽ•āŽĩ❇ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽĒā¯āŽĒāŽ¤ā¯ˆāŽ•ā¯ āŽ•ā¯ˆāŽ¯āŽžāŽŗā¯āŽŽā¯ āŽŽāŽ¨ā¯āŽ¤āŽĩā¯ŠāŽ°ā¯ āŽĒā¯ŠāŽąāŽŋāŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽŠāŽžāŽ˛ā¯.", + "version_announcement_message": "āŽĩāŽŖāŽ•ā¯āŽ•āŽŽā¯! āŽ‡āŽŽā¯āŽŽāŽŋāŽ¯āŽŋāŽŠā¯ āŽĒā¯āŽ¤āŽŋāŽ¯ āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽ•āŽŋāŽŸā¯ˆāŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯. āŽŽāŽ¨ā¯āŽ¤āŽĩā¯ŠāŽ°ā¯ āŽ¤āŽĩāŽąāŽžāŽŠ āŽ•āŽ°ā¯āŽ¤ā¯āŽ¤ā¯āŽ•ā¯āŽ•āŽŗā¯ˆāŽ¯ā¯āŽŽā¯ āŽ¤āŽŸā¯āŽ•ā¯āŽ• āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ…āŽŽā¯ˆāŽĒā¯āŽĒ❁ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ¤ā¯āŽ¤ āŽ¨āŽŋāŽ˛ā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽ‡āŽ°ā¯āŽĒā¯āŽĒāŽ¤ā¯ˆ āŽ‰āŽąā¯āŽ¤āŽŋāŽšā¯†āŽ¯ā¯āŽ¯ āŽĩā¯†āŽŗāŽŋāŽ¯ā¯€āŽŸā¯āŽŸā¯āŽ•ā¯ āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ āŽāŽĒā¯ āŽĒāŽŸāŽŋāŽ•ā¯āŽ•āŽšā¯ āŽšāŽŋāŽąāŽŋāŽ¤ā¯ āŽ¨ā¯‡āŽ°āŽŽā¯ āŽ’āŽ¤ā¯āŽ•ā¯āŽ•ā¯āŽ™ā¯āŽ•āŽŗā¯, āŽ•ā¯āŽąāŽŋāŽĒā¯āŽĒāŽžāŽ• āŽ¨ā¯€āŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽžāŽĩāŽąā¯āŽ•ā¯‹āŽĒā¯āŽ°āŽ¤ā¯āŽ¤ā¯ˆāŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽŠāŽžāŽ˛ā¯ āŽ…āŽ˛ā¯āŽ˛āŽ¤ā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯ āŽ¨āŽŋāŽ•āŽ´ā¯āŽĩā¯ˆāŽ¤ā¯ āŽ¤āŽžāŽŠāŽžāŽ•āŽĩ❇ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽĒā¯āŽĒāŽ¤ā¯ˆāŽ•ā¯ āŽ•ā¯ˆāŽ¯āŽžāŽŗā¯āŽŽā¯ āŽŽāŽ¨ā¯āŽ¤āŽĩā¯ŠāŽ°ā¯ āŽĒā¯ŠāŽąāŽŋāŽŽā¯āŽąā¯ˆāŽ¯ā¯ˆāŽ¯ā¯āŽŽā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽŋāŽŠāŽžāŽ˛ā¯.", "version_history": "āŽĒāŽ¤āŽŋāŽĒā¯āŽĒ❁ āŽĩāŽ°āŽ˛āŽžāŽąā¯", "version_history_item": "{version} āŽ‡āŽ˛ā¯ {date} āŽ¨āŽŋāŽąā¯āŽĩāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", "video": "āŽ’āŽŗāŽŋāŽ¤ā¯‹āŽąā¯āŽąāŽŽā¯", @@ -2189,6 +2370,7 @@ "video_hover_setting_description": "āŽŽāŽĩā¯āŽšā¯ āŽ‰āŽ°ā¯āŽĒā¯āŽĒāŽŸāŽŋāŽ¯ā¯ˆāŽ•ā¯ āŽ•ā¯ŠāŽŖā¯āŽŸā¯ āŽšā¯†āŽ˛ā¯āŽ˛ā¯āŽŽā¯āŽĒā¯‹āŽ¤ā¯ āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹ āŽšāŽŋāŽąā¯ āŽ‰āŽ°ā¯āŽĩāŽ¤ā¯āŽ¤ā¯ˆ āŽ‡āŽ¯āŽ•ā¯āŽ•āŽĩā¯āŽŽā¯. āŽŽā¯āŽŸāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽžāŽ˛ā¯āŽŽā¯ āŽ•ā¯‚āŽŸ, āŽĒāŽŋāŽŗā¯‡ āŽāŽ•āŽžāŽŠā¯āŽ•ā¯āŽ•ā¯ āŽŽā¯‡āŽ˛ā¯ āŽšā¯āŽąā¯āŽąā¯āŽĩāŽ¤āŽŠā¯ āŽŽā¯‚āŽ˛āŽŽā¯ āŽĒāŽŋāŽŗā¯‡āŽĒā¯‡āŽ•ā¯āŽ•ā¯ˆāŽ¤ā¯ āŽ¤ā¯ŠāŽŸāŽ™ā¯āŽ•āŽ˛āŽžāŽŽā¯.", "videos": "āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯", "videos_count": "{count, plural, one {# āŽ•āŽžāŽŖā¯ŠāŽŗāŽŋ} other {# āŽ•āŽžāŽŖā¯ŠāŽŗāŽŋāŽ•āŽŗā¯}}", + "videos_only": "āŽĩā¯€āŽŸāŽŋāŽ¯ā¯‹āŽ•ā¯āŽ•āŽŗā¯ āŽŽāŽŸā¯āŽŸā¯āŽŽā¯‡", "view": "āŽĒāŽžāŽ°ā¯āŽĩ❈", "view_album": "āŽ†āŽ˛ā¯āŽĒāŽ¤ā¯āŽ¤ā¯ˆāŽ•ā¯ āŽ•āŽžāŽŖā¯āŽ•", "view_all": "āŽ…āŽŠā¯ˆāŽ¤ā¯āŽ¤ā¯ˆāŽ¯ā¯āŽŽā¯ āŽ•āŽžāŽŖā¯āŽ•", @@ -2209,18 +2391,36 @@ "viewer_stack_use_as_main_asset": "āŽĒāŽŋāŽ°āŽ¤āŽžāŽŠ āŽšā¯ŠāŽ¤ā¯āŽ¤āŽžāŽ•āŽĒā¯ āŽĒāŽ¯āŽŠā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "viewer_unstack": "āŽ…āŽŸā¯āŽ•ā¯āŽ•ā¯ˆ āŽ¨ā¯€āŽ•ā¯āŽ•ā¯", "visibility_changed": "{count, plural, one {# āŽ¨āŽĒāŽ°ā¯} other {# āŽ¨āŽĒāŽ°ā¯āŽ•āŽŗā¯}} āŽ•ā¯āŽ•āŽžāŽŠ āŽ¤ā¯†āŽ°āŽŋāŽĩā¯āŽ¨āŽŋāŽ˛ā¯ˆ āŽŽāŽžāŽąā¯āŽąāŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "visual": "āŽ•āŽžāŽŸā¯āŽšāŽŋ", + "visual_builder": "āŽ•āŽžāŽŸā¯āŽšāŽŋ āŽ‰āŽ°ā¯āŽĩāŽžāŽ•ā¯āŽ•ā¯āŽĒāŽĩāŽ°ā¯", "waiting": "āŽ•āŽžāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯", + "waiting_count": "āŽ•āŽžāŽ¤ā¯āŽ¤āŽŋāŽ°ā¯āŽ•ā¯āŽ•āŽŋāŽąāŽ¤ā¯: {count}", "warning": "āŽŽāŽšā¯āŽšāŽ°āŽŋāŽ•ā¯āŽ•ā¯ˆ", "week": "āŽĩāŽžāŽ°āŽŽā¯", "welcome": "āŽĩāŽ°āŽĩā¯‡āŽąā¯āŽ•āŽŋāŽąā¯‹āŽŽā¯", "welcome_to_immich": "āŽ‡āŽŽā¯āŽŽāŽŋāŽšā¯āŽšāŽŋāŽąā¯āŽ•ā¯ āŽĩāŽ°ā¯āŽ•", + "width": "āŽ…āŽ•āŽ˛āŽŽā¯", "wifi_name": "āŽĩā¯ˆāŽƒāŽĒ❈ āŽĒā¯†āŽ¯āŽ°ā¯", + "workflow_delete_prompt": "āŽ‡āŽ¨ā¯āŽ¤ āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ˆ āŽ¨āŽŋāŽšā¯āŽšāŽ¯āŽŽāŽžāŽ• āŽ¨ā¯€āŽ•ā¯āŽ• āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", + "workflow_deleted": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽ¨ā¯€āŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "workflow_description": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽĩāŽŋāŽŗāŽ•ā¯āŽ•āŽŽā¯", + "workflow_info": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽšā¯†āŽ¯ā¯āŽ¤āŽŋ", + "workflow_json": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽšāŽžāŽ¤ā¯ŠāŽĒā¯ŠāŽ•ā¯", + "workflow_json_help": "āŽšāŽžāŽ¤ā¯ŠāŽĒā¯ŠāŽ•ā¯ āŽĩāŽŸāŽŋāŽĩāŽ¤ā¯āŽ¤āŽŋāŽ˛ā¯ āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽ‰āŽŗā¯āŽŗāŽŽā¯ˆāŽĩā¯ˆāŽ¤ā¯ āŽ¤āŽŋāŽ°ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯. āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ āŽ•āŽžāŽŸā¯āŽšāŽŋ āŽĒāŽŋāŽ˛ā¯āŽŸāŽ°ā¯āŽŸāŽŠā¯ āŽ’āŽ¤ā¯āŽ¤āŽŋāŽšā¯ˆāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŽā¯.", + "workflow_name": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽĒā¯†āŽ¯āŽ°ā¯", + "workflow_navigation_prompt": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽŽāŽžāŽąā¯āŽąāŽ™ā¯āŽ•āŽŗā¯ˆāŽšā¯ āŽšā¯‡āŽŽāŽŋāŽ•ā¯āŽ•āŽžāŽŽāŽ˛ā¯ āŽ¨āŽŋāŽšā¯āŽšāŽ¯āŽŽāŽžāŽ• āŽĩā¯†āŽŗāŽŋāŽ¯ā¯‡āŽą āŽĩāŽŋāŽ°ā¯āŽŽā¯āŽĒā¯āŽ•āŽŋāŽąā¯€āŽ°ā¯āŽ•āŽŗāŽž?", + "workflow_summary": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽšā¯āŽ°ā¯āŽ•ā¯āŽ•āŽŽā¯", + "workflow_update_success": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽĩā¯†āŽąā¯āŽąāŽŋāŽ•āŽ°āŽŽāŽžāŽ• āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "workflow_updated": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩ❁ āŽĒā¯āŽ¤ā¯āŽĒā¯āŽĒāŽŋāŽ•ā¯āŽ•āŽĒā¯āŽĒāŽŸā¯āŽŸāŽ¤ā¯", + "workflows": "āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯", + "workflows_help_text": "āŽ¤ā¯‚āŽŖā¯āŽŸā¯āŽ¤āŽ˛ā¯āŽ•āŽŗā¯ āŽŽāŽąā¯āŽąā¯āŽŽā¯ āŽĩāŽŸāŽŋāŽĒā¯āŽĒāŽžāŽŠā¯āŽ•āŽŗāŽŋāŽŠā¯ āŽ…āŽŸāŽŋāŽĒā¯āŽĒāŽŸā¯ˆāŽ¯āŽŋāŽ˛ā¯ āŽĒāŽŖāŽŋāŽĒā¯āŽĒāŽžāŽ¯ā¯āŽĩā¯āŽ•āŽŗā¯ āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯āŽ•āŽŗāŽŋāŽ˛ā¯ āŽšā¯†āŽ¯āŽ˛ā¯āŽ•āŽŗā¯ˆ āŽ¤āŽžāŽŠāŽŋāŽ¯āŽ™ā¯āŽ•ā¯āŽĒāŽŸā¯āŽ¤ā¯āŽ¤ā¯āŽ•āŽŋāŽŠā¯āŽąāŽŠ", "wrong_pin_code": "āŽ¤āŽĩāŽąāŽžāŽŠ āŽĒāŽŋāŽŠā¯ āŽ•ā¯āŽąāŽŋāŽ¯ā¯€āŽŸā¯", "year": "āŽ†āŽŖā¯āŽŸā¯", "years_ago": "{years, plural, one {# āŽ†āŽŖā¯āŽŸā¯} other {# āŽ†āŽŖā¯āŽŸā¯āŽ•āŽŗā¯}} āŽŽā¯āŽŠā¯āŽĒ❁", "yes": "āŽ†āŽŽā¯", "you_dont_have_any_shared_links": "āŽ‰āŽ™ā¯āŽ•āŽŗāŽŋāŽŸāŽŽā¯ āŽĒāŽ•āŽŋāŽ°āŽĒā¯āŽĒāŽŸā¯āŽŸ āŽ‡āŽŖā¯ˆāŽĒā¯āŽĒā¯āŽ•āŽŗā¯ āŽŽāŽ¤ā¯āŽĩā¯āŽŽā¯ āŽ‡āŽ˛ā¯āŽ˛ā¯ˆ", "your_wifi_name": "āŽ‰āŽ™ā¯āŽ•āŽŗā¯ āŽĩā¯ˆāŽƒāŽĒ❈ āŽĒā¯†āŽ¯āŽ°ā¯", + "zero_to_clear_rating": "āŽšā¯ŠāŽ¤ā¯āŽ¤ā¯ āŽŽāŽ¤āŽŋāŽĒā¯āŽĒā¯€āŽŸā¯āŽŸā¯ˆ āŽ…āŽ´āŽŋāŽ•ā¯āŽ• 0 āŽ āŽ…āŽ´ā¯āŽ¤ā¯āŽ¤āŽĩā¯āŽŽā¯", "zoom_image": "āŽĒā¯†āŽ°āŽŋāŽ¤āŽžāŽ•ā¯āŽ• āŽĒāŽŸāŽŽā¯", "zoom_to_bounds": "āŽŽāŽ˛ā¯āŽ˛ā¯ˆāŽ•ā¯āŽ•ā¯ āŽĒā¯†āŽ°āŽŋāŽ¤āŽžāŽ•ā¯āŽ•ā¯" } diff --git a/i18n/te.json b/i18n/te.json index 18b38069b4..73288c1a8e 100644 --- a/i18n/te.json +++ b/i18n/te.json @@ -350,7 +350,7 @@ "user_settings": "ā°ĩā°žā°Ąāąā°•ā°°ā°ŋ ā°¸āą†ā°Ÿāąā°Ÿā°ŋā°‚ā°—āąâ€Œā°˛āą", "user_settings_description": "ā°ĩā°žā°Ąāąā°•ā°°ā°ŋ ā°¸āą†ā°Ÿāąā°Ÿā°ŋā°‚ā°—āąâ€Œā°˛ā°¨āą ā°¨ā°ŋā°°āąā°ĩā°šā°ŋā°‚ā°šā°‚ā°Ąā°ŋ", "version_check_enabled_description": "ā°ĩā°°āąā°ˇā°¨āą ⰤⰍā°ŋā°–āą€ā°¨ā°ŋ ā°šāą‡ā°¯ā°‚ā°Ąā°ŋ", - "version_check_implications": "ā°ĩā°°āąā°ˇā°¨āą ⰤⰍā°ŋā°–āą€ ā°Ģāą€ā°šā°°āą github.comā°¤āą‹ ā°•āąā°°ā°Žā°žā°¨āąā°—ā°¤ ā°•ā°Žāąā°¯āą‚ā°¨ā°ŋā°•āą‡ā°ˇā°¨āąâ€Œā°Ēāąˆ ā°†ā°§ā°žā°°ā°Ēā°Ąāąā°¤āąā°‚ā°Ļā°ŋ", + "version_check_implications": "ā°ĩā°°āąā°ˇā°¨āą ⰤⰍā°ŋā°–āą€ ā°Ģāą€ā°šā°°āą {server}ā°¤āą‹ ā°•āąā°°ā°Žā°žā°¨āąā°—ā°¤ ā°•ā°Žāąā°¯āą‚ā°¨ā°ŋā°•āą‡ā°ˇā°¨āąâ€Œā°Ēāąˆ ā°†ā°§ā°žā°°ā°Ēā°Ąāąā°¤āąā°‚ā°Ļā°ŋ", "version_check_settings": "ā°ĩā°°āąā°ˇā°¨āą ⰤⰍā°ŋā°–āą€", "version_check_settings_description": "ā°•āąŠā°¤āąā°¤ ā°ĩā°°āąā°ˇā°¨āą ā°¨āą‹ā°Ÿā°ŋā°Ģā°ŋā°•āą‡ā°ˇā°¨āąâ€Œā°¨āą ā°Ēāąā°°ā°žā°°ā°‚ā°­ā°ŋā°‚ā°šā°‚ā°Ąā°ŋ/ā°†ā°Ēā°ŋā°ĩāą‡ā°¯ā°‚ā°Ąā°ŋ", "video_conversion_job": "ā°ĩāą€ā°Ąā°ŋā°¯āą‹ā°˛ā°¨āą ā°Ÿāąā°°ā°žā°¨āąā°¸āąâ€Œā°•āą‹ā°Ąāą ā°šāą‡ā°¯ā°‚ā°Ąā°ŋ", @@ -523,10 +523,6 @@ "date_range": "ā°¤āą‡ā°Ļāą€ ā°Ēā°°ā°ŋā°§ā°ŋ", "day": "ā°°āą‹ā°œāą", "deduplicate_all": "ā°…ā°¨āąā°¨āą€ ⰍⰕā°ŋā°˛āą€ā°˛āą ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°šāą", - "deduplication_criteria_1": "ā°Ŧāąˆā°Ÿāąâ€Œā°˛ā°˛āą‹ Ⱊā°ŋā°¤āąā°° ā°Ēā°°ā°ŋā°Žā°žā°Ŗā°‚", - "deduplication_criteria_2": "EXIF ā°Ąāą‡ā°Ÿā°ž ā°¸ā°‚ā°–āąā°¯", - "deduplication_info": "ⰍⰕā°ŋā°˛āą€ā°˛ ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°Ēāą ā°¸ā°Žā°žā°šā°žā°°ā°‚", - "deduplication_info_description": "ā°†ā°¸āąā°¤āąā°˛ā°¨āą ā°¸āąā°ĩā°¯ā°‚ā°šā°žā°˛ā°•ā°‚ā°—ā°ž ā°Žāąā°‚ā°Ļā°¸āąā°¤āąā°—ā°ž ā°Žā°‚ā°šāąā°•āą‹ā°ĩā°Ąā°žā°¨ā°ŋā°•ā°ŋ ā°Žā°°ā°ŋā°¯āą ⰍⰕā°ŋā°˛āą€ā°˛ā°¨āą ā°Ēāą†ā°Ļāąā°Ļā°ŽāąŠā°¤āąā°¤ā°‚ā°˛āą‹ ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°šā°Ąā°žā°¨ā°ŋā°•ā°ŋ, ā°Žāą‡ā°Žāą ā°ĩāą€ā°Ÿā°ŋā°¨ā°ŋ ā°Ēā°°ā°ŋā°ļāą€ā°˛ā°ŋā°¸āąā°¤ā°žā°Žāą:", "delete": "ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°šāą", "delete_album": "ā°†ā°˛āąā°Ŧā°Žāąâ€Œā°¨āą ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°šāą", "delete_api_key_prompt": "ā°Žāą€ā°°āą Ⰸ API ā°•āą€ā°¨ā°ŋ ā°–ā°šāąā°šā°ŋā°¤ā°‚ā°—ā°ž ā°¤āąŠā°˛ā°—ā°ŋā°‚ā°šā°žā°˛ā°¨āąā°•āąā°‚ā°Ÿāąā°¨āąā°¨ā°žā°°ā°ž?", diff --git a/i18n/th.json b/i18n/th.json index f22c83dfb8..f0f70638fd 100644 --- a/i18n/th.json +++ b/i18n/th.json @@ -5,6 +5,7 @@ "acknowledge": "ā¸Ŗā¸ąā¸šā¸—ā¸Ŗā¸˛ā¸š", "action": "ā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗ", "action_common_update": "ā¸­ā¸ąā¸›āš€ā¸”ā¸•", + "action_description": "ā¸Šā¸¸ā¸”ā¸ā¸˛ā¸Ŗā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗā¸—ā¸ĩāšˆā¸ˆā¸°ā¸›ā¸ā¸´ā¸šā¸ąā¸•ā¸´ā¸ā¸ąā¸šā¸Ŗā¸˛ā¸ĸ⏁⏞⏪⏗ā¸ĩāšˆā¸œāšˆā¸˛ā¸™ā¸ā¸˛ā¸Ŗā¸ā¸Ŗā¸­ā¸‡", "actions": "ā¸ā¸˛ā¸Ŗā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗ", "active": "⏁⏺ā¸Ĩā¸ąā¸‡ā¸—ā¸ŗā¸‡ā¸˛ā¸™", "active_count": "⏁⏺ā¸Ĩā¸ąā¸‡ā¸—ā¸ŗā¸‡ā¸˛ā¸™: {count}", @@ -16,11 +17,13 @@ "add_a_name": "āš€ā¸žā¸´āšˆā¸Ąā¸Šā¸ˇāšˆā¸­", "add_a_title": "āš€ā¸žā¸´āšˆā¸Ąā¸Ģā¸ąā¸§ā¸‚āš‰ā¸­", "add_action": "āš€ā¸žā¸´āšˆā¸Ąā¸ā¸˛ā¸Ŗā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗ", + "add_action_description": "⏄ā¸Ĩā¸´ā¸āš€ā¸žā¸ˇāšˆā¸­āš€ā¸žā¸´āšˆā¸Ąā¸ā¸˛ā¸Ŗā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗ", "add_assets": "āš€ā¸žā¸´āšˆā¸Ąā¸Ēā¸ˇāšˆā¸­", "add_birthday": "āš€ā¸žā¸´āšˆā¸Ąā¸§ā¸ąā¸™āš€ā¸ā¸´ā¸”", "add_endpoint": "āš€ā¸žā¸´āšˆā¸Ąā¸›ā¸Ĩ⏞ā¸ĸ⏗⏞⏇", "add_exclusion_pattern": "āš€ā¸žā¸´āšˆā¸Ąā¸‚āš‰ā¸­ā¸ĸā¸āš€ā¸§āš‰ā¸™", "add_filter": "āš€ā¸žā¸´āšˆā¸Ąā¸•ā¸ąā¸§ā¸ā¸Ŗā¸­ā¸‡", + "add_filter_description": "⏄ā¸Ĩā¸´ā¸āš€ā¸žā¸ˇāšˆā¸­āš€ā¸žā¸´āšˆā¸Ąā¸ā¸˛ā¸Ŗā¸ā¸Ŗā¸­ā¸‡", "add_location": "āš€ā¸žā¸´āšˆā¸Ąā¸•ā¸ŗāšā¸Ģā¸™āšˆā¸‡", "add_more_users": "āš€ā¸žā¸´āšˆā¸Ąā¸œā¸šāš‰āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™", "add_partner": "āš€ā¸žā¸´āšˆā¸Ąā¸„ā¸šāšˆā¸Ģā¸š", @@ -32,12 +35,14 @@ "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_album_toggle": "ā¸Ēā¸Ĩā¸ąā¸šā¸ā¸˛ā¸Ŗāš€ā¸Ĩ⏎⏭⏁ā¸Ē⏺ā¸Ģā¸Ŗā¸ąā¸š {album}", "add_to_albums": "āš€ā¸žā¸´āšˆā¸Ąāš€ā¸‚āš‰ā¸˛āšƒā¸™ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ą", "add_to_albums_count": "āš€ā¸žā¸´āšˆā¸Ąāš„ā¸›ā¸ĸā¸ąā¸‡ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ą ({count})", "add_to_bottom_bar": "āš€ā¸žā¸´āšˆā¸Ąāš„ā¸›ā¸ĸā¸ąā¸‡", "add_to_shared_album": "āš€ā¸žā¸´āšˆā¸Ąāš„ā¸›ā¸ĸā¸ąā¸‡ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąā¸—ā¸ĩāšˆāšā¸Šā¸ŖāšŒ", "add_upload_to_stack": "āš€ā¸žā¸´āšˆā¸Ąā¸—ā¸ĩāšˆā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”āš€ā¸‚āš‰ā¸˛ stack", "add_url": "āš€ā¸žā¸´āšˆā¸Ą URL", + "add_workflow_step": "āš€ā¸žā¸´āšˆā¸Ąā¸‚ā¸ąāš‰ā¸™ā¸•ā¸­ā¸™ā¸ā¸˛ā¸Ŗā¸—ā¸ŗā¸‡ā¸˛ā¸™", "added_to_archive": "āš€ā¸žā¸´āšˆā¸Ąāš„ā¸›ā¸ĸā¸ąā¸‡ā¸—ā¸ĩāšˆā¸ˆā¸ąā¸”āš€ā¸āš‡ā¸šā¸–ā¸˛ā¸§ā¸Ŗ", "added_to_favorites": "āš€ā¸žā¸´āšˆā¸Ąāš€ā¸‚āš‰ā¸˛ā¸Ŗā¸˛ā¸ĸā¸ā¸˛ā¸Ŗāš‚ā¸›ā¸Ŗā¸”āšā¸Ĩāš‰ā¸§", "added_to_favorites_count": "āš€ā¸žā¸´āšˆā¸Ą {count, number} ā¸Ŗā¸šā¸›āš€ā¸‚āš‰ā¸˛ā¸Ŗā¸˛ā¸ĸā¸ā¸˛ā¸Ŗāš‚ā¸›ā¸Ŗā¸”āšā¸Ĩāš‰ā¸§", @@ -70,6 +75,7 @@ "confirm_reprocess_all_faces": "ā¸„ā¸¸ā¸“āšā¸™āšˆāšƒā¸ˆā¸§āšˆā¸˛ā¸„ā¸¸ā¸“ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸›ā¸Ŗā¸°ā¸Ąā¸§ā¸Ĩ⏜ā¸Ĩāšƒā¸šā¸Ģā¸™āš‰ā¸˛ā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸”āšƒā¸Ģā¸Ąāšˆ? ā¸Šā¸ˇāšˆā¸­ā¸„ā¸™ā¸ˆā¸°ā¸–ā¸šā¸ā¸Ĩā¸šāš„ā¸›ā¸”āš‰ā¸§ā¸ĸ", "confirm_user_password_reset": "ā¸„ā¸¸ā¸“āšā¸™āšˆāšƒā¸ˆā¸§āšˆā¸˛ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸Ŗā¸ĩāš€ā¸‹āš‡ā¸•ā¸Ŗā¸Ģā¸ąā¸Ēā¸œāšˆā¸˛ā¸™ā¸‚ā¸­ā¸‡ {user} ā¸Ģā¸Ŗā¸ˇā¸­āš„ā¸Ąāšˆ?", "confirm_user_pin_code_reset": "ā¸„ā¸¸ā¸“āšā¸™āšˆāšƒā¸ˆā¸Ģā¸Ŗā¸ˇā¸­āš„ā¸Ąāšˆā¸§āšˆā¸˛ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸Ŗā¸ĩāš€ā¸‹āš‡ā¸•ā¸Ŗā¸Ģā¸ąā¸Ē PIN ⏂⏭⏇ {user}", + "copy_config_to_clipboard_description": "ā¸„ā¸ąā¸”ā¸Ĩā¸­ā¸ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸Ŗā¸°ā¸šā¸šā¸›ā¸ąā¸ˆā¸ˆā¸¸ā¸šā¸ąā¸™āšƒā¸™ā¸Ŗā¸šā¸›āšā¸šā¸š JSON āš„ā¸›ā¸ĸā¸ąā¸‡ā¸„ā¸Ĩā¸´ā¸›ā¸šā¸­ā¸ŖāšŒā¸”", "create_job": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸‡ā¸˛ā¸™", "cron_expression": "ā¸Ŗā¸šā¸›āšā¸šā¸š cron", "cron_expression_description": "ā¸•ā¸ąāš‰ā¸‡ā¸Šāšˆā¸§ā¸‡āš€ā¸§ā¸Ĩā¸˛āšƒā¸™ā¸ā¸˛ā¸Ŗā¸Ēāšā¸ā¸™āš‚ā¸”ā¸ĸāšƒā¸Šāš‰ā¸Ŗā¸šā¸›āšā¸šā¸š cron ā¸Ē⏺ā¸Ģā¸Ŗā¸ąā¸šā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩāš€ā¸žā¸´āšˆā¸Ąāš€ā¸•ā¸´ā¸Ąā¸ā¸Ŗā¸¸ā¸“ā¸˛ā¸­ā¸´ā¸‡ Crontab Guru", @@ -77,6 +83,7 @@ "disable_login": "⏛⏴⏔⏁⏞⏪ā¸Ĩāš‡ā¸­ā¸ā¸­ā¸´ā¸™", "duplicate_detection_job_description": "āšƒā¸Šāš‰ machine learning ā¸ā¸ąā¸šā¸Ēā¸ĩāšˆā¸­āš€ā¸žā¸ˇāšˆā¸­ā¸•ā¸Ŗā¸§ā¸ˆā¸ˆā¸ąā¸šā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žā¸—ā¸ĩāšˆā¸„ā¸Ĩāš‰ā¸˛ā¸ĸā¸ā¸ąā¸™ āš‚ā¸”ā¸ĸāšƒā¸Šāš‰ā¸ā¸˛ā¸Ŗā¸„āš‰ā¸™ā¸Ģā¸˛ā¸­ā¸ąā¸ˆā¸‰ā¸Ŗā¸´ā¸ĸ⏰", "exclusion_pattern_description": "ā¸‚āš‰ā¸­ā¸ĸā¸āš€ā¸§āš‰ā¸™ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸°āš€ā¸§āš‰ā¸™āš„ā¸Ÿā¸ĨāšŒāšā¸Ĩā¸°āš‚ā¸Ÿā¸Ĩāš€ā¸”ā¸­ā¸ŖāšŒā¸‚ā¸“ā¸°ā¸Ēāšā¸ā¸™ā¸„ā¸Ĩā¸ąā¸‡ā¸ ā¸˛ā¸žā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“ ā¸Ąā¸ĩā¸›ā¸Ŗā¸°āš‚ā¸ĸā¸Šā¸™āšŒāš€ā¸Ąā¸ˇāšˆā¸­āš‚ā¸Ÿā¸Ĩāš€ā¸”ā¸­ā¸ŖāšŒā¸Ąā¸ĩāš„ā¸Ÿā¸ĨāšŒā¸—ā¸ĩāšˆāš„ā¸Ąāšˆā¸­ā¸ĸā¸˛ā¸ā¸™ā¸ŗāš€ā¸‚āš‰ā¸˛ āš€ā¸Šāšˆā¸™āš„ā¸Ÿā¸ĨāšŒ RAW", + "export_config_as_json_description": "ā¸”ā¸˛ā¸§ā¸™āšŒāš‚ā¸Ģā¸Ĩā¸”ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸Ŗā¸°ā¸šā¸šā¸›ā¸ąā¸ˆā¸ˆā¸¸ā¸šā¸ąā¸™āš„ā¸›ā¸ĸā¸ąā¸‡āš„ā¸Ÿā¸ĨāšŒāšƒā¸™ā¸Ŗā¸šā¸›āšā¸šā¸š JSON", "external_libraries_page_description": "ā¸Ģā¸™āš‰ā¸˛ā¸•āšˆā¸˛ā¸‡ā¸„ā¸Ĩā¸ąā¸‡āšā¸­ā¸”ā¸Ąā¸´ā¸™ā¸ ā¸˛ā¸ĸ⏙⏭⏁", "face_detection": "ā¸ā¸˛ā¸Ŗā¸•ā¸Ŗā¸§ā¸ˆā¸ˆā¸ąā¸šāšƒā¸šā¸Ģā¸™āš‰ā¸˛", "face_detection_description": "ā¸•ā¸Ŗā¸§ā¸ˆā¸ˆā¸ąā¸šāšƒā¸šā¸Ģā¸™āš‰ā¸˛āšƒā¸™ā¸Ēā¸ĩāšˆā¸­āš‚ā¸”ā¸ĸāšƒā¸Šāš‰ machine learning ⏧⏴⏔ā¸ĩāš‚ā¸­ā¸ˆā¸°āšƒā¸Šāš‰ā¸ ā¸˛ā¸žā¸•ā¸ąā¸§ā¸­ā¸ĸāšˆā¸˛ā¸‡ā¸ˆā¸˛ā¸ā¸§ā¸´ā¸”ā¸ĩāš‚ā¸­āš€ā¸—āšˆā¸˛ā¸™ā¸ąāš‰ā¸™ \"ā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸”\" ā¸ˆā¸°ā¸›ā¸Ŗā¸°ā¸Ąā¸§ā¸Ĩ⏜ā¸Ĩā¸Ēā¸ĩāšˆā¸­ā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸” \"⏂⏞⏔ā¸Ģ⏞ā¸ĸ\" ā¸ˆā¸°ā¸›ā¸Ŗā¸°ā¸Ąā¸§ā¸Ĩ⏜ā¸Ĩā¸Ēā¸ĩāšˆā¸­ā¸—ā¸ĩāšˆā¸ĸā¸ąā¸‡āš„ā¸Ąāšˆāš„ā¸”āš‰ā¸›ā¸Ŗā¸°ā¸Ąā¸§ā¸Ĩ⏜ā¸Ĩ āšƒā¸šā¸Ģā¸™āš‰ā¸˛ā¸—ā¸ĩāšˆā¸–ā¸šā¸ā¸•ā¸Ŗā¸§ā¸ˆā¸ˆā¸ąā¸šāšā¸Ĩāš‰ā¸§ā¸ˆā¸°ā¸–ā¸šā¸āš€ā¸‚āš‰ā¸˛ā¸„ā¸´ā¸§ā¸›ā¸Ŗā¸°ā¸Ąā¸§ā¸Ĩ⏜ā¸Ĩā¸ā¸˛ā¸Ŗā¸ˆā¸”ā¸ˆā¸ŗāšƒā¸šā¸Ģā¸™āš‰ā¸˛ āš€ā¸žā¸´āšˆā¸Ąāš€ā¸‚āš‰ā¸˛āš„ā¸›āšƒā¸™ā¸ā¸Ĩā¸¸āšˆā¸Ąā¸—ā¸ĩāšˆā¸Ąā¸ĩ⏭ā¸ĸā¸šāšˆāšā¸Ĩāš‰ā¸§ā¸Ģā¸Ŗā¸ˇā¸­ā¸„ā¸™āšƒā¸Ģā¸Ąāšˆ", @@ -97,6 +104,8 @@ "image_preview_description": "ā¸ ā¸˛ā¸žā¸‚ā¸™ā¸˛ā¸”ā¸›ā¸˛ā¸™ā¸ā¸Ĩ⏞⏇⏗ā¸ĩāšˆā¸–ā¸šā¸ā¸Ĩā¸šā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩāš€ā¸Ąā¸•ā¸˛ āšƒā¸Šāš‰ā¸Ē⏺ā¸Ģā¸Ŗā¸ąā¸šā¸ā¸˛ā¸Ŗā¸”ā¸šāšā¸­ā¸Ēāš€ā¸‹āš‡ā¸•āš€ā¸”ā¸ĩāšˆā¸ĸā¸§āšā¸Ĩ⏰ā¸Ē⏺ā¸Ģā¸Ŗā¸ąā¸šā¸ā¸˛ā¸Ŗāš€ā¸Ŗā¸ĩā¸ĸā¸™ā¸Ŗā¸šāš‰ā¸‚ā¸­ā¸‡āš€ā¸„ā¸Ŗā¸ˇāšˆā¸­ā¸‡ (Machine Learning)", "image_preview_quality_description": "ā¸„ā¸¸ā¸“ā¸ ā¸˛ā¸žā¸ā¸˛ā¸Ŗāšā¸Ēā¸”ā¸‡ā¸•ā¸ąā¸§ā¸­ā¸ĸāšˆā¸˛ā¸‡ā¸•ā¸ąāš‰ā¸‡āšā¸•āšˆ 1-100 ā¸ĸā¸´āšˆā¸‡ā¸Ēā¸šā¸‡ā¸ĸā¸´āšˆā¸‡ā¸”ā¸ĩ āšā¸•āšˆā¸ˆā¸°ā¸—ā¸ŗāšƒā¸Ģāš‰āš„ā¸Ÿā¸ĨāšŒā¸Ąā¸ĩā¸‚ā¸™ā¸˛ā¸”āšƒā¸Ģā¸āšˆā¸‚ā¸ļāš‰ā¸™āšā¸Ĩā¸°ā¸­ā¸˛ā¸ˆā¸—ā¸ŗāšƒā¸Ģāš‰āšā¸­ā¸›ā¸•ā¸­ā¸šā¸Ēā¸™ā¸­ā¸‡ā¸Šāš‰ā¸˛ā¸Ĩ⏇ ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸•āšˆā¸ŗā¸­ā¸˛ā¸ˆā¸Ēāšˆā¸‡ā¸œā¸Ĩā¸•āšˆā¸­ā¸„ā¸¸ā¸“ā¸ ā¸˛ā¸ž Machine Learning", "image_preview_title": "ā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸žā¸Ŗā¸ĩ⏧⏴⏧", + "image_progressive": "ā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žāšā¸šā¸šāš‚ā¸›ā¸Ŗāš€ā¸ā¸Ŗā¸Ē⏋ā¸ĩ⏟", + "image_progressive_description": "āš€ā¸‚āš‰ā¸˛ā¸Ŗā¸Ģā¸ąā¸Ēā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸ž JPEG āšā¸šā¸šāš‚ā¸›ā¸Ŗāš€ā¸ā¸Ŗā¸Ē⏋ā¸ĩā¸Ÿāš€ā¸žā¸ˇāšˆā¸­āšƒā¸Ģāš‰āšā¸Ēā¸”ā¸‡ā¸œā¸Ĩāšā¸šā¸šā¸„āšˆā¸­ā¸ĸāš† ā¸Šā¸ąā¸”ā¸‚ā¸ļāš‰ā¸™ā¸‚ā¸“ā¸°āš‚ā¸Ģā¸Ĩ⏔ ā¸—ā¸ąāš‰ā¸‡ā¸™ā¸ĩāš‰ā¸ˆā¸°āš„ā¸Ąāšˆā¸Ąā¸ĩ⏜ā¸Ĩā¸ā¸ąā¸šā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸ž WebP", "image_quality": "ā¸„ā¸¸ā¸“ā¸ ā¸˛ā¸ž", "image_resolution": "ā¸„ā¸§ā¸˛ā¸Ąā¸Ĩā¸°āš€ā¸­ā¸ĩā¸ĸ⏔", "image_resolution_description": "ā¸„ā¸§ā¸˛ā¸Ąā¸Ĩā¸°āš€ā¸­ā¸ĩā¸ĸ⏔ā¸Ēā¸šā¸ā¸§āšˆā¸˛ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸āš‡ā¸šā¸Ŗā¸˛ā¸ĸā¸Ĩā¸°āš€ā¸­ā¸ĩā¸ĸā¸”āš„ā¸”āš‰ā¸Ąā¸˛ā¸ā¸ā¸§āšˆā¸˛āšā¸•āšˆāšƒā¸Šāš‰āš€ā¸§ā¸Ĩ⏞ encode ā¸™ā¸˛ā¸™ā¸ā¸§āšˆā¸˛ āš„ā¸Ÿā¸ĨāšŒāšƒā¸Ģā¸āšˆā¸ā¸§āšˆā¸˛ āšā¸Ĩ⏰ā¸Ĩā¸”ā¸„ā¸§ā¸˛ā¸Ąā¸•ā¸­ā¸šā¸Ēā¸™ā¸­ā¸‡ā¸‚ā¸­ā¸‡āšā¸­ā¸›", @@ -105,6 +114,7 @@ "image_thumbnail_description": "ā¸Ŗā¸šā¸›ā¸‚ā¸™ā¸˛ā¸”ā¸ĸāšˆā¸­ā¸—ā¸ĩāšˆā¸Ąā¸ĩ⏁⏞⏪ā¸Ĩā¸šā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩāš€ā¸Ąā¸•ā¸˛ā¸”āš‰ā¸˛ā¸•āš‰ā¸˛ āšƒā¸Šāš‰āš€ā¸Ąā¸ˇāšˆā¸­ā¸”ā¸šā¸ ā¸˛ā¸žā¸–āšˆā¸˛ā¸ĸāšƒā¸™ā¸ā¸Ĩā¸¸āšˆā¸Ą āš€ā¸Šāšˆā¸™ āšƒā¸™āš„ā¸—ā¸ĄāšŒāš„ā¸Ĩā¸™āšŒā¸Ģā¸Ĩā¸ąā¸", "image_thumbnail_quality_description": "ā¸„ā¸¸ā¸“ā¸ ā¸˛ā¸žā¸‚ā¸­ā¸‡ā¸ ā¸˛ā¸žā¸‚ā¸™ā¸˛ā¸”ā¸ĸāšˆā¸­ā¸•ā¸ąāš‰ā¸‡āšā¸•āšˆ 1-100 ā¸ĸā¸´āšˆā¸‡ā¸Ēā¸šā¸‡ā¸ĸā¸´āšˆā¸‡ā¸”ā¸ĩ āšā¸•āšˆā¸ˆā¸°ā¸—ā¸ŗāšƒā¸Ģāš‰āš„ā¸Ÿā¸ĨāšŒā¸Ąā¸ĩā¸‚ā¸™ā¸˛ā¸”āšƒā¸Ģā¸āšˆā¸‚ā¸ļāš‰ā¸™āšā¸Ĩā¸°ā¸­ā¸˛ā¸ˆā¸—ā¸ŗāšƒā¸Ģāš‰āšā¸­ā¸›ā¸•ā¸­ā¸šā¸Ēā¸™ā¸­ā¸‡ā¸Šāš‰ā¸˛ā¸Ĩ⏇", "image_thumbnail_title": "ā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ Thumbnail", + "import_config_from_json_description": "ā¸™ā¸ŗāš€ā¸‚āš‰ā¸˛ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸Ŗā¸°ā¸šā¸šāš‚ā¸”ā¸ĸā¸ā¸˛ā¸Ŗā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”āš„ā¸Ÿā¸ĨāšŒā¸„ā¸­ā¸™ā¸Ÿā¸´ā¸ JSON", "job_concurrency": "{job} ā¸‡ā¸˛ā¸™ā¸žā¸Ŗāš‰ā¸­ā¸Ąā¸ā¸ąā¸™", "job_created": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸‡ā¸˛ā¸™āš€ā¸Ŗā¸ĩā¸ĸā¸šā¸Ŗāš‰ā¸­ā¸ĸ", "job_not_concurrency_safe": "⏇⏞⏙⏙ā¸ĩāš‰ā¸—ā¸ŗā¸‡ā¸˛ā¸™ā¸žā¸Ŗāš‰ā¸­ā¸Ąā¸ā¸ąā¸™āšā¸šā¸šā¸›ā¸Ĩā¸­ā¸”ā¸ ā¸ąā¸ĸāš„ā¸Ąāšˆāš„ā¸”āš‰", @@ -422,7 +432,7 @@ "user_successfully_removed": "ā¸Ĩā¸šā¸œā¸šāš‰āšƒā¸Šāš‰ {email} āš€ā¸Ēā¸Ŗāš‡ā¸ˆā¸Ēā¸Ąā¸šā¸šā¸Ŗā¸“āšŒāšā¸Ĩāš‰ā¸§", "users_page_description": "ā¸Ģā¸™āš‰ā¸˛ā¸œā¸šāš‰āšƒā¸Šāš‰ā¸œā¸šāš‰ā¸”ā¸šāšā¸Ĩ", "version_check_enabled_description": "āš€ā¸Šāš‡ā¸„ GitHub āš€ā¸›āš‡ā¸™ā¸Ŗā¸°ā¸ĸ⏰ āš† āš€ā¸žā¸ˇāšˆā¸­ā¸•ā¸Ŗā¸§ā¸ˆā¸Ēā¸­ā¸šā¸Ŗā¸¸āšˆā¸™āšƒā¸Ģā¸Ąāšˆ", - "version_check_implications": "ā¸ā¸˛ā¸Ŗā¸•ā¸Ŗā¸§ā¸ˆā¸Ēā¸­ā¸šāš€ā¸§ā¸­ā¸ŖāšŒā¸Šā¸ąā¸™āšƒā¸Ģā¸Ąāšˆā¸ˆā¸°ā¸•āš‰ā¸­ā¸‡ā¸•ā¸´ā¸”ā¸•āšˆā¸­ā¸ā¸ąā¸š github.com āš€ā¸›āš‡ā¸™ā¸Ŗā¸°ā¸ĸ⏰", + "version_check_implications": "ā¸ā¸˛ā¸Ŗā¸•ā¸Ŗā¸§ā¸ˆā¸Ēā¸­ā¸šāš€ā¸§ā¸­ā¸ŖāšŒā¸Šā¸ąā¸™āšƒā¸Ģā¸Ąāšˆā¸ˆā¸°ā¸•āš‰ā¸­ā¸‡ā¸•ā¸´ā¸”ā¸•āšˆā¸­ā¸ā¸ąā¸š {server} āš€ā¸›āš‡ā¸™ā¸Ŗā¸°ā¸ĸ⏰", "version_check_settings": "ā¸•ā¸Ŗā¸§ā¸ˆā¸Ēā¸­ā¸šā¸Ŗā¸¸āšˆā¸™", "version_check_settings_description": "āš€ā¸›ā¸´ā¸”/ā¸›ā¸´ā¸”ā¸ā¸˛ā¸Ŗāšā¸ˆāš‰ā¸‡āš€ā¸•ā¸ˇā¸­ā¸™ā¸Ŗā¸¸āšˆā¸™āšƒā¸Ģā¸Ąāšˆ", "video_conversion_job": "āš€ā¸‚āš‰ā¸˛ā¸Ŗā¸Ģā¸ąā¸Ē⏧ā¸ĩ⏔ā¸ĩāš‚ā¸­ (transcode)", @@ -510,10 +520,10 @@ "always_keep_photos_hint": "\"āš€ā¸žā¸´āšˆā¸Ąā¸žā¸ˇāš‰ā¸™ā¸—ā¸ĩāšˆā¸§āšˆā¸˛ā¸‡\" ā¸ˆā¸°āš€ā¸āš‡ā¸šā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸”ā¸šā¸™ā¸­ā¸¸ā¸›ā¸ā¸Ŗā¸“āšŒā¸™ā¸ĩāš‰", "always_keep_videos_hint": "\"āš€ā¸žā¸´āšˆā¸Ąā¸žā¸ˇāš‰ā¸™ā¸—ā¸ĩāšˆā¸§āšˆā¸˛ā¸‡\" ā¸ˆā¸°āš€ā¸āš‡ā¸šā¸§ā¸´ā¸”ā¸ĩāš‚ā¸­ā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸”ā¸šā¸™ā¸­ā¸¸ā¸›ā¸ā¸Ŗā¸“āšŒā¸™ā¸ĩāš‰", "anti_clockwise": "ā¸—ā¸§ā¸™āš€ā¸‚āš‡ā¸Ąā¸™ā¸˛ā¸Ŧ⏴⏁⏞", - "api_key": "API key", + "api_key": "⏄ā¸ĩā¸ĸāšŒ API", "api_key_description": "ā¸„āšˆā¸˛ā¸™ā¸ĩāš‰ā¸ˆā¸°āšā¸Ēā¸”ā¸‡āš€ā¸žā¸ĩā¸ĸā¸‡ā¸„ā¸Ŗā¸ąāš‰ā¸‡āš€ā¸”ā¸ĩā¸ĸ⏧ āš‚ā¸›ā¸Ŗā¸”ā¸„ā¸ąā¸”ā¸Ĩā¸­ā¸ā¸āšˆā¸­ā¸™ā¸›ā¸´ā¸”ā¸Ģā¸™āš‰ā¸˛ā¸•āšˆā¸˛ā¸‡", - "api_key_empty": "ā¸Šā¸ˇāšˆā¸­ API Key ā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“āš„ā¸Ąāšˆā¸„ā¸§ā¸Ŗā¸§āšˆā¸˛ā¸‡āš€ā¸›ā¸Ĩāšˆā¸˛", - "api_keys": "API Key", + "api_key_empty": "ā¸Šā¸ˇāšˆā¸­ā¸„ā¸ĩā¸ĸāšŒ API ā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“āš„ā¸Ąāšˆā¸„ā¸§ā¸Ŗā¸§āšˆā¸˛ā¸‡āš€ā¸›ā¸Ĩāšˆā¸˛", + "api_keys": "⏄ā¸ĩā¸ĸāšŒ API", "app_architecture_variant": "ā¸Ŗā¸šā¸›āšā¸šā¸š (ā¸Ēā¸–ā¸˛ā¸›ā¸ąā¸•ā¸ĸā¸ā¸Ŗā¸Ŗā¸Ą)", "app_bar_signout_dialog_content": "ā¸„ā¸¸ā¸“āšā¸™āšˆāšƒā¸ˆā¸§āšˆā¸˛ā¸­ā¸ĸ⏞⏁⏭⏭⏁⏈⏞⏁⏪⏰⏚⏚", "app_bar_signout_dialog_ok": "āšƒā¸Šāšˆ", @@ -864,14 +874,10 @@ "day": "ā¸§ā¸ąā¸™", "days": "ā¸§ā¸ąā¸™", "deduplicate_all": "ā¸Ŗā¸§ā¸Ąāš€ā¸‚āš‰ā¸˛ā¸”āš‰ā¸§ā¸ĸā¸ā¸ąā¸™ā¸—ā¸ąāš‰ā¸‡ā¸Ģā¸Ąā¸”", - "deduplication_criteria_1": "ā¸‚ā¸™ā¸˛ā¸”āš„ā¸šā¸•āšŒā¸‚ā¸­ā¸‡ā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸ž", - "deduplication_criteria_2": "ā¸ˆā¸ŗā¸™ā¸§ā¸™ā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩ EXIF", - "deduplication_info": "ā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩā¸ā¸˛ā¸Ŗā¸‚ā¸ˆā¸ąā¸”ā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩā¸‹āš‰ā¸ŗā¸‹āš‰ā¸­ā¸™", - "deduplication_info_description": "āš€ā¸Ĩ⏎⏭⏁ā¸Ēā¸ˇāšˆā¸­ā¸Ĩāšˆā¸§ā¸‡ā¸Ģā¸™āš‰ā¸˛āš‚ā¸”ā¸ĸā¸­ā¸ąā¸•āš‚ā¸™ā¸Ąā¸ąā¸•ā¸´āšā¸Ĩ⏰ā¸Ĩ⏚⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗā¸‹āš‰ā¸ŗā¸‹āš‰ā¸­ā¸™ā¸ˆā¸ŗā¸™ā¸§ā¸™ā¸Ąā¸˛ā¸ āš€ā¸Ŗā¸˛ā¸ˆā¸°ā¸”ā¸šā¸—ā¸ĩāšˆ:", "delete": "ā¸Ĩ⏚⏭⏭⏁", "delete_action_prompt": "ā¸Ĩ⏚ {count} ⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗāšā¸Ĩāš‰ā¸§", "delete_album": "ā¸Ĩā¸šā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ą", - "delete_api_key_prompt": "ā¸„ā¸¸ā¸“ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸Ĩ⏚ API ⏄ā¸ĩā¸ĸāšŒ ⏙ā¸ĩāš‰āšƒā¸Šāšˆāš„ā¸Ģā¸Ą ?", + "delete_api_key_prompt": "ā¸„ā¸¸ā¸“ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸Ĩā¸šā¸„ā¸ĩā¸ĸāšŒ API ⏙ā¸ĩāš‰ā¸Ģā¸Ŗā¸ˇā¸­āš„ā¸Ąāšˆ?", "delete_dialog_alert": "⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗā¸”ā¸ąā¸‡ā¸ā¸Ĩāšˆā¸˛ā¸§ā¸ˆā¸°ā¸–ā¸šā¸ā¸Ĩ⏚⏈⏞⏁ Immich āšā¸Ĩā¸°āš€ā¸„ā¸Ŗā¸ˇāšˆā¸­ā¸‡ā¸­ā¸ĸāšˆā¸˛ā¸‡ā¸–ā¸˛ā¸§ā¸Ŗ", "delete_dialog_alert_local": "⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗā¸”ā¸ąā¸‡ā¸ā¸Ĩāšˆā¸˛ā¸§ā¸ˆā¸°ā¸–ā¸šā¸ā¸Ĩā¸šā¸ˆā¸˛ā¸āš€ā¸„ā¸Ŗā¸ˇāšˆā¸­ā¸‡ā¸„ā¸¸ā¸“ā¸­ā¸ĸāšˆā¸˛ā¸‡ā¸–ā¸˛ā¸§ā¸Ŗ āšā¸•āšˆā¸ˆā¸°ā¸ĸā¸ąā¸‡ā¸„ā¸‡ā¸­ā¸ĸā¸šāšˆā¸šā¸™āš€ā¸‹ā¸´ā¸ŖāšŒā¸Ÿāš€ā¸§ā¸­ā¸ŖāšŒ Immich", "delete_dialog_alert_local_non_backed_up": "⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗā¸šā¸˛ā¸‡ā¸•ā¸ąā¸§āš„ā¸Ąāšˆāš„ā¸”āš‰ā¸–ā¸šā¸ā¸Ēā¸ŗā¸Ŗā¸­ā¸‡ā¸šā¸™ Immich āšā¸Ĩā¸°ā¸ˆā¸°ā¸–ā¸šā¸ā¸Ĩā¸šā¸ˆā¸˛ā¸āš€ā¸„ā¸Ŗā¸ˇāšˆā¸­ā¸‡ā¸„ā¸¸ā¸“ā¸­ā¸ĸāšˆā¸˛ā¸‡ā¸–ā¸˛ā¸§ā¸Ŗ", @@ -1066,7 +1072,7 @@ "unable_to_connect": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸Šā¸ˇāšˆā¸­ā¸Ąā¸•āšˆā¸­āš„ā¸”āš‰", "unable_to_copy_to_clipboard": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸„ā¸ąā¸”ā¸Ĩā¸­ā¸āš„ā¸›ā¸ĸā¸ąā¸‡ā¸„ā¸Ĩā¸´ā¸›ā¸šā¸­ā¸ŖāšŒā¸”āš„ā¸”āš‰ ā¸•ā¸Ŗā¸§ā¸ˆā¸Ēā¸­ā¸šāšƒā¸Ģāš‰āšā¸™āšˆāšƒā¸ˆā¸§āšˆā¸˛ā¸„ā¸¸ā¸“āš€ā¸‚āš‰ā¸˛ā¸–ā¸ļ⏇ā¸Ģā¸™āš‰ā¸˛ā¸œāšˆā¸˛ā¸™ā¸—ā¸˛ā¸‡ https", "unable_to_create_admin_account": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸šā¸ąā¸ā¸Šā¸ĩā¸œā¸šāš‰ā¸”ā¸šāšā¸Ĩā¸Ŗā¸°ā¸šā¸šāš„ā¸”āš‰", - "unable_to_create_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ API ⏄ā¸ĩā¸ĸāšŒ āš„ā¸”āš‰", + "unable_to_create_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸„ā¸ĩā¸ĸāšŒ API", "unable_to_create_library": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸„ā¸Ĩā¸ąā¸‡ā¸ ā¸˛ā¸žāš„ā¸”āš‰", "unable_to_create_user": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸œā¸šāš‰āšƒā¸Šāš‰āš„ā¸”āš‰", "unable_to_delete_album": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸šā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąāš„ā¸”āš‰", @@ -1093,7 +1099,7 @@ "unable_to_reassign_assets_new_person": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ąā¸­ā¸šā¸Ģā¸Ąā¸˛ā¸ĸ āšƒā¸Ģāš‰ā¸ā¸ąā¸šā¸šā¸¸ā¸„ā¸„ā¸Ĩāšƒā¸Ģā¸Ąāšˆāš„ā¸”āš‰", "unable_to_refresh_user": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ŗā¸ĩāš€ā¸Ÿā¸Ŗā¸Šā¸œā¸šāš‰āšƒā¸Šāš‰āš„ā¸”āš‰", "unable_to_remove_album_users": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸šā¸œā¸šāš‰āšƒā¸Šāš‰ā¸­ā¸­ā¸ā¸ˆā¸˛ā¸ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąāš„ā¸”āš‰", - "unable_to_remove_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩ⏚ API Key āš„ā¸”āš‰", + "unable_to_remove_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸šā¸„ā¸ĩā¸ĸāšŒ API", "unable_to_remove_assets_from_shared_link": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩ⏚⏭⏭⏁⏈⏞⏁ā¸Ĩā¸´ā¸‡ā¸āšŒā¸—ā¸ĩāšˆāšā¸Šā¸ŖāšŒāš„ā¸”āš‰", "unable_to_remove_library": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸šā¸„ā¸Ĩā¸ąā¸‡ā¸ ā¸˛ā¸žāš„ā¸”āš‰", "unable_to_remove_partner": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ĩā¸šā¸„ā¸šāšˆā¸Ģā¸šāš„ā¸”āš‰", @@ -1105,7 +1111,7 @@ "unable_to_restore_trash": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸Ŗā¸ĩā¸ĸā¸ā¸„ā¸ˇā¸™ā¸–ā¸ąā¸‡ā¸‚ā¸ĸā¸°āš„ā¸”āš‰", "unable_to_restore_user": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸Ŗā¸ĩā¸ĸā¸ā¸„ā¸ˇā¸™ā¸œā¸šāš‰āšƒā¸Šāš‰āš„ā¸”āš‰", "unable_to_save_album": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļā¸ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąāš„ā¸”āš‰", - "unable_to_save_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļ⏁ API ⏄ā¸ĩā¸ĸāšŒ āš„ā¸”āš‰", + "unable_to_save_api_key": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļ⏁⏄ā¸ĩā¸ĸāšŒ API", "unable_to_save_date_of_birth": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļā¸ā¸§ā¸ąā¸™āš€ā¸ā¸´ā¸”āš„ā¸”āš‰", "unable_to_save_name": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļā¸ā¸Šā¸ˇāšˆā¸­āš„ā¸”āš‰", "unable_to_save_profile": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸šā¸ąā¸™ā¸—ā¸ļā¸āš‚ā¸›ā¸Ŗāš„ā¸Ÿā¸ĨāšŒāš„ā¸”āš‰", @@ -1199,7 +1205,7 @@ "geolocation_instruction_location": "⏄ā¸Ĩā¸´ā¸ā¸šā¸™ā¸Ēā¸ˇāšˆā¸­ā¸—ā¸ĩāšˆā¸Ąā¸ĩā¸žā¸´ā¸ā¸ąā¸” GPS āš€ā¸žā¸ˇāšˆā¸­āšƒā¸Šāš‰ā¸•ā¸ŗāšā¸Ģā¸™āšˆā¸‡ā¸™ā¸ąāš‰ā¸™ ā¸Ģā¸Ŗā¸ˇā¸­āš€ā¸Ĩā¸ˇā¸­ā¸ā¸•ā¸ŗāšā¸Ģā¸™āšˆā¸‡ā¸ˆā¸˛ā¸āšā¸œā¸™ā¸—ā¸ĩāšˆāš‚ā¸”ā¸ĸ⏕⏪⏇", "get_help": "ā¸‚ā¸­ā¸„ā¸§ā¸˛ā¸Ąā¸Šāšˆā¸§ā¸ĸāš€ā¸Ģā¸Ĩ⏎⏭", "get_people_error": "ā¸‚āš‰ā¸­ā¸œā¸´ā¸”ā¸žā¸Ĩ⏞⏔⏂⏓⏰⏔ā¸ļā¸‡ā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩā¸œā¸šāš‰ā¸„ā¸™", - "get_wifiname_error": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ŗā¸ąā¸šā¸Šā¸ˇāšˆā¸­ Wi-Fi ⏁⏪⏏⏓⏞ā¸ĸ⏎⏙ā¸ĸā¸ąā¸™ā¸ā¸˛ā¸Ŗāšƒā¸Ģāš‰ā¸­ā¸™ā¸¸ā¸ā¸˛ā¸•āšā¸­ā¸ž āšā¸Ĩ⏰ā¸ĸ⏎⏙ā¸ĸā¸ąā¸™ā¸§āšˆā¸˛ Wi-Fi āš€ā¸Šā¸ˇāšˆā¸­ā¸Ąā¸•āšˆā¸­ā¸­ā¸ĸā¸šāšˆ", + "get_wifiname_error": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ŗā¸ąā¸šā¸Šā¸ˇāšˆā¸­ Wi-Fi ⏁⏪⏏⏓⏞ā¸ĸ⏎⏙ā¸ĸā¸ąā¸™ā¸ā¸˛ā¸Ŗāšƒā¸Ģāš‰ā¸­ā¸™ā¸¸ā¸ā¸˛ā¸•āšā¸­ā¸› āšā¸Ĩ⏰ā¸ĸ⏎⏙ā¸ĸā¸ąā¸™ā¸§āšˆā¸˛āš€ā¸Šā¸ˇāšˆā¸­ā¸Ąā¸•āšˆā¸­ā¸ā¸ąā¸šāš€ā¸„ā¸Ŗā¸ˇā¸­ā¸‚āšˆā¸˛ā¸ĸ Wi-Fi ⏭ā¸ĸā¸šāšˆ", "getting_started": "āš€ā¸Ŗā¸´āšˆā¸Ąā¸•āš‰ā¸™āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™", "go_back": "⏁ā¸Ĩā¸ąā¸š", "go_to_folder": "āš„ā¸›ā¸—ā¸ĩāšˆāš‚ā¸Ÿā¸ĨāšŒāš€ā¸”ā¸­ā¸ŖāšŒ", @@ -1434,7 +1440,7 @@ "manage_sharing_with_partners": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸ā¸˛ā¸Ŗāšā¸Šā¸ŖāšŒā¸ā¸ąā¸šā¸„ā¸šāšˆā¸Ģā¸š", "manage_the_app_settings": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛āšā¸­ā¸›", "manage_your_account": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸šā¸ąā¸ā¸Šā¸ĩ⏂⏭⏇⏄⏏⏓", - "manage_your_api_keys": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸ā¸¸ā¸āšā¸ˆ API ⏂⏭⏇⏄⏏⏓", + "manage_your_api_keys": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸„ā¸ĩā¸ĸāšŒ API ⏂⏭⏇⏄⏏⏓", "manage_your_devices": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸­ā¸¸ā¸›ā¸ā¸Ŗā¸“āšŒā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“", "manage_your_oauth_connection": "ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸ā¸˛ā¸Ŗāš€ā¸Šā¸ˇāšˆā¸­ā¸Ąā¸•āšˆā¸­ OAuth ⏂⏭⏇⏄⏏⏓", "map": "āšā¸œā¸™ā¸—ā¸ĩāšˆ", @@ -1520,7 +1526,7 @@ "networking_subtitle": "ā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸›ā¸Ĩ⏞ā¸ĸā¸—ā¸˛ā¸‡āš€ā¸‹ā¸´ā¸ŖāšŒā¸Ÿāš€ā¸§ā¸­ā¸ŖāšŒ", "never": "āš„ā¸Ąāšˆāš€ā¸„ā¸ĸ", "new_album": "ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąāšƒā¸Ģā¸Ąāšˆ", - "new_api_key": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ API ⏄ā¸ĩā¸ĸāšŒāšƒā¸Ģā¸Ąāšˆ", + "new_api_key": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸„ā¸ĩā¸ĸāšŒ API āšƒā¸Ģā¸Ąāšˆ", "new_date_range": "ā¸Šāšˆā¸§ā¸‡ā¸§ā¸ąā¸™ā¸—ā¸ĩāšˆāšƒā¸Ģā¸Ąāšˆ", "new_password": "⏪ā¸Ģā¸ąā¸Ēā¸œāšˆā¸˛ā¸™āšƒā¸Ģā¸Ąāšˆ", "new_person": "ā¸„ā¸™āšƒā¸Ģā¸Ąāšˆ", @@ -1585,7 +1591,7 @@ "on_this_device": "ā¸šā¸™ā¸­ā¸¸ā¸›ā¸ā¸Ŗā¸“āšŒā¸™ā¸ĩāš‰", "onboarding": "ā¸ā¸˛ā¸Ŗāš€ā¸Ŗā¸´āšˆā¸Ąā¸•āš‰ā¸™āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™", "onboarding_locale_description": "āš€ā¸Ĩā¸ˇā¸­ā¸ā¸ ā¸˛ā¸Šā¸˛ā¸—ā¸ĩāšˆā¸„ā¸¸ā¸“ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗ ⏄⏏⏓ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸›ā¸Ĩā¸ĩāšˆā¸ĸā¸™āš„ā¸”āš‰ā¸ ā¸˛ā¸ĸā¸Ģā¸Ĩā¸ąā¸‡āšƒā¸™ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛", - "onboarding_privacy_description": "⏟ā¸ĩāš€ā¸ˆā¸­ā¸ŖāšŒ (ā¸•ā¸ąā¸§āš€ā¸Ĩ⏎⏭⏁) ā¸•āšˆā¸­āš„ā¸›ā¸™ā¸ĩāš‰ā¸•āš‰ā¸­ā¸‡ā¸­ā¸˛ā¸¨ā¸ąā¸ĸ⏚⏪⏴⏁⏞⏪⏠⏞ā¸ĸ⏙⏭⏁ āšā¸Ĩ⏰ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸›ā¸´ā¸”āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™āš„ā¸”āš‰ā¸•ā¸Ĩā¸­ā¸”āš€ā¸§ā¸Ĩā¸˛āšƒā¸™ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸ā¸˛ā¸Ŗ", + "onboarding_privacy_description": "⏄⏏⏓ā¸Ēā¸Ąā¸šā¸ąā¸•ā¸´ (ā¸•ā¸ąā¸§āš€ā¸Ĩ⏎⏭⏁) ā¸•āšˆā¸­āš„ā¸›ā¸™ā¸ĩāš‰ā¸•āš‰ā¸­ā¸‡ā¸­ā¸˛ā¸¨ā¸ąā¸ĸ⏚⏪⏴⏁⏞⏪⏠⏞ā¸ĸ⏙⏭⏁ āšā¸Ĩ⏰ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸›ā¸´ā¸”āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™āš„ā¸”āš‰ā¸•ā¸Ĩā¸­ā¸”āš€ā¸§ā¸Ĩā¸˛āšƒā¸™ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛", "onboarding_server_welcome_description": "ā¸Ąā¸˛ā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛āš€ā¸‹ā¸´ā¸ŖāšŒā¸Ÿāš€ā¸§ā¸­ā¸ŖāšŒā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“ā¸”āš‰ā¸§ā¸ĸā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸—ā¸ĩāšˆāšƒā¸Šāš‰ā¸šāšˆā¸­ā¸ĸā¸ā¸ąā¸™āš€ā¸–ā¸­ā¸°", "onboarding_theme_description": "āš€ā¸Ĩ⏎⏭⏁⏘ā¸ĩā¸Ąā¸Ēā¸ĩ ⏄⏏⏓ā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–āš€ā¸›ā¸Ĩā¸ĩāšˆā¸ĸā¸™āšā¸›ā¸Ĩā¸‡āš„ā¸”āš‰āšƒā¸™ā¸ ā¸˛ā¸ĸā¸Ģā¸Ĩā¸ąā¸‡āšƒā¸™ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“", "onboarding_user_welcome_description": "ā¸Ąā¸˛āš€ā¸Ŗā¸´āšˆā¸Ąā¸•āš‰ā¸™ā¸ā¸ąā¸™āš€ā¸–ā¸­ā¸°!", @@ -1635,7 +1641,7 @@ "pattern": "ā¸Ŗā¸šā¸›āšā¸šā¸š", "pause": "ā¸Ģā¸ĸ⏏⏔", "pause_memories": "ā¸Ģā¸ĸā¸¸ā¸”ā¸”ā¸šā¸„ā¸§ā¸˛ā¸Ąā¸—ā¸Ŗā¸‡ā¸ˆāšā¸˛", - "paused": "ā¸Ģā¸ĸ⏏⏔", + "paused": "ā¸Ģā¸ĸā¸¸ā¸”ā¸Šā¸ąāšˆā¸§ā¸„ā¸Ŗā¸˛ā¸§", "pending": "⏁⏺ā¸Ĩā¸ąā¸‡ā¸Ŗā¸­", "people": "ā¸œā¸šāš‰ā¸„ā¸™", "people_edits_count": "{count, plural, one {# person} other {# people}} ā¸–ā¸šā¸āšā¸āš‰āš„ā¸‚", @@ -1648,11 +1654,13 @@ "permanently_delete_assets_prompt": "ā¸„ā¸¸ā¸“āšā¸™āšˆāšƒā¸ˆā¸Ģā¸Ŗā¸ˇā¸­āš„ā¸Ąāšˆā¸§āšˆā¸˛ā¸•āš‰ā¸­ā¸‡ā¸ā¸˛ā¸Ŗā¸Ĩ⏚ {count, plural, one {this asset?} other {these # asset?}}⏭ā¸ĸāšˆā¸˛ā¸‡ā¸–ā¸˛ā¸§ā¸Ŗ ā¸ā¸˛ā¸Ŗā¸”ā¸ŗāš€ā¸™ā¸´ā¸™ā¸ā¸˛ā¸Ŗā¸™ā¸ĩāš‰ā¸ˆā¸°ā¸Ĩ⏚ {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_denied": "ā¸Ēā¸´ā¸—ā¸˜ā¸´āšŒā¸–ā¸šā¸ā¸›ā¸ā¸´āš€ā¸Ē⏘ ā¸ā¸Ŗā¸¸ā¸“ā¸˛āšƒā¸Ģāš‰ā¸Ēā¸´ā¸—ā¸˜ā¸´āšŒāš€ā¸‚āš‰ā¸˛ā¸–ā¸ļā¸‡ā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žāšā¸Ĩ⏰⏧⏴⏔ā¸ĩāš‚ā¸­āš€ā¸žā¸ˇāšˆā¸­āšƒā¸Šāš‰ā¸‡ā¸˛ā¸™ Immich", "permission_onboarding_permission_granted": "āšƒā¸Ģāš‰ā¸Ēā¸´ā¸—ā¸˜ā¸´āšŒā¸Ēā¸ŗāš€ā¸Ŗāš‡ā¸ˆ ā¸„ā¸¸ā¸“ā¸žā¸Ŗāš‰ā¸­ā¸Ąāšƒā¸Šāš‰ā¸‡ā¸˛ā¸™āšā¸Ĩāš‰ā¸§", "permission_onboarding_permission_limited": "ā¸Ēā¸´ā¸—ā¸˜āšŒā¸ˆā¸ŗā¸ā¸ąā¸” āš€ā¸žā¸ˇāšˆā¸­āšƒā¸Ģāš‰ Immich ā¸Ēā¸ŗā¸Ŗā¸­ā¸‡ā¸‚āš‰ā¸­ā¸Ąā¸šā¸Ĩāšā¸Ĩā¸°ā¸ˆā¸ąā¸”ā¸ā¸˛ā¸Ŗā¸„ā¸Ĩā¸ąā¸‡ā¸ ā¸˛ā¸žāš„ā¸”āš‰ ā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸Ēā¸´ā¸—ā¸˜ā¸´āš€ā¸‚āš‰ā¸˛ā¸–ā¸ļā¸‡ā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žāšā¸Ĩ⏰⏧⏴⏔ā¸ĩāš‚ā¸­", "permission_onboarding_request": "Immich ā¸ˆā¸ŗāš€ā¸›āš‡ā¸™ā¸ˆā¸°ā¸•āš‰ā¸­ā¸‡āš„ā¸”āš‰ā¸Ŗā¸ąā¸šā¸Ēā¸´ā¸—ā¸˜ā¸´āšŒā¸”ā¸šā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žāšā¸Ĩ⏰⏧⏴⏔ā¸ĩāš‚ā¸­", @@ -1787,7 +1795,7 @@ "remove_photo_from_memory": "ā¸Ĩā¸šā¸Ŗā¸šā¸›ā¸­ā¸­ā¸ā¸ˆā¸˛ā¸ā¸„ā¸§ā¸˛ā¸Ąā¸—ā¸Ŗā¸‡ā¸ˆā¸ŗā¸™ā¸ĩāš‰", "remove_url": "ā¸Ĩ⏚ URL", "remove_user": "ā¸Ĩā¸šā¸œā¸šāš‰āšƒā¸Šāš‰", - "removed_api_key": "API ⏄ā¸ĩā¸ĸāšŒā¸‚ā¸­ā¸‡: {name} ā¸–ā¸šā¸ā¸Ĩā¸šāšā¸Ĩāš‰ā¸§", + "removed_api_key": "ā¸Ĩā¸šā¸„ā¸ĩā¸ĸāšŒ API āšā¸Ĩāš‰ā¸§: {name}", "removed_from_archive": "ā¸Ĩā¸šā¸ˆā¸˛ā¸āš€ā¸āš‡ā¸šā¸–ā¸˛ā¸§ā¸Ŗāšā¸Ĩāš‰ā¸§", "removed_from_favorites": "ā¸Ĩ⏚⏈⏞⏁⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗāš‚ā¸›ā¸Ŗā¸”āšā¸Ĩāš‰ā¸§", "removed_from_favorites_count": "{count, plural, other {ā¸–ā¸šā¸ā¸Ĩ⏚#}} ⏈⏞⏁⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗāš‚ā¸›ā¸Ŗā¸”āšā¸Ĩāš‰ā¸§", @@ -1835,7 +1843,7 @@ "save": "ā¸šā¸ąā¸™ā¸—ā¸ļ⏁", "save_to_gallery": "ā¸šā¸ąā¸™ā¸—ā¸ļā¸āš„ā¸›ā¸ĸā¸ąā¸‡āšā¸ā¸Ĩāš€ā¸Ĩ⏭⏪ā¸ĩ", "saved": "ā¸šā¸ąā¸™ā¸—ā¸ļā¸āšā¸Ĩāš‰ā¸§", - "saved_api_key": "ā¸šā¸ąā¸™ā¸—ā¸ļ⏁ API ⏄ā¸ĩā¸ĸāšŒ āšā¸Ĩāš‰ā¸§", + "saved_api_key": "ā¸šā¸ąā¸™ā¸—ā¸ļ⏁⏄ā¸ĩā¸ĸāšŒ API āšā¸Ĩāš‰ā¸§", "saved_profile": "āšā¸āš‰āš„ā¸‚āš‚ā¸›ā¸Ŗāš„ā¸Ÿā¸ĨāšŒā¸Ēā¸ŗāš€ā¸Ŗāš‡ā¸ˆ", "saved_settings": "ā¸šā¸ąā¸™ā¸—ā¸ļā¸ā¸ā¸˛ā¸Ŗā¸•ā¸ąāš‰ā¸‡ā¸„āšˆā¸˛ā¸Ēā¸ŗāš€ā¸Ŗāš‡ā¸ˆ", "say_something": "ā¸žā¸šā¸”ā¸­ā¸°āš„ā¸Ŗā¸Ēā¸ąā¸ā¸­ā¸ĸāšˆā¸˛ā¸‡", @@ -2127,9 +2135,12 @@ "sync_upload_album_setting_subtitle": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡āšā¸Ĩā¸°ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”ā¸Ŗā¸šā¸›ā¸ ā¸˛ā¸žāšā¸Ĩ⏰⏧⏴⏔ā¸ĩāš‚ā¸­ā¸‚ā¸­ā¸‡ā¸„ā¸¸ā¸“āš„ā¸›ā¸ĸā¸ąā¸‡ā¸­ā¸ąā¸Ĩā¸šā¸ąāš‰ā¸Ąā¸—ā¸ĩāšˆāš€ā¸Ĩā¸ˇā¸­ā¸ā¸šā¸™ Immich", "tag": "āšā¸—āš‡ā¸", "tag_created": "ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡āšā¸—āš‡ā¸: {tag}", + "tag_face": "āšā¸—āš‡ā¸āšƒā¸šā¸Ģā¸™āš‰ā¸˛", + "tag_feature_description": "ā¸”ā¸šā¸Ŗā¸šā¸›ā¸–āšˆā¸˛ā¸ĸāšā¸Ĩ⏰⏧ā¸ĩ⏔ā¸ĩāš‚ā¸­ā¸—ā¸ĩāšˆā¸Ēā¸Ŗāš‰ā¸˛ā¸‡ā¸ā¸Ĩā¸¸āšˆā¸Ąā¸•ā¸˛ā¸Ąā¸Ģā¸ąā¸§ā¸‚āš‰ā¸­āšā¸—āš‡ā¸", "tag_not_found_question": "āš„ā¸Ąāšˆā¸Ēā¸˛ā¸Ąā¸˛ā¸Ŗā¸–ā¸Ģā¸˛āšā¸—āš‡ā¸āš„ā¸”āš‰āšƒā¸Šāšˆā¸Ģā¸Ŗā¸ˇā¸­āš„ā¸Ąāšˆ?ā¸Ēā¸Ŗāš‰ā¸˛ā¸‡āšā¸—āš‡ā¸āšƒā¸Ģā¸Ąāšˆ", "tag_people": "āšā¸—āš‡ā¸ā¸œā¸šāš‰ā¸„ā¸™", "tag_updated": "āšā¸—āš‡ā¸ā¸—ā¸ĩāšˆā¸–ā¸šā¸ā¸­ā¸ąā¸žāš€ā¸”ā¸•: {tag}", + "tagged_assets": "⏗ā¸ĩāšˆā¸–ā¸šā¸āšā¸—āš‡ā¸", "tags": "āšā¸—āš‡ā¸", "tap_to_run_job": "āšā¸•ā¸°āš€ā¸žā¸ˇāšˆā¸­ā¸Ŗā¸ąā¸™ā¸‡ā¸˛ā¸™", "template": "āš€ā¸—āš‡ā¸Ąāš€ā¸žā¸Ĩ⏕", @@ -2227,7 +2238,7 @@ "upload_status_duplicates": "⏪⏞ā¸ĸā¸ā¸˛ā¸Ŗā¸‹āš‰ā¸ŗ", "upload_status_errors": "ā¸‚āš‰ā¸­ā¸œā¸´ā¸”ā¸žā¸Ĩ⏞⏔", "upload_status_uploaded": "ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”āšā¸Ĩāš‰ā¸§", - "upload_success": "ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩ⏔ā¸Ēā¸ŗāš€ā¸Ŗāš‡ā¸ˆ ⏪ā¸ĩāš€ā¸Ÿā¸Ŗā¸Šā¸Ģā¸™āš‰ā¸˛āš€ā¸žā¸ˇāšˆā¸­ā¸”ā¸šā¸Ēā¸ˇāšˆā¸­āšƒā¸Ģā¸Ąāšˆā¸—ā¸ĩāšˆā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩ⏔ā¸Ĩāšˆā¸˛ā¸Ē⏏⏔", + "upload_success": "ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩ⏔ā¸Ēā¸ŗāš€ā¸Ŗāš‡ā¸ˆ ⏪ā¸ĩāš€ā¸Ÿā¸Ŗā¸Šā¸Ģā¸™āš‰ā¸˛āš€ā¸žā¸ˇāšˆā¸­ā¸”ā¸šā¸Ēā¸ˇāšˆā¸­ā¸—ā¸ĩāšˆā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”āšƒā¸Ģā¸Ąāšˆ", "upload_to_immich": "ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩā¸”āš„ā¸›ā¸ĸā¸ąā¸‡ Immich ({count})", "uploading": "⏁⏺ā¸Ĩā¸ąā¸‡ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩ⏔", "uploading_media": "⏁⏺ā¸Ĩā¸ąā¸‡ā¸­ā¸ąā¸›āš‚ā¸Ģā¸Ĩ⏔ā¸Ēā¸ˇāšˆā¸­", diff --git a/i18n/tr.json b/i18n/tr.json index 66813d7d9d..e728c73a22 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -208,12 +208,12 @@ "manage_concurrency": "AynÄą anda çalÄąÅŸmayÄą yÃļnet", "manage_concurrency_description": "İş eşzamanlÄąlığınÄą yÃļnetmek için işler sayfasÄąna gidin", "manage_log_settings": "GÃŧnlÃŧk ayarlarÄąnÄą yÃļnet", - "map_dark_style": "Koyu mod", + "map_dark_style": "Koyu stil", "map_enable_description": "Harita ayarlarÄąnÄą etkinleştir", "map_gps_settings": "Harita & GPS AyarlarÄą", "map_gps_settings_description": "Harita YÃļnetimi & GPS (Ters Jeokodlama) AyarlarÄą", "map_implications": "Harita Ãļzelliği, harici bir dÃļşeme hizmetine (tiles.immich.cloud) bağlÄądÄąr", - "map_light_style": "AÃ§Äąk mod", + "map_light_style": "AÃ§Äąk stil", "map_manage_reverse_geocoding_settings": "Coğrafi Kodlama ayarlarÄąnÄą yÃļnet", "map_reverse_geocoding": "Coğrafi Kodlama", "map_reverse_geocoding_enable_description": "Coğrafi KodlamayÄą etkinleştir", @@ -441,7 +441,7 @@ "user_successfully_removed": "KullanÄącÄą {email} başarÄąyla kaldÄąrÄąldÄą.", "users_page_description": "YÃļnetici kullanÄącÄąlar sayfasÄą", "version_check_enabled_description": "SÃŧrÃŧm kontrolÃŧ etkin", - "version_check_implications": "SÃŧrÃŧm kontrol Ãļzelliği, github.com ile periyodik iletişime dayanÄąr", + "version_check_implications": "SÃŧrÃŧm kontrol Ãļzelliği, {server} ile periyodik iletişime dayanÄąr", "version_check_settings": "SÃŧrÃŧm KontrolÃŧ", "version_check_settings_description": "Yeni sÃŧrÃŧm bildirimini etkinleştir/devre dÄąÅŸÄą bÄąrak", "video_conversion_job": "VideolarÄą dÃļnÃŧştÃŧr", @@ -849,9 +849,12 @@ "create_link_to_share": "Paylaşmak için link oluştur", "create_link_to_share_description": "BağlantÄąya sahip olan herkesin seçilen fotoğraflarÄą gÃļrmesine izin ver", "create_new": "YENİ OLUŞTUR", + "create_new_face": "Yeni yÃŧz oluştur", "create_new_person": "Yeni kişi oluştur", "create_new_person_hint": "Seçili Ãļğeleri yeni bir kişiye atayÄąn", "create_new_user": "Yeni kullanÄącÄą oluştur", + "create_person": "Kişi oluştur", + "create_person_subtitle": "Seçilen yÃŧze bir isim ekleyerek yeni kişiyi oluşturun ve etiketleyin", "create_shared_album_page_share_add_assets": "ÖĞELER EKLE", "create_shared_album_page_share_select_photos": "FotoğraflarÄą Seç", "create_shared_link": "PaylaÅŸÄąlan bağlantÄą oluştur", @@ -866,6 +869,7 @@ "crop_aspect_ratio_fixed": "Sabitlenmiş", "crop_aspect_ratio_free": "Boş", "crop_aspect_ratio_original": "Orijinal", + "crop_aspect_ratio_square": "Kare", "curated_object_page_title": "Nesneler", "current_device": "Mevcut cihaz", "current_pin_code": "Mevcut PIN kodu", @@ -880,7 +884,7 @@ "daily_title_text_date": "dd MMM E", "daily_title_text_date_year": "dd MMM yyyy E", "dark": "Koyu", - "dark_theme": "KaranlÄąk temaya geç", + "dark_theme": "Koyu temaya geç", "date": "Tarih", "date_after": "Sonraki tarih", "date_and_time": "Tarih ve Zaman", @@ -891,10 +895,8 @@ "day": "GÃŧn", "days": "GÃŧnler", "deduplicate_all": "TÃŧm kopyalarÄą kaldÄąr", - "deduplication_criteria_1": "Resim boyutu (bayt olarak)", - "deduplication_criteria_2": "EXIF veri sayÄąsÄą", - "deduplication_info": "Tekilleştirme Bilgileri", - "deduplication_info_description": "Öğeleri otomatik olarak Ãļnceden seçmek ve yinelenenleri toplu olarak kaldÄąrmak için şunlara bakÄąyoruz:", + "default_locale": "VarsayÄąlan Dil", + "default_locale_description": "Tarih ve sayÄąlarÄą tarayÄącÄąnÄązÄąn yerel ayarlarÄąna gÃļre biçimlendirin", "delete": "Sil", "delete_action_confirmation_message": "Bu Ãļğeyi silmek istediğinizden emin misiniz? Bu işlem, Ãļğeyi sunucunun çÃļp kutusuna taÅŸÄąyacak ve yerel olarak silmek isteyip istemediğinizi soracaktÄąr", "delete_action_prompt": "{count} silindi", @@ -970,7 +972,7 @@ "downloading_media": "Medya indiriliyor", "drop_files_to_upload": "DosyalarÄą yÃŧklemek için herhangi bir yere bÄąrakÄąn", "duplicates": "Kopyalar", - "duplicates_description": "Her grubu çÃļzmek için, varsa hangilerinin kopya olduğunu belirtin", + "duplicates_description": "Her bir grubu, varsa tekrarlanan Ãļğeleri belirterek çÃļzÃŧmleyin.", "duration": "SÃŧre", "edit": "DÃŧzenle", "edit_album": "AlbÃŧmÃŧ dÃŧzenle", @@ -1256,7 +1258,7 @@ "group_year": "YÄąla gÃļre grupla", "haptic_feedback_switch": "Dokunsal geri bildirimi aç", "haptic_feedback_title": "Dokunsal Geri Bildirim (Haptic Feedback)", - "has_quota": "Kota var", + "has_quota": "KotasÄą var", "hash_asset": "Karma Ãļğe", "hashed_assets": "Karma Ãļğeler", "hashing": "Hashleme", @@ -1387,9 +1389,11 @@ "library_page_sort_title": "AlbÃŧm başlığı", "licenses": "Lisanslar", "light": "AÃ§Äąk", + "light_theme": "AÃ§Äąk temaya geç", "like": "Beğen", "like_deleted": "Beğeni silindi", "link_motion_video": "Hareket videosunu bağla", + "link_to_docs": "Daha fazla bilgi için belgelere bakÄąn.", "link_to_oauth": "OAuth'a bağla", "linked_oauth_account": "BağlÄą OAuth hesabÄą", "list": "Liste", @@ -1498,7 +1502,7 @@ "map_no_location_permission_content": "Mevcut konumunuzdan Ãļğeleri gÃļrÃŧntÃŧlemek için konum iznine ihtiyaç var. Şimdi izin vermek istiyor musunuz?", "map_no_location_permission_title": "Konum izni reddedildi", "map_settings": "Harita ayarlarÄą", - "map_settings_dark_mode": "Koyu tema", + "map_settings_dark_mode": "Koyu mod", "map_settings_date_range_option_day": "Son 24 saat", "map_settings_date_range_option_days": "Son {days} gÃŧn", "map_settings_date_range_option_year": "Son yÄąl", @@ -1618,7 +1622,7 @@ "no_uploads_in_progress": "YÃŧkleme işlemi yok", "none": "Yok", "not_allowed": "İzin verilmiyor", - "not_available": "YOK", + "not_available": "U/D", "not_in_any_album": "Hiçbir albÃŧmde değil", "not_selected": "Seçilmedi", "notes": "Notlar", @@ -1651,6 +1655,7 @@ "only_favorites": "Sadece favoriler", "open": "Aç", "open_calendar": "Takvimi aç", + "open_in_browser": "TarayÄącÄąda aç", "open_in_map_view": "Harita gÃļrÃŧnÃŧmÃŧnde aç", "open_in_openstreetmap": "OpenStreetMap'te Aç", "open_the_search_filters": "Arama filtrelerini aç", @@ -2212,6 +2217,7 @@ "tag": "Etiket", "tag_assets": "Öğeleri etiketle", "tag_created": "Etiket oluşturuldu: {tag}", + "tag_face": "YÃŧzÃŧ etiketle", "tag_feature_description": "Etiket temalarÄąna gÃļre gruplandÄąrÄąlmÄąÅŸ fotoğraf ve videolarÄą keşfedin", "tag_not_found_question": "Etiket bulunamadÄą mÄą? Yeni bir etiket oluşturun.", "tag_people": "İnsanlarÄą etiketle", @@ -2393,6 +2399,7 @@ "viewer_remove_from_stack": "Yığından KaldÄąr", "viewer_stack_use_as_main_asset": "Ana fotoğraf olarak kullan", "viewer_unstack": "YığınÄą KaldÄąr", + "visibility": "GÃļrÃŧnÃŧrlÃŧk", "visibility_changed": "GÃļrÃŧnÃŧrlÃŧk {count, plural, one {# kişi} other {# kişi}} için değiştirildi", "visual": "GÃļrsel", "visual_builder": "GÃļrsel oluşturucu", diff --git a/i18n/uk.json b/i18n/uk.json index 74647210c2..b2b0a01501 100644 --- a/i18n/uk.json +++ b/i18n/uk.json @@ -5,7 +5,7 @@ "acknowledge": "ĐŸŅ€Đ¸ĐšĐŊŅŅ‚Đ¸", "action": "Đ”Ņ–Ņ", "action_common_update": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸", - "action_description": "ĐĐ°ĐąŅ–Ņ€ Đ´Ņ–Đš, ŅĐēŅ– ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž виĐēĐžĐŊĐ°Ņ‚Đ¸ С Đ˛Ņ–Đ´Ņ„Ņ–ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊиĐŧи Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "action_description": "ĐĐ°ĐąŅ–Ņ€ Đ´Ņ–Đš Đ´ĐģŅ виĐēĐžĐŊаĐŊĐŊŅ ĐŊад Đ˛Ņ–Đ´Ņ„Ņ–ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊиĐŧи ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Đŧи", "actions": "Đ”Ņ–Ņ—", "active": "АĐēŅ‚Đ¸Đ˛ĐŊиК", "active_count": "АĐēŅ‚Đ¸Đ˛ĐŊŅ–: {count}", @@ -13,18 +13,18 @@ "activity_changed": "АĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ {enabled, select, true {ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž} other {виĐŧĐēĐŊĐĩĐŊĐž}}", "add": "Đ”ĐžĐ´Đ°Ņ‚Đ¸", "add_a_description": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", - "add_a_location": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "add_a_location": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "add_a_name": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Ņ–Đŧ'Ņ", "add_a_title": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ", "add_action": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ´Ņ–ŅŽ", "add_action_description": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Ņ–ŅŽ", - "add_assets": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", + "add_assets": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "add_birthday": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ´ĐĩĐŊҌ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ", - "add_endpoint": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ", - "add_exclusion_pattern": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ", + "add_endpoint": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", + "add_exclusion_pattern": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃", "add_filter": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ҄ҖĐģŅŒŅ‚Ņ€", "add_filter_description": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą Đ´ĐžĐ´Đ°Ņ‚Đ¸ ҃ĐŧĐžĐ˛Ņƒ ҄ҖĐģŅŒŅ‚Ņ€Đ°", - "add_location": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "add_location": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "add_more_users": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛", "add_partner": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", "add_path": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ҈ĐģŅŅ…", @@ -34,113 +34,113 @@ "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_album_bottom_sheet_some_local_assets": "ДĐĩŅĐēŅ– ĐģĐžĐēаĐģҌĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐĩ вдаĐģĐžŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", "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_upload_to_stack": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ виваĐŊŅ‚Đ°ĐļĐĩĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Đ´Đž ҁ҂ĐĩĐē҃", "add_url": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ URL", - "add_workflow_step": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐēŅ€ĐžĐē Ņ€ĐžĐąĐžŅ‡ĐžĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁ҃", + "add_workflow_step": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐēŅ€ĐžĐē Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", "added_to_archive": "ДодаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", - "added_to_favorites": "ДодаĐŊĐž Đ´Đž ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", - "added_to_favorites_count": "ДодаĐŊĐž {count, number} Đ´Đž ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", + "added_to_favorites": "ДодаĐŊĐž Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "added_to_favorites_count": "{count, plural, one {ДодаĐŊĐž # ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} few {ДодаĐŊĐž # ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} many {ДодаĐŊĐž # ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} other {ДодаĐŊĐž # ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž}}", "admin": { - "add_exclusion_pattern_description": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊи виĐēĐģŅŽŅ‡ĐĩĐŊҌ. ĐŸŅ–Đ´ŅŅ‚Đ°ĐŊОвĐēа С виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅĐŧ *, ** Ņ‚Đ° ? ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ. ДĐģŅ Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛ŅŅ–Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛ ҃ ĐąŅƒĐ´ŅŒ-ŅĐēĐžĐŧ҃ ĐēĐ°Ņ‚Đ°ĐģĐžĐˇŅ– С Ņ–Đŧ'ŅĐŧ ÂĢRawÂģ, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"**/Raw/**\". ДĐģŅ Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛ŅŅ–Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛, Ņ‰Đž СаĐēŅ–ĐŊŅ‡ŅƒŅŽŅ‚ŅŒŅŅ ĐŊа \".tif\", виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"**/*.tif\". ДĐģŅ Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ°ĐąŅĐžĐģŅŽŅ‚ĐŊĐžĐŗĐž ҈ĐģŅŅ…Ņƒ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"/path/to/ignore/**\".", + "add_exclusion_pattern_description": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊи виĐŊŅŅ‚ĐēŅ–Đ˛. ĐŸŅ–Đ´ŅŅ‚Đ°ĐŊОвĐēа С виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅĐŧ *, ** Ņ‚Đ° ? ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ. ЊОй Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– Ņ„Đ°ĐšĐģи в ĐąŅƒĐ´ŅŒ-ŅĐēŅ–Đš ĐŋаĐŋ҆Җ С ĐŊĐ°ĐˇĐ˛ĐžŅŽ ÂĢRawÂģ, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"**/Raw/**\". ЊОй Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– Ņ„Đ°ĐšĐģи, Ņ‰Đž СаĐēŅ–ĐŊŅ‡ŅƒŅŽŅ‚ŅŒŅŅ ĐŊа \".tif\", виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"**/*.tif\". ЊОй Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ°ĐąŅĐžĐģŅŽŅ‚ĐŊиК ҈ĐģŅŅ…, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ \"/path/to/ignore/**\".", "admin_user": "АдĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€", - "asset_offline_description": "ĐĻĐĩĐš Ņ„Đ°ĐšĐģ СОвĐŊŅ–ŅˆĐŊŅŒĐžŅ— ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа Đ´Đ¸ŅĐē҃ Ņ– ĐąŅƒĐ˛ ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊиК Đ´Đž ĐēĐžŅˆĐ¸Đēа. Đ¯ĐēŅ‰Đž Ņ„Đ°ĐšĐģ ĐąŅƒĐ˛ ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊиК ҃ ĐŧĐĩĐļĐ°Ņ… ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ŅĐ˛ĐžŅŽ ҁ҂ҀҖ҇Đē҃ ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛ĐžĐŗĐž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐžĐŗĐž Ņ„Đ°ĐšĐģ҃. ЊОй Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ҆ĐĩĐš Ņ„Đ°ĐšĐģ, ĐŋĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ҈ĐģŅŅ… Đ´Đž Ņ„Đ°ĐšĐģ҃ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиК Đ´ĐģŅ Immich, Ņ– ĐŋŅ€ĐžŅĐēаĐŊŅƒĐšŅ‚Đĩ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃.", - "authentication_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", - "authentication_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐ°Ņ€ĐžĐģŅĐŧи, OAuth Ņ‚Đ° Ņ–ĐŊŅˆĐ¸Đŧи ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", - "authentication_settings_disable_all": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐŧĐēĐŊŅƒŅ‚Đ¸ Đ˛ŅŅ– ĐŧĐĩŅ‚ĐžĐ´Đ¸ Đ˛Ņ…ĐžĐ´Ņƒ? Đ’Ņ…Ņ–Đ´ ĐąŅƒĐ´Đĩ ĐŋОвĐŊŅ–ŅŅ‚ŅŽ виĐŧĐēĐŊĐĩĐŊиК.", - "authentication_settings_reenable": "ДĐģŅ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžĐŗĐž Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ КоĐŧаĐŊĐ´Ņƒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°.", - "background_task_job": "ФОĐŊĐžĐ˛Ņ– ЗавдаĐŊĐŊŅ", + "asset_offline_description": "ĐĻĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ СОвĐŊŅ–ŅˆĐŊŅŒĐžŅ— ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи ĐąŅ–ĐģҌ҈Đĩ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа Đ´Đ¸ŅĐē҃, Ņ‚ĐžĐŧ҃ ĐšĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа. Đ¯ĐēŅ‰Đž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐąŅƒĐģĐž ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž в ĐŧĐĩĐļĐ°Ņ… ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ŅĐ˛ĐžŅŽ Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–ŅŽ ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛ĐžĐŗĐž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°. ЊОй Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚, ĐŋĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ҈ĐģŅŅ… Đ´Đž ĐŊŅŒĐžĐŗĐž Đ´ĐžŅŅ‚ŅƒĐŋĐŊиК Đ´ĐģŅ Immich, Ņ– ĐŋŅ€ĐžŅĐēаĐŊŅƒĐšŅ‚Đĩ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃.", + "authentication_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", + "authentication_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐ°Ņ€ĐžĐģŅĐŧи, OAuth Ņ‚Đ° Ņ–ĐŊŅˆĐ¸Đŧи ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", + "authentication_settings_disable_all": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐŧĐēĐŊŅƒŅ‚Đ¸ Đ˛ŅŅ– ĐŧĐĩŅ‚ĐžĐ´Đ¸ Đ˛Ņ…ĐžĐ´Ņƒ? Đ’Ņ…Ņ–Đ´ ĐąŅƒĐ´Đĩ ĐŋОвĐŊŅ–ŅŅ‚ŅŽ виĐŧĐēĐŊĐĩĐŊĐž.", + "authentication_settings_reenable": "ЊОй ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ КоĐŧаĐŊĐ´Ņƒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°.", + "background_task_job": "ФОĐŊĐžĐ˛Ņ– СавдаĐŊĐŊŅ", "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_2_description": "ĐģĐžĐēаĐģҌĐŊŅ– ĐēĐžĐŋŅ–Ņ— ĐŊа Ņ€Ņ–ĐˇĐŊĐ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ…. ĐĻĐĩ ĐžŅĐŊОвĐŊŅ– Ņ„Đ°ĐšĐģи Ņ‚Đ° Ņ—Ņ… ĐģĐžĐēаĐģҌĐŊŅ– Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ—.", + "backup_onboarding_3_description": "ŅƒŅŅŒĐžĐŗĐž ĐēĐžĐŋŅ–Đš Đ˛Đ°ŅˆĐ¸Ņ… даĐŊĐ¸Ņ…, вĐēĐģŅŽŅ‡ĐŊĐž С ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊиĐŧи Ņ„Đ°ĐšĐģаĐŧи. ĐĻĐĩ 1 Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊа ĐēĐžĐŋŅ–Ņ Ņ‚Đ° 2 ĐģĐžĐēаĐģҌĐŊŅ– ĐēĐžĐŋŅ–Ņ—.", + "backup_onboarding_description": "Đ ĐĩĐēĐžĐŧĐĩĐŊдОваĐŊĐž Đ´ĐžŅ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗŅ–Ņ— Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ 3-2-1 Đ´ĐģŅ ĐˇĐ°Ņ…Đ¸ŅŅ‚Ņƒ Đ˛Đ°ŅˆĐ¸Ņ… даĐŊĐ¸Ņ…. ЗбĐĩŅ€Ņ–ĐŗĐ°ĐšŅ‚Đĩ ĐēĐžĐŋŅ–Ņ— виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Đš Đ˛Ņ–Đ´ĐĩĐž, а Ņ‚Đ°ĐēĐžĐļ йаСи даĐŊĐ¸Ņ… Immich, Ņ‰ĐžĐą СайĐĩСĐŋĐĩŅ‡Đ¸Ņ‚Đ¸ ĐŋОвĐŊĐžŅ†Ņ–ĐŊĐŊĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ.", "backup_onboarding_footer": "ДоĐēĐģадĐŊŅ–ŅˆĐĩ ĐŋŅ€Đž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Immich ĐŧĐžĐļĐŊа Đ´Ņ–ĐˇĐŊĐ°Ņ‚Đ¸ŅŅ С Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", - "backup_onboarding_parts_title": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Са ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗŅ–Ņ”ŅŽ 3-2-1 вĐēĐģŅŽŅ‡Đ°Ņ”:", + "backup_onboarding_parts_title": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Са ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗŅ–Ņ”ŅŽ 3-2-1 ĐžŅ…ĐžĐŋĐģŅŽŅ”:", "backup_onboarding_title": "Đ ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ—", "backup_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ даĐŧĐŋа йаСи даĐŊĐ¸Ņ…", - "backup_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи даĐŧĐŋа йаСи даĐŊĐ¸Ņ….", - "cleared_jobs": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊŅ– СавдаĐŊĐŊŅ Đ´ĐģŅ: {job}", + "backup_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи даĐŧĐŋа йаСи даĐŊĐ¸Ņ….", + "cleared_jobs": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž СавдаĐŊĐŊŅ Đ´ĐģŅ: {job}", "config_set_by_file": "НаĐģĐ°ŅˆŅ‚ĐžĐ˛Đ°ĐŊĐž Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐēĐžĐŊŅ„Ņ–Đŗ-Ņ„Đ°ĐšĐģ҃", - "confirm_delete_library": "Ви Đ´Ņ–ĐšŅĐŊĐž йаĐļĐ°Ņ”Ņ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃ \"{library}\"?", - "confirm_delete_library_assets": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ Ņ†ŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃? ĐĻĐĩ ĐąĐĩСĐŋĐžĐ˛ĐžŅ€ĐžŅ‚ĐŊĐž видаĐģĐ¸Ņ‚ŅŒ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} С Immich. ФаКĐģи СаĐģĐ¸ŅˆĐ°Ņ‚ŅŒŅŅ ĐŊа Đ´Đ¸ŅĐē҃.", - "confirm_email_below": "ДĐģŅ ĐŋŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´ĐļĐĩĐŊĐŊŅ ввĐĩĐ´Ņ–Ņ‚ŅŒ \"{email}\" ĐŊиĐļ҇Đĩ", - "confirm_reprocess_all_faces": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž виСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ? ĐĻĐĩ Ņ‚Đ°ĐēĐžĐļ ĐŋŅ€Đ¸ĐˇĐ˛ĐĩĐ´Đĩ Đ´Đž видаĐģĐĩĐŊĐŊŅ Ņ–ĐŧĐĩĐŊ С ŅƒŅŅ–Ņ… ОйĐģĐ¸Ņ‡.", + "confirm_delete_library": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃ ÂĢ{library}Âģ?", + "confirm_delete_library_assets": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ Ņ†ŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃? ĐĻĐĩ ĐąĐĩСĐŋĐžĐ˛ĐžŅ€ĐžŅ‚ĐŊĐž видаĐģĐ¸Ņ‚ŅŒ {count, plural, one {# ĐŊĐ°ŅĐ˛ĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {ŅƒŅŅ– # ĐŊĐ°ŅĐ˛ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {ŅƒŅŅ– # ĐŊĐ°ŅĐ˛ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {ŅƒŅŅ– # ĐŊĐ°ŅĐ˛ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} С Immich. ФаКĐģи СаĐģĐ¸ŅˆĐ°Ņ‚ŅŒŅŅ ĐŊа Đ´Đ¸ŅĐē҃.", + "confirm_email_below": "ЊОй ĐŋŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸, ввĐĩĐ´Ņ–Ņ‚ŅŒ ÂĢ{email}Âģ ĐŊиĐļ҇Đĩ", + "confirm_reprocess_all_faces": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž виСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ? ĐĻĐĩ Ņ‚Đ°ĐēĐžĐļ видаĐģĐ¸Ņ‚ŅŒ ŅƒŅŅ–Ņ… Ņ–ĐŧĐĩĐŊОваĐŊĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš.", "confirm_user_password_reset": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ҁĐēиĐŊŅƒŅ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {user}?", - "confirm_user_pin_code_reset": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ҁĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд {user}?", + "confirm_user_pin_code_reset": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ҁĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {user}?", "copy_config_to_clipboard_description": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊ҃ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧи ŅĐē Ой'Ņ”ĐēŅ‚ JSON ҃ ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃", "create_job": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ СавдаĐŊĐŊŅ", - "cron_expression": "Cron Đ˛Đ¸Ņ€Đ°Đˇ", - "cron_expression_description": "Đ’ŅŅ‚Đ°ĐŊĐžĐ˛Ņ–Ņ‚ŅŒ Ņ–ĐŊŅ‚ĐĩŅ€Đ˛Đ°Đģ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– cron. Đ”ĐžĐ´Đ°Ņ‚ĐēОва Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ: Crontab Guru", - "cron_expression_presets": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ cron Đ˛Đ¸Ņ€Đ°ĐˇŅ–Đ˛", + "cron_expression": "Cron-Đ˛Đ¸Ņ€Đ°Đˇ", + "cron_expression_description": "ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Ņ–Ņ‚ŅŒ Ņ–ĐŊŅ‚ĐĩŅ€Đ˛Đ°Đģ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– cron. Đ”ĐžĐ´Đ°Ņ‚ĐēОва Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ: Crontab Guru", + "cron_expression_presets": "ШайĐģĐžĐŊи Cron-Đ˛Đ¸Ņ€Đ°ĐˇŅ–Đ˛", "disable_login": "ВиĐŧĐēĐŊŅƒŅ‚Đ¸ Đ˛Ņ…Ņ–Đ´", - "duplicate_detection_job_description": "ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐĩ ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ Đ´ĐģŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ŅŅ…ĐžĐļĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ. ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ” Ņ–ĐŊŅ‚ĐĩĐģĐĩĐēŅ‚ŅƒĐ°ĐģҌĐŊиК ĐŋĐžŅˆŅƒĐē", - "exclusion_pattern_description": "ШайĐģĐžĐŊи виĐēĐģŅŽŅ‡ĐĩĐŊҌ дОСвОĐģŅŅŽŅ‚ŅŒ Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŋаĐŋĐēи ĐŋŅ–Đ´ Ņ‡Đ°Ņ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ°ŅˆĐžŅ— ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи. ĐĻĐĩ ĐēĐžŅ€Đ¸ŅĐŊĐž, ŅĐēŅ‰Đž ҃ Đ˛Đ°Ņ Ņ” ĐŋаĐŋĐēи, ŅĐēŅ– ĐŧŅ–ŅŅ‚ŅŅ‚ŅŒ Ņ„Đ°ĐšĐģи, ŅĐēŅ– ви ĐŊĐĩ Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Ņ–ĐŧĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸, ĐŊаĐŋŅ€Đ¸ĐēĐģад, RAW-Ņ„Đ°ĐšĐģи.", + "duplicate_detection_job_description": "ВиĐēĐžĐŊĐ°Ņ‚Đ¸ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐĩ ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ Đ´ĐģŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ŅŅ…ĐžĐļĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ. ĐŸĐžŅ‚Ņ€ĐĩĐąŅƒŅ” Ņ€ĐžĐˇŅƒĐŧĐŊĐžĐŗĐž ĐŋĐžŅˆŅƒĐē҃", + "exclusion_pattern_description": "ШайĐģĐžĐŊи виĐŊŅŅ‚ĐēŅ–Đ˛ Đ´Đ°ŅŽŅ‚ŅŒ СĐŧĐžĐŗŅƒ Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŋаĐŋĐēи ĐŋŅ–Đ´ Ņ‡Đ°Ņ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи. ĐĻĐĩ ĐēĐžŅ€Đ¸ŅĐŊĐž Đ´ĐģŅ ĐŋаĐŋĐžĐē Ņ–Đˇ ĐŊĐĩйаĐļаĐŊиĐŧи Đ´ĐģŅ Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ Ņ„Đ°ĐšĐģаĐŧи, ĐŊаĐŋŅ€Đ¸ĐēĐģад Ņ„Đ°ĐšĐģаĐŧи RAW.", "export_config_as_json_description": "ЗаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊ҃ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧи ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– JSON", "external_libraries_page_description": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа СОвĐŊŅ–ŅˆĐŊŅŒĐžŅ— ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", - "face_detection": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡Ņ‡Ņ", - "face_detection_description": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ. ДĐģŅ Đ˛Ņ–Đ´ĐĩĐž ĐžĐąŅ€ĐžĐąĐģŅŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ°. \\\"ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸\\\" ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ĐžĐąŅ€ĐžĐąĐģŅŅ” Đ˛ŅŅ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ. \\\"ĐĄĐēиĐŊŅƒŅ‚Đ¸\\\" Đ´ĐžĐ´Đ°Ņ‚ĐēОвО ĐžŅ‡Đ¸Ņ‰Đ°Ņ” Đ˛ŅŅ– ĐŋĐžŅ‚ĐžŅ‡ĐŊŅ– даĐŊŅ– ĐŋŅ€Đž ОйĐģĐ¸Ņ‡Ņ‡Ņ. \\\"Đ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–\\\" ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ҃ ҇ĐĩŅ€ĐŗŅƒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ, ŅĐēŅ– ҉Đĩ ĐŊĐĩ ĐąŅƒĐģи ĐžĐąŅ€ĐžĐąĐģĐĩĐŊŅ–. Đ’Đ¸ŅĐ˛ĐģĐĩĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊŅ– в ҇ĐĩŅ€ĐŗŅƒ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ, ĐŗŅ€ŅƒĐŋŅƒŅŽŅ‡Đ¸ Ņ—Ņ… ҃ вĐļĐĩ ҖҁĐŊŅƒŅŽŅ‡Đ¸Ņ… айО ĐŊĐžĐ˛Đ¸Ņ… ĐģŅŽĐ´ĐĩĐš.", - "facial_recognition_job_description": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐ¸Ņ… ОйĐģĐ¸Ņ‡ ҃ ĐģŅŽĐ´ĐĩĐš. ĐĻĐĩĐš ĐēŅ€ĐžĐē виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡. \"ĐĄĐēиĐŊŅƒŅ‚Đ¸\" ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ¸ĐˇŅƒŅ” Đ˛ŅŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ. \"Đ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–\" ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ҃ ҇ĐĩŅ€ĐŗŅƒ ОйĐģĐ¸Ņ‡Ņ‡Ņ, ŅĐēиĐŧ ҉Đĩ ĐŊĐĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž ĐģŅŽĐ´Đ¸ĐŊ҃.", - "failed_job_command": "КоĐŧаĐŊда {command} ĐŊĐĩ виĐēĐžĐŊаĐģĐ°ŅŅ Đ´ĐģŅ СавдаĐŊĐŊŅ: {job}", - "force_delete_user_warning": "ĐŸĐžĐŸĐ•Đ Đ•Đ”Đ–Đ•ĐĐĐ¯: ĐĻĐĩ ĐŊĐĩĐŗĐ°ĐšĐŊĐž ĐŋŅ€Đ¸ĐˇĐ˛ĐĩĐ´Đĩ Đ´Đž видаĐģĐĩĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ– Đ˛ŅŅ–Ņ… ĐšĐžĐŗĐž Ņ„Đ°ĐšĐģŅ–Đ˛. ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸, Ņ– Ņ„Đ°ĐšĐģи ĐŊĐĩ ĐŧĐžĐļĐŊа ĐąŅƒĐ´Đĩ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸.", + "face_detection": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡", + "face_detection_description": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡ ĐŊа ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Ņ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ. ДĐģŅ Đ˛Ņ–Đ´ĐĩĐž ĐžĐąŅ€ĐžĐąĐģŅŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ°. ÂĢОĐŊĐžĐ˛Đ¸Ņ‚Đ¸Âģ ĐžĐąŅ€ĐžĐąĐģŅŅ” (айО ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ĐžĐąŅ€ĐžĐąĐģŅŅ”) Đ˛ŅŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸. ÂĢĐĄĐēиĐŊŅƒŅ‚Đ¸Âģ Đ´ĐžĐ´Đ°Ņ‚ĐēОвО ĐžŅ‡Đ¸Ņ‰Đ°Ņ” Đ˛ŅŅ– ĐŋĐžŅ‚ĐžŅ‡ĐŊŅ– даĐŊŅ– ĐŋŅ€Đž ОйĐģĐ¸Ņ‡Ņ‡Ņ. ÂĢĐ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–Âģ ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ҃ ҇ĐĩŅ€ĐŗŅƒ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ŅĐēŅ– ҉Đĩ ĐŊĐĩ ĐąŅƒĐģĐž ĐžĐąŅ€ĐžĐąĐģĐĩĐŊĐž. Đ’Đ¸ŅĐ˛ĐģĐĩĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ ĐąŅƒĐ´Đĩ ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐž в ҇ĐĩŅ€ĐŗŅƒ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ, ĐŋŅ€Đ¸Ņ”Đ´ĐŊŅƒŅŽŅ‡Đ¸ Ņ—Ņ… Đ´Đž ĐŊĐ°ŅĐ˛ĐŊĐ¸Ņ… айО ĐŊĐžĐ˛Đ¸Ņ… ĐģŅŽĐ´ĐĩĐš.", + "facial_recognition_job_description": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐ¸Ņ… ОйĐģĐ¸Ņ‡ ҃ ĐģŅŽĐ´ĐĩĐš. ĐĻĐĩĐš ĐēŅ€ĐžĐē виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡. ÂĢĐĄĐēиĐŊŅƒŅ‚Đ¸Âģ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ¸ĐˇŅƒŅ” Đ˛ŅŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ. ÂĢĐ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–Âģ ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ҃ ҇ĐĩŅ€ĐŗŅƒ ОйĐģĐ¸Ņ‡Ņ‡Ņ, ŅĐēиĐŧ ҉Đĩ ĐŊĐĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž ĐģŅŽĐ´Đ¸ĐŊ҃.", + "failed_job_command": "НĐĩ вдаĐģĐžŅŅ виĐēĐžĐŊĐ°Ņ‚Đ¸ ĐēĐžĐŧаĐŊĐ´Ņƒ {command} Đ´ĐģŅ СавдаĐŊĐŊŅ: {job}", + "force_delete_user_warning": "ĐŸĐžĐŸĐ•Đ Đ•Đ”Đ–Đ•ĐĐĐ¯: ĐĻĐĩ ĐŊĐĩĐŗĐ°ĐšĐŊĐž видаĐģĐ¸Ņ‚ŅŒ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ‚Đ° Đ˛ŅŅ– ĐšĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸. ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸, Ņ– Ņ„Đ°ĐšĐģи ĐŊĐĩ ĐŧĐžĐļĐŊа ĐąŅƒĐ´Đĩ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸.", "image_format": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚", - "image_format_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ WebP Đ˛Đ¸Ņ€ĐžĐąĐģŅŅ” ĐŧĐĩĐŊŅˆŅ– Ņ„Đ°ĐšĐģи, ĐŊŅ–Đļ JPEG, аĐģĐĩ ĐšĐžĐŗĐž ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ виĐŧĐ°ĐŗĐ°Ņ” ĐąŅ–ĐģҌ҈Đĩ Ņ‡Đ°ŅŅƒ.", - "image_fullsize_description": "ПовĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐĩ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ С видаĐģĐĩĐŊиĐŧи ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи, ŅĐēŅ– виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅŽŅ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐˇĐąŅ–ĐģҌ҈ĐĩĐŊĐŊŅ", + "image_format_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ WebP ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐŧĐĩĐŊŅˆŅ– Ņ„Đ°ĐšĐģи, ĐŊŅ–Đļ JPEG, аĐģĐĩ ĐēĐžĐ´ŅƒŅ”Ņ‚ŅŒŅŅ ĐŋĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆĐĩ.", + "image_fullsize_description": "ПовĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐĩ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ С видаĐģĐĩĐŊиĐŧи ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐˇĐąŅ–ĐģҌ҈ĐĩĐŊĐŊŅ", "image_fullsize_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŋОвĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "image_fullsize_enabled_description": "ГĐĩĐŊĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋОвĐŊĐžĐŗĐž Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ Đ´ĐģŅ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ–Đ˛, ĐŊĐĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ… Đ´ĐģŅ вĐĩĐąŅƒ. Đ¯ĐēŅ‰Đž ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž \"ĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊĐžĐŧ҃ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ\", Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ– ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ¸ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅŽŅ‚ŅŒŅŅ ĐąĐĩС ĐēĐžĐŊвĐĩŅ€Ņ‚Đ°Ņ†Ņ–Ņ—. НĐĩ вĐŋĐģĐ¸Đ˛Đ°Ņ” ĐŊа вĐĩĐą-Đ´Ņ€ŅƒĐļĐŊŅ– Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸, Ņ‚Đ°ĐēŅ– ŅĐē JPEG.", - "image_fullsize_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŋОвĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ 1 Đ´Đž 100. ЧиĐŧ Đ˛Đ¸Ņ‰Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ, Ņ‚Đ¸Đŧ ĐēŅ€Đ°Ņ‰Đĩ ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ĐąŅ–ĐģҌ҈Đĩ Ņ€ĐžĐˇĐŧŅ–Ņ€ Ņ„Đ°ĐšĐģ҃.", + "image_fullsize_enabled_description": "ĐĄŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋОвĐŊĐžĐŗĐž Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ Đ´ĐģŅ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ–Đ˛, ĐŊĐĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ… Đ´ĐģŅ вĐĩĐąŅƒ. Đ¯ĐēŅ‰Đž ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž ÂĢĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊĐžĐŧ҃ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´ŅƒÂģ, Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ– ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ¸ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅŽŅ‚ŅŒŅŅ ĐąĐĩС ĐŋĐĩŅ€ĐĩŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ. НĐĩ вĐŋĐģĐ¸Đ˛Đ°Ņ” ĐŊа Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸, ҁ҃ĐŧҖҁĐŊŅ– С вĐĩйОĐŧ, Ņ‚Đ°ĐēŅ– ŅĐē JPEG.", + "image_fullsize_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŋОвĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ 1 Đ´Đž 100. ЧиĐŧ Đ˛Đ¸Ņ‰Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ, Ņ‚Đ¸Đŧ ĐēŅ€Đ°Ņ‰Đ° ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ĐąŅ–ĐģŅŒŅˆĐ¸Đš Ņ€ĐžĐˇĐŧŅ–Ņ€ Ņ„Đ°ĐšĐģ҃.", "image_fullsize_title": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋОвĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "image_prefer_embedded_preview": "ĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊĐžĐŧ҃ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ", - "image_prefer_embedded_preview_setting_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ– ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ¸ в RAW-Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅŅ… ŅĐē Đ˛Ņ…Ņ–Đ´ĐŊŅ– даĐŊŅ– Đ´ĐģŅ ĐžĐąŅ€ĐžĐąĐēи ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ, ŅĐēŅ‰Đž вОĐŊи Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ–. ĐĻĐĩ ĐŧĐžĐļĐĩ СайĐĩСĐŋĐĩŅ‡Đ¸Ņ‚Đ¸ Ņ‚ĐžŅ‡ĐŊŅ–ŅˆŅ– ĐēĐžĐģŅŒĐžŅ€Đ¸ Đ´ĐģŅ Đ´ĐĩŅĐēĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ, аĐģĐĩ ŅĐēŅ–ŅŅ‚ŅŒ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐēаĐŧĐĩŅ€Đ¸ Ņ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ ĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ°Ņ€Ņ‚ĐĩŅ„Đ°ĐēŅ‚Ņ–Đ˛ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ.", - "image_prefer_wide_gamut": "Đ’Ņ–Đ´Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ ŅˆĐ¸Ņ€ĐžĐēŅ–Đš ĐŗĐ°ĐŧŅ–", - "image_prefer_wide_gamut_setting_description": "ДĐģŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ Đ´Đ¸ŅĐŋĐģĐĩĐš P3. ĐĻĐĩ ĐēŅ€Đ°Ņ‰Đĩ СйĐĩŅ€Ņ–ĐŗĐ°Ņ” ŅŅĐēŅ€Đ°Đ˛Ņ–ŅŅ‚ŅŒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ С ŅˆĐ¸Ņ€ĐžĐēиĐŧ ĐēĐžĐģŅ–Ņ€ĐŊиĐŧ ĐŋŅ€ĐžŅŅ‚ĐžŅ€ĐžĐŧ, аĐģĐĩ ĐŊа ŅŅ‚Đ°Ņ€Đ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ… ĐˇŅ– ŅŅ‚Đ°Ņ€ĐžŅŽ вĐĩŅ€ŅŅ–Ņ”ŅŽ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ° ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐžĐļŅƒŅ‚ŅŒ Đ˛Đ¸ĐŗĐģŅĐ´Đ°Ņ‚Đ¸ Ņ–ĐŊаĐē҈Đĩ. sRGB-ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ СйĐĩŅ€Ņ–ĐŗĐ°ŅŽŅ‚ŅŒŅŅ ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– sRGB, Ņ‰ĐžĐą ҃ĐŊиĐēĐŊŅƒŅ‚Đ¸ ĐˇŅŅƒĐ˛Ņƒ ĐēĐžĐģŅŒĐžŅ€Ņ–Đ˛.", - "image_preview_description": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҁĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ ĐąĐĩС ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…, ŅĐēĐĩ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņ– ĐžĐēŅ€ĐĩĐŧĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Ņ‚Đ° Đ´ĐģŅ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", - "image_preview_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ Đ˛Ņ–Đ´ 1 Đ´Đž 100. Đ’Đ¸Ņ‰Đ° ĐžŅ†Ņ–ĐŊĐēа ОСĐŊĐ°Ņ‡Đ°Ņ” ĐēŅ€Đ°Ņ‰Ņƒ ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŧĐžĐļĐĩ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃. ĐĐ¸ĐˇŅŒĐēĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ вĐŋĐģиĐŊŅƒŅ‚Đ¸ ĐŊа ŅĐēŅ–ŅŅ‚ŅŒ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ.", + "image_prefer_embedded_preview_setting_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ– ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ¸ в RAW-Ņ„ĐžŅ‚Đž ŅĐē Đ˛Ņ…Ņ–Đ´ĐŊŅ– даĐŊŅ– Đ´ĐģŅ ĐžĐąŅ€ĐžĐąĐēи ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ, ŅĐēŅ‰Đž вОĐŊи Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ–. ĐĻĐĩ ĐŧĐžĐļĐĩ СайĐĩСĐŋĐĩŅ‡Đ¸Ņ‚Đ¸ Ņ‚ĐžŅ‡ĐŊŅ–ŅˆŅ– ĐēĐžĐģŅŒĐžŅ€Đ¸ Đ´ĐģŅ Đ´ĐĩŅĐēĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ, аĐģĐĩ ŅĐēŅ–ŅŅ‚ŅŒ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐēаĐŧĐĩŅ€Đ¸ Ņ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ ĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ°Ņ€Ņ‚ĐĩŅ„Đ°ĐēŅ‚Ņ–Đ˛ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ.", + "image_prefer_wide_gamut": "ĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ ŅˆĐ¸Ņ€ĐžĐēŅ–Đš ĐŗĐ°ĐŧŅ–", + "image_prefer_wide_gamut_setting_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžĐģŅ–Ņ€ĐŊиК ĐŋŅ€ĐžŅŅ‚Ņ–Ņ€ Display P3 Đ´ĐģŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€. ĐĻĐĩ ĐēŅ€Đ°Ņ‰Đĩ СйĐĩŅ€Ņ–ĐŗĐ°Ņ” ĐŊĐ°ŅĐ¸Ņ‡ĐĩĐŊŅ–ŅŅ‚ŅŒ ĐēĐžĐģŅŒĐžŅ€Ņ–Đ˛ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Ņ–Đˇ ŅˆĐ¸Ņ€ĐžĐēиĐŧ ĐēĐžĐģŅ–Ņ€ĐŊиĐŧ ĐŋŅ€ĐžŅŅ‚ĐžŅ€ĐžĐŧ, аĐģĐĩ ĐŊа ĐˇĐ°ŅŅ‚Đ°Ņ€Ņ–ĐģĐ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ… Ņ–Đˇ давĐŊŅŒĐžŅŽ вĐĩŅ€ŅŅ–Ņ”ŅŽ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ° ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐžĐļŅƒŅ‚ŅŒ Đ˛Đ¸ĐŗĐģŅĐ´Đ°Ņ‚Đ¸ Ņ–ĐŊаĐē҈Đĩ. sRGB-ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ СйĐĩŅ€Ņ–ĐŗĐ°ŅŽŅ‚ŅŒŅŅ ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– sRGB, Ņ‰ĐžĐą ҃ĐŊиĐēĐŊŅƒŅ‚Đ¸ ĐˇŅŅƒĐ˛Ņƒ ĐēĐžĐģŅŒĐžŅ€Ņ–Đ˛.", + "image_preview_description": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҁĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ ĐąĐĩС ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…, ŅĐēĐĩ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ ĐžĐēŅ€ĐĩĐŧĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ° Ņ‚Đ° Đ´ĐģŅ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", + "image_preview_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ Đ˛Ņ–Đ´ 1 Đ´Đž 100. Đ’Đ¸Ņ‰Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ОСĐŊĐ°Ņ‡Đ°Ņ” ĐēŅ€Đ°Ņ‰Ņƒ ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŧĐžĐļĐĩ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃. ĐĐ¸ĐˇŅŒĐēĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ вĐŋĐģиĐŊŅƒŅ‚Đ¸ ĐŊа ŅĐēŅ–ŅŅ‚ŅŒ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ.", "image_preview_title": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ", "image_progressive": "ĐŸŅ€ĐžĐŗŅ€ĐĩŅĐ¸Đ˛ĐŊиК", - "image_progressive_description": "ĐšĐžĐ´ŅƒĐšŅ‚Đĩ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ JPEG ĐŋĐžŅŅ‚ŅƒĐŋОвО Đ´ĐģŅ ĐŋĐžŅŅ‚ŅƒĐŋĐžĐ˛ĐžĐŗĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ. ĐĻĐĩ ĐŊĐĩ вĐŋĐģĐ¸Đ˛Đ°Ņ” ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ WebP.", + "image_progressive_description": "ĐšĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ JPEG ĐŋŅ€ĐžĐŗŅ€ĐĩŅĐ¸Đ˛ĐŊĐž Đ´ĐģŅ ĐŋĐžŅŅ‚ŅƒĐŋĐžĐ˛ĐžĐŗĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ. ĐĻĐĩ ĐŊĐĩ вĐŋĐģĐ¸Đ˛Đ°Ņ” ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ WebP.", "image_quality": "Đ¯ĐēŅ–ŅŅ‚ŅŒ", "image_resolution": "Đ ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", "image_resolution_description": "Đ’Đ¸Ņ‰Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ ĐŧĐžĐļĐĩ СйĐĩŅ€Ņ–ĐŗĐ°Ņ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš, аĐģĐĩ СаКĐŧĐ°Ņ” ĐąŅ–ĐģҌ҈Đĩ Ņ‡Đ°ŅŅƒ Đ´ĐģŅ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, ĐŧĐ°Ņ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ€ĐžĐˇĐŧŅ–Ņ€Đ¸ Ņ„Đ°ĐšĐģŅ–Đ˛ Ņ– ĐŧĐžĐļĐĩ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", "image_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "image_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐēŅ–ŅŅ‚ŅŽ Ņ‚Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅŽ ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŽ ĐˇĐŗĐĩĐŊĐĩŅ€ĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ", - "image_thumbnail_description": "МаĐģĐĩĐŊҌĐēа ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ° Ņ–Đˇ видаĐģĐĩĐŊиĐŧи ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ ĐŗŅ€ŅƒĐŋ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš, ĐŊаĐŋŅ€Đ¸ĐēĐģад, ĐŊа ĐžŅĐŊОвĐŊŅ–Đš ĐģŅ–ĐŊŅ–Ņ— Ņ‡Đ°ŅŅƒ", - "image_thumbnail_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ˛Ņ–Đ´ 1 Đ´Đž 100. Đ’Đ¸Ņ‰Đ° ĐžŅ†Ņ–ĐŊĐēа ОСĐŊĐ°Ņ‡Đ°Ņ” ĐēŅ€Đ°Ņ‰Ņƒ ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŧĐžĐļĐĩ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", + "image_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ŅĐēŅ–ŅŅ‚ŅŽ Ņ‚Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅŽ ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŽ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ", + "image_thumbnail_description": "МаĐģĐĩĐŊҌĐēа ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ° Ņ–Đˇ видаĐģĐĩĐŊиĐŧи ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ ĐŗŅ€ŅƒĐŋ Ņ„ĐžŅ‚Đž, ĐŊаĐŋŅ€Đ¸ĐēĐģад, ĐŊа ĐžŅĐŊОвĐŊŅ–Đš Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ—", + "image_thumbnail_quality_description": "Đ¯ĐēŅ–ŅŅ‚ŅŒ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ˛Ņ–Đ´ 1 Đ´Đž 100. Đ’Đ¸Ņ‰Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ОСĐŊĐ°Ņ‡Đ°Ņ” ĐēŅ€Đ°Ņ‰Ņƒ ŅĐēŅ–ŅŅ‚ŅŒ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи Ņ‚Đ° ĐŧĐžĐļĐĩ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", "image_thumbnail_title": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€", - "import_config_from_json_description": "ІĐŧĐŋĐžŅ€Ņ‚ŅƒĐšŅ‚Đĩ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧи, виваĐŊŅ‚Đ°ĐļĐ¸Đ˛ŅˆĐ¸ Ņ„Đ°ĐšĐģ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–Ņ— JSON", - "job_concurrency": "{job} ОдĐŊĐžŅ‡Đ°ŅĐŊĐž", + "import_config_from_json_description": "ІĐŧĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧи, виваĐŊŅ‚Đ°ĐļĐ¸Đ˛ŅˆĐ¸ Ņ„Đ°ĐšĐģ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–Ņ— JSON", + "job_concurrency": "ĐŸĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŒ {job}", "job_created": "ЗавдаĐŊĐŊŅ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž", "job_not_concurrency_safe": "ĐĻĐĩ СавдаĐŊĐŊŅ ĐŊĐĩ Ņ” ĐąĐĩСĐŋĐĩ҇ĐŊиĐŧ Đ´ĐģŅ ОдĐŊĐžŅ‡Đ°ŅĐŊĐžĐŗĐž виĐēĐžĐŊаĐŊĐŊŅ.", "job_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ СавдаĐŊҌ", "job_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŽ СавдаĐŊҌ", - "jobs_delayed": "{jobCount, plural, other {# Đ˛Ņ–Đ´ĐēĐģадĐĩĐŊĐž}}", - "jobs_failed": "{jobCount, plural, other {# ĐŊĐĩ вдаĐģĐžŅŅ}}", + "jobs_delayed": "{jobCount, plural, one {# СавдаĐŊĐŊŅ Đ˛Ņ–Đ´ĐēĐģадĐĩĐŊĐž} few {# СавдаĐŊĐŊŅ Đ˛Ņ–Đ´ĐēĐģадĐĩĐŊĐž} many {# СавдаĐŊҌ Đ˛Ņ–Đ´ĐēĐģадĐĩĐŊĐž} other {# СавдаĐŊҌ Đ˛Ņ–Đ´ĐēĐģадĐĩĐŊĐž}}", + "jobs_failed": "{jobCount, plural, one {# СавдаĐŊĐŊŅ ĐŊĐĩ вдаĐģĐžŅŅ} few {# СавдаĐŊĐŊŅ ĐŊĐĩ вдаĐģĐžŅŅ} many {# СавдаĐŊҌ ĐŊĐĩ вдаĐģĐžŅŅ} other {# СавдаĐŊҌ ĐŊĐĩ вдаĐģĐžŅŅ}}", "jobs_over_time": "ЗавдаĐŊĐŊŅ Са Ņ‡Đ°ŅĐžĐŧ", - "library_created": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊа ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēа: {library}", + "library_created": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃: {library}", "library_deleted": "Đ‘Ņ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃ видаĐģĐĩĐŊĐž", "library_details": "ДĐĩŅ‚Đ°ĐģŅ– ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", - "library_folder_description": "ВĐēаĐļŅ–Ņ‚ŅŒ ĐŋаĐŋĐē҃ Đ´ĐģŅ Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ. ĐĻŅ ĐŋаĐŋĐēа, вĐēĐģŅŽŅ‡Đ°ŅŽŅ‡Đ¸ ĐŋŅ–Đ´ĐŋаĐŋĐēи, ĐąŅƒĐ´Đĩ ĐŋŅ€ĐžŅĐēаĐŊОваĐŊа ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž.", - "library_remove_exclusion_pattern_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ?", + "library_folder_description": "ВĐēаĐļŅ–Ņ‚ŅŒ ĐŋаĐŋĐē҃ Đ´ĐģŅ Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ. ĐĻŅ ĐŋаĐŋĐēа Ņ€Đ°ĐˇĐžĐŧ Ņ–Đˇ ĐŋŅ–Đ´ĐŋаĐŋĐēаĐŧи ĐąŅƒĐ´Đĩ ĐŋŅ€ĐžŅĐēаĐŊОваĐŊа ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž.", + "library_remove_exclusion_pattern_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ҆ĐĩĐš ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃?", "library_remove_folder_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ Ņ†ŅŽ ĐŋаĐŋĐē҃ Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ?", "library_scanning": "ПĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐĩ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", - "library_scanning_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐĩ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", + "library_scanning_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐžĐŗĐž ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "library_scanning_enable_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŋĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐĩ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "library_settings": "ЗовĐŊŅ–ŅˆĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēа", "library_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи СОвĐŊŅ–ŅˆĐŊŅ–Ņ… ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē", - "library_tasks_description": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ СОвĐŊŅ–ŅˆĐŊŅ– ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛Đ¸Ņ… Ņ–/айО СĐŧŅ–ĐŊĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "library_updated": "ОĐŊОвĐģĐĩĐŊа ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēа", + "library_tasks_description": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ СОвĐŊŅ–ŅˆĐŊŅ– ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи ĐŊа ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛Đ¸Ņ… Ņ–/айО СĐŧŅ–ĐŊĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", + "library_updated": "ОĐŊОвĐģĐĩĐŊĐž ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", "library_watching_enable_description": "Đ’Ņ–Đ´ŅŅ‚ĐĩĐļŅƒĐ˛Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи Ņ„Đ°ĐšĐģŅ–Đ˛ ҃ СОвĐŊŅ–ŅˆĐŊŅ–Ņ… ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēĐ°Ņ…", - "library_watching_settings": "ĐĄĐŋĐžŅŅ‚ĐĩŅ€ĐĩĐļĐĩĐŊĐŊŅ Са ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēĐžŅŽ [ЕКСПЕРИМЕНĐĸАЛĐŦНЕ]", - "library_watching_settings_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ ҁĐŋĐžŅŅ‚ĐĩŅ€ĐĩĐļĐĩĐŊĐŊŅ Са СĐŧŅ–ĐŊĐĩĐŊиĐŧи Ņ„Đ°ĐšĐģаĐŧи", + "library_watching_settings": "Đ’Ņ–Đ´ŅŅ‚ĐĩĐļĐĩĐŊĐŊŅ СĐŧŅ–ĐŊ ҃ ĐąŅ–ĐąĐģŅ–ĐžŅ‚Đĩ҆Җ [ЕКСПЕРИМЕНĐĸАЛĐŦНО]", + "library_watching_settings_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Đ˛Ņ–Đ´ŅŅ‚ĐĩĐļĐĩĐŊĐŊŅ СĐŧŅ–ĐŊĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", "logging_enable_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ вĐĩĐ´ĐĩĐŊĐŊŅ ĐļŅƒŅ€ĐŊаĐģ҃", - "logging_level_description": "КоĐģи ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž, ŅĐēиК Ņ€Ņ–Đ˛ĐĩĐŊҌ ĐļŅƒŅ€ĐŊаĐģŅŽĐ˛Đ°ĐŊĐŊŅ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸.", + "logging_level_description": "Đ Ņ–Đ˛ĐĩĐŊҌ Đ´ĐĩŅ‚Đ°ĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ— ĐļŅƒŅ€ĐŊаĐģ҃, ĐēĐžĐģи ĐļŅƒŅ€ĐŊаĐģŅŽĐ˛Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž.", "logging_settings": "Đ–ŅƒŅ€ĐŊаĐģŅŽĐ˛Đ°ĐŊĐŊŅ", "machine_learning_availability_checks": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐžŅŅ‚Ņ–", "machine_learning_availability_checks_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Đ˛Đ¸ŅĐ˛ĐģŅŅ‚Đ¸ Ņ‚Đ° ĐŊĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", @@ -150,71 +150,71 @@ "machine_learning_availability_checks_timeout": "ĐĸаКĐŧ-Đ°ŅƒŅ‚ СаĐŋĐ¸Ņ‚Ņƒ", "machine_learning_availability_checks_timeout_description": "ĐĸаКĐŧ-Đ°ŅƒŅ‚ ҃ ĐŧŅ–ĐģҖҁĐĩĐē҃ĐŊĐ´Đ°Ņ… Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐžŅŅ‚Ņ–", "machine_learning_clip_model": "МодĐĩĐģҌ CLIP", - "machine_learning_clip_model_description": "ІĐŧ'Ņ ОдĐŊҖҔҗ С ĐŧОдĐĩĐģĐĩĐš CLIP, ŅĐēа ĐŋĐĩŅ€ĐĩŅ€Đ°Ņ…ĐžĐ˛Đ°ĐŊа Ņ‚ŅƒŅ‚. Đ—Đ°ŅƒĐ˛Đ°ĐļŅ‚Đĩ, Ņ‰Đž ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž СĐŊĐžĐ˛Ņƒ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ СавдаĐŊĐŊŅ ÂĢĐ ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐēÂģ Đ´ĐģŅ Đ˛ŅŅ–Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ ĐŋҖҁĐģŅ СĐŧŅ–ĐŊи ĐŧОдĐĩĐģŅ–.", + "machine_learning_clip_model_description": "Назва ĐŧОдĐĩĐģŅ– CLIP ĐˇŅ– ҁĐŋĐ¸ŅĐē҃ Ņ‚ŅƒŅ‚. Đ—Đ°ŅƒĐ˛Đ°ĐļŅ‚Đĩ, Ņ‰Đž ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž виĐēĐžĐŊĐ°Ņ‚Đ¸ СавдаĐŊĐŊŅ ÂĢĐ ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐēÂģ Đ´ĐģŅ Đ˛ŅŅ–Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ ĐŋҖҁĐģŅ СĐŧŅ–ĐŊи ĐŧОдĐĩĐģŅ–.", "machine_learning_duplicate_detection": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛", "machine_learning_duplicate_detection_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛", - "machine_learning_duplicate_detection_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, Đ°ĐąŅĐžĐģŅŽŅ‚ĐŊĐž Ņ–Đ´ĐĩĐŊŅ‚Đ¸Ņ‡ĐŊŅ– Ņ„Đ°ĐšĐģи Đ˛ŅĐĩ ОдĐŊĐž ĐąŅƒĐ´ŅƒŅ‚ŅŒ видаĐģĐĩĐŊŅ– ҇ĐĩŅ€ĐĩС Đ´ŅƒĐąĐģŅŽĐ˛Đ°ĐŊĐŊŅ.", - "machine_learning_duplicate_detection_setting_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ Đ˛ĐąŅƒĐ´ĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ CLIP Đ´ĐģŅ ĐŋĐžŅˆŅƒĐē҃ ĐšĐŧĐžĐ˛Ņ–Ņ€ĐŊĐ¸Ņ… Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛", + "machine_learning_duplicate_detection_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, Đ°ĐąŅĐžĐģŅŽŅ‚ĐŊĐž Ņ–Đ´ĐĩĐŊŅ‚Đ¸Ņ‡ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ˛ŅĐĩ ОдĐŊĐž ĐąŅƒĐ´Đĩ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐž ŅĐē Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸.", + "machine_learning_duplicate_detection_setting_description": "ĐŸĐžŅˆŅƒĐē ĐšĐŧĐžĐ˛Ņ–Ņ€ĐŊĐ¸Ņ… Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ CLIP-вĐĩĐēŅ‚ĐžŅ€Ņ–Đ˛", "machine_learning_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐĩ ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", - "machine_learning_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, Đ˛ŅŅ– Ņ„ŅƒĐŊĐē҆Җҗ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ ĐąŅƒĐ´ŅƒŅ‚ŅŒ виĐŧĐēĐŊĐĩĐŊŅ– ĐŊĐĩСаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ ĐŊиĐļ҇Đĩ.", + "machine_learning_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, ĐļОдĐŊа С Ņ„ŅƒĐŊĐēŅ†Ņ–Đš ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ ĐŊĐĩ ĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸ĐŧĐĩ, ĐŊĐĩСаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ ĐŊиĐļ҇Đĩ.", "machine_learning_facial_recognition": "РОСĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡", - "machine_learning_facial_recognition_description": "Đ’Đ¸ŅĐ˛ĐģŅĐšŅ‚Đĩ, Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊĐ°Đ˛Đ°ĐšŅ‚Đĩ Ņ‚Đ° ĐŗŅ€ŅƒĐŋŅƒĐšŅ‚Đĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ…", + "machine_learning_facial_recognition_description": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ, Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚Đ° ĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°ĐŊĐŊŅ ОйĐģĐ¸Ņ‡ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ…", "machine_learning_facial_recognition_model": "МодĐĩĐģҌ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡", - "machine_learning_facial_recognition_model_description": "МодĐĩĐģŅ– Đ˛Ņ–Đ´ŅĐžŅ€Ņ‚ĐžĐ˛Đ°ĐŊŅ– Са СĐŧĐĩĐŊ҈ĐĩĐŊĐŊŅĐŧ Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ. Đ‘Ņ–ĐģŅŒŅˆŅ– ĐŧОдĐĩĐģŅ– ĐŋŅ€Đ°Ņ†ŅŽŅŽŅ‚ŅŒ ĐŋĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆĐĩ, ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅŽŅ‚ŅŒ ĐąŅ–ĐģҌ҈Đĩ ĐŋаĐŧ'ŅŅ‚Ņ–, аĐģĐĩ Đ´Đ°ŅŽŅ‚ŅŒ ĐēŅ€Đ°Ņ‰Ņ– Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đ¸. ЗвĐĩŅ€ĐŊŅ–Ņ‚ŅŒ ŅƒĐ˛Đ°ĐŗŅƒ, Ņ‰Đž ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž СĐŊĐžĐ˛Ņƒ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ СавдаĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡Ņ‡Ņ Đ´ĐģŅ Đ˛ŅŅ–Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ ĐŋҖҁĐģŅ СĐŧŅ–ĐŊи ĐŧОдĐĩĐģŅ–.", + "machine_learning_facial_recognition_model_description": "МодĐĩĐģŅ– Đ˛Ņ–Đ´ŅĐžŅ€Ņ‚ĐžĐ˛Đ°ĐŊŅ– Са СĐŧĐĩĐŊ҈ĐĩĐŊĐŊŅĐŧ Ņ€ĐžĐˇĐŧŅ–Ņ€Ņƒ. Đ‘Ņ–ĐģŅŒŅˆŅ– ĐŧОдĐĩĐģŅ– ĐŋŅ€Đ°Ņ†ŅŽŅŽŅ‚ŅŒ ĐŋĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆĐĩ, ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅŽŅ‚ŅŒ ĐąŅ–ĐģҌ҈Đĩ ĐŋаĐŧ'ŅŅ‚Ņ–, аĐģĐĩ Đ´Đ°ŅŽŅ‚ŅŒ ĐēŅ€Đ°Ņ‰Ņ– Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đ¸. ЗвĐĩŅ€ĐŊŅ–Ņ‚ŅŒ ŅƒĐ˛Đ°ĐŗŅƒ, Ņ‰Đž ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž виĐēĐžĐŊĐ°Ņ‚Đ¸ СавдаĐŊĐŊŅ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡ Đ´ĐģŅ Đ˛ŅŅ–Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ ĐŋҖҁĐģŅ СĐŧŅ–ĐŊи ĐŧОдĐĩĐģŅ–.", "machine_learning_facial_recognition_setting": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡", - "machine_learning_facial_recognition_setting_description": "Đ¯ĐēŅ‰Đž Ņ†Ņ Ņ„ŅƒĐŊĐēŅ†Ņ–Ņ виĐŧĐēĐŊĐĩĐŊа, ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡ Ņ– ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ŅŒ С'ŅĐ˛ĐģŅŅ‚Đ¸ŅŅ в Ņ€ĐžĐˇĐ´Ņ–ĐģŅ– \"Đ›ŅŽĐ´Đ¸\" ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊ҆Җ \"ĐžĐŗĐģŅĐ´\".", + "machine_learning_facial_recognition_setting_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ ĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡ Ņ– ĐŊĐĩ С'ŅĐ˛ĐģŅŅ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ в Ņ€ĐžĐˇĐ´Ņ–ĐģŅ– ÂĢĐ›ŅŽĐ´Đ¸Âģ ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊ҆Җ ÂĢĐžĐŗĐģŅĐ´Âģ.", "machine_learning_max_detection_distance": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐŊŅ", - "machine_learning_max_detection_distance_description": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ ĐŧŅ–Đļ двОĐŧа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅĐŧи, Ņ‰ĐžĐą вОĐŊи вваĐļаĐģĐ¸ŅŅ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ°Đŧи, Đ˛Đ°Ņ€Ņ–ŅŽŅ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ 0.001 Đ´Đž 0.1. Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ дОСвОĐģŅŅŽŅ‚ŅŒ Đ˛Đ¸ŅĐ˛ĐģŅŅ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛, аĐģĐĩ ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŋŅ€Đ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚Đ¸ Đ´Đž ĐŋĐžĐŧиĐģĐēĐžĐ˛Đ¸Ņ… Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊҌ.", + "machine_learning_max_detection_distance_description": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ ĐŧŅ–Đļ двОĐŧа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅĐŧи, Ņ‰ĐžĐą вОĐŊи вваĐļаĐģĐ¸ŅŅ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ°Đŧи, Đ˛Đ°Ņ€Ņ–ŅŽŅ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ 0.001 Đ´Đž 0.1. Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ Đ´Đ°ŅŽŅ‚ŅŒ СĐŧĐžĐŗŅƒ Đ˛Đ¸ŅĐ˛ĐģŅŅ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛, аĐģĐĩ ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŋŅ€Đ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚Đ¸ Đ´Đž Ņ…Đ¸ĐąĐŊĐ¸Ņ… ҁĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°ĐŊҌ.", "machine_learning_max_recognition_distance": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ", - "machine_learning_max_recognition_distance_description": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ ĐŧŅ–Đļ двОĐŧа ОйĐģĐ¸Ņ‡Ņ‡ŅĐŧи, Ņ‰ĐžĐą Ņ—Ņ… вваĐļĐ°Ņ‚Đ¸ ОдĐŊŅ–Ņ”ŅŽ Ņ– Ņ‚Ņ–Ņ”ŅŽ Đļ ŅĐ°ĐŧĐžŅŽ ĐģŅŽĐ´Đ¸ĐŊĐžŅŽ, Đ˛Đ°Ņ€Ņ–ŅŽŅ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ 0 Đ´Đž 2. ЗĐŊиĐļĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ СаĐŋĐžĐąŅ–ĐŗŅ‚Đ¸ ĐŋĐžĐŧиĐģĐēОвОĐŧ҃ виСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅŽ Đ´Đ˛ĐžŅ… Ņ€Ņ–ĐˇĐŊĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš ŅĐē ОдĐŊҖҔҗ ĐžŅĐžĐąĐ¸, Ņ‚ĐžĐ´Ņ– ŅĐē ĐŋŅ–Đ´Đ˛Đ¸Ņ‰ĐĩĐŊĐŊŅ ĐšĐžĐŗĐž ĐŧĐžĐļĐĩ СаĐŋĐžĐąŅ–ĐŗŅ‚Đ¸ ĐŋĐžĐŧиĐģĐēОвОĐŧ҃ виСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅŽ ОдĐŊҖҔҗ Ņ– ҂ҖҔҗ Đļ ŅĐ°ĐŧĐžŅ— ĐģŅŽĐ´Đ¸ĐŊи ŅĐē Đ´Đ˛ĐžŅ… Ņ€Ņ–ĐˇĐŊĐ¸Ņ… ĐžŅŅ–Đą. ЗвĐĩŅ€ĐŊŅ–Ņ‚ŅŒ ŅƒĐ˛Đ°ĐŗŅƒ, Ņ‰Đž ĐģĐĩĐŗŅˆĐĩ Ой'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ´Đ˛ĐžŅ… ĐģŅŽĐ´ĐĩĐš, ĐŊŅ–Đļ Ņ€ĐžĐˇĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ ОдĐŊ҃ ĐģŅŽĐ´Đ¸ĐŊ҃ ĐŊа Đ´Đ˛Ņ–, Ņ‚ĐžĐŧ҃ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒŅ”Ņ‚ŅŒŅŅ ĐŊĐ°Ņ…Đ¸ĐģĐ¸Ņ‚Đ¸ŅŅ ĐŊа ĐąŅ–Đē ĐŧĐĩĐŊŅˆĐžĐŗĐž ĐŋĐžŅ€ĐžĐŗŅƒ, ĐēĐžĐģи ҆Đĩ ĐŧĐžĐļĐģивО.", + "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_min_recognized_faces_description": "ĐœŅ–ĐŊŅ–ĐŧаĐģҌĐŊа ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊĐ¸Ņ… ОйĐģĐ¸Ņ‡ Đ´ĐģŅ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐģŅŽĐ´Đ¸ĐŊи. Đ—ĐąŅ–ĐģҌ҈ĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° Ņ€ĐžĐąĐ¸Ņ‚ŅŒ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡ Ņ‚ĐžŅ‡ĐŊŅ–ŅˆĐ¸Đŧ, аĐģĐĩ ĐŧĐžĐļĐĩ ĐˇĐąŅ–ĐģŅŒŅˆĐ¸Ņ‚Đ¸ Ņ€Đ¸ĐˇĐ¸Đē Ņ‚ĐžĐŗĐž, Ņ‰Đž ОйĐģĐ¸Ņ‡Ņ‡Ņ ĐŊĐĩ ĐąŅƒĐ´Đĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž ĐģŅŽĐ´Đ¸ĐŊŅ–.", "machine_learning_ocr": "OCR", - "machine_learning_ocr_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐĩ ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ…", + "machine_learning_ocr_description": "РОСĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", "machine_learning_ocr_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ OCR", - "machine_learning_ocr_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊĐ°Đ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ Ņ‚ĐĩĐēŅŅ‚Ņƒ.", + "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_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": "Đ ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐē", - "machine_learning_smart_search_description": "ĐŸĐžŅˆŅƒĐē ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ҁĐĩĐŧаĐŊŅ‚Đ¸Ņ‡ĐŊĐ¸Ņ… Đ˛ĐąŅƒĐ´ĐžĐ˛ŅƒĐ˛Đ°ĐŊҌ CLIP", + "machine_learning_smart_search_description": "ĐĄĐĩĐŧаĐŊŅ‚Đ¸Ņ‡ĐŊиК ĐŋĐžŅˆŅƒĐē ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ CLIP-вĐĩĐēŅ‚ĐžŅ€Ņ–Đ˛", "machine_learning_smart_search_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐē", - "machine_learning_smart_search_enabled_description": "Đ¯ĐēŅ‰Đž Ņ†Ņ Ņ„ŅƒĐŊĐēŅ†Ņ–Ņ виĐŧĐēĐŊĐĩĐŊа, ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ Đ´ĐģŅ Ņ€ĐžĐˇŅƒĐŧĐŊĐžĐŗĐž ĐŋĐžŅˆŅƒĐē҃.", - "machine_learning_url_description": "URL ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ. Đ¯ĐēŅ‰Đž ĐŊадаĐŊĐž ĐąŅ–ĐģҌ҈Đĩ ОдĐŊĐžĐŗĐž URL, ҁĐĩŅ€Đ˛ĐĩŅ€Đ¸ ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžĐŋĐ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ ĐŋĐž ҇ĐĩŅ€ĐˇŅ–, ĐŋĐžĐēи ОдиĐŊ С ĐŊĐ¸Ņ… ĐŊĐĩ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–ŅŅ‚ŅŒ ҃ҁĐŋŅ–ŅˆĐŊĐž, ҃ ĐŋĐžŅ€ŅĐ´Đē҃ Đ˛Ņ–Đ´ ĐŋĐĩŅ€ŅˆĐžĐŗĐž Đ´Đž ĐžŅŅ‚Đ°ĐŊĐŊŅŒĐžĐŗĐž. ĐĄĐĩŅ€Đ˛ĐĩŅ€Đ¸, ŅĐēŅ– ĐŊĐĩ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ, ĐąŅƒĐ´ŅƒŅ‚ŅŒ Ņ‚Đ¸ĐŧŅ‡Đ°ŅĐžĐ˛Đž Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ, ĐŋĐžĐēи ĐŊĐĩ ŅŅ‚Đ°ĐŊŅƒŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧи.", + "machine_learning_smart_search_enabled_description": "Đ¯ĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ ĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Đ´ĐģŅ Ņ€ĐžĐˇŅƒĐŧĐŊĐžĐŗĐž ĐŋĐžŅˆŅƒĐē҃.", + "machine_learning_url_description": "URL ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ. Đ¯ĐēŅ‰Đž ĐŊадаĐŊĐž ĐąŅ–ĐģҌ҈Đĩ ОдĐŊĐžĐŗĐž URL, ҁĐĩŅ€Đ˛ĐĩŅ€Đ¸ ĐžĐŋĐ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ ĐŋĐž ҇ĐĩŅ€ĐˇŅ–, ĐŋĐžĐēи ОдиĐŊ С ĐŊĐ¸Ņ… ĐŊĐĩ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–ŅŅ‚ŅŒ ҃ҁĐŋŅ–ŅˆĐŊĐž, ҃ ĐŋĐžŅ€ŅĐ´Đē҃ Đ˛Ņ–Đ´ ĐŋĐĩŅ€ŅˆĐžĐŗĐž Đ´Đž ĐžŅŅ‚Đ°ĐŊĐŊŅŒĐžĐŗĐž. ĐĄĐĩŅ€Đ˛ĐĩŅ€Đ¸, ŅĐēŅ– ĐŊĐĩ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ, Ņ‚Đ¸ĐŧŅ‡Đ°ŅĐžĐ˛Đž Ņ–ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ, ĐŋĐžĐēи ĐŊĐĩ ŅŅ‚Đ°ĐŊŅƒŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧи.", "maintenance_delete_backup": "ВидаĐģĐ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ", "maintenance_delete_backup_description": "ĐĻĐĩĐš Ņ„Đ°ĐšĐģ ĐąŅƒĐ´Đĩ ĐąĐĩСĐŋĐžĐ˛ĐžŅ€ĐžŅ‚ĐŊĐž видаĐģĐĩĐŊĐž.", "maintenance_delete_error": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ.", - "maintenance_restore_backup": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—", + "maintenance_restore_backup": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ", "maintenance_restore_backup_description": "Immich ĐąŅƒĐ´Đĩ ҁ҂ĐĩŅ€Ņ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžŅ— Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—. ПĐĩŅ€ĐĩĐ´ ĐŋŅ€ĐžĐ´ĐžĐ˛ĐļĐĩĐŊĐŊŅĐŧ ĐąŅƒĐ´Đĩ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ.", "maintenance_restore_backup_different_version": "ĐĻŅŽ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ ĐąŅƒĐģĐž ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ Ņ–ĐŊŅˆĐžŅ— вĐĩҀҁҖҗ Immich!", "maintenance_restore_backup_unknown_version": "НĐĩ вдаĐģĐžŅŅ виСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ вĐĩŅ€ŅŅ–ŅŽ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—.", - "maintenance_restore_database_backup": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ— йаСи даĐŊĐ¸Ņ…", - "maintenance_restore_database_backup_description": "Đ’Ņ–Đ´ĐēĐ°Ņ‚ Đ´Đž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ŅŅ‚Đ°ĐŊ҃ йаСи даĐŊĐ¸Ņ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ Ņ„Đ°ĐšĐģ҃ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—", - "maintenance_settings": "ĐĸĐĩŅ…ĐŊҖ҇ĐŊĐĩ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", - "maintenance_settings_description": "ПĐĩŅ€ĐĩвĐĩĐ´ĐĩĐŊĐŊŅ Immich ҃ Ņ€ĐĩĐļиĐŧ Ņ‚ĐĩŅ…ĐŊҖ҇ĐŊĐžĐŗĐž ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", - "maintenance_start": "ПĐĩŅ€ĐĩŅ…Ņ–Đ´ ҃ Ņ€ĐĩĐļиĐŧ Ņ‚ĐĩŅ…ĐŊҖ҇ĐŊĐžĐŗĐž ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", - "maintenance_start_error": "НĐĩ вдаĐģĐžŅŅ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ.", + "maintenance_restore_database_backup": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ йаСи даĐŊĐ¸Ņ…", + "maintenance_restore_database_backup_description": "ПовĐĩŅ€ĐŊĐĩĐŊĐŊŅ Đ´Đž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ŅŅ‚Đ°ĐŊ҃ йаСи даĐŊĐ¸Ņ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ Ņ„Đ°ĐšĐģ҃ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—", + "maintenance_settings": "ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", + "maintenance_settings_description": "ПĐĩŅ€ĐĩвĐĩĐ´ĐĩĐŊĐŊŅ Immich ҃ Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", + "maintenance_start": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ в Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", + "maintenance_start_error": "НĐĩ вдаĐģĐžŅŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ.", "maintenance_upload_backup": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ— йаСи даĐŊĐ¸Ņ…", "maintenance_upload_backup_error": "НĐĩ вдаĐģĐžŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ, ҆Đĩ Ņ„Đ°ĐšĐģ .sql/.sql.gz?", "manage_concurrency": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŽ СавдаĐŊҌ", - "manage_concurrency_description": "ПĐĩŅ€ĐĩŅ…Ņ–Đ´ Đ´Đž ŅŅ‚ĐžŅ€Ņ–ĐŊĐēи СавдаĐŊҌ Đ´ĐģŅ ĐēĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŽ", + "manage_concurrency_description": "ПĐĩŅ€ĐĩĐšĐ´Ņ–Ņ‚ŅŒ Đ´Đž ŅŅ‚ĐžŅ€Ņ–ĐŊĐēи СавдаĐŊҌ, Ņ‰ĐžĐą ĐēĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŽ", "manage_log_settings": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐļŅƒŅ€ĐŊаĐģ҃", "map_dark_style": "ĐĸĐĩĐŧĐŊиК ŅŅ‚Đ¸ĐģҌ", "map_enable_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ„ŅƒĐŊĐē҆Җҗ ĐŧаĐŋи", - "map_gps_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧаĐŋи Ņ‚Đ° ĐŗĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–Ņ—", - "map_gps_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐŧаĐŋи Ņ‚Đ° ĐŗĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–Ņ— (ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊиК ĐŗĐĩĐžĐēОдиĐŊĐŗ)", - "map_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ĐŧаĐŋи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ” СОвĐŊŅ–ŅˆĐŊŅ–Đš ҁĐĩŅ€Đ˛Ņ–Ņ ĐŋĐģĐ¸Ņ‚ĐžĐē (tiles.immich.cloud)", + "map_gps_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧаĐŋи Ņ‚Đ° GPS", + "map_gps_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐŧаĐŋи Ņ‚Đ° GPS (ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊĐĩ ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ)", + "map_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ĐŧаĐŋи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ” СОвĐŊŅ–ŅˆĐŊŅŽ ҁĐģ҃ĐļĐąŅƒ Ņ‚Đ°ĐšĐģŅ–Đ˛ (tiles.immich.cloud)", "map_light_style": "ĐĄĐ˛Ņ–Ņ‚ĐģиК ŅŅ‚Đ¸ĐģҌ", - "map_manage_reverse_geocoding_settings": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊĐžĐŗĐž ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", + "map_manage_reverse_geocoding_settings": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊĐžĐŗĐž ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "map_reverse_geocoding": "Đ—Đ˛ĐžŅ€ĐžŅ‚ĐŊĐĩ ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "map_reverse_geocoding_enable_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊĐĩ ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "map_reverse_geocoding_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊĐžĐŗĐž ĐŗĐĩĐžĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", @@ -222,23 +222,23 @@ "map_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐŧаĐŋи", "map_style_description": "URL Đ´Đž Ņ‚ĐĩĐŧи ĐŧаĐŋи ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– style.json", "memory_cleanup_job": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", - "memory_generate_job": "ГĐĩĐŊĐĩŅ€Đ°Ņ†Ņ–Ņ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", - "metadata_extraction_job": "Đ’Đ¸Ņ‚ŅĐŗĐŊŅƒŅ‚Đ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊŅ–", - "metadata_extraction_job_description": "Đ’Đ¸Đ´ĐžĐąŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…: ĐŗĐĩОдаĐŊŅ–, Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ Ņ‚Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", + "memory_generate_job": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", + "metadata_extraction_job": "Đ’Đ¸Đ´ĐžĐąŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…", + "metadata_extraction_job_description": "Đ’Đ¸Đ´ĐžĐąŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ… С ĐēĐžĐļĐŊĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°, СОĐēŅ€ĐĩĐŧа: GPS-ĐēĐžĐžŅ€Đ´Đ¸ĐŊĐ°Ņ‚Đ¸, ОйĐģĐ¸Ņ‡Ņ‡Ņ Ņ‚Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", "metadata_faces_import_setting": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ–ĐŧĐŋĐžŅ€Ņ‚ ОйĐģĐ¸Ņ‡", - "metadata_faces_import_setting_description": "ІĐŧĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ С EXIF-даĐŊĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Ņ‚Đ° sidecar-Ņ„Đ°ĐšĐģŅ–Đ˛", + "metadata_faces_import_setting_description": "ІĐŧĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ С Exif-даĐŊĐ¸Ņ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ Ņ‚Đ° sidecar-Ņ„Đ°ĐšĐģŅ–Đ˛", "metadata_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…", "metadata_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…", "migration_job": "ĐœŅ–ĐŗŅ€Đ°Ņ†Ņ–Ņ", - "migration_job_description": "ПĐĩŅ€ĐĩĐŊĐĩҁĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€ Ņ„Đ°ĐšĐģŅ–Đ˛ Ņ‚Đ° ОйĐģĐ¸Ņ‡ŅŒ Đ´Đž ĐžĐŊОвĐģĐĩĐŊĐžŅ— ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ¸ ĐŋаĐŋĐžĐē", - "nightly_tasks_cluster_faces_setting_description": "ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡ ĐŊа Ņ‰ĐžĐšĐŊĐž Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐ¸Ņ… ОйĐģĐ¸Ņ‡Ņ‡ŅŅ…", + "migration_job_description": "ПĐĩŅ€ĐĩĐŊĐĩҁĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Ņ‚Đ° ОйĐģĐ¸Ņ‡ Đ´Đž ĐžĐŊОвĐģĐĩĐŊĐžŅ— ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ¸ ĐŋаĐŋĐžĐē", + "nightly_tasks_cluster_faces_setting_description": "ВиĐēĐžĐŊаĐŊĐŊŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ ОйĐģĐ¸Ņ‡ Đ´ĐģŅ ĐŊĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐ¸Ņ… ОйĐģĐ¸Ņ‡", "nightly_tasks_cluster_new_faces_setting": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– ОйĐģĐ¸Ņ‡Ņ‡Ņ", "nightly_tasks_database_cleanup_setting": "ЗавдаĐŊĐŊŅ С ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ йаСи даĐŊĐ¸Ņ…", "nightly_tasks_database_cleanup_setting_description": "ВидаĐģĐĩĐŊĐŊŅ ŅŅ‚Đ°Ņ€Đ¸Ņ… Ņ– ĐŋŅ€ĐžŅŅ‚Ņ€ĐžŅ‡ĐĩĐŊĐ¸Ņ… даĐŊĐ¸Ņ… Ņ–Đˇ йаСи даĐŊĐ¸Ņ…", - "nightly_tasks_generate_memories_setting": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", - "nightly_tasks_generate_memories_setting_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– ҁĐŋĐžĐŗĐ°Đ´Đ¸ С ĐŊĐ°ŅĐ˛ĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Ņ‰ĐžĐŊĐžŅ‡Ņ–", + "nightly_tasks_generate_memories_setting": "ĐĄŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", + "nightly_tasks_generate_memories_setting_description": "ĐĄŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– ҁĐŋĐžĐŗĐ°Đ´Đ¸ С ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "nightly_tasks_missing_thumbnails_setting": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸", - "nightly_tasks_missing_thumbnails_setting_description": "ЧĐĩŅ€ĐŗĐ° Đ´ĐģŅ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€ Đ´ĐģŅ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐąĐĩС ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€", + "nightly_tasks_missing_thumbnails_setting_description": "ĐŸĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚Đ¸ в ҇ĐĩŅ€ĐŗŅƒ ĐŊа ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ŅĐēŅ– Ņ—Ņ… ĐŊĐĩ ĐŧĐ°ŅŽŅ‚ŅŒ", "nightly_tasks_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊҖ҇ĐŊĐ¸Ņ… СавдаĐŊҌ", "nightly_tasks_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊҖ҇ĐŊиĐŧи СавдаĐŊĐŊŅĐŧи", "nightly_tasks_start_time_setting": "Đ§Đ°Ņ ĐŋĐžŅ‡Đ°Ņ‚Đē҃", @@ -247,33 +247,33 @@ "nightly_tasks_sync_quota_usage_setting_description": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐ˛ĐžŅ‚Ņƒ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа ĐžŅĐŊĐžĐ˛Ņ– ĐŋĐžŅ‚ĐžŅ‡ĐŊĐžĐŗĐž виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ", "no_paths_added": "ШĐģŅŅ…Đ¸ ĐŊĐĩ дОдаĐŊĐž", "no_pattern_added": "ШайĐģĐžĐŊ ĐŊĐĩ дОдаĐŊĐž", - "note_apply_storage_label_previous_assets": "ĐŸŅ€Đ¸ĐŧŅ–Ņ‚Đēа: ЊОй ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧŅ–Ņ‚Đē҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛, СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸", + "note_apply_storage_label_previous_assets": "ĐŸŅ€Đ¸ĐŧŅ–Ņ‚Đēа: ЊОй ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧŅ–Ņ‚Đē҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛, виĐēĐžĐŊĐ°ĐšŅ‚Đĩ", "note_cannot_be_changed_later": "ПРИМІĐĸКА: ĐĻĐĩ ĐŊĐĩ ĐŧĐžĐļĐŊа СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ!", - "notification_email_from_address": "ĐĐ´Ņ€ĐĩŅĐ° ĐŊĐ°Đ´ŅĐ¸ĐģĐ°Ņ‡Đ°", - "notification_email_from_address_description": "ĐĐ´Ņ€ĐĩŅĐ° ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅ— ĐŋĐžŅˆŅ‚Đ¸ ĐŊĐ°Đ´ŅĐ¸ĐģĐ°Ņ‡Đ°, ĐŊаĐŋŅ€Đ¸ĐēĐģад: \"Immich Photo Server \". ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ Đ°Đ´Ņ€Đĩҁ҃, С ŅĐēĐžŅ— ваĐŧ дОСвОĐģĐĩĐŊĐž ĐŊĐ°Đ´ŅĐ¸ĐģĐ°Ņ‚Đ¸ ĐģĐ¸ŅŅ‚Đ¸.", + "notification_email_from_address": "ĐĐ´Ņ€ĐĩŅĐ° Đ˛Ņ–Đ´ĐŋŅ€Đ°Đ˛ĐŊиĐēа", + "notification_email_from_address_description": "ĐĐ´Ņ€ĐĩŅĐ° ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅ— ĐŋĐžŅˆŅ‚Đ¸ Đ˛Ņ–Đ´ĐŋŅ€Đ°Đ˛ĐŊиĐēа, ĐŊаĐŋŅ€Đ¸ĐēĐģад: \"Immich Photo Server \". ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ Đ°Đ´Ņ€Đĩҁ҃, С ŅĐēĐžŅ— ваĐŧ дОСвОĐģĐĩĐŊĐž ĐŊĐ°Đ´ŅĐ¸ĐģĐ°Ņ‚Đ¸ ĐģĐ¸ŅŅ‚Đ¸.", "notification_email_host_description": "ĐĐ´Ņ€ĐĩŅĐ° ĐŋĐžŅˆŅ‚ĐžĐ˛ĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° (ĐŊаĐŋŅ€Đ¸ĐēĐģад, smtp.immich.app)", "notification_email_ignore_certificate_errors": "Đ†ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžĐŧиĐģĐēи ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ°", "notification_email_ignore_certificate_errors_description": "Đ†ĐŗĐŊĐžŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžĐŧиĐģĐēи ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Ņ–Đ˛ TLS (ĐŊĐĩ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒŅ”Ņ‚ŅŒŅŅ)", - "notification_email_password_description": "ĐŸĐ°Ņ€ĐžĐģҌ Đ´ĐģŅ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ— ĐŊа ĐŋĐžŅˆŅ‚ĐžĐ˛ĐžĐŧ҃ ҁĐĩŅ€Đ˛ĐĩҀҖ", + "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": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´ĐģŅ ĐŊĐ°Đ´ŅĐ¸ĐģаĐŊĐŊŅ email-ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊҌ", + "notification_email_setting_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊĐ°Đ´ŅĐ¸ĐģаĐŊĐŊŅ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ", "notification_email_test_email": "ĐĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ Ņ‚ĐĩŅŅ‚ĐžĐ˛Đ¸Đš ĐģĐ¸ŅŅ‚", - "notification_email_test_email_failed": "НĐĩ вдаĐģĐžŅŅ ĐŊĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ Ņ‚ĐĩŅŅ‚ĐžĐ˛Đ¸Đš ĐģĐ¸ŅŅ‚. ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ Đ˛Đ°ŅˆŅ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ", - "notification_email_test_email_sent": "ĐĸĐĩŅŅ‚ĐžĐ˛Đ¸Đš ĐģĐ¸ŅŅ‚ ĐąŅƒĐģĐž ĐŊĐ°Đ´Ņ–ŅĐģаĐŊĐž ĐŊа {email}. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ŅĐ˛ĐžŅŽ ҁĐēŅ€Đ¸ĐŊҌĐē҃ Đ˛Ņ…Ņ–Đ´ĐŊĐ¸Ņ….", + "notification_email_test_email_failed": "НĐĩ вдаĐģĐžŅŅ ĐŊĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ Ņ‚ĐĩŅŅ‚ĐžĐ˛Đ¸Đš ĐģĐ¸ŅŅ‚. ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ввĐĩĐ´ĐĩĐŊŅ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ", + "notification_email_test_email_sent": "ĐĸĐĩŅŅ‚ĐžĐ˛Đ¸Đš ĐģĐ¸ŅŅ‚ ĐąŅƒĐģĐž ĐŊĐ°Đ´Ņ–ŅĐģаĐŊĐž ĐŊа {email}. ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ Đ˛Ņ…Ņ–Đ´ĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ.", "notification_email_username_description": "ІĐŧ'Ņ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Đ´ĐģŅ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ— ĐŊа ĐŋĐžŅˆŅ‚ĐžĐ˛ĐžĐŧ҃ ҁĐĩŅ€Đ˛ĐĩҀҖ", "notification_enable_email_notifications": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ", "notification_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ", - "notification_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ, вĐēĐģŅŽŅ‡ĐŊĐž Ņ–Đˇ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ", + "notification_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ, вĐēĐģŅŽŅ‡ĐŊĐž С ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ", "oauth_auto_launch": "ĐĐ˛Ņ‚ĐžĐˇĐ°Đŋ҃ҁĐē", - "oauth_auto_launch_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž СаĐŋ҃ҁĐēĐ°Ņ‚Đ¸ ĐŋŅ€ĐžŅ†Đĩҁ Đ˛Ņ…ĐžĐ´Ņƒ ҇ĐĩŅ€ĐĩС OAuth ĐŋŅ€Đ¸ ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´Ņ– ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃ Đ˛Ņ…ĐžĐ´Ņƒ", + "oauth_auto_launch_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Ņ€ĐžĐˇĐŋĐžŅ‡Đ¸ĐŊĐ°Ņ‚Đ¸ Đ˛Ņ…Ņ–Đ´ ҇ĐĩŅ€ĐĩС OAuth ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´Ņƒ ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃ Đ˛Ņ…ĐžĐ´Ņƒ", "oauth_auto_register": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊа Ņ€ĐĩŅ”ŅŅ‚Ņ€Đ°Ņ†Ņ–Ņ", "oauth_auto_register_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Ņ€ĐĩŅ”ŅŅ‚Ņ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Đ¸Ņ… ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ ĐŋҖҁĐģŅ Đ˛Ņ…ĐžĐ´Ņƒ ҇ĐĩŅ€ĐĩС OAuth", "oauth_button_text": "ĐĸĐĩĐēҁ҂ ĐēĐŊĐžĐŋĐēи", "oauth_client_secret_description": "Обов'ŅĐˇĐēОвО Đ´ĐģŅ ĐēĐžĐŊŅ„Ņ–Đ´ĐĩĐŊŅ†Ņ–ĐšĐŊĐžĐŗĐž ĐēĐģŅ–Ņ”ĐŊŅ‚Đ° айО ŅĐēŅ‰Đž PKCE (ĐēĐģŅŽŅ‡ ĐŋŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´ĐļĐĩĐŊĐŊŅ Đ´ĐģŅ ОйĐŧŅ–ĐŊ҃ ĐēОдОĐŧ) ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐŋŅƒĐąĐģҖ҇ĐŊĐžĐŗĐž ĐēĐģŅ–Ņ”ĐŊŅ‚Đ°.", - "oauth_enable_description": "ĐŖĐ˛Ņ–ĐšŅ‚Đ¸ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ OAuth", + "oauth_enable_description": "Đ’Ņ…Ņ–Đ´ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ OAuth", "oauth_mobile_redirect_uri": "URI ĐŧĐžĐąŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊŅ", "oauth_mobile_redirect_uri_override": "ПĐĩŅ€ĐĩвиСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ URI ĐŧĐžĐąŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊŅ", "oauth_mobile_redirect_uri_override_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸, ŅĐēŅ‰Đž OAuth-ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ” ĐŧĐžĐąŅ–ĐģҌĐŊиК URI, ŅĐē ''{callback}''", @@ -281,31 +281,31 @@ "oauth_role_claim_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐŊĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋŅ€Đ°Đ˛Đ° адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ° ĐŊа ĐžŅĐŊĐžĐ˛Ņ– ĐŊĐ°ŅĐ˛ĐŊĐžŅŅ‚Ņ– Ņ†ŅŒĐžĐŗĐž Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Ņƒ. ĐĻĐĩĐš Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ ĐŧĐžĐļĐĩ ĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ‘user’ айО ‘admin’.", "oauth_settings": "OAuth", "oauth_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи Đ˛Ņ…ĐžĐ´Ņƒ ҇ĐĩŅ€ĐĩС OAuth", - "oauth_settings_more_details": "ДĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛ĐžŅ— Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ— ĐŋŅ€Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ, СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", - "oauth_storage_label_claim": "ĐĸĐĩĐŗ ĐŋаĐŋĐēи ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", - "oauth_storage_label_claim_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Đ˛ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧŅ–Ņ‚Đē҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ҆ҖҔҗ виĐŧĐžĐŗĐ¸.", - "oauth_storage_quota_claim": "Đ—Đ°ŅĐ˛Đēа ĐŊа ĐēĐ˛ĐžŅ‚Ņƒ ĐŊа СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ", - "oauth_storage_quota_claim_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Đ˛ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐ˛ĐžŅ‚Ņƒ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ҆ҖҔҗ виĐŧĐžĐŗĐ¸.", - "oauth_storage_quota_default": "ĐšĐ˛ĐžŅ‚Đ° Са СаĐŧĐžĐ˛Ņ‡ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ (GiB)", - "oauth_storage_quota_default_description": "ĐšĐ˛ĐžŅ‚Đ° в GiB, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ, ĐēĐžĐģи ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊĐĩ ĐŊадаĐŊĐž.", + "oauth_settings_more_details": "ЊОй Đ´Ņ–ĐˇĐŊĐ°Ņ‚Đ¸ŅŅ ĐąŅ–ĐģҌ҈Đĩ ĐŋŅ€Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ, СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", + "oauth_storage_label_claim": "ĐŅ‚Ņ€Đ¸ĐąŅƒŅ‚ ĐŧŅ–Ņ‚Đēи СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ", + "oauth_storage_label_claim_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧŅ–Ņ‚Đē҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Ņƒ.", + "oauth_storage_quota_claim": "ĐŅ‚Ņ€Đ¸ĐąŅƒŅ‚ ĐēĐ˛ĐžŅ‚Đ¸ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", + "oauth_storage_quota_claim_description": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐ˛ĐžŅ‚Ņƒ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Ņƒ.", + "oauth_storage_quota_default": "ĐĸиĐŋОва ĐēĐ˛ĐžŅ‚Đ° ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° (GiB)", + "oauth_storage_quota_default_description": "ĐšĐ˛ĐžŅ‚Đ° в GiB, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ, ĐēĐžĐģи Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ ĐŊĐĩ ĐŊадаĐŊĐž.", "oauth_timeout": "ĐĸаКĐŧ-Đ°ŅƒŅ‚ Đ´ĐģŅ СаĐŋĐ¸Ņ‚Ņ–Đ˛", "oauth_timeout_description": "МаĐēŅĐ¸ĐŧаĐģҌĐŊиК Ņ‡Đ°Ņ ĐžŅ‡Ņ–ĐēŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Ņ– в ĐŧŅ–ĐģҖҁĐĩĐē҃ĐŊĐ´Đ°Ņ…", - "ocr_job_description": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐĩ ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ Đ´ĐģŅ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ…", - "password_enable_description": "ĐŖĐ˛Ņ–ĐšŅ‚Đ¸ Са ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ Ņ‚Đ° ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ", - "password_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ…ĐžĐ´Ņƒ С ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ", + "ocr_job_description": "РОСĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ ĐŊа ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ", + "password_enable_description": "Đ’Ņ…Ņ–Đ´ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅ— ĐŋĐžŅˆŅ‚Đ¸ Ņ‚Đ° ĐŋĐ°Ņ€ĐžĐģŅ", + "password_settings": "Đ’Ņ…Ņ–Đ´ Са ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ", "password_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи Đ˛Ņ…ĐžĐ´Ņƒ Са ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ", - "paths_validated_successfully": "ĐŖŅŅ– ҈ĐģŅŅ…Đ¸ ҃ҁĐŋŅ–ŅˆĐŊĐž ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€ĐĩĐŊĐž", - "person_cleanup_job": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ ĐžŅĐžĐąĐ¸", + "paths_validated_successfully": "ĐŖŅŅ– ҈ĐģŅŅ…Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€ĐĩĐŊĐž", + "person_cleanup_job": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ даĐŊĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš", "queue_details": "ДĐĩŅ‚Đ°ĐģŅ– ҇ĐĩŅ€ĐŗĐ¸", "queues": "ЧĐĩŅ€ĐŗĐ¸ СавдаĐŊҌ", "queues_page_description": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа ҇ĐĩŅ€Đŗ СавдаĐŊҌ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", "quota_size_gib": "РОСĐŧŅ–Ņ€ ĐēĐ˛ĐžŅ‚Đ¸ (GiB)", "refreshing_all_libraries": "ОĐŊОвĐģĐĩĐŊĐŊŅ Đ˛ŅŅ–Ņ… ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē", "registration": "Đ ĐĩŅ”ŅŅ‚Ņ€Đ°Ņ†Ņ–Ņ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", - "registration_description": "ĐžŅĐēŅ–ĐģҌĐēи ви ĐŋĐĩŅ€ŅˆĐ¸Đš ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ в ŅĐ¸ŅŅ‚ĐĩĐŧŅ–, ви ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊŅ– АдĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€ĐžĐŧ Ņ– Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°Ņ‚Đ¸ĐŧĐĩŅ‚Đĩ Са адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚Đ¸Đ˛ĐŊŅ– СавдаĐŊĐŊŅ, а Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Ņ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ– ĐąŅƒĐ´ŅƒŅ‚ŅŒ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊŅ– ваĐŧи.", + "registration_description": "ĐžŅĐēŅ–ĐģҌĐēи ви ĐŋĐĩŅ€ŅˆĐ¸Đš ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧŅ–, Đ˛Đ°Ņ ĐąŅƒĐ´Đĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€ĐžĐŧ Ņ– ви Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°Ņ‚Đ¸ĐŧĐĩŅ‚Đĩ Са адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚Đ¸Đ˛ĐŊŅ– СавдаĐŊĐŊŅ, а Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ĐŧĐĩŅ‚Đĩ ви.", "remove_failed_jobs": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐŊĐĩвдаĐģŅ– СавдаĐŊĐŊŅ", - "require_password_change_on_login": "ВиĐŧĐ°ĐŗĐ°Ņ‚Đ¸ СĐŧŅ–ĐŊи ĐŋĐ°Ņ€ĐžĐģŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŋŅ€Đ¸ ĐŋĐĩŅ€ŅˆĐžĐŧ҃ Đ˛Ņ…ĐžĐ´Ņ–", - "reset_settings_to_default": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´Đž ĐŋĐžŅ‡Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… СĐŊĐ°Ņ‡ĐĩĐŊҌ", + "require_password_change_on_login": "Зобов'ŅĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ŅˆĐžĐŗĐž Đ˛Ņ…ĐžĐ´Ņƒ", + "reset_settings_to_default": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´Đž Ņ‚Đ¸ĐŋĐžĐ˛Đ¸Ņ…", "reset_settings_to_recent_saved": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´Đž ĐŊĐĩдавĐŊĐž СйĐĩŅ€ĐĩĐļĐĩĐŊĐ¸Ņ… ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ", "scanning_library": "ĐĄĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "search_jobs": "ĐŸĐžŅˆŅƒĐē СавдаĐŊҌâ€Ļ", @@ -321,130 +321,130 @@ "server_welcome_message_description": "ĐŸĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊĐŊŅ, ŅĐēĐĩ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐ°Ņ”Ņ‚ŅŒŅŅ ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊ҆Җ Đ˛Ņ…ĐžĐ´Ņƒ.", "settings_page_description": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", "sidecar_job": "МĐĩŅ‚Đ°Đ´Đ°ĐŊŅ– С sidecar-Ņ„Đ°ĐšĐģŅ–Đ˛", - "sidecar_job_description": "ĐŸĐžŅˆŅƒĐē айО ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ ŅĐ°ĐšĐ´ĐēĐ°Ņ€-ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ… С Ņ„Đ°ĐšĐģĐžĐ˛ĐžŅ— ŅĐ¸ŅŅ‚ĐĩĐŧи", + "sidecar_job_description": "ĐŸĐžŅˆŅƒĐē айО ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ sidecar-ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ… С Ņ„Đ°ĐšĐģĐžĐ˛ĐžŅ— ŅĐ¸ŅŅ‚ĐĩĐŧи", "slideshow_duration_description": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ҁĐĩĐē҃ĐŊĐ´ Đ´ĐģŅ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐēĐžĐļĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "smart_search_job_description": "РОСĐŋŅ–ĐˇĐŊĐ°Ņ” вĐŧҖҁ҂ Ņ„Đ°ĐšĐģŅ–Đ˛ Đ´ĐģŅ Ņ€ĐžĐˇŅƒĐŧĐŊĐžĐŗĐž ĐŋĐžŅˆŅƒĐē҃", - "storage_template_date_time_description": "Đ”Đ°Ņ‚ĐžŅŽ Ņ‚Đ° Ņ‡Đ°ŅĐžĐŧ Ņ” ĐŋОСĐŊĐ°Ņ‡Đēа Ņ‡Đ°ŅŅƒ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ Ņ„Đ°ĐšĐģ҃", - "storage_template_date_time_sample": "Đ§Đ°Ņ Đ˛Đ¸ĐąŅ–Ņ€Đēи {date}", - "storage_template_enable_description": "Đ’Đ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŧĐĩŅ…Đ°ĐŊŅ–ĐˇĐŧ ŅˆĐ°ĐąĐģĐžĐŊŅ–Đ˛ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", + "smart_search_job_description": "ВиĐēĐžĐŊаĐŊĐŊŅ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐŊĐ°Đ˛Ņ‡Đ°ĐŊĐŊŅ ĐŊа ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Ņ… Ņ‰ĐžĐą ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐē", + "storage_template_date_time_description": "ДĐģŅ виСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ Đ´Đ°Ņ‚Đ¸ Ņ– Ņ‡Đ°ŅŅƒ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐŧŅ–Ņ‚Đēа Ņ‡Đ°ŅŅƒ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "storage_template_date_time_sample": "ĐŸŅ€Đ¸ĐēĐģад Ņ‡Đ°ŅŅƒ {date}", + "storage_template_enable_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŧĐĩŅ…Đ°ĐŊŅ–ĐˇĐŧ ŅˆĐ°ĐąĐģĐžĐŊŅ–Đ˛ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", "storage_template_hash_verification_enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ Ņ…Đĩ҈҃", - "storage_template_hash_verification_enabled_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ Ņ…ĐĩŅˆĐ°. НĐĩ виĐŧиĐēĐ°ĐšŅ‚Đĩ ҆Đĩ, ŅĐēŅ‰Đž ви ĐŊĐĩ вĐŋĐĩвĐŊĐĩĐŊŅ– в ĐŊĐ°ŅĐģŅ–Đ´ĐēĐ°Ņ…", + "storage_template_hash_verification_enabled_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ Ņ…Đĩ҈҃. НĐĩ виĐŧиĐēĐ°ĐšŅ‚Đĩ ҆Đĩ, ŅĐēŅ‰Đž ви ĐŊĐĩ вĐŋĐĩвĐŊĐĩĐŊŅ– в ĐŊĐ°ŅĐģŅ–Đ´ĐēĐ°Ņ…", "storage_template_migration": "ĐœŅ–ĐŗŅ€Đ°Ņ†Ņ–Ņ ŅˆĐ°ĐąĐģĐžĐŊŅ–Đ˛ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", - "storage_template_migration_description": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊиК {template} Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "storage_template_migration_info": "ШайĐģĐžĐŊ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ ĐēĐžĐŊвĐĩŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧĐĩ Đ˛ŅŅ– Ņ€ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊĐŊŅ ҃ ĐŊиĐļĐŊŅ–Đš Ņ€ĐĩĐŗŅ–ŅŅ‚Ņ€. ЗĐŧŅ–ĐŊи ŅˆĐ°ĐąĐģĐžĐŊ҃ ĐˇĐ°ŅŅ‚ĐžŅĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´Đž ĐŊĐžĐ˛Đ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛. ЊОй ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛, СаĐŋŅƒŅŅ‚Ņ–Ņ‚ŅŒ {job}.", - "storage_template_migration_job": "ЗавдаĐŊĐŊŅ ĐŧŅ–ĐŗŅ€Đ°Ņ†Ņ–Ņ— ŅˆĐ°ĐąĐģĐžĐŊ҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ", - "storage_template_more_details": "ДĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ Đ´ĐĩŅ‚Đ°ĐģҌĐŊŅ–ŅˆĐžŅ— Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ— ĐŋŅ€Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ, СвĐĩŅ€Ņ‚Đ°ĐšŅ‚ĐĩҁҌ Đ´Đž ШайĐģĐžĐŊ҃ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ Ņ‚Đ° ĐšĐžĐŗĐž ĐŊĐ°ŅĐģŅ–Đ´ĐēŅ–Đ˛", - "storage_template_onboarding_description_v2": "Đ¯ĐēŅ‰Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž, Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž вĐŋĐžŅ€ŅĐ´ĐēĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ Са ŅˆĐ°ĐąĐģĐžĐŊĐžĐŧ, виСĐŊĐ°Ņ‡ĐĩĐŊиĐŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐŧ. ДоĐēĐģадĐŊŅ–ŅˆĐĩ Đ´Đ¸Đ˛Ņ–Ņ‚ŅŒŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", + "storage_template_migration_description": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊиК {template} Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", + "storage_template_migration_info": "ШайĐģĐžĐŊ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° ĐŋĐĩŅ€ĐĩŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ĐŧĐĩ Đ˛ŅŅ– Ņ€ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊĐŊŅ ĐŊа ĐŊиĐļĐŊŅ–Đš Ņ€ĐĩĐŗŅ–ŅŅ‚Ņ€. ЗĐŧŅ–ĐŊи ŅˆĐ°ĐąĐģĐžĐŊ҃ ĐˇĐ°ŅŅ‚ĐžŅĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´Đž ĐŊĐžĐ˛Đ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛. ЊОй ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ Đ´Đž Ņ€Đ°ĐŊŅ–ŅˆĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛, виĐēĐžĐŊĐ°ĐšŅ‚Đĩ {job}.", + "storage_template_migration_job": "ЗавдаĐŊĐŊŅ ĐŧŅ–ĐŗŅ€Đ°Ņ†Ņ–Ņ— ŅˆĐ°ĐąĐģĐžĐŊ҃ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", + "storage_template_more_details": "ЊОй Đ´Ņ–ĐˇĐŊĐ°Ņ‚Đ¸ŅŅ ĐąŅ–ĐģҌ҈Đĩ ĐŋŅ€Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ, СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž ШайĐģĐžĐŊ҃ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° Ņ‚Đ° ĐšĐžĐŗĐž ĐŊĐ°ŅĐģŅ–Đ´ĐēŅ–Đ˛", + "storage_template_onboarding_description_v2": "Đ¯ĐēŅ‰Đž Ņ†ŅŽ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅŽ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž, Ņ„Đ°ĐšĐģи Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž вĐŋĐžŅ€ŅĐ´ĐēĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Са ŅˆĐ°ĐąĐģĐžĐŊĐžĐŧ, виСĐŊĐ°Ņ‡ĐĩĐŊиĐŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐŧ. ДоĐēĐģадĐŊŅ–ŅˆĐĩ Đ´Đ¸Đ˛Ņ–Ņ‚ŅŒŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", "storage_template_path_length": "ĐŸŅ€Đ¸ĐąĐģиСĐŊа ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊа дОвĐļиĐŊа ҈ĐģŅŅ…Ņƒ: {length, number}/{limit, number}", "storage_template_settings": "ШайĐģĐžĐŊ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", - "storage_template_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€ĐžŅŽ ĐŋаĐŋĐžĐē Ņ‚Đ° Ņ–ĐŧĐĩĐŊаĐŧи виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "storage_template_user_label": "{label} - ҆Đĩ ĐŧŅ–Ņ‚Đēа СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "storage_template_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€ĐžŅŽ ĐŋаĐŋĐžĐē Ņ‚Đ° ĐŊаСваĐŧи Ņ„Đ°ĐšĐģŅ–Đ˛ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", + "storage_template_user_label": "{label} — ҆Đĩ ĐŧŅ–Ņ‚Đēа ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "system_settings": "ĐĄĐ¸ŅŅ‚ĐĩĐŧĐŊŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", "tag_cleanup_job": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ Ņ‚ĐĩĐŗŅ–Đ˛", - "template_email_available_tags": "Ви ĐŧĐžĐļĐĩŅ‚Đĩ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊŅ– СĐŧŅ–ĐŊĐŊŅ– ҃ ŅĐ˛ĐžŅ”Đŧ҃ ŅˆĐ°ĐąĐģĐžĐŊŅ–: {tags}", - "template_email_if_empty": "Đ¯ĐēŅ‰Đž ŅˆĐ°ĐąĐģĐžĐŊ ĐŋĐžŅ€ĐžĐļĐŊŅ–Đš, ĐąŅƒĐ´Đĩ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊиК ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊиК ĐģĐ¸ŅŅ‚.", + "template_email_available_tags": "Ви ĐŧĐžĐļĐĩŅ‚Đĩ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ‚Đ°ĐēŅ– СĐŧŅ–ĐŊĐŊŅ– ҃ ŅĐ˛ĐžŅ”Đŧ҃ ŅˆĐ°ĐąĐģĐžĐŊŅ–: {tags}", + "template_email_if_empty": "Đ¯ĐēŅ‰Đž ŅˆĐ°ĐąĐģĐžĐŊ ĐŋĐžŅ€ĐžĐļĐŊŅ–Đš, ĐąŅƒĐ´Đĩ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐž Ņ‚Đ¸ĐŋОвиК ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊиК ĐģĐ¸ŅŅ‚.", "template_email_invite_album": "ШайĐģĐžĐŊ СаĐŋŅ€ĐžŅˆĐĩĐŊĐŊŅ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "template_email_preview": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´", + "template_email_preview": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´", "template_email_settings": "ШайĐģĐžĐŊи ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐ¸Ņ… ĐģĐ¸ŅŅ‚Ņ–Đ˛", - "template_email_update_album": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ аĐģŅŒĐąĐžĐŧ҃", + "template_email_update_album": "ШайĐģĐžĐŊ ĐžĐŊОвĐģĐĩĐŊĐŊŅ аĐģŅŒĐąĐžĐŧ҃", "template_email_welcome": "ШайĐģĐžĐŊ Đ˛Ņ–Ņ‚Đ°ĐģҌĐŊĐžĐŗĐž ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐģĐ¸ŅŅ‚Đ°", - "template_settings": "ШайĐģĐžĐŊи ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊҌ", - "template_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊаĐŧи Đ´ĐģŅ ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊҌ", - "theme_custom_css_settings": "ВĐģĐ°ŅĐŊиК CSS", - "theme_custom_css_settings_description": "ĐšĐ°ŅĐēадĐŊŅ– Ņ‚Đ°ĐąĐģĐ¸Ņ†Ņ– ŅŅ‚Đ¸ĐģŅ–Đ˛ дОСвОĐģŅŅŽŅ‚ŅŒ ĐŊĐ°ŅŅ‚Ņ€ĐžŅŽĐ˛Đ°Ņ‚Đ¸ диСаКĐŊ Immich.", - "theme_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ‚ĐĩĐŧи", - "theme_settings_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐĩŅ€ŅĐžĐŊаĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ— вĐĩĐą-Ņ–ĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅƒ Immich", + "template_settings": "ШайĐģĐžĐŊи ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ", + "template_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´ĐžĐ˛Ņ–ĐģҌĐŊиĐŧи ŅˆĐ°ĐąĐģĐžĐŊаĐŧи Đ´ĐģŅ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊҌ", + "theme_custom_css_settings": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊиК CSS", + "theme_custom_css_settings_description": "ĐšĐ°ŅĐēадĐŊŅ– Ņ‚Đ°ĐąĐģĐ¸Ņ†Ņ– ŅŅ‚Đ¸ĐģŅ–Đ˛ Đ´Đ°ŅŽŅ‚ŅŒ СĐŧĐžĐŗŅƒ ĐŊаĐģĐ°ŅˆŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ диСаКĐŊ Immich.", + "theme_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ‚ĐĩĐŧи ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ", + "theme_settings_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ¸ĐŗĐģŅĐ´Ņƒ вĐĩĐą-Ņ–ĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅƒ Immich", "thumbnail_generation_job": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€", - "thumbnail_generation_job_description": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ вĐĩĐģиĐēŅ–, ĐŧаĐģŅ– Ņ‚Đ° Ņ€ĐžĐˇĐŧĐ¸Ņ‚Ņ– ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ´ĐģŅ ĐēĐžĐļĐŊĐžĐŗĐž Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, а Ņ‚Đ°ĐēĐžĐļ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ´ĐģŅ ĐēĐžĐļĐŊĐžŅ— ĐžŅĐžĐąĐ¸", + "thumbnail_generation_job_description": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ вĐĩĐģиĐēŅ–, ĐŧаĐģŅ– Ņ‚Đ° Ņ€ĐžĐˇĐŧĐ¸Ņ‚Ņ– ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ´ĐģŅ ĐēĐžĐļĐŊĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°, а Ņ‚Đ°ĐēĐžĐļ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ´ĐģŅ ĐēĐžĐļĐŊĐžŅ— ĐģŅŽĐ´Đ¸ĐŊи", "transcoding_acceleration_api": "API ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ", - "transcoding_acceleration_api_description": "API, ŅĐēа ĐąŅƒĐ´Đĩ Đ˛ĐˇĐ°Ņ”ĐŧĐžĐ´Ņ–ŅŅ‚Đ¸ С Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ”Đŧ Đ´ĐģŅ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ĐĻĐĩ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋŅ€Đ°Ņ†ŅŽŅ” ҃ \"ĐŊаКĐēŅ€Đ°Ņ‰Đ¸Ņ… ҃ĐŧĐžĐ˛Đ°Ņ…\" Ņ–, в Ņ€Đ°ĐˇŅ– ĐŊĐĩĐ˛Đ´Đ°Ņ‡Ņ–, ĐŋĐĩŅ€ĐĩКдĐĩ ĐŊа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊĐĩ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēа VP9 ĐŧĐžĐļĐĩ айО ĐŊĐĩ ĐŧĐžĐļĐĩ ĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸, СаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ Đ˛Đ°ŅˆĐžĐŗĐž ОйĐģадĐŊаĐŊĐŊŅ.", - "transcoding_acceleration_nvenc": "NVENC (виĐŧĐ°ĐŗĐ°Ņ” ĐŗŅ€Đ°Ņ„Ņ–Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€Đ° NVIDIA)", - "transcoding_acceleration_qsv": "ШвидĐēа ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ (ĐŋĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€ Intel 7-ĐŗĐž ĐŋĐžĐēĐžĐģŅ–ĐŊĐŊŅ айО ĐŊĐžĐ˛Ņ–ŅˆĐžŅ— вĐĩҀҁҖҗ)", - "transcoding_acceleration_rkmpp": "RKMPP (҂ҖĐģҌĐēи ĐŊа SOC Rockchip)", + "transcoding_acceleration_api_description": "API, ŅĐēиК ĐąŅƒĐ´Đĩ Đ˛ĐˇĐ°Ņ”ĐŧĐžĐ´Ņ–ŅŅ‚Đ¸ С Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ”Đŧ Đ´ĐģŅ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ĐĻĐĩ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊĐĩ ĐŗĐ°Ņ€Đ°ĐŊŅ‚ŅƒŅ” Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚: ҃ Ņ€Đ°ĐˇŅ– ĐŊĐĩĐ˛Đ´Đ°Ņ‡Ņ– ĐąŅƒĐ´Đĩ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊĐĩ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēа VP9 ĐŧĐžĐļĐĩ ĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸ айО ĐŊŅ–, СаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ Đ˛Đ°ŅˆĐžĐŗĐž ОйĐģадĐŊаĐŊĐŊŅ.", + "transcoding_acceleration_nvenc": "NVENC (ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅ” ĐŗŅ€Đ°Ņ„Ņ–Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€Đ° NVIDIA)", + "transcoding_acceleration_qsv": "Intel Quick Sync (ĐŋĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€ Intel 7-ĐŗĐž ĐŋĐžĐēĐžĐģŅ–ĐŊĐŊŅ айО ĐŊĐžĐ˛Ņ–ŅˆĐ¸Đš)", + "transcoding_acceleration_rkmpp": "RKMPP (ĐģĐ¸ŅˆĐĩ ĐŊа SoC Rockchip)", "transcoding_acceleration_vaapi": "VAAPI", "transcoding_accepted_audio_codecs": "ĐŸŅ€Đ¸ĐšĐŊŅŅ‚Ņ– Đ°ŅƒĐ´Ņ–ĐžĐēОдĐĩĐēи", "transcoding_accepted_audio_codecs_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ Đ°ŅƒĐ´Ņ–ĐžĐēОдĐĩĐēи, ŅĐēŅ– ĐŊĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅŽŅ‚ŅŒ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ ĐŋĐĩвĐŊĐ¸Ņ… ĐŋĐžĐģŅ–Ņ‚Đ¸Đē Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", "transcoding_accepted_containers": "ĐŸŅ€Đ¸ĐšĐŊŅŅ‚Ņ– ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ¸", - "transcoding_accepted_containers_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ, ŅĐēŅ– Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Ņ–Đ˛ ĐŊĐĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐŋĐĩŅ€ĐĩŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ в MP4. ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ ĐŋĐĩвĐŊĐ¸Ņ… ĐŋĐžĐģŅ–Ņ‚Đ¸Đē ĐŋĐĩŅ€ĐĩĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", + "transcoding_accepted_containers_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ, ŅĐēŅ– Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Ņ–Đ˛ ĐŊĐĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐŋĐĩŅ€ĐĩĐŋаĐēŅƒĐ˛Đ°Ņ‚Đ¸ в MP4. ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ ĐŋĐĩвĐŊĐ¸Ņ… ĐŋĐžĐģŅ–Ņ‚Đ¸Đē Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", "transcoding_accepted_video_codecs": "ĐŸŅ€Đ¸ĐšĐŊŅŅ‚Ņ– Đ˛Ņ–Đ´ĐĩĐžĐēОдĐĩĐēи", "transcoding_accepted_video_codecs_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ Đ˛Ņ–Đ´ĐĩĐžĐēОдĐĩĐēи, ŅĐēŅ– ĐŊĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅŽŅ‚ŅŒ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ ĐŋĐĩвĐŊĐ¸Ņ… ĐŋĐžĐģŅ–Ņ‚Đ¸Đē Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", "transcoding_advanced_options_description": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸, ŅĐēŅ– ĐąŅ–ĐģŅŒŅˆĐžŅŅ‚Ņ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ ĐŊĐĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž СĐŧŅ–ĐŊŅŽĐ˛Đ°Ņ‚Đ¸", "transcoding_audio_codec": "ĐŅƒĐ´Ņ–ĐžĐēОдĐĩĐē", - "transcoding_audio_codec_description": "Opus - ҆Đĩ ĐžĐŋŅ†Ņ–Ņ ĐŊĐ°ĐšĐ˛Đ¸Ņ‰ĐžŅ— ŅĐēĐžŅŅ‚Ņ–, аĐģĐĩ ĐŧĐĩĐŊ҈Đĩ ҁ҃ĐŧҖҁĐŊа ĐˇŅ– ŅŅ‚Đ°Ņ€Đ¸Đŧи ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи айО ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊиĐŧ СайĐĩСĐŋĐĩ҇ĐĩĐŊĐŊŅĐŧ.", + "transcoding_audio_codec_description": "Opus — Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚ ĐŊĐ°ĐšĐ˛Đ¸Ņ‰ĐžŅ— ŅĐēĐžŅŅ‚Ņ–, аĐģĐĩ ĐŧĐ°Ņ” ĐŊиĐļŅ‡Ņƒ ҁ҃ĐŧҖҁĐŊŅ–ŅŅ‚ŅŒ ĐˇŅ– ŅŅ‚Đ°Ņ€Đ¸Đŧи ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи айО ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧаĐŧи.", "transcoding_bitrate_description": "Đ’Ņ–Đ´ĐĩĐž С ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚ĐžĐŧ Đ˛Đ¸Ņ‰Đĩ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐžĐŗĐž айО ĐŊĐĩ в ĐŋŅ€Đ¸ĐšĐŊŅŅ‚ĐžĐŧ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ–", - "transcoding_codecs_learn_more": "ДĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛ĐžŅ— Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ— ĐŋŅ€Đž Ņ‚ĐĩŅ€ĐŧŅ–ĐŊĐžĐģĐžĐŗŅ–ŅŽ, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Ņ‚ŅƒŅ‚, СвĐĩŅ€Ņ‚Đ°ĐšŅ‚ĐĩŅŅ Đ´Đž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ— FFmpeg Đ´ĐģŅ ĐēОдĐĩĐēŅ–Đ˛ H.264, HEVC Ņ‚Đ° VP9.", + "transcoding_codecs_learn_more": "ЊОй Đ´Ņ–ĐˇĐŊĐ°Ņ‚Đ¸ŅŅ ĐąŅ–ĐģҌ҈Đĩ ĐŋŅ€Đž Ņ‚ĐĩŅ€ĐŧŅ–ĐŊĐžĐģĐžĐŗŅ–ŅŽ, Ņ‰Đž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Ņ‚ŅƒŅ‚, СвĐĩŅ€Ņ‚Đ°ĐšŅ‚ĐĩŅŅ Đ´Đž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ— FFmpeg Đ´ĐģŅ ĐēОдĐĩĐēŅ–Đ˛ H.264, HEVC Ņ‚Đ° VP9.", "transcoding_constant_quality_mode": "Đ ĐĩĐļиĐŧ ĐŋĐžŅŅ‚Ņ–ĐšĐŊĐžŅ— ŅĐēĐžŅŅ‚Ņ–", - "transcoding_constant_quality_mode_description": "ICQ ĐēŅ€Đ°Ņ‰Đĩ, ĐŊŅ–Đļ CQP, аĐģĐĩ Đ´ĐĩŅĐēŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— аĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅŽŅ‚ŅŒ ҆ĐĩĐš Ņ€ĐĩĐļиĐŧ. Đ’ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° ĐąŅƒĐ´Đĩ Đ˛Ņ–Đ´Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ СаСĐŊĐ°Ņ‡ĐĩĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧ҃ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊа ĐžŅĐŊĐžĐ˛Ņ– ŅĐēĐžŅŅ‚Ņ–. Đ†ĐŗĐŊĐžŅ€ŅƒŅ”Ņ‚ŅŒŅŅ NVENC, ĐžŅĐēŅ–ĐģҌĐēи Đ˛Ņ–ĐŊ ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ” ICQ.", - "transcoding_constant_rate_factor": "КоĐĩ҄Җ҆ҖҔĐŊŅ‚ ĐŋĐžŅŅ‚Ņ–ĐšĐŊĐžŅ— ŅĐēĐžŅŅ‚Ņ– (-crf)", + "transcoding_constant_quality_mode_description": "ICQ СайĐĩСĐŋĐĩŅ‡ŅƒŅ” ĐēŅ€Đ°Ņ‰Ņƒ ŅĐēŅ–ŅŅ‚ŅŒ, ĐŊŅ–Đļ CQP, аĐģĐĩ Đ´ĐĩŅĐēŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— аĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅŽŅ‚ŅŒ ҆ĐĩĐš Ņ€ĐĩĐļиĐŧ. ĐŖŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° ĐŊĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ĐŧĐĩ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ СаСĐŊĐ°Ņ‡ĐĩĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧ҃ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊа ĐžŅĐŊĐžĐ˛Ņ– ŅĐēĐžŅŅ‚Ņ–. NVENC Ņ–ĐŗĐŊĐžŅ€ŅƒŅ” ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, ĐžŅĐēŅ–ĐģҌĐēи ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ” ICQ.", + "transcoding_constant_rate_factor": "ФаĐēŅ‚ĐžŅ€ ĐŋĐžŅŅ‚Ņ–ĐšĐŊĐžŅ— ŅĐēĐžŅŅ‚Ņ– (-crf)", "transcoding_constant_rate_factor_description": "Đ Ņ–Đ˛ĐĩĐŊҌ ŅĐēĐžŅŅ‚Ņ– Đ˛Ņ–Đ´ĐĩĐž. Đ—Đ°ĐˇĐ˛Đ¸Ņ‡Đ°Đš СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ Đ´ĐģŅ H.264 - 23, HEVC - 28, VP9 - 31, AV1 - 35. НиĐļ҇Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐēŅ€Đ°Ņ‰Đĩ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи.", "transcoding_disabled_description": "БĐĩС Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž — ĐŧĐžĐļĐĩ ĐŋŅ€Đ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ Đ´Đž ĐŋŅ€ĐžĐąĐģĐĩĐŧ С Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅĐŧ ĐŊа Đ´ĐĩŅĐēĐ¸Ņ… ĐēĐģŅ–Ņ”ĐŊŅ‚Đ°Ņ…", "transcoding_encoding_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "transcoding_encoding_options_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēОдĐĩĐēŅ–Đ˛, Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅ— ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ–, ŅĐēĐžŅŅ‚Ņ– Ņ‚Đ° Ņ–ĐŊŅˆĐ¸Ņ… ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Ņ–Đ˛ Đ´ĐģŅ ĐēОдОваĐŊĐ¸Ņ… Đ˛Ņ–Đ´ĐĩĐž", "transcoding_hardware_acceleration": "АĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐĩ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ", - "transcoding_hardware_acceleration_description": "ЕĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊĐž: ŅˆĐ˛Đ¸Đ´ŅˆĐĩ ĐŋĐĩŅ€ĐĩĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, аĐģĐĩ ĐŧĐžĐļĐĩ СĐŊиĐļŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐēŅ–ŅŅ‚ŅŒ ĐŋŅ€Đ¸ Ņ‚ĐžĐŧ҃ ŅĐ°ĐŧĐžĐŧ҃ ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņ–", + "transcoding_hardware_acceleration_description": "ЕĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊĐž: ŅˆĐ˛Đ¸Đ´ŅˆĐĩ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, аĐģĐĩ ĐŧĐžĐļĐĩ СĐŊиĐļŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐēŅ–ŅŅ‚ŅŒ Са Ņ‚ĐžĐŗĐž ŅĐ°ĐŧĐžĐŗĐž ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ", "transcoding_hardware_decoding": "АĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐĩ Đ´ĐĩĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "transcoding_hardware_decoding_setting_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ ĐŊĐ°ŅĐēŅ€Ņ–ĐˇĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ СаĐŧŅ–ŅŅ‚ŅŒ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅ ĐģĐ¸ŅˆĐĩ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. МоĐļĐĩ ĐŊĐĩ ĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸ Đ´ĐģŅ Đ˛ŅŅ–Ņ… Đ˛Ņ–Đ´ĐĩĐž.", - "transcoding_max_b_frames": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐŋŅ€ĐžĐŧŅ–ĐļĐŊĐ¸Ņ… ĐēĐ°Đ´Ņ€Ņ–Đ˛", - "transcoding_max_b_frames_description": "Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐˇĐąŅ–ĐģŅŒŅˆŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. МоĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ ĐŊĐĩҁ҃ĐŧҖҁĐŊŅ– С аĐŋĐ°Ņ€Đ°Ņ‚ĐŊиĐŧ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅĐŧ ĐŊа ŅŅ‚Đ°Ņ€Đ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ…. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 виĐŧиĐēĐ°Ņ” B-҄ҀĐĩĐšĐŧи, а -1 Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐŊаĐģĐ°ŅˆŅ‚ĐžĐ˛ŅƒŅ” ҆Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ.", + "transcoding_max_b_frames": "МаĐēŅĐ¸ĐŧаĐģҌĐŊа ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ B-ĐēĐ°Đ´Ņ€Ņ–Đ˛", + "transcoding_max_b_frames_description": "Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐˇĐąŅ–ĐģŅŒŅˆŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. МоĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ ĐŊĐĩҁ҃ĐŧҖҁĐŊŅ– С аĐŋĐ°Ņ€Đ°Ņ‚ĐŊиĐŧ ĐŋŅ€Đ¸ŅĐēĐžŅ€ĐĩĐŊĐŊŅĐŧ ĐŊа ŅŅ‚Đ°Ņ€Đ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ…. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 виĐŧиĐēĐ°Ņ” B-ĐēĐ°Đ´Ņ€Đ¸, а -1 виСĐŊĐ°Ņ‡Đ°Ņ” ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž.", "transcoding_max_bitrate": "МаĐēŅĐ¸ĐŧаĐģҌĐŊиК ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚", - "transcoding_max_bitrate_description": "Đ’ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐžŅ— ŅˆĐ˛Đ¸Đ´ĐēĐžŅŅ‚Ņ– ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Ņ– даĐŊĐ¸Ņ… ĐŧĐžĐļĐĩ ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ Ņ€ĐžĐˇĐŧŅ–Ņ€Đ¸ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐąŅ–ĐģҌ҈ ĐŋĐĩŅ€ĐĩĐ´ĐąĐ°Ņ‡ŅƒĐ˛Đ°ĐŊиĐŧи Са ĐŊĐĩСĐŊĐ°Ņ‡ĐŊĐžŅ— Đ˛Ņ‚Ņ€Đ°Ņ‚Đ¸ ŅĐēĐžŅŅ‚Ņ–. ĐŸŅ€Đ¸ Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊŅ–Đš ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ– 720p Ņ‚Đ¸ĐŋĐžĐ˛Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ŅŅ‚Đ°ĐŊОвĐģŅŅ‚ŅŒ 2600 ĐēĐąŅ–Ņ‚/ҁ Đ´ĐģŅ VP9 айО HEVC, айО 4500 ĐēĐąŅ–Ņ‚/ҁ Đ´ĐģŅ H.264. ВиĐŧĐēĐŊĐĩĐŊĐž, ŅĐēŅ‰Đž Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0. Đ¯ĐēŅ‰Đž ОдиĐŊĐ¸Ņ†Ņ виĐŧŅ–Ņ€Ņƒ ĐŊĐĩ вĐēаСаĐŊа, ĐŋŅ€Đ¸ĐšĐŧĐ°Ņ”Ņ‚ŅŒŅŅ k (Đ´ĐģŅ ĐēĐąŅ–Ņ‚/ҁ); ĐžŅ‚ĐļĐĩ, 5000, 5000k Ņ– 5M (Đ´ĐģŅ ĐœĐąŅ–Ņ‚/ҁ) Ņ” ĐĩĐēĐ˛Ņ–Đ˛Đ°ĐģĐĩĐŊŅ‚ĐŊиĐŧи.", + "transcoding_max_bitrate_description": "ĐŖŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐžĐŗĐž ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ ĐŧĐžĐļĐĩ ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ Ņ€ĐžĐˇĐŧŅ–Ņ€ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐąŅ–ĐģҌ҈ ĐŋĐĩŅ€ĐĩĐ´ĐąĐ°Ņ‡ŅƒĐ˛Đ°ĐŊиĐŧ Са ĐŊĐĩСĐŊĐ°Ņ‡ĐŊĐžŅ— Đ˛Ņ‚Ņ€Đ°Ņ‚Đ¸ ŅĐēĐžŅŅ‚Ņ–. За Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅ— ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ– 720p Ņ‚Đ¸ĐŋĐžĐ˛Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ŅŅ‚Đ°ĐŊОвĐģŅŅ‚ŅŒ 2600 ĐēĐąŅ–Ņ‚/ҁ Đ´ĐģŅ VP9 айО HEVC, айО 4500 ĐēĐąŅ–Ņ‚/ҁ Đ´ĐģŅ H.264. ВиĐŧĐēĐŊĐĩĐŊĐž, ŅĐēŅ‰Đž ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0. Đ¯ĐēŅ‰Đž ОдиĐŊĐ¸Ņ†Ņ виĐŧŅ–Ņ€Ņƒ ĐŊĐĩ вĐēаСаĐŊа, ĐŋŅ€Đ¸ĐšĐŧĐ°Ņ”Ņ‚ŅŒŅŅ k (Đ´ĐģŅ ĐēĐąŅ–Ņ‚/ҁ); ĐžŅ‚ĐļĐĩ, 5000, 5000k Ņ– 5M (Đ´ĐģŅ ĐœĐąŅ–Ņ‚/ҁ) Ņ” ĐĩĐēĐ˛Ņ–Đ˛Đ°ĐģĐĩĐŊŅ‚ĐŊиĐŧи.", "transcoding_max_keyframe_interval": "МаĐēŅĐ¸ĐŧаĐģҌĐŊиК Ņ–ĐŊŅ‚ĐĩŅ€Đ˛Đ°Đģ ĐēĐģŅŽŅ‡ĐžĐ˛Đ¸Ņ… ĐēĐ°Đ´Ņ€Ņ–Đ˛", - "transcoding_max_keyframe_interval_description": "Đ’ŅŅ‚Đ°ĐŊОвĐģŅŽŅ” ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊ҃ Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ ĐŧŅ–Đļ ĐēĐģŅŽŅ‡ĐžĐ˛Đ¸Đŧи ĐēĐ°Đ´Ņ€Đ°Đŧи. НиĐļ҇Җ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐŗŅ–Ņ€ŅˆŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐŋĐžŅˆŅƒĐē҃ Ņ– ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŋĐžĐēŅ€Đ°Ņ‰Đ¸Ņ‚Đ¸ ŅĐēŅ–ŅŅ‚ŅŒ в ҁ҆ĐĩĐŊĐ°Ņ… С ŅˆĐ˛Đ¸Đ´ĐēиĐŧи Ņ€ŅƒŅ…Đ°Đŧи. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž Đ˛ŅŅ‚Đ°ĐŊОвĐģŅŽŅ” ҆Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ.", + "transcoding_max_keyframe_interval_description": "ĐŖŅŅ‚Đ°ĐŊОвĐģŅŽŅ” ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊ҃ Đ˛Ņ–Đ´ŅŅ‚Đ°ĐŊҌ ĐŧŅ–Đļ ĐēĐģŅŽŅ‡ĐžĐ˛Đ¸Đŧи ĐēĐ°Đ´Ņ€Đ°Đŧи. НиĐļ҇Җ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐŗŅ–Ņ€ŅˆŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐŋĐĩŅ€ĐĩĐŧĐžŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ– ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŋĐžĐēŅ€Đ°Ņ‰Đ¸Ņ‚Đ¸ ŅĐēŅ–ŅŅ‚ŅŒ ҃ ҁ҆ĐĩĐŊĐ°Ņ… ĐˇŅ– ŅˆĐ˛Đ¸Đ´ĐēиĐŧи Ņ€ŅƒŅ…Đ°Đŧи. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 виСĐŊĐ°Ņ‡Đ°Ņ” ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž.", "transcoding_optimal_description": "Đ’Ņ–Đ´ĐĩĐž С Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅŽ ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŽ Đ˛Đ¸Ņ‰Đĩ ҆ҖĐģŅŒĐžĐ˛ĐžŅ— айО ĐŊĐĩ в ĐŋŅ€Đ¸ĐšĐŊŅŅ‚ĐžĐŧ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ–", "transcoding_policy": "ПоĐģŅ–Ņ‚Đ¸Đēа Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", "transcoding_policy_description": "ВизĐŊĐ°Ņ‡Đ°Ņ”, ĐēĐžĐģи Đ˛Ņ–Đ´ĐĩĐž ĐąŅƒĐ´Đĩ Ņ‚Ņ€Đ°ĐŊҁĐēОдОваĐŊĐž", - "transcoding_preferred_hardware_device": "ПĐĩŅ€ĐĩваĐļĐŊиК аĐŋĐ°Ņ€Đ°Ņ‚ĐŊиК ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš", - "transcoding_preferred_hardware_device_description": "Đ—Đ°ŅŅ‚ĐžŅĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ҂ҖĐģҌĐēи Đ´Đž VAAPI Ņ– QSV. Đ’ŅŅ‚Đ°ĐŊОвĐģŅŽŅ” Đ˛ŅƒĐˇĐžĐģ DRI, ŅĐēиК виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ аĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐžĐŗĐž Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", - "transcoding_preset_preset": "ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ (-preset)", - "transcoding_preset_preset_description": "ШвидĐēŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ. ĐŸĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆŅ– ĐŋŅ€ĐĩҁĐĩŅ‚Đ¸ ŅŅ‚Đ˛ĐžŅ€ŅŽŅŽŅ‚ŅŒ ĐŧĐĩĐŊŅˆŅ– Ņ„Đ°ĐšĐģи Ņ– ĐŋŅ–Đ´Đ˛Đ¸Ņ‰ŅƒŅŽŅ‚ŅŒ ŅĐēŅ–ŅŅ‚ŅŒ ĐŋŅ€Đ¸ ĐŋĐĩвĐŊĐžĐŧ҃ ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņ–. VP9 Ņ–ĐŗĐŊĐžŅ€ŅƒŅ” ŅˆĐ˛Đ¸Đ´ĐēĐžŅŅ‚Ņ– Đ˛Đ¸Ņ‰Đĩ 'ŅˆĐ˛Đ¸Đ´ŅˆĐĩ'.", - "transcoding_reference_frames": "ĐžŅĐŊОвĐŊŅ– ĐēĐ°Đ´Ņ€Đ¸", - "transcoding_reference_frames_description": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐēĐ°Đ´Ņ€Ņ–Đ˛, ĐŊа ŅĐēŅ– ĐŋĐžŅĐ¸ĐģĐ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ– даĐŊĐžĐŗĐž ĐēĐ°Đ´Ņ€Ņƒ. Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐˇĐąŅ–ĐģŅŒŅˆŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐŊаĐģĐ°ŅˆŅ‚ĐžĐ˛ŅƒŅ” ҆Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ.", - "transcoding_required_description": "Đ›Đ¸ŅˆĐĩ Đ˛Ņ–Đ´ĐĩĐž, Ņ‰Đž ĐŊĐĩ ҃ ĐŋŅ€Đ¸ĐšĐŊŅŅ‚ĐžĐŧ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ–", + "transcoding_preferred_hardware_device": "БаĐļаĐŊиК аĐŋĐ°Ņ€Đ°Ņ‚ĐŊиК ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš", + "transcoding_preferred_hardware_device_description": "Đ—Đ°ŅŅ‚ĐžŅĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ Đ´Đž VAAPI Ņ– QSV. ĐŖŅŅ‚Đ°ĐŊОвĐģŅŽŅ” Đ˛ŅƒĐˇĐžĐģ DRI, ŅĐēиК виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ аĐŋĐ°Ņ€Đ°Ņ‚ĐŊĐžĐŗĐž Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ.", + "transcoding_preset_preset": "ĐŸŅ€ĐĩҁĐĩŅ‚ (-preset)", + "transcoding_preset_preset_description": "ШвидĐēŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ. ĐŸĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆŅ– ĐŋŅ€ĐĩҁĐĩŅ‚Đ¸ ŅŅ‚Đ˛ĐžŅ€ŅŽŅŽŅ‚ŅŒ ĐŧĐĩĐŊŅˆŅ– Ņ„Đ°ĐšĐģи Ņ– ĐŋŅ–Đ´Đ˛Đ¸Ņ‰ŅƒŅŽŅ‚ŅŒ ŅĐēŅ–ŅŅ‚ŅŒ Са ĐŋĐĩвĐŊĐžĐŗĐž ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ. VP9 Ņ–ĐŗĐŊĐžŅ€ŅƒŅ” ŅˆĐ˛Đ¸Đ´ĐēĐžŅŅ‚Ņ– Đ˛Đ¸Ņ‰Đĩ 'faster'.", + "transcoding_reference_frames": "ОĐŋĐžŅ€ĐŊŅ– ĐēĐ°Đ´Ņ€Đ¸", + "transcoding_reference_frames_description": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐēĐ°Đ´Ņ€Ņ–Đ˛, ĐŊа ŅĐēŅ– ĐŋĐžŅĐ¸ĐģĐ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ ĐŋĐĩвĐŊĐžĐŗĐž ĐēĐ°Đ´Ņ€Ņƒ. Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋĐžĐēŅ€Đ°Ņ‰ŅƒŅŽŅ‚ŅŒ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ŅŅ‚Đ¸ŅĐŊĐĩĐŊĐŊŅ, аĐģĐĩ ĐˇĐąŅ–ĐģŅŒŅˆŅƒŅŽŅ‚ŅŒ Ņ‡Đ°Ņ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ 0 виСĐŊĐ°Ņ‡Đ°Ņ” ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž.", + "transcoding_required_description": "Đ›Đ¸ŅˆĐĩ Đ˛Ņ–Đ´ĐĩĐž, Ņ‰Đž ĐŊĐĩ ĐŧĐ°ŅŽŅ‚ŅŒ ĐŋŅ€Đ¸ĐšĐŊŅŅ‚ĐŊĐžĐŗĐž Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņƒ", "transcoding_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž", - "transcoding_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ŅĐēŅ– Đ˛Ņ–Đ´ĐĩĐž Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ– ŅĐē Ņ—Ņ… ĐžĐąŅ€ĐžĐąĐģŅŅ‚Đ¸", - "transcoding_target_resolution": "Đ ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", + "transcoding_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ‚Đ¸Đŧ, ŅĐēŅ– Đ˛Ņ–Đ´ĐĩĐž Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ– ŅĐē Ņ—Ņ… ĐžĐąŅ€ĐžĐąĐģŅŅ‚Đ¸", + "transcoding_target_resolution": "ĐĻŅ–ĐģŅŒĐžĐ˛Đ° Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊа ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", "transcoding_target_resolution_description": "Đ’Đ¸Ņ‰Ņ– Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊŅ– ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ– ĐŧĐžĐļŅƒŅ‚ŅŒ СйĐĩŅ€Ņ–ĐŗĐ°Ņ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš, аĐģĐĩ СаКĐŧĐ°ŅŽŅ‚ŅŒ ĐąŅ–ĐģҌ҈Đĩ Ņ‡Đ°ŅŅƒ ĐŊа ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, ĐŧĐ°ŅŽŅ‚ŅŒ ĐąŅ–ĐģŅŒŅˆŅ– Ņ€ĐžĐˇĐŧŅ–Ņ€Đ¸ Ņ„Đ°ĐšĐģŅ–Đ˛ Ņ– ĐŧĐžĐļŅƒŅ‚ŅŒ СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Ņ€ĐžĐąĐžŅ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", - "transcoding_temporal_aq": "ĐĸиĐŧŅ‡Đ°ŅĐžĐ˛Đĩ AQ", - "transcoding_temporal_aq_description": "ĐĄŅ‚ĐžŅŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ NVENC. Đ§Đ°ŅĐžĐ˛Đ° адаĐŋŅ‚Đ¸Đ˛ĐŊа ĐēваĐŊŅ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ ĐŋŅ–Đ´Đ˛Đ¸Ņ‰ŅƒŅ” ŅĐēŅ–ŅŅ‚ŅŒ ҁ҆ĐĩĐŊ С Đ˛Đ¸ŅĐžĐēĐžŅŽ Đ´ĐĩŅ‚Đ°ĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ”ŅŽ Ņ‚Đ° ĐŊĐ¸ĐˇŅŒĐēиĐŧ Ņ€Ņ–Đ˛ĐŊĐĩĐŧ Ņ€ŅƒŅ…Ņƒ. МоĐļĐĩ ĐąŅƒŅ‚Đ¸ ĐŊĐĩҁ҃ĐŧҖҁĐŊиĐŧ ĐˇŅ– ŅŅ‚Đ°Ņ€Đ¸Đŧи ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи.", + "transcoding_temporal_aq": "Đ§Đ°ŅĐžĐ˛Đĩ AQ", + "transcoding_temporal_aq_description": "ĐĄŅ‚ĐžŅŅƒŅ”Ņ‚ŅŒŅŅ ĐģĐ¸ŅˆĐĩ NVENC. Đ§Đ°ŅĐžĐ˛Đ° адаĐŋŅ‚Đ¸Đ˛ĐŊа ĐēваĐŊŅ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ ĐŋŅ–Đ´Đ˛Đ¸Ņ‰ŅƒŅ” ŅĐēŅ–ŅŅ‚ŅŒ ҁ҆ĐĩĐŊ С Đ˛Đ¸ŅĐžĐēĐžŅŽ Đ´ĐĩŅ‚Đ°ĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ”ŅŽ Ņ‚Đ° ĐŊĐ¸ĐˇŅŒĐēиĐŧ Ņ€Ņ–Đ˛ĐŊĐĩĐŧ Ņ€ŅƒŅ…Ņƒ. МоĐļĐĩ ĐąŅƒŅ‚Đ¸ ĐŊĐĩҁ҃ĐŧҖҁĐŊĐžŅŽ ĐˇŅ– ŅŅ‚Đ°Ņ€Đ¸Đŧи ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи.", "transcoding_threads": "ĐŸĐžŅ‚ĐžĐēи", - "transcoding_threads_description": "Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋŅ€Đ¸ŅĐēĐžŅ€ŅŽŅŽŅ‚ŅŒ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, аĐģĐĩ СаĐģĐ¸ŅˆĐ°ŅŽŅ‚ŅŒ ĐŧĐĩĐŊ҈Đĩ ĐŧŅ–ŅŅ†Ņ Đ´ĐģŅ ĐžĐąŅ€ĐžĐąĐēи Ņ–ĐŊŅˆĐ¸Ņ… СавдаĐŊҌ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐŋŅ–Đ´ Ņ‡Đ°Ņ аĐēŅ‚Đ¸Đ˛ĐŊĐžŅŅ‚Ņ–. ĐĻĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŊĐĩ ĐŋОвиĐŊĐŊĐž ĐąŅƒŅ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ ĐēŅ–ĐģҌĐēĐžŅŅ‚Ņ– ŅĐ´ĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€Đ°. МаĐēŅĐ¸ĐŧŅ–ĐˇŅƒŅ” виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ, ŅĐēŅ‰Đž Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž ĐŊа 0.", + "transcoding_threads_description": "Đ’Đ¸Ņ‰Ņ– СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŋŅ€Đ¸ŅĐēĐžŅ€ŅŽŅŽŅ‚ŅŒ ĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ, аĐģĐĩ СаĐģĐ¸ŅˆĐ°ŅŽŅ‚ŅŒ ĐŧĐĩĐŊ҈Đĩ ĐŧŅ–ŅŅ†Ņ Đ´ĐģŅ ĐžĐąŅ€ĐžĐąĐēи Ņ–ĐŊŅˆĐ¸Ņ… СавдаĐŊҌ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐŋŅ–Đ´ Ņ‡Đ°Ņ аĐēŅ‚Đ¸Đ˛ĐŊĐžŅŅ‚Ņ–. ĐĻĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŊĐĩ ĐŧĐ°Ņ” ĐŋĐĩŅ€ĐĩĐ˛Đ¸Ņ‰ŅƒĐ˛Đ°Ņ‚Đ¸ ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ŅĐ´ĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅĐžŅ€Đ°. МаĐēŅĐ¸ĐŧŅ–ĐˇŅƒŅ” виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ, ŅĐēŅ‰Đž ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž ĐŊа 0.", "transcoding_tone_mapping": "ĐĸĐžĐŊОвĐĩ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "transcoding_tone_mapping_description": "НаĐŧĐ°ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ Đ˛Đ¸ĐŗĐģŅĐ´ HDR-Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ€Đ¸ ĐēĐžĐŊвĐĩŅ€Ņ‚Đ°Ņ†Ņ–Ņ— в SDR. КоĐļĐĩĐŊ аĐģĐŗĐžŅ€Đ¸Ņ‚Đŧ Ņ€ĐžĐąĐ¸Ņ‚ŅŒ Ņ€Ņ–ĐˇĐŊŅ– ĐēĐžĐŧĐŋŅ€ĐžĐŧŅ–ŅĐ¸ Ņ‰ĐžĐ´Đž ĐēĐžĐģŅŒĐžŅ€Ņƒ, Đ´ĐĩŅ‚Đ°ĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ— Ņ‚Đ° ŅŅĐēŅ€Đ°Đ˛ĐžŅŅ‚Ņ–. АĐģĐŗĐžŅ€Đ¸Ņ‚Đŧ Hable СйĐĩŅ€Ņ–ĐŗĐ°Ņ” Đ´ĐĩŅ‚Đ°ĐģŅ–, Mobius - ĐēĐžĐģŅŒĐžŅ€Đ¸, Reinhard - ŅŅĐēŅ€Đ°Đ˛Ņ–ŅŅ‚ŅŒ.", - "transcoding_transcode_policy": "ПоĐģŅ–Ņ‚Đ¸Đēа ĐŋĐĩŅ€ĐĩĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", - "transcoding_transcode_policy_description": "ПоĐģŅ–Ņ‚Đ¸Đēа Ņ‰ĐžĐ´Đž Ņ‚ĐžĐŗĐž, ĐēĐžĐģи Đ˛Ņ–Đ´ĐĩĐž ҁĐģŅ–Đ´ ĐŋĐĩŅ€ĐĩĐēĐžĐ´ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸. Đ’Ņ–Đ´ĐĩĐž С HDR Ņ– Đ˛Ņ–Đ´ĐĩĐž С ĐŋŅ–ĐēҁĐĩĐģҌĐŊиĐŧ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ĐžĐŧ, Đ˛Ņ–Đ´ĐŧŅ–ĐŊĐŊиĐŧ Đ˛Ņ–Đ´ YUV 4:2:0, СавĐļди ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐēОдОваĐŊĐž (ĐēҀҖĐŧ виĐŋадĐēŅ–Đ˛, ĐēĐžĐģи ĐŋĐĩŅ€ĐĩĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ виĐŧĐēĐŊĐĩĐŊĐž).", + "transcoding_tone_mapping_description": "НаĐŧĐ°ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ Đ˛Đ¸ĐŗĐģŅĐ´ HDR-Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ĐĩŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŊа SDR. КоĐļĐĩĐŊ аĐģĐŗĐžŅ€Đ¸Ņ‚Đŧ Ņ€ĐžĐąĐ¸Ņ‚ŅŒ Ņ€Ņ–ĐˇĐŊŅ– ĐēĐžĐŧĐŋŅ€ĐžĐŧŅ–ŅĐ¸ Ņ‰ĐžĐ´Đž ĐēĐžĐģŅŒĐžŅ€Ņƒ, Đ´ĐĩŅ‚Đ°ĐģŅ–ĐˇĐ°Ņ†Ņ–Ņ— Ņ‚Đ° ŅŅĐēŅ€Đ°Đ˛ĐžŅŅ‚Ņ–. АĐģĐŗĐžŅ€Đ¸Ņ‚Đŧ Hable СйĐĩŅ€Ņ–ĐŗĐ°Ņ” Đ´ĐĩŅ‚Đ°ĐģŅ–, Mobius - ĐēĐžĐģŅŒĐžŅ€Đ¸, Reinhard - ŅŅĐēŅ€Đ°Đ˛Ņ–ŅŅ‚ŅŒ.", + "transcoding_transcode_policy": "ПоĐģŅ–Ņ‚Đ¸Đēа Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ", + "transcoding_transcode_policy_description": "ПоĐģŅ–Ņ‚Đ¸Đēа Ņ‰ĐžĐ´Đž Ņ‚ĐžĐŗĐž, ĐēĐžĐģи Đ˛Ņ–Đ´ĐĩĐž ҁĐģŅ–Đ´ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸. Đ’Ņ–Đ´ĐĩĐž С HDR Ņ– Đ˛Ņ–Đ´ĐĩĐž С ĐŋŅ–ĐēҁĐĩĐģҌĐŊиĐŧ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ĐžĐŧ, Đ˛Ņ–Đ´ĐŧŅ–ĐŊĐŊиĐŧ Đ˛Ņ–Đ´ YUV 4:2:0, СавĐļди ĐąŅƒĐ´Đĩ Ņ‚Ņ€Đ°ĐŊҁĐēОдОваĐŊĐž (ĐēҀҖĐŧ виĐŋадĐēŅ–Đ˛, ĐēĐžĐģи Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ виĐŧĐēĐŊĐĩĐŊĐž).", "transcoding_two_pass_encoding": "ĐšĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ С двОĐŧа ĐŋŅ€ĐžŅ…ĐžĐ´Đ°Đŧи", - "transcoding_two_pass_encoding_setting_description": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ Са двОĐŧа ĐŋŅ€ĐžŅ…ĐžĐ´Đ°Đŧи Đ´ĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ ĐēŅ€Đ°Ņ‰Đ¸Ņ… СаĐēОдОваĐŊĐ¸Ņ… Đ˛Ņ–Đ´ĐĩĐž. КоĐģи Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊиК ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚ (ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊиК Đ´ĐģŅ Ņ€ĐžĐąĐžŅ‚Đ¸ С H.264 Ņ‚Đ° HEVC), ҆ĐĩĐš Ņ€ĐĩĐļиĐŧ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ” Đ´Ņ–Đ°ĐŋаСОĐŊ ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ, ĐˇĐ°ŅĐŊОваĐŊиК ĐŊа ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐžĐŧ҃ ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņ–, Ņ– Ņ–ĐŗĐŊĐžŅ€ŅƒŅ” CRF. ДĐģŅ VP9 ĐŧĐžĐļĐŊа виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ CRF, ŅĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊиК ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚.", + "transcoding_two_pass_encoding_setting_description": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ Са двОĐŧа ĐŋŅ€ĐžŅ…ĐžĐ´Đ°Đŧи Đ´ĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ ĐēŅ€Đ°Ņ‰Đ¸Ņ… СаĐēОдОваĐŊĐ¸Ņ… Đ˛Ņ–Đ´ĐĩĐž. КоĐģи ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊиК ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚ (ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊиК Đ´ĐģŅ Ņ€ĐžĐąĐžŅ‚Đ¸ С H.264 Ņ‚Đ° HEVC), ҆ĐĩĐš Ņ€ĐĩĐļиĐŧ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ” Đ´Ņ–Đ°ĐŋаСОĐŊ ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ, ĐŊа ĐžŅĐŊĐžĐ˛Ņ– ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐžĐŗĐž ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚Ņƒ, Ņ– Ņ–ĐŗĐŊĐžŅ€ŅƒŅ” CRF. ДĐģŅ VP9 ĐŧĐžĐļĐŊа виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ CRF, ŅĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊиК ĐąŅ–Ņ‚Ņ€ĐĩĐšŅ‚.", "transcoding_video_codec": "Đ’Ņ–Đ´ĐĩĐžĐēОдĐĩĐē", "transcoding_video_codec_description": "VP9 ĐŧĐ°Ņ” Đ˛Đ¸ŅĐžĐē҃ ĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ Ņ– ҁ҃ĐŧҖҁĐŊŅ–ŅŅ‚ŅŒ С вĐĩйОĐŧ, аĐģĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅ” ĐąŅ–ĐģҌ҈Đĩ Ņ‡Đ°ŅŅƒ ĐŊа Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. HEVC ĐŋŅ€Đ°Ņ†ŅŽŅ” ŅŅ…ĐžĐļĐĩ, аĐģĐĩ ĐŧĐ°Ņ” ĐŧĐĩĐŊ҈҃ ҁ҃ĐŧҖҁĐŊŅ–ŅŅ‚ŅŒ С вĐĩйОĐŧ. H.264 ĐŧĐ°Ņ” ŅˆĐ¸Ņ€ĐžĐē҃ ҁ҃ĐŧҖҁĐŊŅ–ŅŅ‚ŅŒ Ņ– ŅˆĐ˛Đ¸Đ´ĐēĐž Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒŅ”Ņ‚ŅŒŅŅ, аĐģĐĩ ŅŅ‚Đ˛ĐžŅ€ŅŽŅ” СĐŊĐ°Ņ‡ĐŊĐž ĐąŅ–ĐģŅŒŅˆŅ– Ņ„Đ°ĐšĐģи. AV1 - ĐŊаКĐĩŅ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅˆĐ¸Đš ĐēОдĐĩĐē, аĐģĐĩ ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ ĐŊа ŅŅ‚Đ°Ņ€Ņ–ŅˆĐ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ….", "trash_enabled_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ ĐēĐžŅˆĐ¸Đēа", "trash_number_of_days": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Đ´ĐŊŅ–Đ˛", - "trash_number_of_days_description": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Đ´ĐŊŅ–Đ˛, ĐŋŅ€ĐžŅ‚ŅĐŗĐžĐŧ ŅĐēĐ¸Ņ… СаĐģĐ¸ŅˆĐ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ҃ ĐēĐžŅˆĐ¸Đē҃ ĐŋĐĩŅ€ĐĩĐ´ Ņ—Ņ… ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊиĐŧ видаĐģĐĩĐŊĐŊŅĐŧ", + "trash_number_of_days_description": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Đ´ĐŊŅ–Đ˛ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ҃ ĐēĐžŅˆĐ¸Đē҃ ĐŋĐĩŅ€ĐĩĐ´ Ņ—Ņ… ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊиĐŧ видаĐģĐĩĐŊĐŊŅĐŧ", "trash_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐžŅˆĐ¸Đēа", "trash_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐēĐžŅˆĐ¸Đēа", "unlink_all_oauth_accounts": "Đ’Ņ–Đ´â€™Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ˛ŅŅ– ОйĐģŅ–ĐēĐžĐ˛Ņ– СаĐŋĐ¸ŅĐ¸ OAuth", "unlink_all_oauth_accounts_description": "НĐĩ ĐˇĐ°ĐąŅƒĐ´ŅŒŅ‚Đĩ Đ˛Ņ–Đ´â€™Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ˛ŅŅ– ОйĐģŅ–ĐēĐžĐ˛Ņ– СаĐŋĐ¸ŅĐ¸ OAuth ĐŋĐĩŅ€ĐĩĐ´ ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´ĐžĐŧ Đ´Đž ĐŊĐžĐ˛ĐžĐŗĐž ĐŋĐžŅŅ‚Đ°Ņ‡Đ°ĐģҌĐŊиĐēа.", "unlink_all_oauth_accounts_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Ņ–Đ´â€™Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ˛ŅŅ– ОйĐģŅ–ĐēĐžĐ˛Ņ– СаĐŋĐ¸ŅĐ¸ OAuth? ĐĻĐĩ ҁĐēиĐŊĐĩ Ņ–Đ´ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ĐžŅ€ OAuth Đ´ĐģŅ ĐēĐžĐļĐŊĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°, Ņ– Ņ†ŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ĐąŅƒĐ´Đĩ ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸.", "user_cleanup_job": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "user_delete_delay": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ {user} Ņ– ĐšĐžĐŗĐž Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ СаĐŋĐģаĐŊОваĐŊŅ– Đ´ĐģŅ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ ҇ĐĩŅ€ĐĩС {delay, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}.", - "user_delete_delay_settings": "Đ’Ņ–Đ´ĐēĐģадĐĩĐŊĐĩ видаĐģĐĩĐŊĐŊŅ", - "user_delete_delay_settings_description": "ПĐĩŅ€Ņ–ĐžĐ´ Đ˛Ņ–Đ´Ņ‚ĐĩŅ€ĐŧŅ–ĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ ОйĐģŅ–ĐēĐžĐ˛ĐžĐŗĐž СаĐŋĐ¸ŅŅƒ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ‚Đ° ĐšĐžĐŗĐž Ņ„Đ°ĐšĐģŅ–Đ˛. ЗавдаĐŊĐŊŅ С видаĐģĐĩĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° СаĐŋ҃ҁĐēĐ°Ņ”Ņ‚ŅŒŅŅ Ņ‰ĐžĐŊĐžŅ‡Ņ– Đž ĐŋŅ–Đ˛ĐŊĐžŅ‡Ņ– Ņ– ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€ŅŅ” ОйĐģŅ–ĐēĐžĐ˛Ņ– СаĐŋĐ¸ŅĐ¸, ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊŅ– Đ´ĐģŅ видаĐģĐĩĐŊĐŊŅ. ЗĐŧŅ–ĐŊи Ņ†ŅŒĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° ĐąŅƒĐ´ŅƒŅ‚ŅŒ Đ˛Ņ€Đ°Ņ…ĐžĐ˛Đ°ĐŊŅ– ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž СаĐŋ҃ҁĐē҃ СавдаĐŊĐŊŅ.", - "user_delete_immediately": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ Ņ‚Đ° Ņ„Đ°ĐšĐģи ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {user} ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐŊĐĩĐŗĐ°ĐšĐŊĐž ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊŅ– в ҇ĐĩŅ€ĐŗŅƒ ĐŊа ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐĩ видаĐģĐĩĐŊĐŊŅ.", - "user_delete_immediately_checkbox": "ĐŸĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ‚Đ° Ņ„Đ°ĐšĐģи в ҇ĐĩŅ€ĐŗŅƒ Đ´ĐģŅ ĐŊĐĩĐŗĐ°ĐšĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ", + "user_delete_delay": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ {user} Ņ‚Đ° ĐšĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐ´Đĩ СаĐŋĐģаĐŊОваĐŊĐž Đ´ĐģŅ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ ҇ĐĩŅ€ĐĩС {delay, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}.", + "user_delete_delay_settings": "Đ—Đ°Ņ‚Ņ€Đ¸ĐŧĐēа видаĐģĐĩĐŊĐŊŅ", + "user_delete_delay_settings_description": "ПĐĩŅ€Ņ–ĐžĐ´ Đ˛Ņ–Đ´Ņ‚ĐĩŅ€ĐŧŅ–ĐŊŅƒĐ˛Đ°ĐŊĐŊŅ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ ОйĐģŅ–ĐēĐžĐ˛ĐžĐŗĐž СаĐŋĐ¸ŅŅƒ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ‚Đ° ĐšĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛. ЗавдаĐŊĐŊŅ С видаĐģĐĩĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ Ņ‰ĐžĐŊĐžŅ‡Ņ– Đž ĐŋŅ–Đ˛ĐŊĐžŅ‡Ņ– Ņ– ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€ŅŅ” ОйĐģŅ–ĐēĐžĐ˛Ņ– СаĐŋĐ¸ŅĐ¸, ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊŅ– Đ´ĐģŅ видаĐģĐĩĐŊĐŊŅ. ЗĐŧŅ–ĐŊи Ņ†ŅŒĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° ĐąŅƒĐ´Đĩ Đ˛Ņ€Đ°Ņ…ĐžĐ˛Đ°ĐŊĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž виĐēĐžĐŊаĐŊĐŊŅ СавдаĐŊĐŊŅ.", + "user_delete_immediately": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ Ņ‚Đ° ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {user} ĐąŅƒĐ´Đĩ ĐŊĐĩĐŗĐ°ĐšĐŊĐž ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐž в ҇ĐĩŅ€ĐŗŅƒ ĐŊа ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐĩ видаĐģĐĩĐŊĐŊŅ.", + "user_delete_immediately_checkbox": "ĐŸĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° Ņ‚Đ° ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ в ҇ĐĩŅ€ĐŗŅƒ Đ´ĐģŅ ĐŊĐĩĐŗĐ°ĐšĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ", "user_details": "ДаĐŊŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "user_management": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи", "user_password_has_been_reset": "ĐŸĐ°Ņ€ĐžĐģҌ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐąŅƒĐģĐž ҁĐēиĐŊŅƒŅ‚Đž:", - "user_password_reset_description": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŊĐ°Đ´Đ°ĐšŅ‚Đĩ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐ˛Ņ– Ņ‚Đ¸ĐŧŅ‡Đ°ŅĐžĐ˛Đ¸Đš ĐŋĐ°Ņ€ĐžĐģҌ Ņ– ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧŅ‚Đĩ КОĐŧ҃, Ņ‰Đž Đ˛Ņ–ĐŊ ĐŋОвиĐŊĐĩĐŊ ĐąŅƒĐ´Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ ĐŋŅ€Đ¸ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŧ҃ Đ˛Ņ…ĐžĐ´Ņ–.", + "user_password_reset_description": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŊĐ°Đ´Đ°ĐšŅ‚Đĩ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐ˛Ņ– Ņ‚Đ¸ĐŧŅ‡Đ°ŅĐžĐ˛Đ¸Đš ĐŋĐ°Ņ€ĐžĐģҌ Ņ– ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧŅ‚Đĩ, Ņ‰Đž ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐąŅƒĐ´Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐšĐžĐŗĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž Đ˛Ņ…ĐžĐ´Ņƒ.", "user_restore_description": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ {user} ĐąŅƒĐ´Đĩ Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž.", "user_restore_scheduled_removal": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° - СаĐŋĐģаĐŊОваĐŊĐž ĐŊа видаĐģĐĩĐŊĐŊŅ {date, date, long}", "user_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "user_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛", - "user_successfully_removed": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {email} ҃ҁĐŋŅ–ŅˆĐŊĐž видаĐģĐĩĐŊĐž.", - "users_page_description": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Ņ–Đ˛", - "version_check_enabled_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ вĐĩҀҁҖҗ", - "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи вĐĩҀҁҖҗ СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐŋĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐžŅ— ĐēĐžĐŧ҃ĐŊŅ–ĐēĐ°Ņ†Ņ–Ņ— С github.com", + "user_successfully_removed": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {email} виĐģŅƒŅ‡ĐĩĐŊĐž.", + "users_page_description": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", + "version_check_enabled_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи вĐĩҀҁҖҗ", + "version_check_implications": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи вĐĩҀҁҖҗ СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐŋĐĩŅ€Ņ–ĐžĐ´Đ¸Ņ‡ĐŊĐžŅ— ĐēĐžĐŧ҃ĐŊŅ–ĐēĐ°Ņ†Ņ–Ņ— С {server}", "version_check_settings": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēа вĐĩҀҁҖҗ", "version_check_settings_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸/виĐŧĐēĐŊŅƒŅ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐŋŅ€Đž ĐŊĐžĐ˛Ņƒ вĐĩŅ€ŅŅ–ŅŽ", - "video_conversion_job": "ПĐĩŅ€ĐĩĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž", + "video_conversion_job": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž", "video_conversion_job_description": "ĐĸŅ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž Đ´ĐģŅ ŅˆĐ¸Ņ€ŅˆĐžŅ— ҁ҃ĐŧҖҁĐŊĐžŅŅ‚Ņ– С ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°Đŧи Ņ‚Đ° ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи" }, "admin_email": "ЕĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊа ĐŋĐžŅˆŅ‚Đ° адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", @@ -453,84 +453,84 @@ "advanced": "Đ ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊŅ–", "advanced_settings_clear_image_cache": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐĩ҈ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ", "advanced_settings_clear_image_cache_error": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐĩ҈ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ", - "advanced_settings_clear_image_cache_success": "ĐŖŅĐŋŅ–ŅˆĐŊĐž ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž {size}", - "advanced_settings_enable_alternate_media_filter_subtitle": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ҆ĐĩĐš Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚ Đ´ĐģŅ ҄ҖĐģŅŒŅ‚Ņ€Đ°Ņ†Ņ–Ņ— Ņ„Đ°ĐšĐģŅ–Đ˛ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ— Са аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊиĐŧи ĐēŅ€Đ¸Ņ‚ĐĩŅ€Ņ–ŅĐŧи. ĐĄĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ ҆Đĩ, ŅĐēŅ‰Đž ҃ Đ˛Đ°Ņ виĐŊиĐēĐ°ŅŽŅ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧи С Ņ‚Đ¸Đŧ, Ņ‰Đž ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŊĐĩ Đ˛Đ¸ŅĐ˛ĐģŅŅ” Đ˛ŅŅ– аĐģŅŒĐąĐžĐŧи.", - "advanced_settings_enable_alternate_media_filter_title": "[ЕКСПЕРИМЕНĐĸАЛĐŦНИЙ] ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊиК ҄ҖĐģŅŒŅ‚Ņ€ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ— аĐģŅŒĐąĐžĐŧŅ–Đ˛ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "advanced_settings_clear_image_cache_success": "ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž {size}", + "advanced_settings_enable_alternate_media_filter_subtitle": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ҆ĐĩĐš Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚ Đ´ĐģŅ ҄ҖĐģŅŒŅ‚Ņ€Đ°Ņ†Ņ–Ņ— ĐŧĐĩĐ´Ņ–Đ° ĐŋŅ–Đ´ Ņ‡Đ°Ņ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ— Са аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊиĐŧи ĐēŅ€Đ¸Ņ‚ĐĩŅ€Ņ–ŅĐŧи. ĐĄĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ ҆Đĩ, ŅĐēŅ‰Đž ҃ Đ˛Đ°Ņ виĐŊиĐēĐ°ŅŽŅ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧи С Ņ‚Đ¸Đŧ, Ņ‰Đž ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŊĐĩ Đ˛Đ¸ŅĐ˛ĐģŅŅ” Đ˛ŅŅ– аĐģŅŒĐąĐžĐŧи.", + "advanced_settings_enable_alternate_media_filter_title": "[ЕКСПЕРИМЕНĐĸАЛĐŦНО] АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊиК ҄ҖĐģŅŒŅ‚Ņ€ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ— аĐģŅŒĐąĐžĐŧŅ–Đ˛ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", "advanced_settings_log_level_title": "Đ Ņ–Đ˛ĐĩĐŊҌ ĐļŅƒŅ€ĐŊаĐģŅŽĐ˛Đ°ĐŊĐŊŅ: {level}", - "advanced_settings_prefer_remote_subtitle": "ДĐĩŅĐēŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— вĐĩĐģҌĐŧи ĐŋĐžĐ˛Ņ–ĐģҌĐŊĐž СаваĐŊŅ‚Đ°ĐļŅƒŅŽŅ‚ŅŒ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Ņ–Đˇ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—. ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, Ņ‰ĐžĐą СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ С ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ.", - "advanced_settings_prefer_remote_title": "ПĐĩŅ€ĐĩĐ˛Đ°ĐŗĐ° Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊиĐŧ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅĐŧ", + "advanced_settings_prefer_remote_subtitle": "ДĐĩŅĐēŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— Đ´ŅƒĐļĐĩ ĐŋĐžĐ˛Ņ–ĐģҌĐŊĐž СаваĐŊŅ‚Đ°ĐļŅƒŅŽŅ‚ŅŒ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ С ĐģĐžĐēаĐģҌĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛. ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ ҆ĐĩĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, Ņ‰ĐžĐą ĐŊĐ°Ņ‚ĐžĐŧŅ–ŅŅ‚ŅŒ СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊŅ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ.", + "advanced_settings_prefer_remote_title": "ĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊиĐŧ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅĐŧ", "advanced_settings_proxy_headers_subtitle": "ВизĐŊĐ°Ņ‡Ņ‚Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēҁҖ-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ŅĐēŅ– Immich ĐŧĐ°Ņ” ĐŊĐ°Đ´ŅĐ¸ĐģĐ°Ņ‚Đ¸ С ĐēĐžĐļĐŊиĐŧ ĐŧĐĩŅ€ĐĩĐļĐĩвиĐŧ СаĐŋĐ¸Ņ‚ĐžĐŧ", - "advanced_settings_proxy_headers_title": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēŅ– ĐŋŅ€ĐžĐēҁҖ-ĐˇĐ°ĐŗĐžĐģОвĐēи [ЕКСПЕРИМЕНĐĸАЛĐŦНА Đ’Đ•Đ ĐĄĐ†Đ¯]", - "advanced_settings_readonly_mode_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ Ņ€ĐĩĐļиĐŧ҃ ҂ҖĐģҌĐēи Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, в ŅĐēĐžĐŧ҃ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— ĐŧĐžĐļĐŊа ҂ҖĐģҌĐēи ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸, а Ņ‚Đ°ĐēŅ– Ņ„ŅƒĐŊĐē҆Җҗ, ŅĐē Đ˛Đ¸ĐąŅ–Ņ€ Đ´ĐĩĐēŅ–ĐģҌĐēĐžŅ… ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ, ҁĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ, ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ°, видаĐģĐĩĐŊĐŊŅ, виĐŧĐēĐŊĐĩĐŊŅ–. ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ/виĐŧĐēĐŊĐĩĐŊĐŊŅ Ņ€ĐĩĐļиĐŧ҃ ҂ҖĐģҌĐēи Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ Đ°Đ˛Đ°Ņ‚Đ°Ņ€Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐŊа ĐŗĐžĐģОвĐŊĐžĐŧ҃ ĐĩĐēŅ€Đ°ĐŊŅ–", + "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_sync_remote_deletions_subtitle": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž видаĐģŅŅ‚Đ¸ айО Đ˛Ņ–Đ´ĐŊОвĐģŅŽĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģ ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—, ĐēĐžĐģи Ņ†Ņ Đ´Ņ–Ņ виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ в вĐĩĐą-Ņ–ĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅ–", + "advanced_settings_self_signed_ssl_title": "ХаĐŧĐžĐŋŅ–Đ´ĐŋĐ¸ŅĐ°ĐŊŅ– SSL-ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ¸ [ЕКСПЕРИМЕНĐĸАЛĐŦНО]", + "advanced_settings_sync_remote_deletions_subtitle": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž видаĐģŅŅ‚Đ¸ айО Đ˛Ņ–Đ´ĐŊОвĐģŅŽĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—, ĐēĐžĐģи Ņ†Ņ Đ´Ņ–Ņ виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ ҃ вĐĩĐą-Ņ–ĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅ–", "advanced_settings_sync_remote_deletions_title": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊĐ¸Ņ… видаĐģĐĩĐŊҌ [ЕКСПЕРИМЕНĐĸАЛĐŦНО]", - "advanced_settings_tile_subtitle": "Đ ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "advanced_settings_troubleshooting_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Ņ– Ņ„ŅƒĐŊĐē҆Җҗ Đ´ĐģŅ ҃ҁ҃ĐŊĐĩĐŊĐŊŅ ĐŊĐĩҁĐŋŅ€Đ°Đ˛ĐŊĐžŅŅ‚ĐĩĐš", + "advanced_settings_tile_subtitle": "Đ ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", + "advanced_settings_troubleshooting_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐŊŅ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Ņ–Đš Đ´ĐģŅ ҃ҁ҃ĐŊĐĩĐŊĐŊŅ ĐŊĐĩҁĐŋŅ€Đ°Đ˛ĐŊĐžŅŅ‚ĐĩĐš", "advanced_settings_troubleshooting_title": "ĐŖŅŅƒĐŊĐĩĐŊĐŊŅ ĐŊĐĩҁĐŋŅ€Đ°Đ˛ĐŊĐžŅŅ‚ĐĩĐš", "age_months": "Đ’Ņ–Đē {months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", "age_year_months": "Đ’Ņ–Đē 1 ҀҖĐē, {months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", - "age_years": "{years, plural, other {Đ’Ņ–Đē #}}", + "age_years": "{years, plural, one {Đ’Ņ–Đē #} few {Đ’Ņ–Đē #} many {Đ’Ņ–Đē #} other {Đ’Ņ–Đē #}}", "album": "АĐģŅŒĐąĐžĐŧ", "album_added": "АĐģŅŒĐąĐžĐŧ дОдаĐŊĐž", "album_added_notification_setting_description": "ĐžŅ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°Ņ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ, ĐēĐžĐģи Đ˛Đ°Ņ Đ´ĐžĐ´Đ°ŅŽŅ‚ŅŒ Đ´Đž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž аĐģŅŒĐąĐžĐŧ҃", - "album_cover_updated": "ОбĐēĐģадиĐŊĐēа аĐģŅŒĐąĐžĐŧ҃ ĐžĐŊОвĐģĐĩĐŊа", + "album_cover_updated": "ОбĐēĐģадиĐŊĐē҃ аĐģŅŒĐąĐžĐŧ҃ ĐžĐŊОвĐģĐĩĐŊĐž", "album_delete_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ {album}?", - "album_delete_confirmation_description": "Đ¯ĐēŅ‰Đž аĐģŅŒĐąĐžĐŧ ĐąŅƒĐ˛ ҁĐŋŅ–ĐģҌĐŊиĐŧ, Ņ–ĐŊŅˆŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ– ĐŊĐĩ СĐŧĐžĐļŅƒŅ‚ŅŒ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐŊŅŒĐžĐŗĐž.", + "album_delete_confirmation_description": "Đ¯ĐēŅ‰Đž аĐģŅŒĐąĐžĐŧ Ņ” ҁĐŋŅ–ĐģҌĐŊиĐŧ, Ņ–ĐŊŅˆŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ– ĐąŅ–ĐģҌ҈Đĩ ĐŊĐĩ СĐŧĐžĐļŅƒŅ‚ŅŒ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐŊŅŒĐžĐŗĐž.", "album_deleted": "АĐģŅŒĐąĐžĐŧ видаĐģĐĩĐŊĐž", - "album_info_card_backup_album_excluded": "Đ’Đ˜Đ›ĐŖĐ§Đ•ĐĐ˜Đ™", - "album_info_card_backup_album_included": "ВКЛЮЧЕНИЙ", - "album_info_updated": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž аĐģŅŒĐąĐžĐŧ ĐžĐŊОвĐģĐĩĐŊа", - "album_leave": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ?", - "album_leave_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ СаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ {album}?", - "album_name": "Назва АĐģŅŒĐąĐžĐŧ҃", - "album_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ аĐģŅŒĐąĐžĐŧ҃", - "album_remove_user": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°?", - "album_remove_user_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ {user}?", + "album_info_card_backup_album_excluded": "НЕ ВРАĐĨĐžĐ’ĐŖĐ„ĐĸĐŦĐĄĐ¯", + "album_info_card_backup_album_included": "ВРАĐĨĐžĐ’ĐŖĐ„ĐĸĐŦĐĄĐ¯", + "album_info_updated": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž аĐģŅŒĐąĐžĐŧ ĐžĐŊОвĐģĐĩĐŊĐž", + "album_leave": "ПоĐēиĐŊŅƒŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ?", + "album_leave_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋĐžĐēиĐŊŅƒŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ {album}?", + "album_name": "Назва аĐģŅŒĐąĐžĐŧ҃", + "album_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ҃", + "album_remove_user": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°?", + "album_remove_user_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ {user}?", "album_search_not_found": "АĐģŅŒĐąĐžĐŧŅ–Đ˛, Ņ‰Đž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ Đ˛Đ°ŅˆĐžĐŧ҃ СаĐŋĐ¸Ņ‚Ņƒ, ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", "album_selected": "АĐģŅŒĐąĐžĐŧ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž", - "album_share_no_users": "ĐĄŅ…ĐžĐļĐĩ, ви ĐŋĐžĐ´Ņ–ĐģиĐģĐ¸ŅŅ Ņ†Đ¸Đŧ аĐģŅŒĐąĐžĐŧĐžĐŧ С ŅƒŅŅ–Đŧа ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи айО ҃ Đ˛Đ°Ņ ĐŊĐĩĐŧĐ°Ņ” ĐļОдĐŊĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°, С ŅĐēиĐŧ ĐŧĐžĐļĐŊа ĐąŅƒĐģĐž Đą ĐŋĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ.", - "album_summary": "ĐšĐžŅ€ĐžŅ‚ĐēиК ĐžĐŋĐ¸Ņ аĐģŅŒĐąĐžĐŧ҃", + "album_share_no_users": "ĐĄŅ…ĐžĐļĐĩ, ҆ĐĩĐš аĐģŅŒĐąĐžĐŧ вĐļĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиК ŅƒŅŅ–Đŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧ, айО ĐŊĐĩĐŧĐ°Ņ” ĐēĐžĐŗĐž Đ´ĐžĐ´Đ°Ņ‚Đ¸.", + "album_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ аĐģŅŒĐąĐžĐŧ҃", "album_updated": "АĐģŅŒĐąĐžĐŧ ĐžĐŊОвĐģĐĩĐŊĐž", - "album_updated_setting_description": "ĐžŅ‚Ņ€Đ¸ĐŧŅƒĐšŅ‚Đĩ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐŊа ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ, ĐēĐžĐģи ҃ ҁĐŋŅ–ĐģҌĐŊĐžĐŧ҃ аĐģŅŒĐąĐžĐŧŅ– С'ŅĐ˛ĐģŅŅŽŅ‚ŅŒŅŅ ĐŊĐžĐ˛Ņ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "album_upload_assets": "ВиваĐŊŅ‚Đ°ĐļŅ‚Đĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐˇŅ– ŅĐ˛ĐžĐŗĐž ĐēĐžĐŧĐŋ'ŅŽŅ‚ĐĩŅ€Đ° Ņ‚Đ° Đ´ĐžĐ´Đ°ĐšŅ‚Đĩ Ņ—Ņ… Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "album_updated_setting_description": "ĐžŅ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°Ņ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ, ĐēĐžĐģи ҃ ҁĐŋŅ–ĐģҌĐŊĐžĐŧ҃ аĐģŅŒĐąĐžĐŧŅ– С'ŅĐ˛ĐģŅŅŽŅ‚ŅŒŅŅ ĐŊĐžĐ˛Ņ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "album_upload_assets": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐˇŅ– ŅĐ˛ĐžĐŗĐž ĐēĐžĐŧĐŋ'ŅŽŅ‚ĐĩŅ€Đ° Ņ‚Đ° Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", "album_user_left": "Ви ĐŋĐžĐēиĐŊ҃Đģи {album}", - "album_user_removed": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ {user} видаĐģĐĩĐŊиК", + "album_user_removed": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° {user} виĐģŅƒŅ‡ĐĩĐŊĐž", "album_viewer_appbar_delete_confirm": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš аĐģŅŒĐąĐžĐŧ ĐˇŅ– ŅĐ˛ĐžĐŗĐž ОйĐģŅ–ĐēĐžĐ˛ĐžĐŗĐž СаĐŋĐ¸ŅŅƒ?", "album_viewer_appbar_share_err_delete": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "album_viewer_appbar_share_err_leave": "НĐĩ вдаĐģĐžŅŅ Đ˛Đ¸ĐšŅ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃", - "album_viewer_appbar_share_err_remove": "ВиĐŊиĐēĐģи ĐŋŅ€ĐžĐąĐģĐĩĐŧи С видаĐģĐĩĐŊĐŊŅĐŧ Ņ„Đ°ĐšĐģŅ–Đ˛ С аĐģŅŒĐąĐžĐŧ҃", + "album_viewer_appbar_share_err_remove": "НĐĩ вдаĐģĐžŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃", "album_viewer_appbar_share_err_title": "НĐĩ вдаĐģĐžŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ аĐģŅŒĐąĐžĐŧ҃", "album_viewer_appbar_share_leave": "Đ’Đ¸ĐšŅ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃", "album_viewer_appbar_share_to": "ĐŸĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ", "album_viewer_page_share_add_users": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛", - "album_with_link_access": "Đ‘ŅƒĐ´ŅŒ-Ņ…Ņ‚Đž С ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ ĐŧĐžĐļĐĩ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž в Ņ†ŅŒĐžĐŧ҃ аĐģŅŒĐąĐžĐŧŅ–.", + "album_with_link_access": "Đ‘ŅƒĐ´ŅŒ-Ņ…Ņ‚Đž С ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ ĐŧĐžĐļĐĩ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž Ņ‚Đ° ĐģŅŽĐ´ĐĩĐš ҃ Ņ†ŅŒĐžĐŧ҃ аĐģŅŒĐąĐžĐŧŅ–.", "albums": "АĐģŅŒĐąĐžĐŧи", - "albums_count": "{count, plural, one {1 аĐģŅŒĐąĐžĐŧ} few {{count, number} аĐģŅŒĐąĐžĐŧи} many {{count, number} аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {{count, number} аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", - "albums_default_sort_order": "ĐŸĐžŅ€ŅĐ´ĐžĐē ŅĐžŅ€Ņ‚ŅƒĐ˛Đ°ĐŊĐŊŅ аĐģŅŒĐąĐžĐŧŅ–Đ˛ Са СаĐŧĐžĐ˛Ņ‡ŅƒĐ˛Đ°ĐŊŅĐŧ", - "albums_default_sort_order_description": "ĐŸĐžŅ‡Đ°Ņ‚ĐēОвиК ĐŋĐžŅ€ŅĐ´ĐžĐē ŅĐžŅ€Ņ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŊĐžĐ˛Đ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛.", - "albums_feature_description": "КоĐģĐĩĐē҆Җҗ Ņ„Đ°ĐšĐģŅ–Đ˛, ŅĐēŅ– ĐŧĐžĐļĐŊа ҁĐŋŅ–ĐģҌĐŊĐž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ С Ņ–ĐŊŅˆĐ¸Đŧи ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи.", + "albums_count": "{count, plural, one {{count, number} аĐģŅŒĐąĐžĐŧ} few {{count, number} аĐģŅŒĐąĐžĐŧи} many {{count, number} аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {{count, number} аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", + "albums_default_sort_order": "ĐĸиĐŋОвиК ĐŋĐžŅ€ŅĐ´ĐžĐē ŅĐžŅ€Ņ‚ŅƒĐ˛Đ°ĐŊĐŊŅ аĐģŅŒĐąĐžĐŧŅ–Đ˛", + "albums_default_sort_order_description": "ĐŸĐžŅ‡Đ°Ņ‚ĐēОвиК ĐŋĐžŅ€ŅĐ´ĐžĐē ŅĐžŅ€Ņ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŊĐžĐ˛Đ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛.", + "albums_feature_description": "КоĐģĐĩĐē҆Җҗ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛, ŅĐēиĐŧи ĐŧĐžĐļĐŊа Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ С Ņ–ĐŊŅˆĐ¸Đŧи ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи.", "albums_on_device_count": "АĐģŅŒĐąĐžĐŧи ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— ({count})", "albums_selected": "{count, plural, one {# аĐģŅŒĐąĐžĐŧ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} few {# аĐģŅŒĐąĐžĐŧи Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} many {# аĐģŅŒĐąĐžĐŧŅ–Đ˛ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} other {# аĐģŅŒĐąĐžĐŧŅ–Đ˛ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž}}", "all": "ĐŖŅŅ–", "all_albums": "ĐŖŅŅ– аĐģŅŒĐąĐžĐŧи", "all_people": "ĐŖŅŅ– ĐģŅŽĐ´Đ¸", - "all_photos": "ĐŖŅŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—", + "all_photos": "ĐŖŅŅ– Ņ„ĐžŅ‚Đž", "all_videos": "ĐŖŅŅ– Đ˛Ņ–Đ´ĐĩĐž", - "allow_dark_mode": "ДозвоĐģĐ¸Ņ‚Đ¸ Ņ‚ĐĩĐŧĐŊиК Ņ€ĐĩĐļиĐŧ", - "allow_edits": "ДозвоĐģĐ¸Ņ‚Đ¸ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°ĐŊĐŊŅ", - "allow_public_user_to_download": "ДозвоĐģĐ¸Ņ‚Đ¸ ĐŋŅƒĐąĐģҖ҇ĐŊĐžĐŧ҃ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐ˛Ņ– СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", - "allow_public_user_to_upload": "ДозвоĐģĐ¸Ņ‚Đ¸ ĐŋŅƒĐąĐģҖ҇ĐŊиĐŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧ виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸", + "allow_dark_mode": "ĐĸĐĩĐŧĐŊа Ņ‚ĐĩĐŧа ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ", + "allow_edits": "Đ”Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸", + "allow_public_user_to_download": "Đ”Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ ĐŋŅƒĐąĐģҖ҇ĐŊĐžĐŧ҃ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐ˛Ņ– СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "allow_public_user_to_upload": "Đ”Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ ĐŋŅƒĐąĐģҖ҇ĐŊĐžĐŧ҃ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐ˛Ņ– виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "allowed": "ДозвоĐģĐĩĐŊĐž", "alt_text_qr_code": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ QR-ĐēĐžĐ´Ņƒ", "always_keep": "ЗавĐļди СйĐĩŅ€Ņ–ĐŗĐ°Ņ‚Đ¸", - "always_keep_photos_hint": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ÂĢĐ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩÂģ СйĐĩŅ€ĐĩĐļĐĩ Đ˛ŅŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—.", + "always_keep_photos_hint": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ÂĢĐ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩÂģ СйĐĩŅ€ĐĩĐļĐĩ Đ˛ŅŅ– Ņ„ĐžŅ‚Đž ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—.", "always_keep_videos_hint": "Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ÂĢĐ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩÂģ СйĐĩŅ€ĐĩĐļĐĩ Đ˛ŅŅ– Đ˛Ņ–Đ´ĐĩĐž ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—.", "anti_clockwise": "ĐŸŅ€ĐžŅ‚Đ¸ ĐŗĐžĐ´Đ¸ĐŊĐŊиĐēĐžĐ˛ĐžŅ— ҁ҂ҀҖĐģĐēи", "api_key": "КĐģŅŽŅ‡ API", - "api_key_description": "ĐĻĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐąŅƒĐ´Đĩ ĐŋĐžĐēаСаĐŊĐĩ ĐģĐ¸ŅˆĐĩ ОдиĐŊ Ņ€Đ°Đˇ. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ОйОв'ŅĐˇĐēОвО ҁĐēĐžĐŋŅ–ŅŽĐšŅ‚Đĩ ĐšĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐ´ СаĐēŅ€Đ¸Ņ‚Ņ‚ŅĐŧ Đ˛Ņ–ĐēĐŊа.", + "api_key_description": "ĐĻĐĩ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐąŅƒĐ´Đĩ ĐŋĐžĐēаСаĐŊĐž ĐģĐ¸ŅˆĐĩ ОдиĐŊ Ņ€Đ°Đˇ. Обов'ŅĐˇĐēОвО ҁĐēĐžĐŋŅ–ŅŽĐšŅ‚Đĩ ĐšĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐ´ СаĐēŅ€Đ¸Ņ‚Ņ‚ŅĐŧ Đ˛Ņ–ĐēĐŊа.", "api_key_empty": "Назва Đ˛Đ°ŅˆĐžĐŗĐž ĐēĐģŅŽŅ‡Đ° API ĐŊĐĩ ĐŧĐžĐļĐĩ ĐąŅƒŅ‚Đ¸ ĐŋĐžŅ€ĐžĐļĐŊŅŒĐžŅŽ", "api_keys": "КĐģŅŽŅ‡Ņ– API", "app_architecture_variant": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚ (ĐŅ€Ņ…Ņ–Ņ‚ĐĩĐēŅ‚ŅƒŅ€Đ°)", @@ -541,179 +541,179 @@ "app_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", "app_stores": "ĐœĐ°ĐŗĐ°ĐˇĐ¸ĐŊи ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐēŅ–Đ˛", "app_update_available": "ОĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐĩ", - "appears_in": "З'ŅĐ˛ĐģŅŅ”Ņ‚ŅŒŅŅ в", + "appears_in": "Đ¤Ņ–ĐŗŅƒŅ€ŅƒŅ” в", "apply_count": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ({count, number})", "archive": "ĐŅ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸", - "archive_action_prompt": "{count, plural, one {# Ņ„Đ°ĐšĐģ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} few {# Ņ„Đ°ĐšĐģи дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} other {# Ņ„Đ°ĐšĐģŅ–Đ˛ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ}}", - "archive_or_unarchive_photo": "ĐŅ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ айО Ņ€ĐžĐˇĐ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž", - "archive_page_no_archived_assets": "НĐĩĐŧĐ°Ņ” Đ°Ņ€Ņ…Ņ–Đ˛ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", + "archive_action_prompt": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ дОдаĐŊĐž Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ}}", + "archive_or_unarchive_photo": "ĐŅ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ айО виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ Ņ„ĐžŅ‚Đž", + "archive_page_no_archived_assets": "НĐĩĐŧĐ°Ņ” Đ°Ņ€Ņ…Ņ–Đ˛ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "archive_page_title": "ĐŅ€Ņ…Ņ–Đ˛ ({count})", "archive_size": "РОСĐŧŅ–Ņ€ Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", "archive_size_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐžĐˇĐŧŅ–Ņ€ Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ Đ´ĐģŅ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ (҃ GiB)", - "archived": "ĐŅ€Ņ…Ņ–Đ˛", - "archived_count": "{count, plural, other {ĐŅ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž #}}", + "archived": "Đ—Đ°Đ°Ņ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž", + "archived_count": "{count, plural, one {ĐŅ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž #} few {ĐŅ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž #} many {ĐŅ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž #} other {ĐŅ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊĐž #}}", "are_these_the_same_person": "ĐĻĐĩ Ņ‚Đ° ŅĐ°Đŧа ĐģŅŽĐ´Đ¸ĐŊа?", "are_you_sure_to_do_this": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ҆Đĩ ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸?", "array_field_not_fully_supported": "ПоĐģŅ ĐŧĐ°ŅĐ¸Đ˛Ņƒ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅŽŅ‚ŅŒ Ņ€ŅƒŅ‡ĐŊĐžĐŗĐž Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°ĐŊĐŊŅ JSON", - "asset_action_delete_err_read_only": "НĐĩĐŧĐžĐļĐģивО видаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ(и) ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "asset_action_share_err_offline": "НĐĩĐŧĐžĐļĐģивО ĐžĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– Ņ„Đ°ĐšĐģ(и), ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", + "asset_action_delete_err_read_only": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", + "asset_action_share_err_offline": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ĐŋŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", "asset_added_to_album": "ДодаĐŊĐž Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "asset_adding_to_album": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃â€Ļ", - "asset_created": "ФаКĐģ дОдаĐŊĐž", - "asset_description_updated": "ОĐŊОвĐģĐĩĐŊĐž ĐžĐŋĐ¸Ņ Ņ„Đ°ĐšĐģ҃", - "asset_filename_is_offline": "ФаКĐģ {filename} ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК", - "asset_has_unassigned_faces": "Є ĐŊĐĩŅ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "asset_adding_to_album": "ДодаваĐŊĐŊŅ Đ´Đž аĐģŅŒĐąĐžĐŧ҃â€Ļ", + "asset_created": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž", + "asset_description_updated": "ОĐŊОвĐģĐĩĐŊĐž ĐžĐŋĐ¸Ņ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "asset_filename_is_offline": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ {filename} ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК", + "asset_has_unassigned_faces": "Є ĐŊĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ", "asset_hashing": "ĐĨĐĩŅˆŅƒĐ˛Đ°ĐŊĐŊŅâ€Ļ", "asset_list_group_by_sub_title": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ Са", - "asset_list_layout_settings_dynamic_layout_title": "ДиĐŊаĐŧҖ҇ĐŊĐĩ ĐēĐžĐŧĐŋĐžĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", + "asset_list_layout_settings_dynamic_layout_title": "ДиĐŊаĐŧҖ҇ĐŊиК ĐŧаĐēĐĩŅ‚", "asset_list_layout_settings_group_automatically": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž", - "asset_list_layout_settings_group_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐŋĐž", + "asset_list_layout_settings_group_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Са", "asset_list_layout_settings_group_by_month_day": "ĐœŅ–ŅŅŅ†ŅŒ + Đ´ĐĩĐŊҌ", - "asset_list_layout_sub_title": "РОСĐŧŅ–Ņ‚Đēа", + "asset_list_layout_sub_title": "МаĐēĐĩŅ‚", "asset_list_settings_subtitle": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ¸ĐŗĐģŅĐ´Ņƒ ҁҖ҂Đēи Ņ„ĐžŅ‚Đž", - "asset_list_settings_title": "Đ¤ĐžŅ‚Đž-ҁҖ҂Đēа", - "asset_not_found_on_device_android": "ФаКĐģ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "asset_not_found_on_device_ios": "ФаКĐģ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—. Đ¯ĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ iCloud, Ņ„Đ°ĐšĐģ ĐŧĐžĐļĐĩ ĐąŅƒŅ‚Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧ ҇ĐĩŅ€ĐĩС ĐŋĐžŅˆĐēОдĐļĐĩĐŊиК Ņ„Đ°ĐšĐģ, Ņ‰Đž СйĐĩŅ€Ņ–ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ в iCloud", - "asset_not_found_on_icloud": "ФаКĐģ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž в iCloud. МоĐļĐģивО, Ņ„Đ°ĐšĐģ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК ҇ĐĩŅ€ĐĩС ĐŋĐžŅˆĐēОдĐļĐĩĐŊиК Ņ„Đ°ĐšĐģ, Ņ‰Đž СйĐĩŅ€Ņ–ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ в iCloud", - "asset_offline": "ФаКĐģ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК", - "asset_offline_description": "ĐĻĐĩĐš Ņ„Đ°ĐšĐģ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа Đ´Đ¸ŅĐē҃. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ° Immich Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ.", - "asset_restored_successfully": "ФаКĐģ ҃ҁĐŋŅ–ŅˆĐŊĐž Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž", + "asset_list_settings_title": "Đ¤ĐžŅ‚ĐžŅŅ–Ņ‚Đēа", + "asset_not_found_on_device_android": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", + "asset_not_found_on_device_ios": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—. Đ¯ĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ iCloud, ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŧĐžĐļĐĩ ĐąŅƒŅ‚Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧ ҇ĐĩŅ€ĐĩС ĐŋĐžŅˆĐēОдĐļĐĩĐŊиК Ņ„Đ°ĐšĐģ, Ņ‰Đž СйĐĩŅ€Ņ–ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ в iCloud", + "asset_not_found_on_icloud": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž в iCloud. МоĐļĐģивО, ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК ҇ĐĩŅ€ĐĩС ĐŋĐžŅˆĐēОдĐļĐĩĐŊиК Ņ„Đ°ĐšĐģ, Ņ‰Đž СйĐĩŅ€Ņ–ĐŗĐ°Ņ”Ņ‚ŅŒŅŅ в iCloud", + "asset_offline": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК", + "asset_offline_description": "ĐĻĐĩĐš СОвĐŊŅ–ŅˆĐŊŅ–Đš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐŊа Đ´Đ¸ŅĐē҃. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ° Immich Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ.", + "asset_restored_successfully": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž", "asset_skipped": "ĐŸŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", "asset_skipped_in_trash": "ĐŖ ĐēĐžŅˆĐ¸Đē҃", - "asset_trashed": "ФаКĐģ видаĐģĐĩĐŊĐž", - "asset_troubleshoot": "Đ’Đ¸Ņ€Ņ–ŅˆĐĩĐŊĐŊŅ ĐŋŅ€ĐžĐąĐģĐĩĐŧ С Ņ„Đ°ĐšĐģаĐŧи", + "asset_trashed": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа", + "asset_troubleshoot": "Đ’Đ¸Ņ€Ņ–ŅˆĐĩĐŊĐŊŅ ĐŋŅ€ĐžĐąĐģĐĩĐŧ Ņ–Đˇ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Đŧи", "asset_uploaded": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐž", "asset_uploading": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅâ€Ļ", "asset_viewer_settings_subtitle": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡Đ° ĐŗĐ°ĐģĐĩŅ€ĐĩŅ—", - "asset_viewer_settings_title": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊҌ", - "assets": "Ņ„Đ°ĐšĐģи", - "assets_added_count": "ДодаĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_added_to_album_count": "ДодаĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "assets_added_to_albums_count": "ДодаĐŊĐž {assetTotal, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} Đ´Đž {albumTotal, plural, one {# аĐģŅŒĐąĐžĐŧ҃} few {# аĐģŅŒĐąĐžĐŧŅ–Đ˛} many {# аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {# аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", - "assets_cannot_be_added_to_album_count": "{count, plural, one {ФаКĐģ} few {ФаКĐģи} many {ФаКĐģи} other {ФаКĐģи}} ĐŊĐĩ ĐŧĐžĐļĐŊа Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "assets_cannot_be_added_to_albums": "{count, plural, one {ФаКĐģ} few {ФаКĐģи} many {ФаКĐģŅ–Đ˛} other {ФаКĐģŅ–Đ˛}} ĐŊĐĩ ĐŧĐžĐļĐŊа Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž ĐļОдĐŊĐžĐŗĐž С аĐģŅŒĐąĐžĐŧŅ–Đ˛", - "assets_count": "{count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_deleted_permanently": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_deleted_permanently_from_server": "ВидаĐģĐĩĐŊĐž ĐŊаСавĐļди {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} С ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Immich", - "assets_downloaded_failed": "{count, plural, one {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģ — {error} ĐŊĐĩ вдаĐģĐžŅŅ} few {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģи — {error} ĐŊĐĩ вдаĐģĐžŅŅ} many {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛ — {error} ĐŊĐĩ вдаĐģĐžŅŅ} other {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛ — {error} ĐŊĐĩ вдаĐģĐžŅŅ}}", - "assets_downloaded_successfully": "{count, plural, one {ĐŖŅĐŋŅ–ŅˆĐŊĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģ} few {ĐŖŅĐŋŅ–ŅˆĐŊĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģи} many {ĐŖŅĐŋŅ–ŅˆĐŊĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛} other {ĐŖŅĐŋŅ–ŅˆĐŊĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_moved_to_trash_count": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} Đ´Đž ĐēĐžŅˆĐ¸Đēа", - "assets_permanently_deleted_count": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_removed_count": "ВиĐģŅƒŅ‡ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_removed_permanently_from_device": "НазавĐļди виĐģŅƒŅ‡ĐĩĐŊĐž С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_restore_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ŅĐ˛ĐžŅ— Ņ„Đ°ĐšĐģи С ĐēĐžŅˆĐ¸Đēа? ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸! ЗвĐĩŅ€ĐŊŅ–Ņ‚ŅŒ ŅƒĐ˛Đ°ĐŗŅƒ, Ņ‰Đž ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– Ņ„Đ°ĐšĐģи ĐŊĐĩ ĐŧĐžĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊŅ– Ņ‚Đ°ĐēиĐŧ Ņ‡Đ¸ĐŊĐžĐŧ.", - "assets_restored_count": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_restored_successfully": "ĐŖŅĐŋŅ–ŅˆĐŊĐž Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_trashed": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_trashed_count": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_trashed_from_server": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "assets_were_part_of_album_count": "{count, plural, one {ФаКĐģ ĐąŅƒĐ˛} few {ФаКĐģи ĐąŅƒĐģи} other {ФаКĐģи ĐąŅƒĐģи}} вĐļĐĩ Ņ‡Đ°ŅŅ‚Đ¸ĐŊĐžŅŽ аĐģŅŒĐąĐžĐŧ҃", - "assets_were_part_of_albums_count": "{count, plural, one {ФаКĐģ вĐļĐĩ ĐąŅƒĐ˛} few {ФаКĐģи вĐļĐĩ ĐąŅƒĐģи} many {ФаКĐģŅ–Đ˛ вĐļĐĩ ĐąŅƒĐģи} other {ФаКĐģŅ–Đ˛ вĐļĐĩ ĐąŅƒĐģи}} Ņ‡Đ°ŅŅ‚Đ¸ĐŊĐžŅŽ аĐģŅŒĐąĐžĐŧŅ–Đ˛", + "asset_viewer_settings_title": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", + "assets": "ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "assets_added_count": "ДодаĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_added_to_album_count": "ДодаĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "assets_added_to_albums_count": "ДодаĐŊĐž {assetTotal, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž {albumTotal, plural, one {# аĐģŅŒĐąĐžĐŧ҃} few {# аĐģŅŒĐąĐžĐŧŅ–Đ˛} many {# аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {# аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", + "assets_cannot_be_added_to_album_count": "{count, plural, one {ЕĐģĐĩĐŧĐĩĐŊŅ‚} few {ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "assets_cannot_be_added_to_albums": "{count, plural, one {ЕĐģĐĩĐŧĐĩĐŊŅ‚} few {ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž ĐļОдĐŊĐžĐŗĐž С аĐģŅŒĐąĐžĐŧŅ–Đ˛", + "assets_count": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_deleted_permanently": "НазавĐļди видаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_deleted_permanently_from_server": "ВидаĐģĐĩĐŊĐž ĐŊаСавĐļди {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Ņ–Đˇ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Immich", + "assets_downloaded_failed": "{count, plural, one {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģ — ĐŊĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {error}} few {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģи — ĐŊĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {error}} many {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛ — ĐŊĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {error}} other {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛ — ĐŊĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {error}}}", + "assets_downloaded_successfully": "{count, plural, one {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģ} few {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģи} many {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛} other {ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž # Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "assets_moved_to_trash_count": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž ĐēĐžŅˆĐ¸Đēа", + "assets_permanently_deleted_count": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_removed_count": "ВиĐģŅƒŅ‡ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_removed_permanently_from_device": "НазавĐļди виĐģŅƒŅ‡ĐĩĐŊĐž С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_restore_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ŅĐ˛ĐžŅ— ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ С ĐēĐžŅˆĐ¸Đēа? ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸! ЗвĐĩŅ€ĐŊŅ–Ņ‚ŅŒ ŅƒĐ˛Đ°ĐŗŅƒ, Ņ‰Đž ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐĩ Đ˛Đ´Đ°ŅŅ‚ŅŒŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ‚Đ°ĐēиĐŧ Ņ‡Đ¸ĐŊĐžĐŧ.", + "assets_restored_count": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_restored_successfully": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_trashed": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_trashed_count": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_trashed_from_server": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "assets_were_part_of_album_count": "{count, plural, one {ЕĐģĐĩĐŧĐĩĐŊŅ‚ ĐąŅƒĐ˛} few {ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐģи} many {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐąŅƒĐģĐž} other {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐąŅƒĐģĐž}} вĐļĐĩ Ņ‡Đ°ŅŅ‚Đ¸ĐŊĐžŅŽ аĐģŅŒĐąĐžĐŧ҃", + "assets_were_part_of_albums_count": "{count, plural, one {ЕĐģĐĩĐŧĐĩĐŊŅ‚ вĐļĐĩ ĐąŅƒĐ˛} few {ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ вĐļĐĩ ĐąŅƒĐģи} many {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ вĐļĐĩ ĐąŅƒĐģĐž} other {ЕĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ вĐļĐĩ ĐąŅƒĐģĐž}} Ņ‡Đ°ŅŅ‚Đ¸ĐŊĐžŅŽ аĐģŅŒĐąĐžĐŧŅ–Đ˛", "authorized_devices": "ĐĐ˛Ņ‚ĐžŅ€Đ¸ĐˇĐžĐ˛Đ°ĐŊŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "automatic_endpoint_switching_subtitle": "ĐŸŅ–Đ´ĐēĐģŅŽŅ‡Đ°Ņ‚Đ¸ŅŅ ĐģĐžĐēаĐģҌĐŊĐž ҇ĐĩŅ€ĐĩС СаСĐŊĐ°Ņ‡ĐĩĐŊ҃ Wi-Fi ĐŧĐĩŅ€ĐĩĐļ҃, ĐēĐžĐģи ҆Đĩ ĐŧĐžĐļĐģивО, Ņ– виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅ– С'Ņ”Đ´ĐŊаĐŊĐŊŅ в Ņ–ĐŊŅˆĐ¸Ņ… виĐŋадĐēĐ°Ņ…", + "automatic_endpoint_switching_subtitle": "ĐŸŅ–Đ´'Ņ”Đ´ĐŊŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ ĐģĐžĐēаĐģҌĐŊĐž ҇ĐĩŅ€ĐĩС СаСĐŊĐ°Ņ‡ĐĩĐŊ҃ ĐŧĐĩŅ€ĐĩĐļ҃ Wi-Fi, ĐēĐžĐģи ҆Đĩ ĐŧĐžĐļĐģивО, Ņ– виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅ– С'Ņ”Đ´ĐŊаĐŊĐŊŅ в Ņ–ĐŊŅˆĐ¸Ņ… виĐŋадĐēĐ°Ņ…", "automatic_endpoint_switching_title": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ ĐŋĐĩŅ€ĐĩĐŧиĐēаĐŊĐŊŅ URL", - "autoplay_slideshow": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ҁĐģĐ°ĐšĐ´ŅˆĐžŅƒ", + "autoplay_slideshow": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ҁĐģаКд-ŅˆĐžŅƒ", "back": "Назад", "back_close_deselect": "ПовĐĩŅ€ĐŊŅƒŅ‚Đ¸ŅŅ, СаĐēŅ€Đ¸Ņ‚Đ¸ айО ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Đ¸ĐąŅ–Ņ€", - "background_backup_running_error": "ĐĐ°Ņ€Đ°ĐˇŅ– виĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ Ņ„ĐžĐŊОвĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ, ĐŊĐĩĐŧĐžĐļĐģивО Ņ€ĐžĐˇĐŋĐžŅ‡Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ€ŅƒŅ‡ĐŊ҃", - "background_location_permission": "Đ”ĐžĐˇĐ˛Ņ–Đģ Đ´Đž ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ ҃ Ņ„ĐžĐŊŅ–", - "background_location_permission_content": "ЊОй ĐŋĐĩŅ€ĐĩĐŧиĐēĐ°Ņ‚Đ¸ ĐŧĐĩŅ€ĐĩĐļŅ– ҃ Ņ„ĐžĐŊОвОĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–, Immich ĐŧĐ°Ņ” *СавĐļди* ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž Ņ‚ĐžŅ‡ĐŊĐžŅ— ĐŗĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–Ņ—, Ņ‰ĐžĐą ĐˇŅ‡Đ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ Wi-Fi ĐŧĐĩŅ€ĐĩĐļŅ–", - "background_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ Ņ„ĐžĐŊ҃", + "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": "ĐĸĐžŅ€ĐēĐŊŅ–Ņ‚ŅŒŅŅ, Ņ‰ĐžĐą Đ´ĐžĐ´Đ°Ņ‚Đ¸, Đ´Đ˛Ņ–Ņ‡Ņ–, Ņ‰ĐžĐą виĐģŅƒŅ‡Đ¸Ņ‚Đ¸", - "backup_album_selection_page_assets_scatter": "ФаКĐģи ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŊаĐģĐĩĐļĐ°Ņ‚Đ¸ Đ´Đž ĐēŅ–ĐģҌĐēĐžŅ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ вОдĐŊĐžŅ‡Đ°Ņ. ĐĸаĐēиĐŧ Ņ‡Đ¸ĐŊĐžĐŧ, аĐģŅŒĐąĐžĐŧи ĐŧĐžĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ дОдаĐŊŅ– айО виĐģŅƒŅ‡ĐĩĐŊŅ– ĐŋŅ–Đ´ Ņ‡Đ°Ņ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ.", - "backup_album_selection_page_select_albums": "ОбĐĩŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧи", - "backup_album_selection_page_selection_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž ĐžĐąŅ€Đ°ĐŊĐĩ", - "backup_album_selection_page_total_assets": "Đ—Đ°ĐŗĐ°ĐģҌĐŊа ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ҃ĐŊŅ–ĐēаĐģҌĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", + "backup_album_selection_page_albums_tap": "ОдĐŊĐĩ Ņ‚ĐžŅ€ĐēаĐŊĐŊŅ — Đ´ĐžĐ´Đ°Ņ‚Đ¸, ĐŋĐžĐ´Đ˛Ņ–ĐšĐŊĐĩ — виĐģŅƒŅ‡Đ¸Ņ‚Đ¸", + "backup_album_selection_page_assets_scatter": "ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŧĐžĐļŅƒŅ‚ŅŒ ĐŊаĐģĐĩĐļĐ°Ņ‚Đ¸ Đ´Đž ĐēŅ–ĐģҌĐēĐžŅ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ вОдĐŊĐžŅ‡Đ°Ņ. ĐĸаĐēиĐŧ Ņ‡Đ¸ĐŊĐžĐŧ, аĐģŅŒĐąĐžĐŧи ĐŧĐžĐļĐŊа Đ˛Ņ€Đ°Ņ…ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ айО ĐŊĐĩ Đ˛Ņ€Đ°Ņ…ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋŅ–Đ´ Ņ‡Đ°Ņ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ.", + "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_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": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€ŅŅŽ ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛Đ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛â€Ļ", - "backup_background_service_error_title": "ПоĐŧиĐģĐēа Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", - "backup_background_service_in_progress_notification": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Đ°ŅˆĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛â€Ļ", + "backup_background_service_default_notification": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€ŅŅŽ ĐŊĐ°ŅĐ˛ĐŊŅ–ŅŅ‚ŅŒ ĐŊĐžĐ˛Đ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛â€Ļ", + "backup_background_service_error_title": "Đ—ĐąŅ–Đš Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", + "backup_background_service_in_progress_notification": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Đ°ŅˆĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛â€Ļ", "backup_background_service_upload_failure_notification": "НĐĩ вдаĐģĐžŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {filename}", "backup_controller_page_albums": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ аĐģŅŒĐąĐžĐŧŅ–Đ˛", - "backup_controller_page_background_app_refresh_disabled_content": "ДĐģŅ Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ„ĐžĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ в ĐŧĐĩĐŊŅŽ \"НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ > Đ—Đ°ĐŗĐ°ĐģҌĐŊŅ– > ФОĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃\".", - "backup_controller_page_background_app_refresh_disabled_title": "ФОĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ виĐŧĐēĐŊĐĩĐŊĐĩ", + "backup_controller_page_background_app_refresh_disabled_content": "ДĐģŅ Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ„ĐžĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ в ĐŧĐĩĐŊŅŽ ÂĢНаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ > Đ—Đ°ĐŗĐ°ĐģҌĐŊŅ– > ФОĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃Âģ.", + "backup_controller_page_background_app_refresh_disabled_title": "ФОĐŊОвĐĩ ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ виĐŧĐēĐŊĐĩĐŊĐž", "backup_controller_page_background_app_refresh_enable_button_text": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ", "backup_controller_page_background_battery_info_link": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ŅĐē", - "backup_controller_page_background_battery_info_message": "ДĐģŅ ĐŊаКĐēŅ€Đ°Ņ‰ĐžĐŗĐž Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ виĐŧĐēĐŊŅ–Ņ‚ŅŒ ĐąŅƒĐ´ŅŒ-ŅĐē҃ ĐžĐŋŅ‚Đ¸ĐŧŅ–ĐˇĐ°Ņ†Ņ–ŅŽ аĐē҃Đŧ҃ĐģŅŅ‚ĐžŅ€Đ°, ŅĐēа ОйĐŧĐĩĐļŅƒŅ” Ņ„ĐžĐŊĐžĐ˛Ņƒ аĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ Đ´ĐģŅ Immich.\n\nĐĄĐŋĐžŅŅ–Đą СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, Ņ‚ĐžĐŧ҃ ҈҃ĐēĐ°ĐšŅ‚Đĩ ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊ҃ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ҃ Đ˛Đ¸Ņ€ĐžĐąĐŊиĐēа Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ.", + "backup_controller_page_background_battery_info_message": "ДĐģŅ ĐŊаКĐēŅ€Đ°Ņ‰ĐžĐŗĐž Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ виĐŧĐēĐŊŅ–Ņ‚ŅŒ ĐąŅƒĐ´ŅŒ-ŅĐē҃ ĐžĐŋŅ‚Đ¸ĐŧŅ–ĐˇĐ°Ņ†Ņ–ŅŽ аĐē҃Đŧ҃ĐģŅŅ‚ĐžŅ€Đ°, ŅĐēа ОйĐŧĐĩĐļŅƒŅ” Ņ„ĐžĐŊĐžĐ˛Ņƒ аĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ Đ´ĐģŅ Immich.\n\nĐžŅĐēŅ–ĐģҌĐēи ҆Đĩ СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, СĐŊĐ°ĐšĐ´Ņ–Ņ‚ŅŒ ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊ҃ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ҃ Đ˛Đ¸Ņ€ĐžĐąĐŊиĐēа Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ.", "backup_controller_page_background_battery_info_ok": "ОК", - "backup_controller_page_background_battery_info_title": "ОĐŋŅ‚Đ¸ĐŧŅ–ĐˇĐ°Ņ†Ņ–Ņ ĐąĐ°Ņ‚Đ°Ņ€ĐĩŅ—", + "backup_controller_page_background_battery_info_title": "ОĐŋŅ‚Đ¸ĐŧŅ–ĐˇĐ°Ņ†Ņ–Ņ аĐē҃Đŧ҃ĐģŅŅ‚ĐžŅ€Đ°", "backup_controller_page_background_charging": "Đ›Đ¸ŅˆĐĩ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐˇĐ°Ņ€ŅĐ´ĐļаĐŊĐŊŅ", - "backup_controller_page_background_configure_error": "НĐĩ вдаĐģĐžŅŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„ĐžĐŊОвиК ҁĐĩŅ€Đ˛Ņ–Ņ", - "backup_controller_page_background_delay": "Đ—Đ°Ņ‚Ņ€Đ¸ĐŧĐēа Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐŊĐžĐ˛Đ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛: {duration}", - "backup_controller_page_background_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ„ĐžĐŊĐžĐ˛Ņƒ ҁĐģ҃ĐļĐąŅƒ, Ņ‰ĐžĐą Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ĐąŅƒĐ´ŅŒ-ŅĐēĐ¸Ņ… ĐŊĐžĐ˛Đ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛ ĐąĐĩС ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊĐžŅŅ‚Ņ– Đ˛Ņ–Đ´ĐēŅ€Đ¸Đ˛Đ°Ņ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē", + "backup_controller_page_background_configure_error": "НĐĩ вдаĐģĐžŅŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„ĐžĐŊĐžĐ˛Ņƒ ҁĐģ҃ĐļĐąŅƒ", + "backup_controller_page_background_delay": "Đ—Đ°Ņ‚Ņ€Đ¸ĐŧĐēа Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐŊĐžĐ˛Đ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛: {duration}", + "backup_controller_page_background_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ„ĐžĐŊĐžĐ˛Ņƒ ҁĐģ҃ĐļĐąŅƒ, Ņ‰ĐžĐą Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ĐąŅƒĐ´ŅŒ-ŅĐēĐ¸Ņ… ĐŊĐžĐ˛Đ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐąĐĩС ĐŋĐžŅ‚Ņ€Đĩйи Đ˛Ņ–Đ´ĐēŅ€Đ¸Đ˛Đ°Ņ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē", "backup_controller_page_background_is_off": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ„ĐžĐŊОвĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ виĐŧĐēĐŊĐĩĐŊĐž", - "backup_controller_page_background_is_on": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ„ĐžĐŊОвĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", - "backup_controller_page_background_turn_off": "ВиĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ„ĐžĐŊОвиК ҁĐĩŅ€Đ˛Ņ–Ņ", - "backup_controller_page_background_turn_on": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ„ĐžĐŊОвиК ҁĐĩŅ€Đ˛Ņ–Ņ", + "backup_controller_page_background_is_on": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ„ĐžĐŊОвĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", + "backup_controller_page_background_turn_off": "ВиĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ„ĐžĐŊĐžĐ˛Ņƒ ҁĐģ҃ĐļĐąŅƒ", + "backup_controller_page_background_turn_on": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ„ĐžĐŊĐžĐ˛Ņƒ ҁĐģ҃ĐļĐąŅƒ", "backup_controller_page_background_wifi": "Đ›Đ¸ŅˆĐĩ ĐŊа Wi-Fi", "backup_controller_page_backup": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", - "backup_controller_page_backup_selected": "ĐžĐąŅ€Đ°ĐŊĐž: ", + "backup_controller_page_backup_selected": "Đ’Đ¸ĐąŅ€Đ°ĐŊĐž: ", "backup_controller_page_backup_sub": "Đ ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", "backup_controller_page_created": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž: {date}", - "backup_controller_page_desc_backup": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐŊа ĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŧ҃ ĐŋĐģаĐŊŅ–, Ņ‰ĐžĐą Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ–Đ´ Ņ‡Đ°Ņ Đ˛Ņ–Đ´ĐēŅ€Đ¸Ņ‚Ņ‚Ņ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", + "backup_controller_page_desc_backup": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–, Ņ‰ĐžĐą Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ–Đ´ Ņ‡Đ°Ņ Đ˛Ņ–Đ´ĐēŅ€Đ¸Ņ‚Ņ‚Ņ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃.", "backup_controller_page_excluded": "ВиĐģŅƒŅ‡ĐĩĐŊĐž: ", "backup_controller_page_failed": "НĐĩвдаĐģŅ– ({count})", "backup_controller_page_filename": "Назва Ņ„Đ°ĐšĐģ҃: {filename} [{size}]", "backup_controller_page_id": "ID: {id}", "backup_controller_page_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ", - "backup_controller_page_none_selected": "ĐŅ–Ņ‡ĐžĐŗĐž ĐŊĐĩ ĐžĐąŅ€Đ°ĐŊĐž", + "backup_controller_page_none_selected": "ĐŅ–Ņ‡ĐžĐŗĐž ĐŊĐĩ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž", "backup_controller_page_remainder": "ЗаĐģĐ¸ŅˆĐžĐē", - "backup_controller_page_remainder_sub": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, Ņ‰Đž СаĐģĐ¸ŅˆĐ¸ĐģĐ¸ŅŅ Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "backup_controller_page_remainder_sub": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, ŅĐēŅ– СаĐģĐ¸ŅˆĐ¸ĐģĐžŅŅ ҁĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛", "backup_controller_page_server_storage": "ĐĄŅ…ĐžĐ˛Đ¸Ņ‰Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", "backup_controller_page_start_backup": "ĐŸĐžŅ‡Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", "backup_controller_page_status_off": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ– виĐŧĐēĐŊĐĩĐŊĐž", - "backup_controller_page_status_on": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ– Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", + "backup_controller_page_status_on": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ– ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", "backup_controller_page_storage_format": "ВиĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐž: {used} С {total}", "backup_controller_page_to_backup": "АĐģŅŒĐąĐžĐŧи Đ´Đž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", "backup_controller_page_total_sub": "ĐŖŅŅ– ҃ĐŊŅ–ĐēаĐģҌĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛", "backup_controller_page_turn_off": "ВиĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–", "backup_controller_page_turn_on": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ в аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–", - "backup_controller_page_uploading_file_info": "ВиваĐŊŅ‚Đ°ĐļŅƒŅŽ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž Ņ„Đ°ĐšĐģ", - "backup_err_only_album": "НĐĩ ĐŧĐžĐļ҃ видаĐģĐ¸Ņ‚Đ¸ Ņ”Đ´Đ¸ĐŊиК аĐģŅŒĐąĐžĐŧ", - "backup_error_sync_failed": "ПоĐŧиĐģĐēа ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ—. НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐąŅ€ĐžĐąĐ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ.", - "backup_info_card_assets": "Ņ„Đ°ĐšĐģи", + "backup_controller_page_uploading_file_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Ņ„Đ°ĐšĐģ, Ņ‰Đž виваĐŊŅ‚Đ°ĐļŅƒŅ”Ņ‚ŅŒŅŅ", + "backup_err_only_album": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ Ņ”Đ´Đ¸ĐŊиК аĐģŅŒĐąĐžĐŧ", + "backup_error_sync_failed": "НĐĩ вдаĐģĐžŅŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸. НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐēĐžĐŊĐ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ.", + "backup_info_card_assets": "ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "backup_manual_cancelled": "ĐĄĐēĐ°ŅĐžĐ˛Đ°ĐŊĐž", "backup_manual_in_progress": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ вĐļĐĩ Đ˛Ņ–Đ´ĐąŅƒĐ˛Đ°Ņ”Ņ‚ŅŒŅŅ. ĐĄĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ ĐˇĐŗĐžĐ´ĐžĐŧ", - "backup_manual_success": "ĐŖŅĐŋŅ–Ņ…", + "backup_manual_success": "Đ“ĐžŅ‚ĐžĐ˛Đž", "backup_manual_title": "ĐĄŅ‚Đ°ĐŊ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "backup_options": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", - "backup_options_page_title": "Đ ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", + "backup_options_page_title": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", "backup_setting_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ҃ Ņ„ĐžĐŊОвОĐŧ҃ Ņ‚Đ° аĐēŅ‚Đ¸Đ˛ĐŊĐžĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–", "backup_settings_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "backup_upload_details_page_more_details": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą Đ´Ņ–ĐˇĐŊĐ°Ņ‚Đ¸ŅŅ ĐąŅ–ĐģҌ҈Đĩ", "backward": "Назад", - "biometric_auth_enabled": "Đ‘Ņ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊа Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊа", - "biometric_locked_out": "ВаĐŧ СаĐēŅ€Đ¸Ņ‚Đž Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐąŅ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊĐžŅ— Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", - "biometric_no_options": "Đ‘Ņ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊŅ– ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ–", + "biometric_auth_enabled": "Đ‘Ņ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊ҃ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–ŅŽ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", + "biometric_locked_out": "Đ”ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐąŅ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊĐžŅ— Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ— СайĐģĐžĐēОваĐŊĐž", + "biometric_no_options": "Đ‘Ņ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊŅ– Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ–", "biometric_not_available": "Đ‘Ņ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊа Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "birthdate_saved": "Đ”Đ°Ņ‚Đ° ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ ҃ҁĐŋŅ–ŅˆĐŊĐž СйĐĩŅ€ĐĩĐļĐĩĐŊа", - "birthdate_set_description": "Đ”Đ°Ņ‚Đ° ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐžĐąŅ‡Đ¸ŅĐģĐĩĐŊĐŊŅ Đ˛Ņ–Đē҃ ҆ҖҔҗ ĐžŅĐžĐąĐ¸ ĐŊа ĐŧĐžĐŧĐĩĐŊŅ‚ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—.", + "birthdate_saved": "Đ”Đ°Ņ‚Ņƒ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", + "birthdate_set_description": "Đ”Đ°Ņ‚Đ° ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐžĐąŅ‡Đ¸ŅĐģĐĩĐŊĐŊŅ Đ˛Ņ–Đē҃ ҆ҖҔҗ ĐģŅŽĐ´Đ¸ĐŊи ĐŊа ĐŧĐžĐŧĐĩĐŊŅ‚ Ņ„ĐžŅ‚Đž.", "blurred_background": "РОСĐŧĐ¸Ņ‚Đ¸Đš Ņ„ĐžĐŊ", - "bugs_and_feature_requests": "ПоĐŧиĐģĐēи Ņ‚Đ° ЗаĐŋĐ¸Ņ‚Đ¸", + "bugs_and_feature_requests": "Đ—Đ˛Ņ–Ņ‚Đ¸ ĐŋŅ€Đž ĐŋĐžĐŧиĐģĐēи Ņ‚Đ° ĐŋОйаĐļаĐŊĐŊŅ", "build": "Đ—ĐąŅ–Ņ€Đēа", - "build_image": "ВĐĩŅ€ŅŅ–Ņ ĐˇĐąŅ–Ņ€Đēи", - "bulk_delete_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŧĐ°ŅĐžĐ˛Đž видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК Ņ„Đ°ĐšĐģ} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– Ņ„Đ°ĐšĐģи} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛}}? ĐĻŅ Đ´Ņ–Ņ СаĐģĐ¸ŅˆĐ¸Ņ‚ŅŒ ĐŊĐ°ĐšĐąŅ–ĐģŅŒŅˆĐ¸Đš Ņ„Đ°ĐšĐģ ҃ ĐēĐžĐļĐŊŅ–Đš ĐŗŅ€ŅƒĐŋŅ– Ņ– ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐ¸Ņ‚ŅŒ Đ˛ŅŅ– Ņ–ĐŊŅˆŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸. ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩĐŧĐžĐļĐģивО ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸!", - "bulk_keep_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ СаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК Ņ„Đ°ĐšĐģ} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– Ņ„Đ°ĐšĐģи} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛}}? ĐĻĐĩ дОСвОĐģĐ¸Ņ‚ŅŒ Đ˛Đ¸Ņ€Ņ–ŅˆĐ¸Ņ‚Đ¸ Đ˛ŅŅ– ĐŗŅ€ŅƒĐŋи Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛ ĐąĐĩС видаĐģĐĩĐŊĐŊŅ Ņ‡ĐžĐŗĐž-ĐŊĐĩĐąŅƒĐ´ŅŒ.", - "bulk_trash_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК Ņ„Đ°ĐšĐģ} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– Ņ„Đ°ĐšĐģи} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛}}? ĐĻĐĩ СаĐģĐ¸ŅˆĐ¸Ņ‚ŅŒ ĐŊĐ°ĐšĐąŅ–ĐģŅŒŅˆĐ¸Đš Ņ„Đ°ĐšĐģ ҃ ĐēĐžĐļĐŊŅ–Đš ĐŗŅ€ŅƒĐŋŅ– Đš ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚ŅŒ Đ´Đž ĐēĐžŅˆĐ¸Đēа Đ˛ŅŅ– Ņ–ĐŊŅˆŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸.", + "build_image": "ĐžĐąŅ€Đ°Đˇ ĐˇĐąŅ–Ņ€Đēи", + "bulk_delete_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŧĐ°ŅĐžĐ˛Đž видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}? ĐĻŅ Đ´Ņ–Ņ СаĐģĐ¸ŅˆĐ¸Ņ‚ŅŒ ĐŊĐ°ĐšĐąŅ–ĐģŅŒŅˆĐ¸Đš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ҃ ĐēĐžĐļĐŊŅ–Đš ĐŗŅ€ŅƒĐŋŅ– Đš ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐ¸Ņ‚ŅŒ ŅƒŅŅ– Ņ–ĐŊŅˆŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸. ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸!", + "bulk_keep_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ СаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}? ĐĻĐĩ Đ´Đ°ŅŅ‚ŅŒ СĐŧĐžĐŗŅƒ Đ˛Đ¸Ņ€Ņ–ŅˆĐ¸Ņ‚Đ¸ Đ˛ŅŅ– ĐŗŅ€ŅƒĐŋи Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛ ĐąĐĩС видаĐģĐĩĐŊĐŊŅ ĐąŅƒĐ´ŅŒ-Ņ‡ĐžĐŗĐž.", + "bulk_trash_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž ĐēĐžŅˆĐ¸Đēа {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}? ĐĻĐĩ СаĐģĐ¸ŅˆĐ¸Ņ‚ŅŒ ĐŊĐ°ĐšĐąŅ–ĐģŅŒŅˆĐ¸Đš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ҃ ĐēĐžĐļĐŊŅ–Đš ĐŗŅ€ŅƒĐŋŅ– Đš ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚ŅŒ Đ´Đž ĐēĐžŅˆĐ¸Đēа Đ˛ŅŅ– Ņ–ĐŊŅˆŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸.", "buy": "ĐŸŅ€Đ¸Đ´ĐąĐ°Ņ‚Đ¸ Immich", "cache_settings_clear_cache_button": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐĩ҈", "cache_settings_clear_cache_button_title": "ĐžŅ‡Đ¸Ņ‰Đ°Ņ” ĐēĐĩ҈ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃. ĐĻĐĩ ŅŅƒŅ‚Ņ‚Ņ”Đ˛Đž СĐŊĐ¸ĐˇĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃, Đ´ĐžĐēи ĐēĐĩ҈ ĐŊĐĩ ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐąŅƒĐ´ĐžĐ˛Đ°ĐŊĐž.", "cache_settings_duplicated_assets_clear_button": "ОЧИСĐĸИĐĸИ", - "cache_settings_duplicated_assets_subtitle": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, ŅĐēŅ– Ņ–ĐŗĐŊĐžŅ€ŅƒŅŽŅ‚ŅŒŅŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐēĐžĐŧ", - "cache_settings_duplicated_assets_title": "Đ”ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ({count})", - "cache_settings_statistics_album": "Đ‘Ņ–ĐąĐģŅ–ĐžŅ‚Đĩ҇ĐŊŅ– ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸", + "cache_settings_duplicated_assets_subtitle": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, вĐŊĐĩҁĐĩĐŊŅ– ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐēĐžĐŧ Đ´Đž ҁĐŋĐ¸ŅĐē҃ Ņ–ĐŗĐŊĐžŅ€ĐžĐ˛Đ°ĐŊĐ¸Ņ…", + "cache_settings_duplicated_assets_title": "Đ”ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ({count})", + "cache_settings_statistics_album": "ĐœŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "cache_settings_statistics_full": "ПовĐŊĐžŅ€ĐžĐˇĐŧŅ–Ņ€ĐŊŅ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "cache_settings_statistics_shared": "ĐœŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛", "cache_settings_statistics_thumbnail": "ĐœŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸", "cache_settings_statistics_title": "ВиĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ ĐēĐĩ҈҃", - "cache_settings_subtitle": "КоĐŊŅ‚Ņ€ĐžĐģŅŽŅ” ĐēĐĩŅˆŅƒĐ˛Đ°ĐŊĐŊŅ ҃ ĐŧĐžĐąŅ–ĐģҌĐŊĐžĐŧ҃ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", + "cache_settings_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐĩŅˆŅƒĐ˛Đ°ĐŊĐŊŅĐŧ ҃ ĐŧĐžĐąŅ–ĐģҌĐŊĐžĐŧ҃ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich", "cache_settings_tile_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋОвĐĩĐ´Ņ–ĐŊĐēĐžŅŽ ĐģĐžĐēаĐģҌĐŊĐžĐŗĐž ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", "cache_settings_tile_title": "ЛоĐēаĐģҌĐŊĐĩ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đĩ", "cache_settings_title": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐĩŅˆŅƒĐ˛Đ°ĐŊĐŊŅ", @@ -724,20 +724,20 @@ "cancel_search": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅˆŅƒĐē", "canceled": "ĐĄĐēĐ°ŅĐžĐ˛Đ°ĐŊĐž", "canceling": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°ĐŊĐŊŅ", - "cannot_merge_people": "НĐĩĐŧĐžĐļĐģивО Ой'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", - "cannot_undo_this_action": "Ви ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ Ņ†ŅŽ Đ´Ņ–ŅŽ!", - "cannot_update_the_description": "НĐĩĐŧĐžĐļĐģивО ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", + "cannot_merge_people": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Ой'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", + "cannot_undo_this_action": "ĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸!", + "cannot_update_the_description": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", "cast": "ĐĸŅ€Đ°ĐŊҁĐģŅŽĐ˛Đ°Ņ‚Đ¸", - "cast_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐŧŅ–ŅŅ†Ņ Ņ‚Ņ€Đ°ĐŊҁĐģŅŅ†Ņ–Ņ—", + "cast_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— Đ´ĐģŅ Ņ‚Ņ€Đ°ĐŊҁĐģŅŅ†Ņ–Ņ—", "change_date": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ", "change_description": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", "change_display_order": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐžŅ€ŅĐ´ĐžĐē Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "change_expiration_time": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ‚ĐĩŅ€ĐŧŅ–ĐŊ Đ´Ņ–Ņ—", - "change_location": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "change_location": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "change_name": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ–Đŧ'Ņ", - "change_name_successfully": "ІĐŧ'Ņ ҃ҁĐŋŅ–ŅˆĐŊĐž СĐŧŅ–ĐŊĐĩĐŊĐž", + "change_name_successfully": "ІĐŧ'Ņ СĐŧŅ–ĐŊĐĩĐŊĐž", "change_password": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "change_password_description": "ĐĻĐĩ айО ĐŋĐĩŅ€ŅˆĐ¸Đš Ņ€Đ°Đˇ, ĐēĐžĐģи ви ŅƒĐ˛Ņ–ĐšŅˆĐģи в ŅĐ¸ŅŅ‚ĐĩĐŧ҃, айО ĐąŅƒĐģĐž ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž СаĐŋĐ¸Ņ‚ ĐŊа СĐŧŅ–ĐŊ҃ Đ˛Đ°ŅˆĐžĐŗĐž ĐŋĐ°Ņ€ĐžĐģŅ. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ввĐĩĐ´Ņ–Ņ‚ŅŒ ĐŊОвиК ĐŋĐ°Ņ€ĐžĐģҌ ĐŊиĐļ҇Đĩ.", + "change_password_description": "ĐĻĐĩ Đ˛Đ°Ņˆ ĐŋĐĩŅ€ŅˆĐ¸Đš Đ˛Ņ…Ņ–Đ´ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ айО ĐąŅƒĐģĐž ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž СаĐŋĐ¸Ņ‚ ĐŊа СĐŧŅ–ĐŊ҃ ĐŋĐ°Ņ€ĐžĐģŅ. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ввĐĩĐ´Ņ–Ņ‚ŅŒ ĐŊОвиК ĐŋĐ°Ņ€ĐžĐģҌ ĐŊиĐļ҇Đĩ.", "change_password_form_confirm_password": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", "change_password_form_description": "ĐŸŅ€Đ¸Đ˛Ņ–Ņ‚, {name},\n\nĐĻĐĩ айО Đ˛Đ°Ņˆ ĐŋĐĩŅ€ŅˆĐ¸Đš Đ˛Ņ…Ņ–Đ´ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧ҃, айО ĐąŅƒĐģĐž ĐŊĐ°Đ´Ņ–ŅĐģаĐŊĐž СаĐŋĐ¸Ņ‚ ĐŊа СĐŧŅ–ĐŊ҃ ĐŋĐ°Ņ€ĐžĐģŅ. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ввĐĩĐ´Ņ–Ņ‚ŅŒ ĐŊОвиК ĐŋĐ°Ņ€ĐžĐģҌ ĐŊиĐļ҇Đĩ.", "change_password_form_log_out": "Đ’Đ¸ĐšŅ‚Đ¸ Ņ–Đˇ ŅĐ¸ŅŅ‚ĐĩĐŧи ĐŊа Đ˛ŅŅ–Ņ… Ņ–ĐŊŅˆĐ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŅ…", @@ -749,93 +749,93 @@ "change_trigger": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ‚Ņ€Đ¸ĐŗĐĩŅ€", "change_trigger_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ‚Ņ€Đ¸ĐŗĐĩŅ€? ĐĻĐĩ видаĐģĐ¸Ņ‚ŅŒ ŅƒŅŅ– ĐŊĐ°ŅĐ˛ĐŊŅ– Đ´Ņ–Ņ— Ņ‚Đ° ҄ҖĐģŅŒŅ‚Ņ€Đ¸.", "change_your_password": "ЗĐŧŅ–ĐŊŅ–Ņ‚ŅŒ ŅĐ˛Ņ–Đš ĐŋĐ°Ņ€ĐžĐģҌ", - "changed_visibility_successfully": "ВидиĐŧŅ–ŅŅ‚ŅŒ ҃ҁĐŋŅ–ŅˆĐŊĐž СĐŧŅ–ĐŊĐĩĐŊĐž", - "charging": "Đ—Đ°Ņ€ŅĐ´Đēа", - "charging_requirement_mobile_backup": "ДĐģŅ Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš ĐŋОвиĐŊĐĩĐŊ ĐˇĐ°Ņ€ŅĐ´ĐļĐ°Ņ‚Đ¸ŅŅ", - "check_corrupt_asset_backup": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đ¸Ņ‚Đ¸ ĐŊа ĐŋĐžŅˆĐēОдĐļĐĩĐŊŅ– Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ„Đ°ĐšĐģŅ–Đ˛", + "changed_visibility_successfully": "ВидиĐŧŅ–ŅŅ‚ŅŒ СĐŧŅ–ĐŊĐĩĐŊĐž", + "charging": "Đ—Đ°Ņ€ŅĐ´ĐļĐ°Ņ”Ņ‚ŅŒŅŅ", + "charging_requirement_mobile_backup": "ДĐģŅ Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš ĐŧĐ°Ņ” ĐˇĐ°Ņ€ŅĐ´ĐļĐ°Ņ‚Đ¸ŅŅ", + "check_corrupt_asset_backup": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đ¸Ņ‚Đ¸ ĐŊа ĐŋĐžŅˆĐēОдĐļĐĩĐŊŅ– Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "check_corrupt_asset_backup_button": "ВиĐēĐžĐŊĐ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃", - "check_corrupt_asset_backup_description": "ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ Ņ†ŅŽ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ ĐģĐ¸ŅˆĐĩ ҇ĐĩŅ€ĐĩС Wi-Fi Ņ‚Đ° ĐŋҖҁĐģŅ Ņ‚ĐžĐŗĐž, ŅĐē Đ˛ŅŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ СаваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€. ĐŸŅ€ĐžŅ†Đĩҁ ĐŧĐžĐļĐĩ СаКĐŊŅŅ‚Đ¸ ĐēŅ–ĐģҌĐēа Ņ…Đ˛Đ¸ĐģиĐŊ.", + "check_corrupt_asset_backup_description": "ВиĐēĐžĐŊŅƒĐšŅ‚Đĩ Ņ†ŅŽ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃ ĐģĐ¸ŅˆĐĩ ҇ĐĩŅ€ĐĩС Wi-Fi Ņ‚Đ° ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛ŅŅ–Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛. ĐŸŅ€ĐžŅ†Đĩҁ ĐŧĐžĐļĐĩ СаКĐŊŅŅ‚Đ¸ ĐēŅ–ĐģҌĐēа Ņ…Đ˛Đ¸ĐģиĐŊ.", "check_logs": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đ¸Ņ‚Đ¸ ĐļŅƒŅ€ĐŊаĐģи", "checksum": "КоĐŊŅ‚Ņ€ĐžĐģҌĐŊа ҁ҃Đŧа", "choose_matching_people_to_merge": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐģŅŽĐ´ĐĩĐš Đ´ĐģŅ Ой'Ņ”Đ´ĐŊаĐŊĐŊŅ", "city": "ĐœŅ–ŅŅ‚Đž", - "cleanup_confirm_description": "Immich СĐŊĐ°ĐšŅˆĐžĐ˛ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… Đ´Đž {date}), ĐąĐĩСĐŋĐĩ҇ĐŊĐž СйĐĩŅ€ĐĩĐļĐĩĐŊĐ¸Ņ… ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ. ВидаĐģĐ¸Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– ĐēĐžĐŋŅ–Ņ— С Ņ†ŅŒĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ?", + "cleanup_confirm_description": "Immich СĐŊĐ°ĐšŅˆĐžĐ˛ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… Đ´Đž {date}), ĐąĐĩСĐŋĐĩ҇ĐŊĐž СйĐĩŅ€ĐĩĐļĐĩĐŊĐ¸Ņ… ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ. ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– ĐēĐžĐŋŅ–Ņ— С Ņ†ŅŒĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ?", "cleanup_confirm_prompt_title": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ С Ņ†ŅŒĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ?", - "cleanup_deleted_assets": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "cleanup_deleting": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐŊŅ Đ´Đž ĐēĐžŅˆĐ¸Đēа...", - "cleanup_found_assets": "ЗĐŊаКдĐĩĐŊĐž {count} Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐ¸Ņ… ĐēĐžĐŋŅ–Đš Ņ„Đ°ĐšĐģŅ–Đ˛", - "cleanup_found_assets_with_size": "ЗĐŊаКдĐĩĐŊĐž {count} Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐ¸Ņ… ĐēĐžĐŋŅ–Đš Ņ„Đ°ĐšĐģŅ–Đ˛ ({size})", - "cleanup_icloud_shared_albums_excluded": "ĐĄĐŋŅ–ĐģҌĐŊŅ– аĐģŅŒĐąĐžĐŧи iCloud виĐēĐģŅŽŅ‡Đ°ŅŽŅ‚ŅŒŅŅ ĐˇŅ– ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", - "cleanup_no_assets_found": "НĐĩ СĐŊаКдĐĩĐŊĐž Ņ„Đ°ĐšĐģŅ–Đ˛, Ņ‰Đž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ ĐŊавĐĩĐ´ĐĩĐŊиĐŧ Đ˛Đ¸Ņ‰Đĩ ĐēŅ€Đ¸Ņ‚ĐĩŅ€Ņ–ŅĐŧ. Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ÂĢĐ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩÂģ ĐŧĐžĐļĐĩ видаĐģĐ¸Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ Ņ„Đ°ĐšĐģи, Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ŅĐēĐ¸Ņ… ĐąŅƒĐģĐž ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ", - "cleanup_preview_title": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Đ´ĐģŅ виĐģŅƒŅ‡ĐĩĐŊĐŊŅ ({count})", - "cleanup_step3_description": "ĐĄĐēаĐŊŅƒĐšŅ‚Đĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ„Đ°ĐšĐģŅ–Đ˛, Ņ‰Đž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ Đ˛Đ°ŅˆŅ–Đš Đ´Đ°Ņ‚Ņ–, Ņ‚Đ° СйĐĩŅ€ĐĩĐļŅ–Ņ‚ŅŒ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ.", - "cleanup_step4_summary": "{count} Ņ„Đ°ĐšĐģŅ–Đ˛ (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… Đ´Đž {date}) Đ´ĐģŅ видаĐģĐĩĐŊĐŊŅ С Đ˛Đ°ŅˆĐžĐŗĐž ĐģĐžĐēаĐģҌĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ. Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— СаĐģĐ¸ŅˆĐ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧи Ņ–Đˇ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich.", - "cleanup_trash_hint": "ЊОй ĐŋОвĐŊŅ–ŅŅ‚ŅŽ ĐˇĐ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ Đ´ĐģŅ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ, Đ˛Ņ–Đ´ĐēŅ€Đ¸ĐšŅ‚Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐŊ҃ ĐŗĐ°ĐģĐĩŅ€ĐĩŅŽ Ņ‚Đ° ĐžŅ‡Đ¸ŅŅ‚Ņ–Ņ‚ŅŒ ĐēĐžŅˆĐ¸Đē", + "cleanup_deleted_assets": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "cleanup_deleting": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐŊŅ Đ´Đž ĐēĐžŅˆĐ¸Đēаâ€Ļ", + "cleanup_found_assets": "ЗĐŊаКдĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Ņ–Đˇ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊиĐŧи ĐēĐžĐŋŅ–ŅĐŧи", + "cleanup_found_assets_with_size": "ЗĐŊаКдĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Ņ–Đˇ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊиĐŧи ĐēĐžĐŋŅ–ŅĐŧи ({size})", + "cleanup_icloud_shared_albums_excluded": "ĐĄĐŋŅ–ĐģҌĐŊŅ– аĐģŅŒĐąĐžĐŧи iCloud ĐŊĐĩ Đ˛Ņ€Đ°Ņ…ĐžĐ˛ŅƒŅŽŅ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", + "cleanup_no_assets_found": "НĐĩ СĐŊаКдĐĩĐŊĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛, Ņ‰Đž Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°ŅŽŅ‚ŅŒ ĐŊавĐĩĐ´ĐĩĐŊиĐŧ Đ˛Đ¸Ņ‰Đĩ ĐēŅ€Đ¸Ņ‚ĐĩŅ€Ņ–ŅĐŧ. Đ¤ŅƒĐŊĐēŅ†Ņ–Ņ ÂĢĐ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩÂģ ĐŧĐžĐļĐĩ видаĐģĐ¸Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ŅĐēĐ¸Ņ… ĐąŅƒĐģĐž ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ", + "cleanup_preview_title": "ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž виĐģŅƒŅ‡ĐĩĐŊĐŊŅ ({count})", + "cleanup_step3_description": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐž Đ´Đž ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ Đ´Đ°Ņ‚Đ¸ Ņ‚Đ° СйĐĩŅ€ĐĩĐļĐĩĐŊĐŊŅ.", + "cleanup_step4_summary": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊиК Đ´Đž {date})} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊŅ– Đ´Đž {date})} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… Đ´Đž {date})} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ (ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐ¸Ņ… Đ´Đž {date})}} Đ´ĐģŅ видаĐģĐĩĐŊĐŊŅ С Đ˛Đ°ŅˆĐžĐŗĐž ĐģĐžĐēаĐģҌĐŊĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ. Đ¤ĐžŅ‚Đž СаĐģĐ¸ŅˆĐ°Ņ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧи Ņ–Đˇ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich.", + "cleanup_trash_hint": "ЊОй ĐŋОвĐŊŅ–ŅŅ‚ŅŽ ĐˇĐ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ ҃ ŅŅ…ĐžĐ˛Đ¸Ņ‰Ņ–, Đ˛Ņ–Đ´ĐēŅ€Đ¸ĐšŅ‚Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐŊ҃ ĐŗĐ°ĐģĐĩŅ€ĐĩŅŽ Ņ‚Đ° ĐžŅ‡Đ¸ŅŅ‚Ņ–Ņ‚ŅŒ ĐēĐžŅˆĐ¸Đē", "clear": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸", "clear_all": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ŅĐĩ", "clear_all_recent_searches": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ĐžŅŅ‚Đ°ĐŊĐŊŅ– ĐŋĐžŅˆŅƒĐēĐžĐ˛Ņ– СаĐŋĐ¸Ņ‚Đ¸", "clear_file_cache": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐĩ҈ Ņ„Đ°ĐšĐģŅ–Đ˛", - "clear_message": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊĐŊŅ", + "clear_message": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ", "clear_value": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ СĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ", "client_cert_dialog_msg_confirm": "ОК", "client_cert_enter_password": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ĐŋĐ°Ņ€ĐžĐģҌ", - "client_cert_import": "ІĐŧĐŋĐžŅ€Ņ‚", + "client_cert_import": "ІĐŧĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸", "client_cert_import_success_msg": "КĐģŅ–Ņ”ĐŊŅ‚ŅŅŒĐēиК ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ Ņ–ĐŧĐŋĐžŅ€Ņ‚ĐžĐ˛Đ°ĐŊĐž", "client_cert_invalid_msg": "НĐĩĐ´Ņ–ĐšŅĐŊиК Ņ„Đ°ĐšĐģ ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ° айО ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊиК ĐŋĐ°Ņ€ĐžĐģҌ", "client_cert_password_message": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ĐŋĐ°Ņ€ĐžĐģҌ Đ´ĐģŅ Ņ†ŅŒĐžĐŗĐž ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ°", "client_cert_password_title": "ĐŸĐ°Ņ€ĐžĐģҌ ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ°", - "client_cert_remove_msg": "КĐģŅ–Ņ”ĐŊŅ‚ŅŅŒĐēиК ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ видаĐģĐĩĐŊĐž", - "client_cert_subtitle": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ” ĐģĐ¸ŅˆĐĩ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ PKCS12 (.p12, .pfx). ІĐŧĐŋĐžŅ€Ņ‚/видаĐģĐĩĐŊĐŊŅ ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ° Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐĩ ĐģĐ¸ŅˆĐĩ ĐŋĐĩŅ€ĐĩĐ´ Đ˛Ņ…ĐžĐ´ĐžĐŧ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧ҃", - "client_cert_title": "SSL-ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ ĐēĐģŅ–Ņ”ĐŊŅ‚Đ° [ЕКСПЕРИМЕНĐĸАЛĐŦНИЙ]", + "client_cert_remove_msg": "КĐģŅ–Ņ”ĐŊŅ‚ŅŅŒĐēиК ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ виĐģŅƒŅ‡ĐĩĐŊĐž", + "client_cert_subtitle": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ” ĐģĐ¸ŅˆĐĩ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ PKCS12 (.p12, .pfx). ІĐŧĐŋĐžŅ€Ņ‚/виĐģŅƒŅ‡ĐĩĐŊĐŊŅ ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ° Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐĩ ĐģĐ¸ŅˆĐĩ ĐŋĐĩŅ€ĐĩĐ´ Đ˛Ņ…ĐžĐ´ĐžĐŧ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧ҃", + "client_cert_title": "SSL-ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ ĐēĐģŅ–Ņ”ĐŊŅ‚Đ° [ЕКСПЕРИМЕНĐĸАЛĐŦНО]", "clockwise": "По ĐŗĐžĐ´Đ¸ĐŊĐŊиĐēĐžĐ˛Ņ–Đš ҁ҂ҀҖĐģ҆Җ", "close": "ЗаĐēŅ€Đ¸Ņ‚Đ¸", "collapse": "Đ—ĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸", "collapse_all": "Đ—ĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸ Đ˛ŅĐĩ", "color": "КоĐģŅ–Ņ€", - "color_theme": "КоĐģŅŒĐžŅ€ĐžĐ˛Đ° Ņ‚ĐĩĐŧа", + "color_theme": "ĐĸĐĩĐŧа ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ", "command": "КоĐŧаĐŊда", - "command_palette_prompt": "ШвидĐēĐž СĐŊĐ°Ņ…ĐžĐ´ŅŒŅ‚Đĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊ҃ ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃, Đ´Ņ–ŅŽ Ņ‡Đ¸ ĐēĐžĐŧаĐŊĐ´Ņƒ", + "command_palette_prompt": "ШвидĐēиК ĐŋĐžŅˆŅƒĐē ŅŅ‚ĐžŅ€Ņ–ĐŊĐžĐē, Đ´Ņ–Đš Ņ‚Đ° ĐēĐžĐŧаĐŊĐ´", "command_palette_to_close": "СаĐēŅ€Đ¸Ņ‚Đ¸", - "command_palette_to_navigate": "Đ˛Đ˛Ņ–ĐšŅ‚Đ¸", - "command_palette_to_select": "ĐžĐąŅ€Đ°Ņ‚Đ¸", + "command_palette_to_navigate": "ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸", + "command_palette_to_select": "Đ˛Đ¸ĐąŅ€Đ°Ņ‚Đ¸", "command_palette_to_show_all": "ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚Đ¸ Đ˛ŅĐĩ", "comment_deleted": "КоĐŧĐĩĐŊŅ‚Đ°Ņ€ видаĐģĐĩĐŊĐž", - "comment_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ–Đ˛", + "comment_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ–Đ˛", "comments_and_likes": "КоĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ– Ņ‚Đ° вĐŋОдОйаĐŊĐŊŅ", "comments_are_disabled": "КоĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ– виĐŧĐēĐŊĐĩĐŊĐž", "common_create_new_album": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК аĐģŅŒĐąĐžĐŧ", "completed": "ЗавĐĩŅ€ŅˆĐĩĐŊĐž", "confirm": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸", "confirm_admin_password": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", - "confirm_delete_face": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ {name} С Ņ†ŅŒĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ?", + "confirm_delete_face": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ {name} С Ņ†ŅŒĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°?", "confirm_delete_shared_link": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆Đĩ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ?", - "confirm_keep_this_delete_others": "ĐŖŅŅ– Ņ–ĐŊŅˆŅ– ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ в ҁ҂ĐĩĐē҃ ĐąŅƒĐ´Đĩ видаĐģĐĩĐŊĐž, ĐžĐēҀҖĐŧ Ņ†ŅŒĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ. Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ´ĐžĐ˛ĐļĐ¸Ņ‚Đ¸?", - "confirm_new_pin_code": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´ŅŒŅ‚Đĩ ĐŊОвиК PIN-ĐēОд", + "confirm_keep_this_delete_others": "ĐŖŅŅ– Ņ–ĐŊŅˆŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ в ҁ҂ĐĩĐē҃ ĐąŅƒĐ´Đĩ видаĐģĐĩĐŊĐž, ĐžĐēҀҖĐŧ Ņ†ŅŒĐžĐŗĐž. Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ´ĐžĐ˛ĐļĐ¸Ņ‚Đ¸?", + "confirm_new_pin_code": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸ ĐŊОвиК PIN-ĐēОд", "confirm_password": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "confirm_tag_face": "БаĐļĐ°Ņ”Ņ‚Đĩ ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ҆Đĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ ŅĐē {name}?", - "confirm_tag_face_unnamed": "БаĐļĐ°Ņ”Ņ‚Đĩ ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ҆Đĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ?", - "connected_device": "ĐŸŅ–Đ´ĐēĐģŅŽŅ‡ĐĩĐŊиК ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš", - "connected_to": "ĐŸŅ–Đ´ĐēĐģŅŽŅ‡ĐĩĐŊĐž Đ´Đž", - "contain": "ĐœŅ–ŅŅ‚Đ¸Ņ‚Đ¸", + "confirm_tag_face": "ĐĨĐžŅ‡ĐĩŅ‚Đĩ ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ҆Đĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ ŅĐē {name}?", + "confirm_tag_face_unnamed": "ĐĨĐžŅ‡ĐĩŅ‚Đĩ ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ҆Đĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ?", + "connected_device": "ĐŸŅ–Đ´'Ņ”Đ´ĐŊаĐŊиК ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš", + "connected_to": "ĐŸŅ–Đ´'Ņ”Đ´ĐŊаĐŊĐž Đ´Đž", + "contain": "ВĐŋĐ¸ŅĐ°Ņ‚Đ¸", "context": "КоĐŊŅ‚ĐĩĐēҁ҂", "continue": "ĐŸŅ€ĐžĐ´ĐžĐ˛ĐļĐ¸Ņ‚Đ¸", "control_bottom_app_bar_create_new_album": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК аĐģŅŒĐąĐžĐŧ", "control_bottom_app_bar_delete_from_immich": "ВидаĐģĐ¸Ņ‚Đ¸ С Immich", "control_bottom_app_bar_delete_from_local": "ВидаĐģĐ¸Ņ‚Đ¸ С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "control_bottom_app_bar_edit_location": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "control_bottom_app_bar_edit_location": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "control_bottom_app_bar_edit_time": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ Ņ‚Đ° Ņ‡Đ°Ņ", - "control_bottom_app_bar_share_link": "ĐŸĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ", + "control_bottom_app_bar_share_link": "ĐŸĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ", "control_bottom_app_bar_share_to": "ĐŸĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ", - "control_bottom_app_bar_trash_from_immich": "До ĐēĐžŅˆĐ¸Đēа", - "copied_image_to_clipboard": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҁĐēĐžĐŋŅ–ĐšĐžĐ˛Đ°ĐŊĐž в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃.", - "copied_to_clipboard": "ĐĄĐēĐžĐŋŅ–ĐšĐžĐ˛Đ°ĐŊĐž в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃!", - "copy_error": "ПоĐŧиĐģĐēа ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", + "control_bottom_app_bar_trash_from_immich": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž ĐēĐžŅˆĐ¸Đēа", + "copied_image_to_clipboard": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҁĐēĐžĐŋŅ–ĐšĐžĐ˛Đ°ĐŊĐž Đ´Đž ĐąŅƒŅ„ĐĩŅ€Đ° ОйĐŧŅ–ĐŊ҃.", + "copied_to_clipboard": "ĐĄĐēĐžĐŋŅ–ĐšĐžĐ˛Đ°ĐŊĐž Đ´Đž ĐąŅƒŅ„ĐĩŅ€Đ° ОйĐŧŅ–ĐŊ҃!", + "copy_error": "НĐĩ вдаĐģĐžŅŅ ҁĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸", "copy_file_path": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ҈ĐģŅŅ… Đ´Đž Ņ„Đ°ĐšĐģ҃", "copy_image": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "copy_link": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "copy_link_to_clipboard": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃", + "copy_link_to_clipboard": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ Đ´Đž ĐąŅƒŅ„ĐĩŅ€Đ° ОйĐŧŅ–ĐŊ҃", "copy_password": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "copy_to_clipboard": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃", + "copy_to_clipboard": "ĐĄĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ Đ´Đž ĐąŅƒŅ„ĐĩŅ€Đ° ОйĐŧŅ–ĐŊ҃", "country": "ĐšŅ€Đ°Ņ—ĐŊа", "cover": "ОбĐēĐģадиĐŊĐēа", "covers": "ОбĐēĐģадиĐŊĐēи", @@ -843,90 +843,92 @@ "create_album": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "create_album_page_untitled": "БĐĩС ĐŊаСви", "create_api_key": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ API", - "create_first_workflow": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐĩŅ€ŅˆĐ¸Đš Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", + "create_first_workflow": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐĩŅ€ŅˆŅƒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", "create_library": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", "create_link": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "create_link_to_share": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž Đ´ĐžŅŅ‚ŅƒĐŋ҃", - "create_link_to_share_description": "ДозвоĐģĐ¸Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš Са ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ ĐąŅƒĐ´ŅŒ-ĐēĐžĐŧ҃", + "create_link_to_share_description": "Đ”Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ ĐąŅƒĐ´ŅŒ-ĐēĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– Ņ„ĐžŅ‚Đž Са ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ", "create_new": "ĐĄĐĸВОРИĐĸИ НОВИЙ", - "create_new_person": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņƒ ĐžŅĐžĐąŅƒ", - "create_new_person_hint": "ĐŸŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐžĐąŅ€Đ°ĐŊиĐŧ Ņ„ĐžŅ‚Đž ĐŊĐžĐ˛Ņƒ ĐžŅĐžĐąŅƒ", + "create_new_face": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвĐĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "create_new_person": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņƒ ĐģŅŽĐ´Đ¸ĐŊ҃", + "create_new_person_hint": "ĐŸŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐžĐ˛Ņ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–", "create_new_user": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛ĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "create_shared_album_page_share_add_assets": "ДОДАĐĸИ ФОĐĸО/ВІДЕО", + "create_person": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", + "create_person_subtitle": "Đ”ĐžĐ´Đ°ĐšŅ‚Đĩ Ņ–Đŧ'Ņ Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž ОйĐģĐ¸Ņ‡Ņ‡Ņ, Ņ‰ĐžĐą ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ‚Đ° ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņƒ ĐžŅĐžĐąŅƒ", + "create_shared_album_page_share_add_assets": "ДОДАĐĸИ ЕЛЕМЕНĐĸИ", "create_shared_album_page_share_select_photos": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž", "create_shared_link": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "create_tag": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ‚ĐĩĐŗ", - "create_tag_description": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК Ņ‚ĐĩĐŗ. ДĐģŅ вĐēĐģадĐĩĐŊĐ¸Ņ… Ņ‚ĐĩĐŗŅ–Đ˛ вĐēаĐļŅ–Ņ‚ŅŒ ĐŋОвĐŊиК ҈ĐģŅŅ… Ņ‚ĐĩĐŗĐ°, вĐēĐģŅŽŅ‡Đ°ŅŽŅ‡Đ¸ ҁĐģĐĩŅˆŅ–.", + "create_tag_description": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК Ņ‚ĐĩĐŗ. ДĐģŅ вĐēĐģадĐĩĐŊĐ¸Ņ… Ņ‚ĐĩĐŗŅ–Đ˛ вĐēаĐļŅ–Ņ‚ŅŒ ĐŋОвĐŊиК ҈ĐģŅŅ… Ņ‚ĐĩĐŗĐ°, Ņ€Đ°ĐˇĐžĐŧ ĐˇŅ– ҁĐēҖҁĐŊĐžŅŽ Ņ€Đ¸ŅĐēĐžŅŽ (/).", "create_user": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "create_workflow": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", + "create_workflow": "ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", "created": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž", "created_at": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž", - "creating_linked_albums": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŋĐžĐ˛â€™ŅĐˇĐ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛...", + "creating_linked_albums": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŋĐžĐ˛â€™ŅĐˇĐ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛â€Ļ", "crop": "ĐšĐ°Đ´Ņ€ŅƒĐ˛Đ°Ņ‚Đ¸", "crop_aspect_ratio_fixed": "Đ¤Ņ–ĐēŅĐžĐ˛Đ°ĐŊĐĩ", "crop_aspect_ratio_free": "Đ’Ņ–ĐģҌĐŊĐĩ", - "crop_aspect_ratio_original": "ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ", + "crop_aspect_ratio_original": "ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐĩ", + "crop_aspect_ratio_square": "ĐšĐ˛Đ°Đ´Ņ€Đ°Ņ‚ĐŊĐĩ", "curated_object_page_title": "Đ Đĩ҇Җ", "current_device": "ĐŸĐžŅ‚ĐžŅ‡ĐŊиК ĐŋŅ€Đ¸ŅŅ‚Ņ€Ņ–Đš", "current_pin_code": "ĐŸĐžŅ‚ĐžŅ‡ĐŊиК PIN-ĐēОд", "current_server_address": "ĐŸĐžŅ‚ĐžŅ‡ĐŊа Đ°Đ´Ņ€ĐĩŅĐ° ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", - "custom_date": "ВĐģĐ°ŅĐŊа Đ´Đ°Ņ‚Đ°", - "custom_locale": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēиК Ņ€ĐĩĐŗŅ–ĐžĐŊ", - "custom_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ, Ņ‡Đ°Ņ Ņ‚Đ° Ņ‡Đ¸ŅĐģа С ŅƒŅ€Đ°Ņ…ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ ĐžĐąŅ€Đ°ĐŊĐžŅ— ĐŧОви Ņ‚Đ° Ņ€ĐĩĐŗŅ–ĐžĐŊ҃", - "custom_url": "ВĐģĐ°ŅĐŊа URL-Đ°Đ´Ņ€ĐĩŅĐ°", - "cutoff_date_description": "ЗбĐĩŅ€ĐĩĐļŅ–Ņ‚ŅŒ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— С ĐžŅŅ‚Đ°ĐŊĐŊŅŒĐžĐŗĐžâ€Ļ", + "custom_date": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊа Đ´Đ°Ņ‚Đ°", + "custom_locale": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊŅ– Ņ€ĐĩĐŗŅ–ĐžĐŊаĐģҌĐŊŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", + "custom_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ, Ņ‡Đ°Ņ Ņ‚Đ° Ņ‡Đ¸ŅĐģа С ŅƒŅ€Đ°Ņ…ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžŅ— ĐŧОви Ņ‚Đ° Ņ€ĐĩĐŗŅ–ĐžĐŊ҃", + "custom_url": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊа URL-Đ°Đ´Ņ€ĐĩŅĐ°", + "cutoff_date_description": "ЗбĐĩŅ€Ņ–ĐŗĐ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž Са ĐžŅŅ‚Đ°ĐŊĐŊŅ–â€Ļ", "cutoff_day": "{count, plural, one {Đ´ĐĩĐŊҌ} few {Đ´ĐŊŅ–} many {Đ´ĐŊŅ–Đ˛} other {Đ´ĐŊŅ–Đ˛}}", "cutoff_year": "{count, plural, one {ҀҖĐē} few {Ņ€ĐžĐēи} many {Ņ€ĐžĐēŅ–Đ˛} other {Ņ€ĐžĐēŅ–Đ˛}}", - "daily_title_text_date": "Е, МММ Đ´Đ´", - "daily_title_text_date_year": "Е, МММ Đ´Đ´, ҀҀҀҀ", + "daily_title_text_date": "E, dd MMM", + "daily_title_text_date_year": "E, dd MMM yyyy", "dark": "ĐĸĐĩĐŧĐŊа", - "dark_theme": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ‚ĐĩĐŧĐŊ҃ Ņ‚ĐĩĐŧ҃", + "dark_theme": "ПĐĩŅ€ĐĩĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŊа Ņ‚ĐĩĐŧĐŊ҃ Ņ‚ĐĩĐŧ҃", "date": "Đ”Đ°Ņ‚Đ°", "date_after": "Đ”Đ°Ņ‚Đ° ĐŋҖҁĐģŅ", - "date_and_time": "Đ”Đ°Ņ‚Đ° Ņ– Ņ‡Đ°Ņ", + "date_and_time": "Đ”Đ°Ņ‚Đ° Đš Ņ‡Đ°Ņ", "date_before": "Đ”Đ°Ņ‚Đ° Đ´Đž", - "date_format": "Е, ЛЛЛ Đ´, Ņ€ â€ĸ Đŗ:ĐŧĐŧ дĐŋ", - "date_of_birth_saved": "Đ”Đ°Ņ‚Đ° ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ ҃ҁĐŋŅ–ŅˆĐŊĐž СйĐĩŅ€ĐĩĐļĐĩĐŊа", - "date_range": "ĐŸŅ€ĐžĐŧŅ–ĐļĐžĐē Ņ‡Đ°ŅŅƒ", + "date_format": "E, d LLL y â€ĸ HH:mm", + "date_of_birth_saved": "Đ”Đ°Ņ‚Ņƒ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", + "date_range": "Đ”Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", "day": "ДĐĩĐŊҌ", "days": "ДĐŊŅ–", "deduplicate_all": "ВидаĐģĐ¸Ņ‚Đ¸ Đ˛ŅŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", - "deduplication_criteria_1": "РОСĐŧŅ–Ņ€ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ в ĐąĐ°ĐšŅ‚Đ°Ņ…", - "deduplication_criteria_2": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ даĐŊĐ¸Ņ… EXIF", - "deduplication_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Đ´ĐĩĐ´ŅƒĐŋĐģŅ–ĐēĐ°Ņ†Ņ–ŅŽ", - "deduplication_info_description": "ДĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐžĐŗĐž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž Đ˛Đ¸ĐąĐžŅ€Ņƒ Ņ„Đ°ĐšĐģŅ–Đ˛ Ņ– ĐŧĐ°ŅĐžĐ˛ĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛ Đŧи Đ˛Ņ€Đ°Ņ…ĐžĐ˛ŅƒŅ”ĐŧĐž:", + "default_locale": "ĐĸиĐŋОва ĐģĐžĐēаĐģҌ", + "default_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Đ¸ Ņ‚Đ° Ņ‡Đ¸ŅĐģа Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐž Đ´Đž ĐģĐžĐēаĐģŅ– Đ˛Đ°ŅˆĐžĐŗĐž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°", "delete": "ВидаĐģĐ¸Ņ‚Đ¸", - "delete_action_confirmation_message": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš Ņ„Đ°ĐšĐģ? Đ™ĐžĐŗĐž ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ, а Ņ‚Đ°ĐēĐžĐļ СĘŧŅĐ˛Đ¸Ņ‚ŅŒŅŅ СаĐŋĐ¸Ņ‚ ĐŊа ĐšĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "delete_action_prompt": "ВидаĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "delete_action_confirmation_message": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚? Đ™ĐžĐŗĐž ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ, а Ņ‚Đ°ĐēĐžĐļ С'ŅĐ˛Đ¸Ņ‚ŅŒŅŅ СаĐŋĐ¸Ņ‚ ĐŊа ĐšĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "delete_action_prompt": "ВидаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "delete_album": "ВидаĐģĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "delete_api_key_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš ĐēĐģŅŽŅ‡ API?", - "delete_dialog_alert": "ĐĻŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊŅ– С ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ Immich Ņ‚Đ° Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "delete_dialog_alert_local": "ĐĻŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊŅ– С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, аĐģĐĩ СаĐģĐ¸ŅˆĐ°Ņ‚ŅŒŅŅ Đ´ĐžŅŅ‚ŅƒĐŋĐŊиĐŧи ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich", - "delete_dialog_alert_local_non_backed_up": "ДĐĩŅĐēŅ– Ņ„Đ°ĐšĐģи ĐŊĐĩ ĐąŅƒĐģи СйĐĩŅ€ĐĩĐļĐĩĐŊŅ– ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich Ņ– ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊŅ– С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "delete_dialog_alert_remote": "ĐĻŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐŊаСавĐļди видаĐģĐĩĐŊŅ– С ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ Immich", + "delete_dialog_alert": "ĐĻŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐ´Đĩ ĐŊаСавĐļди видаĐģĐĩĐŊĐž С Immich Ņ‚Đ° С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "delete_dialog_alert_local": "ĐĻŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐ´Đĩ ĐŊаСавĐļди видаĐģĐĩĐŊĐž С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, аĐģĐĩ вОĐŊи СаĐģĐ¸ŅˆĐ°Ņ‚ŅŒŅŅ ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich", + "delete_dialog_alert_local_non_backed_up": "ДĐĩŅĐēŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐĩ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ Immich, Ņ– Ņ—Ņ… ĐąŅƒĐ´Đĩ ĐŊаСавĐļди видаĐģĐĩĐŊĐž С Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "delete_dialog_alert_remote": "ĐĻŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐ´Đĩ ĐŊаСавĐļди видаĐģĐĩĐŊĐž С ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Immich", "delete_dialog_ok_force": "Đ’ŅĐĩ ОдĐŊĐž видаĐģĐ¸Ņ‚Đ¸", - "delete_dialog_title": "ВидаĐģĐ¸Ņ‚Đ¸ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž", + "delete_dialog_title": "ВидаĐģĐ¸Ņ‚Đ¸ ĐŊаСавĐļди", "delete_duplicates_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŊаСавĐļди видаĐģĐ¸Ņ‚Đ¸ ҆Җ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸?", "delete_face": "ВидаĐģĐ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", "delete_key": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡", "delete_library": "ВидаĐģĐ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", "delete_link": "ВидаĐģĐ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "delete_local_action_prompt": "ВидаĐģĐĩĐŊĐž С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "delete_local_dialog_ok_backed_up_only": "ВидаĐģĐ¸Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ—", + "delete_local_action_prompt": "ВидаĐģĐĩĐŊĐž С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "delete_local_dialog_ok_backed_up_only": "ВидаĐģĐ¸Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, СйĐĩŅ€ĐĩĐļĐĩĐŊŅ– ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ", "delete_local_dialog_ok_force": "Đ’ŅĐĩ ОдĐŊĐž видаĐģĐ¸Ņ‚Đ¸", "delete_others": "ВидаĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆŅ–", "delete_permanently": "ВидаĐģĐ¸Ņ‚Đ¸ ĐŊаСавĐļди", - "delete_permanently_action_prompt": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "delete_permanently_action_prompt": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "delete_shared_link": "ВидаĐģĐ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "delete_shared_link_dialog_title": "ВидаĐģĐ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "delete_tag": "ВидаĐģĐ¸Ņ‚Đ¸ ĐĸĐĩĐŗ", + "delete_tag": "ВидаĐģĐ¸Ņ‚Đ¸ Ņ‚ĐĩĐŗ", "delete_tag_confirmation_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ Ņ‚ĐĩĐŗ {tagName}?", "delete_user": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "deleted_shared_link": "ВидаĐģĐĩĐŊĐž ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "deletes_missing_assets": "ВидаĐģŅŅ” Ņ„Đ°ĐšĐģи, ŅĐēŅ– Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– ĐŊа Đ´Đ¸ŅĐē҃", + "deletes_missing_assets": "ВидаĐģŅŅ” ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ŅĐēŅ– Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– ĐŊа Đ´Đ¸ŅĐē҃", "description": "ОĐŋĐ¸Ņ", - "description_input_hint_text": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņ...", - "description_input_submit_error": "ПоĐŧиĐģĐēа ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐžĐŋĐ¸ŅŅƒ, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ĐļŅƒŅ€ĐŊаĐģ Đ´ĐģŅ ĐŋĐžĐ´Ņ€ĐžĐąĐ¸Ņ†ŅŒ", + "description_input_hint_text": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņâ€Ļ", + "description_input_submit_error": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ. ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅŒŅ‚Đĩ ĐļŅƒŅ€ĐŊаĐģ Đ´ĐģŅ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš", "deselect_all": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Đ¸ĐąŅ–Ņ€ ŅƒŅŅ–Ņ…", "details": "ДĐĩŅ‚Đ°ĐģŅ–", "direction": "НаĐŋŅ€ŅĐŧ", @@ -934,77 +936,77 @@ "disabled": "ВиĐŧĐēĐŊĐĩĐŊĐž", "disallow_edits": "Đ—Đ°ĐąĐžŅ€ĐžĐŊĐ¸Ņ‚Đ¸ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°ĐŊĐŊŅ", "discord": "Discord", - "discover": "Đ’Đ¸ŅĐ˛Đ¸Ņ‚Đ¸", + "discover": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Ņ‚Ņ", "discovered_devices": "Đ’Đ¸ŅĐ˛ĐģĐĩĐŊŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "dismiss_all_errors": "ĐŸŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ŅŅ– ĐŋĐžĐŧиĐģĐēи", - "dismiss_error": "ĐŸŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ ĐŋĐžĐŧиĐģĐē҃", - "display_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", + "dismiss_all_errors": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– ĐŋĐžĐŧиĐģĐēи", + "dismiss_error": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐŋĐžĐŧиĐģĐē҃", + "display_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "display_order": "ĐŸĐžŅ€ŅĐ´ĐžĐē Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "display_original_photos": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐ¸Ņ… Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš", - "display_original_photos_setting_description": "ĐĐ°Đ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŽ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐžĐŗĐž Ņ„ĐžŅ‚Đž ĐŋŅ€Đ¸ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—, ŅĐēŅ‰Đž ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐĩ Ņ„ĐžŅ‚Đž ҁ҃ĐŧҖҁĐŊĐĩ С вĐĩйОĐŧ. ĐĻĐĩ ĐŧĐžĐļĐĩ ĐŋŅ€Đ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ Đ´Đž ĐŋĐžĐ˛Ņ–ĐģҌĐŊŅ–ŅˆĐžĐŗĐž Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš.", - "do_not_show_again": "НĐĩ ĐŋĐžĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ҆Đĩ ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊĐŊŅ СĐŊĐžĐ˛Ņƒ", + "display_original_photos": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊŅ– Ņ„ĐžŅ‚Đž", + "display_original_photos_setting_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ СаĐŧŅ–ŅŅ‚ŅŒ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸, ŅĐēŅ‰Đž Ņ„ĐžŅ€ĐŧĐ°Ņ‚ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ° ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ĐžĐŧ. ĐĻĐĩ ĐŧĐžĐļĐĩ ҁĐŋĐžĐ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ.", + "do_not_show_again": "Đ‘Ņ–ĐģҌ҈Đĩ ĐŊĐĩ ĐŋĐžĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ҆Đĩ ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊĐŊŅ", "documentation": "ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ", "done": "Đ“ĐžŅ‚ĐžĐ˛Đž", "download": "ЗаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", - "download_action_prompt": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ {count} Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "download_action_prompt": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "download_canceled": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ҁĐēĐ°ŅĐžĐ˛Đ°ĐŊĐž", "download_complete": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ СаĐēŅ–ĐŊ҇ĐĩĐŊĐž", "download_enqueue": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐž в ҇ĐĩŅ€ĐŗŅƒ", - "download_error": "ПоĐŧиĐģĐēа СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", - "download_failed": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ вдаĐģĐžŅŅ", + "download_error": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", + "download_failed": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", "download_finished": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ СаĐēŅ–ĐŊ҇ĐĩĐŊĐž", "download_include_embedded_motion_videos": "Đ’ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– Đ˛Ņ–Đ´ĐĩĐž", - "download_include_embedded_motion_videos_description": "ВĐēĐģŅŽŅ‡Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž, Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– в Ņ€ŅƒŅ…ĐžĐŧŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—, ŅĐē ĐžĐēŅ€ĐĩĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", - "download_notfound": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐž", + "download_include_embedded_motion_videos_description": "Đ”ĐžĐ´Đ°Đ˛Đ°Ņ‚Đ¸ Đ˛ĐąŅƒĐ´ĐžĐ˛Đ°ĐŊŅ– Đ˛Ņ–Đ´ĐĩĐž С Ņ€ŅƒŅ…ĐžĐŧĐ¸Ņ… Ņ„ĐžŅ‚Đž ŅĐē ĐžĐēŅ€ĐĩĐŧиК Ņ„Đ°ĐšĐģ", + "download_notfound": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", "download_original": "ЗаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ", "download_paused": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊĐž", - "download_settings": "ЗаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", - "download_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи, ĐŋОв'ŅĐˇĐ°ĐŊиĐŧи С СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅĐŧ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "download_settings": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", + "download_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "download_started": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ Ņ€ĐžĐˇĐŋĐžŅ‡Đ°Ņ‚Đž", - "download_sucess": "ĐŖŅĐŋŅ–ŅˆĐŊĐĩ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", - "download_sucess_android": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž в DCIM/Immich", + "download_sucess": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž", + "download_sucess_android": "МĐĩĐ´Ņ–Đ° СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž в DCIM/Immich", "download_waiting_to_retry": "ĐžŅ‡Ņ–ĐēŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžŅ— ҁĐŋŅ€ĐžĐąĐ¸", "downloading": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", - "downloading_asset_filename": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ Ņ„Đ°ĐšĐģ҃ {filename}", + "downloading_asset_filename": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ° {filename}", "downloading_from_icloud": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ С iCloud", "downloading_media": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐĩĐ´Ņ–Đ°", - "drop_files_to_upload": "ПĐĩŅ€ĐĩĐŊĐĩŅŅ–Ņ‚ŅŒ Ņ„Đ°ĐšĐģи в ĐąŅƒĐ´ŅŒ-ŅĐēĐĩ ĐŧҖҁ҆Đĩ Đ´ĐģŅ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", + "drop_files_to_upload": "ПĐĩŅ€ĐĩŅ‚ŅĐŗĐŊŅ–Ņ‚ŅŒ Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅŒ-ĐēŅƒĐ´Đ¸, Ņ‰ĐžĐą виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", "duplicates": "Đ”ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", - "duplicates_description": "ВизĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸, ŅĐēŅ– ĐŗŅ€ŅƒĐŋи Ņ” Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ°Đŧи", + "duplicates_description": "ОĐŋŅ€Đ°Ņ†ŅŽĐšŅ‚Đĩ ĐēĐžĐļĐŊ҃ ĐŗŅ€ŅƒĐŋ҃, вĐēĐ°ĐˇĐ°Đ˛ŅˆĐ¸, ŅĐēŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ŅĐēŅ‰Đž Ņ‚Đ°ĐēŅ– Ņ”, Ņ” Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ°Đŧи", "duration": "ĐĸŅ€Đ¸Đ˛Đ°ĐģŅ–ŅŅ‚ŅŒ", - "edit": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸", + "edit": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸", "edit_album": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "edit_avatar": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ°Đ˛Đ°Ņ‚Đ°Ņ€", "edit_birthday": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ", "edit_date": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ", "edit_date_and_time": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ Ņ‚Đ° Ņ‡Đ°Ņ", - "edit_date_and_time_action_prompt": "ЗĐŧŅ–ĐŊĐĩĐŊĐž Đ´Đ°Ņ‚Ņƒ Ņ‚Đ° Ņ‡Đ°Ņ ҃ {count, plural, one {# Ņ„Đ°ĐšĐģŅ–} few {# Ņ„Đ°ĐšĐģĐ°Ņ…} other {# Ņ„Đ°ĐšĐģĐ°Ņ…}}", - "edit_date_and_time_by_offset": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ Са СĐŧҖ҉ĐĩĐŊĐŊŅĐŧ", + "edit_date_and_time_action_prompt": "ЗĐŧŅ–ĐŊĐĩĐŊĐž Đ´Đ°Ņ‚Ņƒ Ņ‚Đ° Ņ‡Đ°Ņ ҃ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊ҂Җ} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Ņ…} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Ņ…} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Ņ…}}", + "edit_date_and_time_by_offset": "ЗĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ Са ĐˇŅŅƒĐ˛ĐžĐŧ", "edit_date_and_time_by_offset_interval": "Новий Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚: {from} - {to}", "edit_description": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", - "edit_description_prompt": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, вийĐĩŅ€Ņ–Ņ‚ŅŒ ĐŊОвиК ĐžĐŋĐ¸Ņ:", + "edit_description_prompt": "ОбĐĩŅ€Ņ–Ņ‚ŅŒ ĐŊОвиК ĐžĐŋĐ¸Ņ:", "edit_exclusion_pattern": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊҌ", - "edit_faces": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°ĐŊĐŊŅ ОйĐģĐ¸Ņ‡", - "edit_key": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡", + "edit_faces": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "edit_key": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐģŅŽŅ‡", "edit_link": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "edit_location": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", - "edit_location_action_prompt": "ЗĐŧŅ–ĐŊĐĩĐŊĐž ĐŧŅ–ŅŅ†ŅŒ СКОĐŧĐēи: {count}", - "edit_location_dialog_title": "ĐœŅ–ŅŅ†ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", - "edit_name": "Đ’Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Ņ–Đŧ'Ņ", + "edit_location": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", + "edit_location_action_prompt": "ЗĐŧŅ–ĐŊĐĩĐŊĐž ĐŧҖҁ҆Đĩ СКОĐŧĐēи Đ´ĐģŅ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "edit_location_dialog_title": "ĐœŅ–ŅŅ†Đĩ", + "edit_name": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Ņ–Đŧ'Ņ", "edit_people": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", "edit_tag": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Ņ‚ĐĩĐŗ", "edit_title": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐˇĐ°ĐŗĐžĐģОвОĐē", "edit_user": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "edit_workflow": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", + "edit_workflow": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", "editor": "Đ ĐĩдаĐēŅ‚ĐžŅ€", - "editor_close_without_save_prompt": "ЗĐŧŅ–ĐŊи ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ŅŒ СйĐĩŅ€ĐĩĐļĐĩĐŊŅ–", + "editor_close_without_save_prompt": "ЗĐŧŅ–ĐŊи ĐŊĐĩ ĐąŅƒĐ´Đĩ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", "editor_close_without_save_title": "ЗаĐēŅ€Đ¸Ņ‚Đ¸ Ņ€ĐĩдаĐēŅ‚ĐžŅ€?", "editor_confirm_reset_all_changes": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ҁĐēиĐŊŅƒŅ‚Đ¸ Đ˛ŅŅ– СĐŧŅ–ĐŊи?", "editor_discard_edits_confirm": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи", "editor_discard_edits_prompt": "ĐŖ Đ˛Đ°Ņ Ņ” ĐŊĐĩСйĐĩŅ€ĐĩĐļĐĩĐŊŅ– СĐŧŅ–ĐŊи. Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Ņ—Ņ… ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸?", "editor_discard_edits_title": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи?", "editor_edits_applied_error": "НĐĩ вдаĐģĐžŅŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи", - "editor_edits_applied_success": "ЗĐŧŅ–ĐŊи ҃ҁĐŋŅ–ŅˆĐŊĐž ĐˇĐ°ŅŅ‚ĐžŅĐžĐ˛Đ°ĐŊĐž", + "editor_edits_applied_success": "ЗĐŧŅ–ĐŊи ĐˇĐ°ŅŅ‚ĐžŅĐžĐ˛Đ°ĐŊĐž", "editor_flip_horizontal": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐˇĐ¸Ņ‚Đ¸ ĐŗĐžŅ€Đ¸ĐˇĐžĐŊŅ‚Đ°ĐģҌĐŊĐž", "editor_flip_vertical": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐˇĐ¸Ņ‚Đ¸ вĐĩŅ€Ņ‚Đ¸ĐēаĐģҌĐŊĐž", "editor_handle_corner": "{corner, select, top_left {Đ›Ņ–Đ˛Đ¸Đš вĐĩҀ҅ĐŊŅ–Đš ĐēŅƒŅ‚} top_right {ĐŸŅ€Đ°Đ˛Đ¸Đš вĐĩҀ҅ĐŊŅ–Đš ĐēŅƒŅ‚} bottom_left {Đ›Ņ–Đ˛Đ¸Đš ĐŊиĐļĐŊŅ–Đš ĐēŅƒŅ‚} bottom_right {ĐŸŅ€Đ°Đ˛Đ¸Đš ĐŊиĐļĐŊŅ–Đš ĐēŅƒŅ‚} other {ĐšŅƒŅ‚}}", @@ -1017,158 +1019,158 @@ "email_notifications": "ĐĄĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐĩĐģ. ĐŋĐžŅˆŅ‚ĐžŅŽ", "empty_folder": "ĐĻŅ ĐŋаĐŋĐēа ĐŋĐžŅ€ĐžĐļĐŊŅ", "empty_trash": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē", - "empty_trash_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē? ĐĻĐĩ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐ¸Ņ‚ŅŒ Đ˛ŅŅ– Ņ„Đ°ĐšĐģи ҃ ĐēĐžŅˆĐ¸Đē҃ С Immich.\nĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸!", + "empty_trash_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē? ĐĻĐĩ ĐŊаСавĐļди видаĐģĐ¸Ņ‚ŅŒ С Immich ŅƒŅŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, Ņ‰Đž ĐŋĐĩŅ€ĐĩĐąŅƒĐ˛Đ°ŅŽŅ‚ŅŒ ҃ ĐēĐžŅˆĐ¸Đē҃.\nĐĻŅŽ Đ´Ņ–ŅŽ ĐŊĐĩ ĐŧĐžĐļĐŊа ҁĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸!", "enable": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸", "enable_backup": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐĩ ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", - "enable_biometric_auth_description": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ŅĐ˛Ņ–Đš PIN-ĐēОд, Ņ‰ĐžĐą ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐąŅ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊ҃ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–ŅŽ", + "enable_biometric_auth_description": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ PIN-ĐēОд, Ņ‰ĐžĐą ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐąŅ–ĐžĐŧĐĩŅ‚Ņ€Đ¸Ņ‡ĐŊ҃ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–ŅŽ", "enabled": "ĐŖĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", "end_date": "Đ”Đ°Ņ‚Đ° СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ", "enqueued": "ĐŖ ҇ĐĩŅ€ĐˇŅ–", "enter_wifi_name": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ĐŊĐ°ĐˇĐ˛Ņƒ Wi-Fi", - "enter_your_pin_code": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ŅĐ˛Ņ–Đš PIN-ĐēОд", - "enter_your_pin_code_subtitle": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ ŅĐ˛Ņ–Đš PIN-ĐēОд, Ņ‰ĐžĐą ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", + "enter_your_pin_code": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ PIN-ĐēОд", + "enter_your_pin_code_subtitle": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ PIN-ĐēОд, Ņ‰ĐžĐą ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", "error": "ПоĐŧиĐģĐēа", "error_change_sort_album": "НĐĩ вдаĐģĐžŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐžŅ€ŅĐ´ĐžĐē ŅĐžŅ€Ņ‚ŅƒĐ˛Đ°ĐŊĐŊŅ аĐģŅŒĐąĐžĐŧ҃", - "error_delete_face": "ПоĐŧиĐģĐēа ĐŋŅ€Đ¸ видаĐģĐĩĐŊĐŊŅ– ОйĐģĐ¸Ņ‡Ņ‡Ņ С Ņ„Đ°ĐšĐģ҃", - "error_getting_places": "ПоĐŧиĐģĐēа ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ ĐŧŅ–ŅŅ†ŅŒ", - "error_loading_albums": "ПоĐŧиĐģĐēа СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ аĐģŅŒĐąĐžĐŧŅ–Đ˛", - "error_loading_image": "ПоĐŧиĐģĐēа СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "error_loading_partners": "ПоĐŧиĐģĐēа СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Ņ–Đ˛: {error}", - "error_retrieving_asset_information": "ПоĐŧиĐģĐēа ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ— ĐŋŅ€Đž Ņ„Đ°ĐšĐģ", + "error_delete_face": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ С ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "error_getting_places": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŧŅ–ŅŅ†Ņ", + "error_loading_albums": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", + "error_loading_image": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", + "error_loading_partners": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Ņ–Đ˛: {error}", + "error_retrieving_asset_information": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", "error_saving_image": "ПоĐŧиĐģĐēа: {error}", - "error_tag_face_bounding_box": "ПоĐŧиĐģĐēа ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋОСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡Ņ‡Ņ – ĐŊĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐēĐžĐžŅ€Đ´Đ¸ĐŊĐ°Ņ‚Đ¸ Ņ€Đ°ĐŧĐēи", - "error_title": "ПоĐŧиĐģĐēа: Ņ‰ĐžŅŅŒ ĐŋŅ–ŅˆĐģĐž ĐŊĐĩ Ņ‚Đ°Đē", - "error_while_navigating": "ПоĐŧиĐģĐēа ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´Ņƒ Đ´Đž Ņ„Đ°ĐšĐģ҃", + "error_tag_face_bounding_box": "НĐĩ вдаĐģĐžŅŅ ĐŋОСĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ — ĐŊĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐēĐžĐžŅ€Đ´Đ¸ĐŊĐ°Ņ‚Đ¸ Ņ€Đ°ĐŧĐēи", + "error_title": "ПоĐŧиĐģĐēа — Ņ‰ĐžŅŅŒ ĐŋŅ–ŅˆĐģĐž ĐŊĐĩ Ņ‚Đ°Đē", + "error_while_navigating": "НĐĩ вдаĐģĐžŅŅ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", "errors": { - "cannot_navigate_next_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž Ņ„Đ°ĐšĐģ҃", - "cannot_navigate_previous_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž Ņ„Đ°ĐšĐģ҃", + "cannot_navigate_next_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "cannot_navigate_previous_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", "cant_apply_changes": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи", - "cant_change_activity": "НĐĩ ĐŧĐžĐļĐŊа {enabled, select, true {виĐŧĐēĐŊŅƒŅ‚Đ¸} other {ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸}} аĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ", - "cant_change_asset_favorite": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐžĐąŅ€Đ°ĐŊĐĩ Đ´ĐģŅ Ņ„Đ°ĐšĐģ҃", - "cant_change_metadata_assets_count": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊŅ– {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "cant_get_faces": "НĐĩ ĐŧĐžĐļ҃ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊĐ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "cant_change_activity": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ {enabled, select, true {виĐŧĐēĐŊŅƒŅ‚Đ¸} other {ŅƒĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸}} аĐēŅ‚Đ¸Đ˛ĐŊŅ–ŅŅ‚ŅŒ", + "cant_change_asset_favorite": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐĩ Đ´ĐģŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "cant_change_metadata_assets_count": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊŅ– {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "cant_get_faces": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", "cant_get_number_of_comments": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ–Đ˛", "cant_search_people": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐēĐžĐŊĐ°Ņ‚Đ¸ ĐŋĐžŅˆŅƒĐē ĐģŅŽĐ´ĐĩĐš", "cant_search_places": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐēĐžĐŊĐ°Ņ‚Đ¸ ĐŋĐžŅˆŅƒĐē ĐŧŅ–ŅŅ†ŅŒ", - "error_adding_assets_to_album": "ПоĐŧиĐģĐēа дОдаваĐŊĐŊŅ Ņ„Đ°ĐšĐģŅ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "error_adding_users_to_album": "ПоĐŧиĐģĐēа дОдаваĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "error_deleting_shared_user": "ПоĐŧиĐģĐēа ĐŋŅ–Đ´ Ņ‡Đ°Ņ видаĐģĐĩĐŊĐŊŅ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ĐˇŅ– ҁĐŋŅ–ĐģҌĐŊиĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐžĐŧ", - "error_downloading": "ПоĐŧиĐģĐēа СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ {filename}", - "error_hiding_buy_button": "ПоĐŧиĐģĐēа ĐŋŅ€Đ¸ ҁĐŋŅ€ĐžĐąŅ– ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐēĐŊĐžĐŋĐē҃ ĐŋĐžĐē҃ĐŋĐēи", - "error_removing_assets_from_album": "ПоĐŧиĐģĐēа видаĐģĐĩĐŊĐŊŅ Ņ„Đ°ĐšĐģŅ–Đ˛ С аĐģŅŒĐąĐžĐŧ҃, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ĐēĐžĐŊŅĐžĐģҌ Đ´ĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… Đ˛Ņ–Đ´ĐžĐŧĐžŅŅ‚ĐĩĐš", - "error_selecting_all_assets": "ПоĐŧиĐģĐēа Đ˛Đ¸ĐąĐžŅ€Ņƒ Đ˛ŅŅ–Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "exclusion_pattern_already_exists": "ĐĻĐĩĐš ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ вĐļĐĩ ҖҁĐŊŅƒŅ”.", + "error_adding_assets_to_album": "НĐĩ вдаĐģĐžŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "error_adding_users_to_album": "НĐĩ вдаĐģĐžŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "error_deleting_shared_user": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ ŅƒŅ‡Đ°ŅĐŊиĐēа ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž Đ´ĐžŅŅ‚ŅƒĐŋ҃", + "error_downloading": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {filename}", + "error_hiding_buy_button": "НĐĩ вдаĐģĐžŅŅ ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐēĐŊĐžĐŋĐē҃ Đē҃ĐŋŅ–Đ˛ĐģŅ–", + "error_removing_assets_from_album": "НĐĩ вдаĐģĐžŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ĐēĐžĐŊŅĐžĐģҌ Đ´ĐģŅ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… Đ˛Ņ–Đ´ĐžĐŧĐžŅŅ‚ĐĩĐš", + "error_selecting_all_assets": "НĐĩ вдаĐģĐžŅŅ Đ˛Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Đ˛ŅŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "exclusion_pattern_already_exists": "ĐĻĐĩĐš ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃ вĐļĐĩ ҖҁĐŊŅƒŅ”.", "failed_to_create_album": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "failed_to_create_shared_link": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "failed_to_edit_shared_link": "НĐĩ вдаĐģĐžŅŅ Đ˛Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "failed_to_get_people": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž ĐģŅŽĐ´ĐĩĐš", - "failed_to_keep_this_delete_others": "НĐĩ вдаĐģĐžŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ҆ĐĩĐš Ņ„Đ°ĐšĐģ Ņ– видаĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆŅ– Ņ„Đ°ĐšĐģи", - "failed_to_load_asset": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", - "failed_to_load_assets": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", + "failed_to_keep_this_delete_others": "НĐĩ вдаĐģĐžŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Ņ– видаĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "failed_to_load_asset": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "failed_to_load_assets": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "failed_to_load_notifications": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ", - "failed_to_load_people": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", - "failed_to_remove_product_key": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ", + "failed_to_load_people": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ҁĐŋĐ¸ŅĐžĐē ĐģŅŽĐ´ĐĩĐš", + "failed_to_remove_product_key": "НĐĩ вдаĐģĐžŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ", "failed_to_reset_pin_code": "НĐĩ вдаĐģĐžŅŅ ҁĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд", - "failed_to_stack_assets": "НĐĩ вдаĐģĐžŅŅ ĐˇĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸ Ņ„Đ°ĐšĐģи", - "failed_to_unstack_assets": "НĐĩ вдаĐģĐžŅŅ Ņ€ĐžĐˇĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸ Ņ„Đ°ĐšĐģи", + "failed_to_stack_assets": "НĐĩ вдаĐģĐžŅŅ ĐˇĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "failed_to_unstack_assets": "НĐĩ вдаĐģĐžŅŅ Ņ€ĐžĐˇĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "failed_to_update_notification_status": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ŅŅ‚Đ°Ņ‚ŅƒŅ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ", "incorrect_email_or_password": "НĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊа Đ°Đ´Ņ€ĐĩŅĐ° ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅ— ĐŋĐžŅˆŅ‚Đ¸ айО ĐŋĐ°Ņ€ĐžĐģҌ", "library_folder_already_exists": "ĐĻĐĩĐš ҈ĐģŅŅ… Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ вĐļĐĩ ҖҁĐŊŅƒŅ”.", - "page_not_found": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа ĐŊĐĩ СĐŊаКдĐĩĐŊа", - "paths_validation_failed": "{paths, plural, one {# ҈ĐģŅŅ…} few {# ҈ĐģŅŅ…Đ¸} many {# ҈ĐģŅŅ…Ņ–Đ˛} other {# ҈ĐģŅŅ…Ņƒ}} ĐŊĐĩ ĐŋŅ€ĐžĐšŅˆĐģĐž ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đē҃", - "profile_picture_transparent_pixels": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ ĐŊĐĩ ĐŧĐžĐļĐĩ ĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐŋŅ€ĐžĐˇĐžŅ€Đ¸Ņ… ĐŋŅ–ĐēҁĐĩĐģŅ–Đ˛. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐˇĐąŅ–ĐģŅŒŅˆŅ–Ņ‚ŅŒ ĐŧĐ°ŅŅˆŅ‚Đ°Đą Ņ‚Đ°/айО ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Ņ–Ņ‚ŅŒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ.", - "quota_higher_than_disk_size": "Ви Đ˛ŅŅ‚Đ°ĐŊОвиĐģи ĐēĐ˛ĐžŅ‚Ņƒ, Ņ‰Đž ĐŋĐĩŅ€ĐĩĐ˛Đ¸Ņ‰ŅƒŅ” Ņ€ĐžĐˇĐŧŅ–Ņ€ Đ´Đ¸ŅĐēа", + "page_not_found": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐē҃ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", + "paths_validation_failed": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēа ĐŊĐĩ ĐŋŅ€ĐžĐšĐ´ĐĩĐŊа Đ´ĐģŅ {paths, plural, one {# ҈ĐģŅŅ…Ņƒ} few {# ҈ĐģŅŅ…Ņ–Đ˛} many {# ҈ĐģŅŅ…Ņ–Đ˛} other {# ҈ĐģŅŅ…Ņ–Đ˛}}", + "profile_picture_transparent_pixels": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ ĐŊĐĩ ĐŧĐžĐļĐĩ ĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐŋŅ€ĐžĐˇĐžŅ€Đ¸Ņ… ĐŋŅ–ĐēҁĐĩĐģŅ–Đ˛. Đ—ĐąŅ–ĐģŅŒŅˆŅ–Ņ‚ŅŒ ĐŧĐ°ŅŅˆŅ‚Đ°Đą Ņ‚Đ°/айО ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Ņ–Ņ‚ŅŒ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ.", + "quota_higher_than_disk_size": "Ви ŅƒŅŅ‚Đ°ĐŊОвиĐģи ĐēĐ˛ĐžŅ‚Ņƒ, Ņ‰Đž ĐŋĐĩŅ€ĐĩĐ˛Đ¸Ņ‰ŅƒŅ” Ņ€ĐžĐˇĐŧŅ–Ņ€ Đ´Đ¸ŅĐēа", "something_went_wrong": "ĐŠĐžŅŅŒ ĐŋŅ–ŅˆĐģĐž ĐŊĐĩ Ņ‚Đ°Đē", - "unable_to_add_album_users": "НĐĩĐŧĐžĐļĐģивО Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", - "unable_to_add_assets_to_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи Đ´Đž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "unable_to_add_comment": "НĐĩĐŧĐžĐļĐģивО Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€", - "unable_to_add_exclusion_pattern": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ", + "unable_to_add_album_users": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "unable_to_add_assets_to_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", + "unable_to_add_comment": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€", + "unable_to_add_exclusion_pattern": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃", "unable_to_add_partners": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Ņ–Đ˛", - "unable_to_add_remove_archive": "НĐĩĐŧĐžĐļĐģивО {archived, select, true {виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ Ņ–Đˇ} other {Đ´ĐžĐ´Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģ Đ´Đž}} Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", - "unable_to_add_remove_favorites": "НĐĩĐŧĐžĐļĐģивО {favorite, select, true {Đ´ĐžĐ´Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģ Đ´Đž} other {виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ Ņ–Đˇ}} ĐžĐąŅ€Đ°ĐŊĐ¸Ņ…", - "unable_to_archive_unarchive": "НĐĩĐŧĐžĐļĐģивО {archived, select, true {Đ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸} other {Ņ€ĐžĐˇĐ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸}}", - "unable_to_change_album_user_role": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ€ĐžĐģҌ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° аĐģŅŒĐąĐžĐŧ҃", - "unable_to_change_date": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ", - "unable_to_change_description": "НĐĩ вдаĐģĐžŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", - "unable_to_change_favorite": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ŅŅ‚Đ°Ņ‚ŅƒŅ ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž Đ´ĐģŅ Ņ„Đ°ĐšĐģ҃", - "unable_to_change_location": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "unable_to_add_remove_archive": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ {archived, select, true {виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Ņ–Đˇ} other {Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Đ´Đž}} Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", + "unable_to_add_remove_favorites": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ {favorite, select, true {Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Đ´Đž} other {виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Ņ–Đˇ}} Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "unable_to_archive_unarchive": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ {archived, select, true {Đ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸} other {виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ}}", + "unable_to_change_album_user_role": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ€ĐžĐģҌ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° аĐģŅŒĐąĐžĐŧ҃", + "unable_to_change_date": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ", + "unable_to_change_description": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", + "unable_to_change_favorite": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ŅŅ‚Đ°Ņ‚ŅƒŅ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž Đ´ĐģŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", + "unable_to_change_location": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "unable_to_change_password": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "unable_to_change_visibility": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ видиĐŧŅ–ŅŅ‚ŅŒ Đ´ĐģŅ {count, plural, one {# ĐžŅĐžĐąĐ¸} few {# ĐžŅŅ–Đą} other {# ĐģŅŽĐ´ĐĩĐš}}", - "unable_to_complete_oauth_login": "НĐĩĐŧĐžĐļĐģивО СавĐĩŅ€ŅˆĐ¸Ņ‚Đ¸ Đ˛Ņ…Ņ–Đ´ ҇ĐĩŅ€ĐĩС OAuth", - "unable_to_connect": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´ĐēĐģŅŽŅ‡Đ¸Ņ‚Đ¸ŅŅ", - "unable_to_copy_to_clipboard": "НĐĩĐŧĐžĐļĐģивО ҁĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃. ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ви ĐˇĐ°Ņ…ĐžĐ´Đ¸Ņ‚Đĩ ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃ ҇ĐĩŅ€ĐĩС https", - "unable_to_create": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", - "unable_to_create_admin_account": "НĐĩĐŧĐžĐļĐģивО ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", - "unable_to_create_api_key": "НĐĩĐŧĐžĐļĐģивО ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК ĐēĐģŅŽŅ‡ API", - "unable_to_create_library": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", - "unable_to_create_user": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "unable_to_change_visibility": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ видиĐŧŅ–ŅŅ‚ŅŒ Đ´ĐģŅ {count, plural, one {# ĐģŅŽĐ´Đ¸ĐŊи} few {# ĐģŅŽĐ´ĐĩĐš} many {# ĐģŅŽĐ´ĐĩĐš} other {# ĐģŅŽĐ´ĐĩĐš}}", + "unable_to_complete_oauth_login": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СавĐĩŅ€ŅˆĐ¸Ņ‚Đ¸ Đ˛Ņ…Ņ–Đ´ ҇ĐĩŅ€ĐĩС OAuth", + "unable_to_connect": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ŅŅ", + "unable_to_copy_to_clipboard": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ҁĐēĐžĐŋŅ–ŅŽĐ˛Đ°Ņ‚Đ¸ в ĐąŅƒŅ„ĐĩŅ€ ОйĐŧŅ–ĐŊ҃. ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ви ĐˇĐ°Ņ…ĐžĐ´Đ¸Ņ‚Đĩ ĐŊа ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃ ҇ĐĩŅ€ĐĩС https", + "unable_to_create": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", + "unable_to_create_admin_account": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ°", + "unable_to_create_api_key": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК ĐēĐģŅŽŅ‡ API", + "unable_to_create_library": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "unable_to_create_user": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "unable_to_delete_album": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", - "unable_to_delete_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", - "unable_to_delete_assets": "ПоĐŧиĐģĐēа видаĐģĐĩĐŊĐŊŅ Ņ„Đ°ĐšĐģŅ–Đ˛", - "unable_to_delete_exclusion_pattern": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ", - "unable_to_delete_shared_link": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", + "unable_to_delete_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "unable_to_delete_assets": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "unable_to_delete_exclusion_pattern": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃", + "unable_to_delete_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "unable_to_delete_user": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "unable_to_delete_workflow": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", - "unable_to_download_files": "НĐĩĐŧĐžĐļĐģивО СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", - "unable_to_edit_exclusion_pattern": "НĐĩ вдаĐģĐžŅŅ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ", - "unable_to_empty_trash": "НĐĩĐŧĐžĐļĐģивО ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē", - "unable_to_enter_fullscreen": "НĐĩĐŧĐžĐļĐģивО ŅƒĐ˛Ņ–ĐšŅ‚Đ¸ в ĐŋОвĐŊĐžĐĩĐēŅ€Đ°ĐŊĐŊиК Ņ€ĐĩĐļиĐŧ", - "unable_to_exit_fullscreen": "НĐĩĐŧĐžĐļĐģивО Đ˛Đ¸ĐšŅ‚Đ¸ С ĐŋОвĐŊĐžĐĩĐēŅ€Đ°ĐŊĐŊĐžĐŗĐž Ņ€ĐĩĐļиĐŧ҃", - "unable_to_get_comments_number": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ–Đ˛", - "unable_to_get_shared_link": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "unable_to_hide_person": "НĐĩĐŧĐžĐļĐģивО ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", - "unable_to_link_motion_video": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Св'ŅĐˇĐ°Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", - "unable_to_link_oauth_account": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸Đ˛'ŅĐˇĐ°Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth", + "unable_to_delete_workflow": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", + "unable_to_download_files": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", + "unable_to_edit_exclusion_pattern": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ŅˆĐ°ĐąĐģĐžĐŊ виĐŊŅŅ‚Đē҃", + "unable_to_empty_trash": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē", + "unable_to_enter_fullscreen": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅƒĐ˛Ņ–ĐšŅ‚Đ¸ в ĐŋОвĐŊĐžĐĩĐēŅ€Đ°ĐŊĐŊиК Ņ€ĐĩĐļиĐŧ", + "unable_to_exit_fullscreen": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Đ¸ĐšŅ‚Đ¸ С ĐŋОвĐŊĐžĐĩĐēŅ€Đ°ĐŊĐŊĐžĐŗĐž Ņ€ĐĩĐļиĐŧ҃", + "unable_to_get_comments_number": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐēŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐēĐžĐŧĐĩĐŊŅ‚Đ°Ņ€Ņ–Đ˛", + "unable_to_get_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", + "unable_to_hide_person": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", + "unable_to_link_motion_video": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", + "unable_to_link_oauth_account": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth", "unable_to_log_out_all_devices": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Đ¸ĐšŅ‚Đ¸ С ŅƒŅŅ–Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛", "unable_to_log_out_device": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Đ¸ĐšŅ‚Đ¸ С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", "unable_to_login_with_oauth": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅƒĐ˛Ņ–ĐšŅ‚Đ¸ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ OAuth", "unable_to_play_video": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž", - "unable_to_reassign_assets_existing_person": "НĐĩ вдаĐģĐžŅŅ ĐŋĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи {name, select, null {ҖҁĐŊŅƒŅŽŅ‡Ņ–Đš ĐžŅĐžĐąŅ–} other {{name}}}", - "unable_to_reassign_assets_new_person": "НĐĩĐŧĐžĐļĐģивО ĐŋĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐŊĐžĐ˛Ņ–Đš ĐžŅĐžĐąŅ–", - "unable_to_refresh_user": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "unable_to_remove_album_users": "НĐĩĐŧĐžĐļĐģивО видаĐģĐ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ С аĐģŅŒĐąĐžĐŧ҃", - "unable_to_remove_api_key": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ API", - "unable_to_remove_assets_from_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐˇŅ– ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "unable_to_remove_library": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", - "unable_to_remove_partner": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ видаĐģĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", - "unable_to_remove_reaction": "НĐĩ вдаĐģĐžŅŅ видаĐģĐ¸Ņ‚Đ¸ Ņ€ĐĩаĐēŅ†Ņ–ŅŽ", + "unable_to_reassign_assets_existing_person": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ {name, select, null {ĐŊĐ°ŅĐ˛ĐŊŅ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–} other {{name}}}", + "unable_to_reassign_assets_new_person": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐžĐ˛Ņ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–", + "unable_to_refresh_user": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "unable_to_remove_album_users": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛ С аĐģŅŒĐąĐžĐŧ҃", + "unable_to_remove_api_key": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ API", + "unable_to_remove_assets_from_shared_link": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐˇŅ– ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", + "unable_to_remove_library": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "unable_to_remove_partner": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", + "unable_to_remove_reaction": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ Ņ€ĐĩаĐēŅ†Ņ–ŅŽ", "unable_to_reset_password": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ҁĐēиĐŊŅƒŅ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "unable_to_reset_pin_code": "НĐĩĐŧĐžĐļĐģивО ҁĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд", - "unable_to_resolve_duplicate": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Đ¸Ņ€Ņ–ŅˆĐ¸Ņ‚Đ¸ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚", - "unable_to_restore_assets": "НĐĩĐŧĐžĐļĐģивО Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", - "unable_to_restore_trash": "НĐĩ вдаĐģĐžŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ вĐŧҖҁ҂", + "unable_to_reset_pin_code": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ҁĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд", + "unable_to_resolve_duplicate": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°Ņ‚Đ¸ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚", + "unable_to_restore_assets": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "unable_to_restore_trash": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ вĐŧҖҁ҂ ĐēĐžŅˆĐ¸Đēа", "unable_to_restore_user": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", "unable_to_save_album": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "unable_to_save_api_key": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐēĐģŅŽŅ‡ API", - "unable_to_save_date_of_birth": "НĐĩ вдаĐģĐžŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ Đ´Đ°Ņ‚Ņƒ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "unable_to_save_date_of_birth": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ Đ´Đ°Ņ‚Ņƒ ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ", "unable_to_save_name": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ Ņ–Đŧ'Ņ", "unable_to_save_profile": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐŋŅ€ĐžŅ„Ņ–ĐģҌ", "unable_to_save_settings": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", "unable_to_scan_libraries": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€ĐžŅĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", - "unable_to_scan_library": "НĐĩ вдаĐģĐžŅŅ ĐŋŅ€ĐžŅĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", - "unable_to_set_feature_photo": "НĐĩ вдаĐģĐžŅŅ Đ˛ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅŽ ĐŊа ОйĐēĐģадиĐŊĐē҃", - "unable_to_set_profile_picture": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ", - "unable_to_set_rating": "НĐĩ вдаĐģĐžŅŅ Đ˛ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", - "unable_to_submit_job": "НĐĩ вдаĐģĐžŅŅ ĐŊĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ СавдаĐŊĐŊŅ", - "unable_to_trash_asset": "НĐĩĐŧĐžĐļĐģивО видаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", - "unable_to_unlink_account": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´Đ˛'ŅĐˇĐ°Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ", + "unable_to_scan_library": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ€ĐžŅĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "unable_to_set_feature_photo": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŗĐžĐģОвĐŊĐĩ Ņ„ĐžŅ‚Đž", + "unable_to_set_profile_picture": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ", + "unable_to_set_rating": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", + "unable_to_submit_job": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŊĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ СавдаĐŊĐŊŅ", + "unable_to_trash_asset": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Đ´Đž ĐēĐžŅˆĐ¸Đēа", + "unable_to_unlink_account": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ", "unable_to_unlink_motion_video": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ˛Ņ–Đ´'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", - "unable_to_update_album_cover": "НĐĩĐŧĐžĐļĐģивО ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ОйĐēĐģадиĐŊĐē҃ аĐģŅŒĐąĐžĐŧ҃", - "unable_to_update_album_info": "НĐĩĐŧĐžĐļĐģивО ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž аĐģŅŒĐąĐžĐŧ", - "unable_to_update_library": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", - "unable_to_update_location": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "unable_to_update_album_cover": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ОйĐēĐģадиĐŊĐē҃ аĐģŅŒĐąĐžĐŧ҃", + "unable_to_update_album_info": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ ĐŋŅ€Đž аĐģŅŒĐąĐžĐŧ", + "unable_to_update_library": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "unable_to_update_location": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", "unable_to_update_settings": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "unable_to_update_timeline_display_status": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ŅŅ‚Đ°ĐŊ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҈ĐēаĐģи Ņ‡Đ°ŅŅƒ", - "unable_to_update_user": "НĐĩĐŧĐžĐļĐģивО ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ даĐŊŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "unable_to_update_workflow": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", - "unable_to_upload_file": "НĐĩ вдаĐģĐžŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ" + "unable_to_update_timeline_display_status": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ŅŅ‚Đ°ĐŊ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ—", + "unable_to_update_user": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ даĐŊŅ– ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "unable_to_update_workflow": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", + "unable_to_upload_file": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ" }, "errors_text": "ПоĐŧиĐģĐēи", - "exclusion_pattern": "ШайĐģĐžĐŊ виĐēĐģŅŽŅ‡ĐĩĐŊĐŊŅ", + "exclusion_pattern": "ШайĐģĐžĐŊ виĐŊŅŅ‚Đē҃", "exif": "Exif", - "exif_bottom_sheet_description": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņ...", - "exif_bottom_sheet_description_error": "ПоĐŧиĐģĐēа ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐžĐŋĐ¸ŅŅƒ", - "exif_bottom_sheet_details": "ДĐĩŅ‚Đ°ĐģŅ–", + "exif_bottom_sheet_description": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐžĐŋĐ¸Ņâ€Ļ", + "exif_bottom_sheet_description_error": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐžĐŋĐ¸Ņ", + "exif_bottom_sheet_details": "ДЕĐĸАЛІ", "exif_bottom_sheet_location": "МІСĐĻЕ", "exif_bottom_sheet_no_description": "БĐĩС ĐžĐŋĐ¸ŅŅƒ", "exif_bottom_sheet_people": "ЛЮДИ", @@ -1176,39 +1178,39 @@ "exit_slideshow": "Đ’Đ¸ĐšŅ‚Đ¸ ĐˇŅ– ҁĐģаКд-ŅˆĐžŅƒ", "expand": "Đ ĐžĐˇĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸", "expand_all": "Đ ĐžĐˇĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸ Đ˛ŅĐĩ", - "experimental_settings_new_asset_list_subtitle": "В Ņ€ĐžĐˇŅ€ĐžĐąŅ†Ņ–", - "experimental_settings_new_asset_list_title": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐĩĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊ҃ ҁҖ҂Đē҃ Ņ„ĐžŅ‚Đž", - "experimental_settings_subtitle": "На вĐģĐ°ŅĐŊиК Ņ€Đ¸ĐˇĐ¸Đē!", + "experimental_settings_new_asset_list_subtitle": "ĐŖ Ņ€ĐžĐˇŅ€ĐžĐąŅ†Ņ–", + "experimental_settings_new_asset_list_title": "ВĐŧиĐēĐ°Ņ‚Đ¸ ĐĩĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊ҃ ҁҖ҂Đē҃ Ņ„ĐžŅ‚Đž", + "experimental_settings_subtitle": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ĐŊа вĐģĐ°ŅĐŊиК Ņ€Đ¸ĐˇĐ¸Đē!", "experimental_settings_title": "ЕĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊŅ–", - "expire_after": "ĐĸĐĩŅ€ĐŧŅ–ĐŊ Đ´Ņ–Ņ— СаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС", + "expire_after": "ĐĄĐŋĐģĐ¸Đ˛Đ°Ņ” ҇ĐĩŅ€ĐĩС", "expired": "ЗаĐēŅ–ĐŊŅ‡Đ¸Đ˛ŅŅ Ņ‚ĐĩŅ€ĐŧŅ–ĐŊ Đ´Ņ–Ņ—", "expires_date": "ĐĸĐĩŅ€ĐŧŅ–ĐŊ Đ´Ņ–Ņ— СаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ {date}", - "explore": "Đ”ĐžŅĐģŅ–Đ´Đ¸Ņ‚Đ¸", + "explore": "ĐžĐŗĐģŅĐ´", "explorer": "ĐŸŅ€ĐžĐ˛Ņ–Đ´ĐŊиĐē", "export": "ЕĐēҁĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸", - "export_as_json": "ЕĐēҁĐŋĐžŅ€Ņ‚ в JSON", + "export_as_json": "ЕĐēҁĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐē JSON", "export_database": "ЕĐēҁĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐąĐ°ĐˇŅƒ даĐŊĐ¸Ņ…", "export_database_description": "ЕĐēҁĐŋĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐąĐ°ĐˇŅƒ даĐŊĐ¸Ņ… SQLite", "extension": "Đ ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊĐŊŅ", "external": "ЗовĐŊŅ–ŅˆĐŊŅ–", "external_libraries": "ЗовĐŊŅ–ŅˆĐŊŅ– ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "external_network": "ЗовĐŊŅ–ŅˆĐŊŅ ĐŧĐĩŅ€ĐĩĐļа", - "external_network_sheet_info": "КоĐģи ви ĐŊĐĩ ĐŋŅ–Đ´ĐēĐģŅŽŅ‡ĐĩĐŊŅ– Đ´Đž ĐžĐąŅ€Đ°ĐŊĐžŅ— ĐŧĐĩŅ€ĐĩĐļŅ– Wi-Fi, ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŋŅ–Đ´ĐēĐģŅŽŅ‡Đ°Ņ‚Đ¸ĐŧĐĩŅ‚ŅŒŅŅ Đ´Đž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҇ĐĩŅ€ĐĩС ĐŋĐĩŅ€ŅˆŅƒ С ĐŊавĐĩĐ´ĐĩĐŊĐ¸Ņ… ĐŊиĐļ҇Đĩ URL-Đ°Đ´Ņ€Đĩҁ, ŅĐē҃ Đ˛Ņ–ĐŊ СĐŧĐžĐļĐĩ Đ´ĐžŅŅĐŗŅ‚Đ¸, ĐŋĐžŅ‡Đ¸ĐŊĐ°ŅŽŅ‡Đ¸ СвĐĩŅ€Ņ…Ņƒ вĐŊиС", + "external_network_sheet_info": "КоĐģи ви ĐŊĐĩ ĐŋŅ–Đ´'Ņ”Đ´ĐŊаĐŊŅ– Đ´Đž ĐžĐąŅ€Đ°ĐŊĐžŅ— ĐŧĐĩŅ€ĐĩĐļŅ– Wi-Fi, ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŋŅ–Đ´'Ņ”Đ´ĐŊŅƒĐ˛Đ°Ņ‚Đ¸ĐŧĐĩŅ‚ŅŒŅŅ Đ´Đž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҇ĐĩŅ€ĐĩС ĐŋĐĩŅ€ŅˆŅƒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊ҃ URL-Đ°Đ´Ņ€Đĩҁ҃ С ĐŊавĐĩĐ´ĐĩĐŊĐ¸Ņ… ĐŊиĐļ҇Đĩ, ĐŋĐžŅ‡Đ¸ĐŊĐ°ŅŽŅ‡Đ¸ СвĐĩŅ€Ņ…Ņƒ вĐŊиС", "face_unassigned": "НĐĩ ĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž", "failed": "НĐĩ вдаĐģĐžŅŅ", "failed_count": "НĐĩ вдаĐģĐžŅŅ: {count}", - "failed_to_authenticate": "ПоĐŧиĐģĐēа Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–Ņ—", - "failed_to_load_assets": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", + "failed_to_authenticate": "НĐĩ вдаĐģĐžŅŅ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ", + "failed_to_load_assets": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "failed_to_load_folder": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐŋаĐŋĐē҃", - "favorite": "До ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", - "favorite_action_prompt": "{count} дОдаĐŊĐž Đ´Đž ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", - "favorite_or_unfavorite_photo": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Đ´Đž ĐžĐąŅ€Đ°ĐŊĐ¸Ņ… айО видаĐģĐ¸Ņ‚Đ¸ С ĐžĐąŅ€Đ°ĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž", - "favorites": "ĐžĐąŅ€Đ°ĐŊĐĩ", - "favorites_page_no_favorites": "НĐĩĐŧĐ°Ņ” ĐžĐąŅ€Đ°ĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "feature_photo_updated": "Đ’Đ¸ĐąŅ€Đ°ĐŊĐĩ Ņ„ĐžŅ‚Đž ĐžĐŊОвĐģĐĩĐŊĐž", - "features": "Đ”ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Ņ– ĐŧĐžĐļĐģĐ¸Đ˛ĐžŅŅ‚Ņ–", + "favorite": "До Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "favorite_action_prompt": "{count} дОдаĐŊĐž Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "favorite_or_unfavorite_photo": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž айО виĐģŅƒŅ‡Đ¸Ņ‚Đ¸", + "favorites": "Đ’Đ¸ĐąŅ€Đ°ĐŊĐĩ", + "favorites_page_no_favorites": "НĐĩĐŧĐ°Ņ” Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "feature_photo_updated": "ГоĐģОвĐŊĐĩ Ņ„ĐžŅ‚Đž ĐžĐŊОвĐģĐĩĐŊĐž", + "features": "Đ¤ŅƒĐŊĐē҆Җҗ", "features_in_development": "Đ¤ŅƒĐŊĐē҆Җҗ в Ņ€ĐžĐˇŅ€ĐžĐąŅ†Ņ–", - "features_setting_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ´ĐžĐ´Đ°Ņ‚ĐēОвиĐŧи ĐŧĐžĐļĐģĐ¸Đ˛ĐžŅŅ‚ŅĐŧи ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", + "features_setting_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ„ŅƒĐŊĐēŅ†Ņ–ŅĐŧи ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", "file_name_or_extension": "ІĐŧ'Ņ Ņ„Đ°ĐšĐģ҃ айО Ņ€ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊĐŊŅ", "file_name_text": "ІĐŧ'Ņ Ņ„Đ°ĐšĐģ҃", "file_name_with_value": "ІĐŧ'Ņ Ņ„Đ°ĐšĐģ҃: {file_name}", @@ -1216,10 +1218,10 @@ "filename": "ІĐŧ'Ņ Ņ„Đ°ĐšĐģ҃", "filetype": "ĐĸиĐŋ Ņ„Đ°ĐšĐģ҃", "filter": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€", - "filter_description": "ĐŖĐŧОви Đ´ĐģŅ ҄ҖĐģŅŒŅ‚Ņ€Đ°Ņ†Ņ–Ņ— ҆ҖĐģŅŒĐžĐ˛Đ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", + "filter_description": "ĐŖĐŧОви Đ´ĐģŅ ҄ҖĐģŅŒŅ‚Ņ€Đ°Ņ†Ņ–Ņ— ҆ҖĐģŅŒĐžĐ˛Đ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "filter_people": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€ Са ĐģŅŽĐ´ŅŒĐŧи", "filter_places": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€ Са ĐŧŅ–ŅŅ†ŅĐŧи", - "filter_tags": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ‚ĐĩĐŗĐ¸", + "filter_tags": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€ Са Ņ‚ĐĩĐŗĐ°Đŧи", "filters": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€Đ¸", "find_them_fast": "ШвидĐēĐž СĐŊĐ°Ņ…ĐžĐ´ŅŒŅ‚Đĩ Ņ—Ņ… Са ĐŊĐ°ĐˇĐ˛ĐžŅŽ Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŋĐžŅˆŅƒĐē҃", "first": "ПĐĩŅ€ŅˆĐ¸Đš", @@ -1227,184 +1229,186 @@ "folder": "ПаĐŋĐēа", "folder_not_found": "ПаĐŋĐē҃ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", "folders": "ПаĐŋĐēи", - "folders_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ ĐŋаĐŋĐžĐē С Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅĐŧи Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ҃ Ņ„Đ°ĐšĐģĐžĐ˛Ņ–Đš ŅĐ¸ŅŅ‚ĐĩĐŧŅ–", - "forgot_pin_code_question": "Đ—Đ°ĐąŅƒĐģи ŅĐ˛Ņ–Đš PIN-ĐēОд?", + "folders_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ ĐŋаĐŋĐžĐē С Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ҃ Ņ„Đ°ĐšĐģĐžĐ˛Ņ–Đš ŅĐ¸ŅŅ‚ĐĩĐŧŅ–", + "forgot_pin_code_question": "Đ—Đ°ĐąŅƒĐģи PIN-ĐēОд?", "forward": "ПĐĩŅ€ĐĩҁĐģĐ°Ņ‚Đ¸", "free_up_space": "Đ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", - "free_up_space_description": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Ņ–Ņ‚ŅŒ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš Ņ– Đ˛Ņ–Đ´ĐĩĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, Ņ‰ĐžĐą ĐˇĐ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ. Đ’Đ°ŅˆŅ– ĐēĐžĐŋŅ–Ņ— ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ СаĐģĐ¸ŅˆĐ°ŅŽŅ‚ŅŒŅŅ в ĐąĐĩСĐŋĐĩ҆Җ.", - "free_up_space_settings_subtitle": "Đ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŋаĐŧ'ŅŅ‚ŅŒ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "free_up_space_description": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Ņ–Ņ‚ŅŒ Ņ„ĐžŅ‚Đž Đš Đ˛Ņ–Đ´ĐĩĐž, Đ´ĐģŅ ŅĐēĐ¸Ņ… Ņ” Ņ€ĐĩСĐĩŅ€Đ˛ĐŊа ĐēĐžĐŋŅ–Ņ, Đ´Đž ĐēĐžŅˆĐ¸Đēа Đ˛Đ°ŅˆĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ, Ņ‰ĐžĐą ĐˇĐ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ. Đ’Đ°ŅˆŅ– ĐēĐžĐŋŅ–Ņ— ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ СаĐģĐ¸ŅˆĐ°ŅŽŅ‚ŅŒŅŅ в ĐąĐĩСĐŋĐĩ҆Җ.", + "free_up_space_settings_subtitle": "Đ—Đ˛Ņ–ĐģҌĐŊĐ¸Ņ‚Đ¸ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đĩ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", "full_path": "ПовĐŊиК ҈ĐģŅŅ…: {path}", "gcast_enabled": "Google Cast", "gcast_enabled_description": "ĐĻŅ Ņ„ŅƒĐŊĐēŅ†Ņ–Ņ СаваĐŊŅ‚Đ°ĐļŅƒŅ” СОвĐŊŅ–ŅˆĐŊŅ– Ņ€ĐĩŅŅƒŅ€ŅĐ¸ С Google Đ´ĐģŅ ŅĐ˛ĐžŅ”Ņ— Ņ€ĐžĐąĐžŅ‚Đ¸.", "general": "Đ—Đ°ĐŗĐ°ĐģҌĐŊŅ–", - "geolocation_instruction_location": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ ĐŊа Ņ„Đ°ĐšĐģ Ņ–Đˇ ĐŗĐĩОдаĐŊиĐŧи, Ņ‰ĐžĐą виĐēĐžŅ€Đ¸ŅŅ‚Đ°Ņ‚Đ¸ ĐšĐžĐŗĐž ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ, айО вийĐĩŅ€Ņ–Ņ‚ŅŒ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ ĐąĐĩСĐŋĐžŅĐĩŅ€ĐĩĐ´ĐŊŅŒĐž ĐŊа ĐŧаĐŋŅ–", + "geolocation_instruction_location": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ ĐŊа ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Ņ–Đˇ ĐŗĐĩОдаĐŊиĐŧи, Ņ‰ĐžĐą виĐēĐžŅ€Đ¸ŅŅ‚Đ°Ņ‚Đ¸ ĐšĐžĐŗĐž ĐŧҖҁ҆Đĩ, айО вийĐĩŅ€Ņ–Ņ‚ŅŒ ĐŧҖҁ҆Đĩ ĐąĐĩСĐŋĐžŅĐĩŅ€ĐĩĐ´ĐŊŅŒĐž ĐŊа ĐŧаĐŋŅ–", "get_help": "ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžĐŋĐžĐŧĐžĐŗŅƒ", - "get_people_error": "ПоĐŧиĐģĐēа ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ ĐģŅŽĐ´ĐĩĐš", - "get_wifiname_error": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ Wi-Fi. ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ви ĐŊадаĐģи ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊŅ– дОСвОĐģи Ņ‚Đ° ĐŋŅ–Đ´ĐēĐģŅŽŅ‡ĐĩĐŊŅ– Đ´Đž Wi-Fi ĐŧĐĩŅ€ĐĩĐļŅ–", - "getting_started": "ĐŸĐžŅ‡Đ°Ņ‚ĐžĐē", + "get_people_error": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ҁĐŋĐ¸ŅĐžĐē ĐģŅŽĐ´ĐĩĐš", + "get_wifiname_error": "НĐĩ вдаĐģĐžŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ Wi-Fi. ПĐĩŅ€ĐĩĐēĐžĐŊĐ°ĐšŅ‚ĐĩŅŅ, Ņ‰Đž ви ĐŊадаĐģи ĐŊĐĩĐžĐąŅ…Ņ–Đ´ĐŊŅ– дОСвОĐģи Ņ‚Đ° ĐŋŅ–Đ´'Ņ”Đ´ĐŊаĐŊŅ– Đ´Đž Wi-Fi ĐŧĐĩŅ€ĐĩĐļŅ–", + "getting_started": "ĐŸĐžŅ‡Đ°Ņ‚ĐžĐē Ņ€ĐžĐąĐžŅ‚Đ¸", "go_back": "ПовĐĩŅ€ĐŊŅƒŅ‚Đ¸ŅŅ ĐŊаСад", "go_to_folder": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŋаĐŋĐēи", "go_to_search": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŋĐžŅˆŅƒĐē҃", - "gps": "ГĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–Ņ", + "gps": "GPS", "gps_missing": "НĐĩĐŧĐ°Ņ” ĐŗĐĩОдаĐŊĐ¸Ņ…", "grant_permission": "ĐĐ°Đ´Đ°Ņ‚Đ¸ Đ´ĐžĐˇĐ˛Ņ–Đģ", - "group_albums_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи Са...", - "group_country": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ Са ĐēŅ€Đ°Ņ—ĐŊĐžŅŽ", + "group_albums_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи Саâ€Ļ", + "group_country": "За ĐēŅ€Đ°Ņ—ĐŊĐžŅŽ", "group_no": "БĐĩС ĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°ĐŊĐŊŅ", "group_owner": "За вĐģĐ°ŅĐŊиĐēĐžĐŧ", - "group_places_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧŅ–ŅŅ†Ņ Са...", + "group_places_by": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧŅ–ŅŅ†Ņ Саâ€Ļ", "group_year": "За Ņ€ĐžĐēĐžĐŧ", - "haptic_feedback_switch": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ‚Đ°ĐēŅ‚Đ¸ĐģҌĐŊ҃ Đ˛Ņ–Đ´Đ´Đ°Ņ‡Ņƒ", - "haptic_feedback_title": "ĐĸаĐēŅ‚Đ¸ĐģҌĐŊа Đ˛Ņ–Đ´Đ´Đ°Ņ‡Đ°", - "has_quota": "ĐšĐ˛ĐžŅ‚Đ°", - "hash_asset": "ĐĨĐĩŅˆŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", - "hashed_assets": "ĐĨĐĩŅˆĐ¸", + "haptic_feedback_switch": "ВĐŧиĐēĐ°Ņ‚Đ¸ Ņ‚Đ°ĐēŅ‚Đ¸ĐģҌĐŊиК Đ˛Ņ–Đ´ĐŗŅƒĐē", + "haptic_feedback_title": "ĐĸаĐēŅ‚Đ¸ĐģҌĐŊиК Đ˛Ņ–Đ´ĐŗŅƒĐē", + "has_quota": "ĐœĐ°Ņ” ĐēĐ˛ĐžŅ‚Ņƒ", + "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": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°ĐģҌĐŊĐ¸Ņ†ŅŒĐēŅ– ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēҁҖ", + "header_settings_header_name_input": "Назва ĐˇĐ°ĐŗĐžĐģОвĐēа", + "header_settings_header_value_input": "ЗĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐˇĐ°ĐŗĐžĐģОвĐēа", + "headers_settings_tile_title": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊŅ– ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēҁҖ", "height": "Đ’Đ¸ŅĐžŅ‚Đ°", "hi_user": "ĐŸŅ€Đ¸Đ˛Ņ–Ņ‚ {name} ({email})", - "hide_all_people": "ĐĄŅ…ĐžĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ–Ņ…", + "hide_all_people": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ–Ņ… ĐģŅŽĐ´ĐĩĐš", "hide_gallery": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐŗĐ°ĐģĐĩŅ€ĐĩŅŽ", - "hide_named_person": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ {name}", + "hide_named_person": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃ {name}", "hide_password": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", "hide_person": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", "hide_schema": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ҁ҅ĐĩĐŧ҃", "hide_text_recognition": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ", - "hide_unnamed_people": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš ĐąĐĩС Ņ–Đŧ'Ņ", - "home_page_add_to_album_conflicts": "ДодаĐŊĐž {added} Ņ„Đ°ĐšĐģŅ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃ {album}. {failed} Ņ„Đ°ĐšĐģŅ–Đ˛ вĐļĐĩ ĐąŅƒĐģĐž в аĐģŅŒĐąĐžĐŧŅ–.", - "home_page_add_to_album_err_local": "НĐĩĐŧĐžĐļĐģивО Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– Ņ„Đ°ĐšĐģи Đ´Đž аĐģŅŒĐąĐžĐŧŅ–Đ˛, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_add_to_album_success": "ДодаĐŊĐž {added} Ņ„Đ°ĐšĐģŅ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃ {album}.", - "home_page_album_err_partner": "ПоĐēи Ņ‰Đž ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ° Đ´Đž аĐģŅŒĐąĐžĐŧ҃, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_archive_err_local": "ПоĐēи Ņ‰Đž ĐŊĐĩĐŧĐžĐļĐģивО ĐˇĐ°Đ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– Ņ„Đ°ĐšĐģи, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_archive_err_partner": "НĐĩĐŧĐžĐļĐģивО Đ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", + "hide_unnamed_people": "ĐŸŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš ĐąĐĩС Ņ–ĐŧĐĩĐŊŅ–", + "home_page_add_to_album_conflicts": "ДодаĐŊĐž {added} ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃ {album}. {failed} ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ вĐļĐĩ Ņ” в аĐģŅŒĐąĐžĐŧŅ–.", + "home_page_add_to_album_err_local": "ĐĐ°Ņ€Đ°ĐˇŅ– ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Đ´ĐžĐ´Đ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž аĐģŅŒĐąĐžĐŧŅ–Đ˛, ĐŋŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", + "home_page_add_to_album_success": "ДодаĐŊĐž {added} ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ´Đž аĐģŅŒĐąĐžĐŧ҃ {album}.", + "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": "Đ¯ĐēŅ‰Đž ви ĐēĐžŅ€Đ¸ŅŅ‚ŅƒŅ”Ņ‚ĐĩŅŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐēĐžĐŧ вĐŋĐĩŅ€ŅˆĐĩ, ĐąŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ОйĐĩŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ, Ņ‰ĐžĐą ĐŊа ҈ĐēаĐģŅ– Ņ‡Đ°ŅŅƒ Đˇâ€™ŅĐ˛Đ¸ĐģĐ¸ŅŅ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "home_page_locked_error_local": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– Ņ„Đ°ĐšĐģи Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_locked_error_partner": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€ŅŅŒĐēŅ– Ņ„Đ°ĐšĐģи Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_share_err_local": "НĐĩĐŧĐžĐļĐģивО ĐŋĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ ĐģĐžĐēаĐģҌĐŊиĐŧи Ņ„Đ°ĐšĐģаĐŧи ҇ĐĩŅ€ĐĩС ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "home_page_upload_err_limit": "МоĐļĐŊа виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐĩ ĐąŅ–ĐģҌ҈Đĩ 30 Ņ„Đ°ĐšĐģŅ–Đ˛ вОдĐŊĐžŅ‡Đ°Ņ, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", + "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": "Đ¯ĐēŅ‰Đž ви ĐēĐžŅ€Đ¸ŅŅ‚ŅƒŅ”Ņ‚ĐĩŅŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐēĐžĐŧ ҃ĐŋĐĩŅ€ŅˆĐĩ, ĐąŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ОйĐĩŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ, Ņ‰ĐžĐą ҃ Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ— Đˇâ€™ŅĐ˛Đ¸ĐģĐ¸ŅŅ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "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": "ID", "idle": "ĐŸŅ€ĐžŅŅ‚Ņ–Đš", - "ignore_icloud_photos": "ĐŸŅ€ĐžĐŋ҃ҁĐēĐ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи С iCloud", - "ignore_icloud_photos_description": "НĐĩ СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи в Immich, ŅĐēŅ‰Đž вОĐŊи СйĐĩŅ€Ņ–ĐŗĐ°ŅŽŅ‚ŅŒŅŅ в iCloud", + "ignore_icloud_photos": "ĐŸŅ€ĐžĐŋ҃ҁĐēĐ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž С iCloud", + "ignore_icloud_photos_description": "Đ¤ĐžŅ‚Đž, Ņ‰Đž СйĐĩŅ€Ņ–ĐŗĐ°ŅŽŅ‚ŅŒŅŅ в iCloud, ĐŊĐĩ ĐąŅƒĐ´Đĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ Immich", "image": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "image_alt_text_date": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} СĐŊŅŅ‚Đž {date}", - "image_alt_text_date_1_person": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1} ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž {date}", - "image_alt_text_date_2_people": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1} Ņ‚Đ° {person2} ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž {date}", - "image_alt_text_date_3_people": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1}, {person2} Ņ– {person3} ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž {date}", - "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_alt_text_date_1_person": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1} СĐŊŅŅ‚Đž {date}", + "image_alt_text_date_2_people": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1} Ņ‚Đ° {person2} СĐŊŅŅ‚Đž {date}", + "image_alt_text_date_3_people": "{isVideo, select, true {Đ’Ņ–Đ´ĐĩĐž} other {Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ}} С {person1}, {person2} Ņ– {person3} СĐŊŅŅ‚Đž {date}", + "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": "ПоĐŧиĐģĐēа ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž Đ´ĐžŅŅ‚ŅƒĐŋ҃", + "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_from_json": "ІĐŧĐŋĐžŅ€Ņ‚ Ņ–Đˇ JSON", "import_path": "ШĐģŅŅ… Ņ–ĐŧĐŋĐžŅ€Ņ‚Ņƒ", "in_albums": "ĐŖ {count, plural, one {# аĐģŅŒĐąĐžĐŧŅ–} few {# аĐģŅŒĐąĐžĐŧĐ°Ņ…} many {# аĐģŅŒĐąĐžĐŧĐ°Ņ…} other {# аĐģŅŒĐąĐžĐŧĐ°Ņ…}}", "in_archive": "В Đ°Ņ€Ņ…Ņ–Đ˛Ņ–", "in_year": "ĐŖ {year}", "in_year_selector": "ĐŖ", - "include_archived": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐ°Ņ‚Đ¸ Đ°Ņ€Ņ…Ņ–Đ˛", - "include_shared_albums": "ВĐēĐģŅŽŅ‡Đ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊŅ– аĐģŅŒĐąĐžĐŧи", - "include_shared_partner_assets": "ВĐēĐģŅŽŅ‡Đ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", - "individual_share": "ІĐŊĐ´Đ¸Đ˛Ņ–Đ´ŅƒĐ°ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ", - "individual_shares": "ОĐēŅ€ĐĩĐŧŅ– ҁĐŋŅ–ĐģҌĐŊŅ– Đ´ĐžŅŅ‚ŅƒĐŋи", + "include_archived": "Đ’Ņ€Đ°Ņ…ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Đ°Ņ€Ņ…Ņ–Đ˛ĐžĐ˛Đ°ĐŊŅ–", + "include_shared_albums": "Đ’Ņ€Đ°Ņ…ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊŅ– аĐģŅŒĐąĐžĐŧи", + "include_shared_partner_assets": "Đ’Ņ€Đ°Ņ…ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", + "individual_share": "ОĐēŅ€ĐĩĐŧиК Đ´ĐžŅŅ‚ŅƒĐŋ", + "individual_shares": "ОĐēŅ€ĐĩĐŧŅ– Đ´ĐžŅŅ‚ŅƒĐŋи", "info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ", "interval": { "day_at_onepm": "ЊОдĐŊŅ Đž 13:00", - "hours": "КоĐļĐŊ҃ {hours, plural, one {ĐŗĐžĐ´Đ¸ĐŊ҃} few {ĐŗĐžĐ´Đ¸ĐŊи} many {ĐŗĐžĐ´Đ¸ĐŊ} other {ĐŗĐžĐ´Đ¸ĐŊи}}", + "hours": "КоĐļĐŊ҃ {hours, plural, one {# ĐŗĐžĐ´Đ¸ĐŊ҃} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊ}}", "night_at_midnight": "КоĐļĐŊĐžŅ— ĐŊĐžŅ‡Ņ– Đž ĐŋŅ–Đ˛ĐŊĐžŅ‡Ņ–", "night_at_twoam": "КоĐļĐŊĐžŅ— ĐŊĐžŅ‡Ņ– Đž 2:00" }, - "invalid_date": "НĐĩĐ´Ņ–ĐšŅĐŊа Đ´Đ°Ņ‚Đ°", - "invalid_date_format": "НĐĩĐ´Ņ–ĐšŅĐŊиК Ņ„ĐžŅ€ĐŧĐ°Ņ‚ Đ´Đ°Ņ‚Đ¸", - "invite_people": "ЗаĐŋŅ€ĐžŅĐ¸Ņ‚Đ¸", + "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_no_sync_yet": "ФОĐŊОвĐĩ СавдаĐŊĐŊŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ— ҉Đĩ ĐŊĐĩ виĐēĐžĐŊŅƒĐ˛Đ°ĐģĐžŅŅ", "ios_debug_info_processes_queued": "{count, plural, one {{count} Ņ„ĐžĐŊОвиК ĐŋŅ€ĐžŅ†Đĩҁ ҃ ҇ĐĩŅ€ĐˇŅ–} few {{count} Ņ„ĐžĐŊĐžĐ˛Ņ– ĐŋŅ€ĐžŅ†ĐĩŅĐ¸ ҃ ҇ĐĩŅ€ĐˇŅ–} many {{count} Ņ„ĐžĐŊĐžĐ˛Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅ–Đ˛ ҃ ҇ĐĩŅ€ĐˇŅ–} other {{count} Ņ„ĐžĐŊĐžĐ˛Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅ–Đ˛ ҃ ҇ĐĩŅ€ĐˇŅ–}}", "ios_debug_info_processing_ran_at": "ĐžĐąŅ€ĐžĐąĐē҃ виĐēĐžĐŊаĐŊĐž {dateTime}", - "items_count": "{count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "items_count": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "jobs": "ЗавдаĐŊĐŊŅ", "json_editor": "JSON-Ņ€ĐĩдаĐēŅ‚ĐžŅ€", "json_error": "ПоĐŧиĐģĐēа JSON", "keep": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸", - "keep_albums": "ЗбĐĩŅ€Ņ–ĐŗĐ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", - "keep_albums_count": "ЗбĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ {count} {count, plural, one {аĐģŅŒĐąĐžĐŧ} few {аĐģŅŒĐąĐžĐŧи} many {аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", - "keep_all": "ЗбĐĩŅ€ĐĩĐŗŅ‚Đ¸ Đ˛ŅĐĩ", + "keep_albums": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", + "keep_albums_count": "ЗаĐģĐ¸ŅˆĐ°Ņ”Ņ‚ŅŒŅŅ: {count} {count, plural, one {аĐģŅŒĐąĐžĐŧ} few {аĐģŅŒĐąĐžĐŧи} many {аĐģŅŒĐąĐžĐŧŅ–Đ˛} other {аĐģŅŒĐąĐžĐŧŅ–Đ˛}}", + "keep_all": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ Đ˛ŅĐĩ", "keep_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ, Ņ‰Đž СаĐģĐ¸ŅˆĐ¸Ņ‚ŅŒŅŅ ĐŊа Đ˛Đ°ŅˆĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— ĐŋҖҁĐģŅ ĐˇĐ˛Ņ–ĐģҌĐŊĐĩĐŊĐŊŅ ĐŧŅ–ŅŅ†Ņ.", - "keep_favorites": "ЗбĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐžĐąŅ€Đ°ĐŊĐĩ", - "keep_on_device": "ЗбĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", + "keep_favorites": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐĩ", + "keep_on_device": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", "keep_on_device_hint": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸, ŅĐēŅ– ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž СйĐĩŅ€ĐĩĐŗŅ‚Đ¸ ĐŊа Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "keep_this_delete_others": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ ҆ĐĩĐš Ņ„Đ°ĐšĐģ, видаĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆŅ–", - "keeping": "ЗбĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ: {items}", - "kept_this_deleted_others": "ЗбĐĩŅ€ĐĩĐļĐĩĐŊĐž ҆ĐĩĐš Ņ„Đ°ĐšĐģ Ņ– видаĐģĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "keep_this_delete_others": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ ҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚, видаĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆŅ–", + "keeping": "ЗаĐģĐ¸ŅˆĐ°Ņ”Ņ‚ŅŒŅŅ: {items}", + "kept_this_deleted_others": "ЗбĐĩŅ€ĐĩĐļĐĩĐŊĐž ҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ Ņ– видаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "keyboard_shortcuts": "ĐĄĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ ĐēĐģĐ°Đ˛Ņ–Ņˆ", "language": "Мова", "language_no_results_subtitle": "ĐĄĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐžŅˆŅƒĐēОвиК СаĐŋĐ¸Ņ‚", "language_no_results_title": "Мови ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", - "language_search_hint": "ĐŸĐžŅˆŅƒĐē ĐŧОв...", + "language_search_hint": "ĐŸĐžŅˆŅƒĐē ĐŧОвâ€Ļ", "language_setting_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐŧĐžĐ˛Ņƒ, ŅĐēŅ–Đš ви ĐŊĐ°Đ´Đ°Ņ”Ņ‚Đĩ ĐŋĐĩŅ€ĐĩĐ˛Đ°ĐŗŅƒ", "large_files": "ВĐĩĐģиĐēŅ– Ņ„Đ°ĐšĐģи", "last": "ĐžŅŅ‚Đ°ĐŊĐŊŅ–Đš", - "last_months": "{count, plural, one {МиĐŊ҃ĐģĐžĐŗĐž ĐŧŅ–ŅŅŅ†Ņ} few {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–} many {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", - "last_seen": "Đ’ĐžŅŅ‚Đ°ĐŊĐŊŅ” ĐąĐ°Ņ‡Đ¸Đģи", + "last_months": "{count, plural, one {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Đš ĐŧŅ–ŅŅŅ†ŅŒ} few {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–} many {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", + "last_seen": "Đ’ĐžŅŅ‚Đ°ĐŊĐŊŅ” ĐŋĐžĐŧҖ҇ĐĩĐŊĐž", "latest_version": "ĐžŅŅ‚Đ°ĐŊĐŊŅ вĐĩŅ€ŅŅ–Ņ", "latitude": "Đ¨Đ¸Ņ€ĐžŅ‚Đ°", "leave": "ПоĐēиĐŊŅƒŅ‚Đ¸", - "leave_album": "Đ’Đ¸ĐšŅ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃", + "leave_album": "ПоĐēиĐŊŅƒŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ", "lens_model": "МодĐĩĐģҌ Ой'Ņ”ĐēŅ‚Đ¸Đ˛Đ°", - "let_others_respond": "ДозвоĐģĐ¸Ņ‚Đ¸ Ņ–ĐŊŅˆĐ¸Đŧ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°Ņ‚Đ¸", + "let_others_respond": "Đ”Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ Ņ–ĐŊŅˆĐ¸Đŧ Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´Đ°Ņ‚Đ¸", "level": "Đ Ņ–Đ˛ĐĩĐŊҌ", "library": "Đ‘Ņ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēа", "library_add_folder": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ ĐŋаĐŋĐē҃", "library_edit_folder": "Đ ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋаĐŋĐē҃", - "library_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", + "library_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "library_page_device_albums": "АĐģŅŒĐąĐžĐŧи ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", "library_page_new_album": "Новий аĐģŅŒĐąĐžĐŧ", - "library_page_sort_asset_count": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Ņ„Đ°ĐšĐģŅ–Đ˛", - "library_page_sort_created": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊŅ–", + "library_page_sort_asset_count": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", + "library_page_sort_created": "Đ”Đ°Ņ‚Đ° ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ", "library_page_sort_last_modified": "ĐžŅŅ‚Đ°ĐŊĐŊŅ СĐŧŅ–ĐŊа", "library_page_sort_title": "Назва аĐģŅŒĐąĐžĐŧ҃", "licenses": "Đ›Ņ–Ņ†ĐĩĐŊĐˇŅ–Ņ—", "light": "ĐĄĐ˛Ņ–Ņ‚Đģа", + "light_theme": "ПĐĩŅ€ĐĩĐŧĐēĐŊŅƒŅ‚Đ¸ ĐŊа ŅĐ˛Ņ–Ņ‚Đģ҃ Ņ‚ĐĩĐŧ҃", "like": "ĐŸĐžĐ´ĐžĐąĐ°Ņ”Ņ‚ŅŒŅŅ", "like_deleted": "ВĐŋОдОйаĐŊĐŊŅ видаĐģĐĩĐŊĐž", - "link_motion_video": "ĐŸĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", - "link_to_oauth": "ĐŸŅ€Đ¸Ņ”Đ´ĐŊаĐŊĐŊŅ Đ´Đž OAuth", - "linked_oauth_account": "ĐŸŅ€Đ¸Đ˛'ŅĐˇĐ°ĐŊиК ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth", - "list": "ПĐĩŅ€ĐĩĐģŅ–Đē", + "link_motion_video": "ĐŸŅ€Đ¸Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", + "link_to_docs": "ДоĐēĐģадĐŊŅ–ŅˆĐĩ Đ´Đ¸Đ˛Ņ–Ņ‚ŅŒŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Ņ–Ņ—.", + "link_to_oauth": "ĐŸŅ€Đ¸Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ´Đž OAuth", + "linked_oauth_account": "ĐŸŅ€Đ¸Ņ”Đ´ĐŊаĐŊиК ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth", + "list": "ĐĄĐŋĐ¸ŅĐžĐē", "loading": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "loading_search_results_failed": "НĐĩ вдаĐģĐžŅŅ СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đ¸ ĐŋĐžŅˆŅƒĐē҃", "local": "На ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "local_asset_cast_failed": "НĐĩĐŧĐžĐļĐģивО Ņ‚Ņ€Đ°ĐŊҁĐģŅŽĐ˛Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģ, ŅĐēиК ĐŊĐĩ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€", + "local_asset_cast_failed": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Ņ‚Ņ€Đ°ĐŊҁĐģŅŽĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚, ŅĐēиК ĐŊĐĩ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€", "local_assets": "ЛоĐēаĐģҌĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "local_id": "ĐœŅ–ŅŅ†ĐĩвиК Ņ–Đ´ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ĐžŅ€", - "local_media_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ ĐģĐžĐēаĐģҌĐŊĐ¸Ņ… ĐŧĐĩĐ´Ņ–Đ°Ņ„Đ°ĐšĐģŅ–Đ˛", + "local_id": "ЛоĐēаĐģҌĐŊиК Ņ–Đ´ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ĐžŅ€", + "local_media_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ ĐģĐžĐēаĐģҌĐŊĐ¸Ņ… ĐŧĐĩĐ´Ņ–Đ°", "local_network": "ЛоĐēаĐģҌĐŊа ĐŧĐĩŅ€ĐĩĐļа", - "local_network_sheet_info": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŋŅ–Đ´ĐēĐģŅŽŅ‡Đ°Ņ‚Đ¸ĐŧĐĩŅ‚ŅŒŅŅ Đ´Đž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҇ĐĩŅ€ĐĩС ҆ĐĩĐš URL, ĐēĐžĐģи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ вĐēаСаĐŊа Wi-Fi ĐŧĐĩŅ€ĐĩĐļа", - "location": "Đ ĐžĐˇŅ‚Đ°ŅˆŅƒĐ˛Đ°ĐŊĐŊŅ", - "location_permission": "Đ”ĐžĐˇĐ˛Ņ–Đģ Đ´Đž ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", - "location_permission_content": "ЊОй ĐŋĐĩŅ€ĐĩĐŧиĐēĐ°Ņ‚Đ¸ ĐŧĐĩŅ€ĐĩĐļŅ– ҃ Ņ„ĐžĐŊОвОĐŧ҃ Ņ€ĐĩĐļиĐŧŅ–, Immich ĐŧĐ°Ņ” СавĐļди ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž Ņ‚ĐžŅ‡ĐŊĐžŅ— ĐŗĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–Ņ—, Ņ‰ĐžĐą ĐˇŅ‡Đ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ Wi-Fi ĐŧĐĩŅ€ĐĩĐļŅ–", + "local_network_sheet_info": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŋŅ–Đ´'Ņ”Đ´ĐŊŅƒĐ˛Đ°Ņ‚Đ¸ĐŧĐĩŅ‚ŅŒŅŅ Đ´Đž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҇ĐĩŅ€ĐĩС ҆ĐĩĐš URL, ĐēĐžĐģи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚ŅŒŅŅ вĐēаСаĐŊа ĐŧĐĩŅ€ĐĩĐļа Wi-Fi", + "location": "ĐœŅ–ŅŅ†Đĩ", + "location_permission": "Đ”ĐžĐˇĐ˛Ņ–Đģ ĐŊа виСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŧŅ–ŅŅ†Ņ", + "location_permission_content": "ЊОй Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐĩ ĐŋĐĩŅ€ĐĩĐŧиĐēаĐŊĐŊŅ ĐŋŅ€Đ°Ņ†ŅŽĐ˛Đ°ĐģĐž, Immich ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅ” дОСвОĐģ҃ ĐŊа Ņ‚ĐžŅ‡ĐŊĐĩ виСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ ĐŧŅ–ŅŅ†Ņ, Ņ‰ĐžĐą ĐˇŅ‡Đ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊĐ°ĐˇĐ˛Ņƒ ĐŋĐžŅ‚ĐžŅ‡ĐŊĐžŅ— ĐŧĐĩŅ€ĐĩĐļŅ– Wi-Fi", "location_picker_choose_on_map": "ĐžĐąŅ€Đ°Ņ‚Đ¸ ĐŊа ĐŧаĐŋŅ–", "location_picker_latitude_error": "ВĐēаĐļŅ–Ņ‚ŅŒ Đ´Ņ–ĐšŅĐŊ҃ ŅˆĐ¸Ņ€ĐžŅ‚Ņƒ", "location_picker_latitude_hint": "ВĐēаĐļŅ–Ņ‚ŅŒ ŅˆĐ¸Ņ€ĐžŅ‚Ņƒ", @@ -1415,57 +1419,57 @@ "log_detail_title": "ДĐĩŅ‚Đ°ĐģŅ– ĐļŅƒŅ€ĐŊаĐģ҃", "log_out": "Đ’Đ¸ĐšŅ‚Đ¸", "log_out_all_devices": "Đ’Đ¸ĐšŅ‚Đ¸ С ŅƒŅŅ–Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛", - "logged_in_as": "Đ’Ņ…Ņ–Đ´ виĐēĐžĐŊаĐŊĐž ŅĐē {user}", - "logged_out_all_devices": "Đ’Đ¸ĐšŅˆĐģи С ŅƒŅŅ–Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛", - "logged_out_device": "Đ’Đ¸Ņ…Ņ–Đ´ С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "logged_in_as": "Ви Đ˛Đ˛Ņ–ĐšŅˆĐģи ŅĐē {user}", + "logged_out_all_devices": "ВийдĐĩĐŊĐž С ŅƒŅŅ–Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛", + "logged_out_device": "ВийдĐĩĐŊĐž С ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", "login": "Đ’Ņ…Ņ–Đ´", - "login_disabled": "ĐĐ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ виĐŧĐēĐŊĐĩĐŊĐž", + "login_disabled": "Đ’Ņ…Ņ–Đ´ виĐŧĐēĐŊĐĩĐŊĐž", "login_form_api_exception": "ПоĐŧиĐģĐēа API. ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Ņ– ҁĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ СĐŊĐžĐ˛Ņƒ.", "login_form_back_button_text": "Назад", "login_form_email_hint": "youremail@email.com", "login_form_endpoint_hint": "http://your-server-ip:port", - "login_form_endpoint_url": "ĐĐ´Ņ€ĐĩŅĐ° ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ", + "login_form_endpoint_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, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", + "login_form_err_trailing_whitespace": "ĐŸŅ€ĐžĐąŅ–Đģ ҃ ĐēŅ–ĐŊ҆Җ", + "login_form_failed_get_oauth_server_config": "НĐĩ вдаĐģĐžŅŅ Đ˛Đ˛Ņ–ĐšŅ‚Đ¸ ҇ĐĩŅ€ĐĩС OAuth, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", "login_form_failed_get_oauth_server_disable": "OAuth ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК ĐŊа Ņ†ŅŒĐžĐŧ҃ ҁĐĩŅ€Đ˛ĐĩҀҖ", - "login_form_failed_login": "ПоĐŧиĐģĐēа Đ˛Ņ…ĐžĐ´Ņƒ, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ URL-Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ Ņ‚Đ° ĐŋĐ°Ņ€ĐžĐģҌ", - "login_form_handshake_exception": "ПоĐŧиĐģĐēа Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ С'Ņ”Đ´ĐŊаĐŊĐŊŅ С ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ. ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐē҃ ŅĐ°ĐŧĐžĐŋŅ–Đ´ĐŋĐ¸ŅĐ°ĐŊĐžĐŗĐž ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ° в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…, ŅĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ ŅĐ°ĐŧĐžĐŋŅ–Đ´ĐŋĐ¸ŅĐ°ĐŊиК ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚.", + "login_form_failed_login": "НĐĩ вдаĐģĐžŅŅ Đ˛Đ˛Ņ–ĐšŅ‚Đ¸, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ URL-Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ Ņ‚Đ° ĐŋĐ°Ņ€ĐžĐģҌ", + "login_form_handshake_exception": "НĐĩ вдаĐģĐžŅŅ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ С'Ņ”Đ´ĐŊаĐŊĐŊŅ Ņ–Đˇ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ. ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐē҃ ŅĐ°ĐŧĐžĐŋŅ–Đ´ĐŋĐ¸ŅĐ°ĐŊĐžĐŗĐž ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚Đ° в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…, ŅĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ ŅĐ°ĐŧĐžĐŋŅ–Đ´ĐŋĐ¸ŅĐ°ĐŊиК ҁĐĩŅ€Ņ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚.", "login_form_password_hint": "ĐŋĐ°Ņ€ĐžĐģҌ", - "login_form_save_login": "ЗаĐŋаĐŧ'ŅŅ‚Đ°Ņ‚Đ¸ Đ˛Ņ…Ņ–Đ´", + "login_form_save_login": "ЗаĐģĐ¸ŅˆĐ°Ņ‚Đ¸ŅŅ ҃ ŅĐ¸ŅŅ‚ĐĩĐŧŅ–", "login_form_server_empty": "ВвĐĩĐ´Ņ–Ņ‚ŅŒ URL-Đ°Đ´Ņ€Đĩҁ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°.", - "login_form_server_error": "НĐĩ вдаĐģĐžŅŅ ĐŋŅ–Đ´ĐēĐģŅŽŅ‡Đ¸Ņ‚Đ¸ŅŅ Đ´Đž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°.", + "login_form_server_error": "НĐĩ вдаĐģĐžŅŅ С'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ŅŅ Ņ–Đˇ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ.", "login_has_been_disabled": "Đ’Ņ…Ņ–Đ´ ĐąŅƒĐģĐž виĐŧĐēĐŊĐĩĐŊĐž.", - "login_password_changed_error": "ПоĐŧиĐģĐēа ҃ ĐžĐŊОвĐģĐĩĐŊŅ– Đ˛Đ°ŅˆĐžĐŗĐž ĐŋĐ°Ņ€ĐžĐģŅ", - "login_password_changed_success": "ĐŸĐ°Ņ€ĐžĐģҌ ĐžĐŊОвĐģĐĩĐŊĐž ҃ҁĐŋŅ–ŅˆĐŊĐž", + "login_password_changed_error": "НĐĩ вдаĐģĐžŅŅ ĐžĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", + "login_password_changed_success": "ĐŸĐ°Ņ€ĐžĐģҌ ĐžĐŊОвĐģĐĩĐŊĐž", "logout_all_device_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Đ¸ĐšŅ‚Đ¸ С ŅƒŅŅ–Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛?", "logout_this_device_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Đ¸ĐšŅ‚Đ¸ С Ņ†ŅŒĐžĐŗĐž ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ?", "logs": "Đ–ŅƒŅ€ĐŊаĐģи", "longitude": "Đ”ĐžĐ˛ĐŗĐžŅ‚Đ°", "look": "Đ’Đ¸ĐŗĐģŅĐ´", - "loop_videos": "ĐĻиĐēĐģҖ҇ĐŊŅ– Đ˛Ņ–Đ´ĐĩĐž", - "loop_videos_description": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ†Đ¸ĐēĐģҖ҇ĐŊĐĩ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž.", + "loop_videos": "ĐŸĐžĐ˛Ņ‚ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Đ˛Ņ–Đ´ĐĩĐž", + "loop_videos_description": "ВĐŧиĐēĐ°Ņ‚Đ¸ Ņ†Đ¸ĐēĐģҖ҇ĐŊĐĩ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ Đ´ĐĩŅ‚Đ°ĐģҌĐŊĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ.", "main_branch_warning": "Ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ вĐĩŅ€ŅŅ–ŅŽ Đ´ĐģŅ Ņ€ĐžĐˇŅ€ĐžĐąĐŊиĐēŅ–Đ˛; ĐŊĐ°ŅŅ‚Ņ–ĐšĐŊĐž Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒŅ”ĐŧĐž виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩĐģŅ–ĐˇĐŊ҃ вĐĩŅ€ŅŅ–ŅŽ!", "main_menu": "ГоĐģОвĐŊĐĩ ĐŧĐĩĐŊŅŽ", "maintenance_action_restore": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ йаСи даĐŊĐ¸Ņ…", - "maintenance_description": "Immich ĐŋĐĩŅ€ĐĩвĐĩĐ´ĐĩĐŊĐž в Ņ€ĐĩĐļиĐŧ Ņ‚ĐĩŅ…ĐŊҖ҇ĐŊĐžĐŗĐž ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ.", - "maintenance_end": "ЗавĐĩŅ€ŅˆĐ¸Ņ‚Đ¸ Ņ€ĐĩĐļиĐŧ Ņ‚ĐĩŅ…ĐŊҖ҇ĐŊĐžĐŗĐž ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", + "maintenance_description": "Immich ĐŋĐĩŅ€ĐĩвĐĩĐ´ĐĩĐŊĐž в Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ.", + "maintenance_end": "ЗавĐĩŅ€ŅˆĐ¸Ņ‚Đ¸ Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ", "maintenance_end_error": "НĐĩ вдаĐģĐžŅŅ СавĐĩŅ€ŅˆĐ¸Ņ‚Đ¸ Ņ€ĐĩĐļиĐŧ ĐžĐąŅĐģŅƒĐŗĐžĐ˛ŅƒĐ˛Đ°ĐŊĐŊŅ.", "maintenance_logged_in_as": "ĐĐ°Ņ€Đ°ĐˇŅ– ви Đ˛Đ˛Ņ–ĐšŅˆĐģи ŅĐē {user}", "maintenance_restore_from_backup": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ С Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—", "maintenance_restore_library": "Đ’Ņ–Đ´ĐŊĐžĐ˛Ņ–Ņ‚ŅŒ ŅĐ˛ĐžŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", - "maintenance_restore_library_confirm": "Đ¯ĐēŅ‰Đž ҆Đĩ Đ˛Đ¸ĐŗĐģŅĐ´Đ°Ņ” ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž, ĐŋŅ€ĐžĐ´ĐžĐ˛ĐļŅƒĐšŅ‚Đĩ Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—!", + "maintenance_restore_library_confirm": "Đ¯ĐēŅ‰Đž Đ˛ŅĐĩ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž, ĐŋŅ€ĐžĐ´ĐžĐ˛ĐļŅƒĐšŅ‚Đĩ Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ—!", "maintenance_restore_library_description": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ йаСи даĐŊĐ¸Ņ…", - "maintenance_restore_library_folder_has_files": "{folder} ĐŧĐ°Ņ” {count} ĐŋаĐŋĐžĐē(ĐžĐē)", + "maintenance_restore_library_folder_has_files": "{folder} ĐŧĐ°Ņ” {count, plural, one {# ĐŋаĐŋĐē҃} few {# ĐŋаĐŋĐēи} many {# ĐŋаĐŋĐžĐē} other {# ĐŋаĐŋĐžĐē}}", "maintenance_restore_library_folder_no_files": "ĐŖ ĐŋаĐŋ҆Җ {folder} Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– Ņ„Đ°ĐšĐģи!", - "maintenance_restore_library_folder_pass": "Ņ‡Đ¸Ņ‚Đ°ĐąĐĩĐģҌĐŊиК Ņ‚Đ° СаĐŋĐ¸ŅŅƒĐ˛Đ°ĐŊиК", - "maintenance_restore_library_folder_read_fail": "ĐŊĐĩŅ‡Đ¸Ņ‚Đ°ĐąĐĩĐģҌĐŊĐž", - "maintenance_restore_library_folder_write_fail": "ĐŊĐĩ ĐŧĐžĐļĐŊа СаĐŋĐ¸ŅŅƒĐ˛Đ°Ņ‚Đ¸", - "maintenance_restore_library_hint_missing_files": "МоĐļĐģивО, ви ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°Ņ”Ņ‚Đĩ ваĐļĐģĐ¸Đ˛Ņ– Ņ„Đ°ĐšĐģи", - "maintenance_restore_library_hint_regenerate_later": "Ви ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ—Ņ… ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…", + "maintenance_restore_library_folder_pass": "Đ´ĐžŅŅ‚ŅƒĐŋĐŊа Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ Ņ‚Đ° СаĐŋĐ¸ŅŅƒ", + "maintenance_restore_library_folder_read_fail": "ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ", + "maintenance_restore_library_folder_write_fail": "ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа Đ´ĐģŅ СаĐŋĐ¸ŅŅƒ", + "maintenance_restore_library_hint_missing_files": "МоĐļĐģивО, ҃ Đ˛Đ°Ņ Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– ваĐļĐģĐ¸Đ˛Ņ– Ņ„Đ°ĐšĐģи", + "maintenance_restore_library_hint_regenerate_later": "Ви ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ—Ņ… ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…", "maintenance_restore_library_hint_storage_template_missing_files": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ ŅˆĐ°ĐąĐģĐžĐŊ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°? МоĐļĐģивО, ваĐŧ ĐąŅ€Đ°ĐēŅƒŅ” Ņ„Đ°ĐšĐģŅ–Đ˛", "maintenance_restore_library_loading": "ЗаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€ĐžĐē ҆ҖĐģҖҁĐŊĐžŅŅ‚Ņ– Ņ‚Đ° ĐĩĐ˛Ņ€Đ¸ŅŅ‚Đ¸Đēâ€Ļ", "maintenance_task_backup": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžŅ— ĐēĐžĐŋŅ–Ņ— ҖҁĐŊŅƒŅŽŅ‡ĐžŅ— йаСи даĐŊĐ¸Ņ…â€Ļ", @@ -1474,102 +1478,102 @@ "maintenance_task_rollback": "НĐĩ вдаĐģĐžŅŅ Đ˛Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸, ĐŋОвĐĩŅ€ĐŊĐĩĐŊĐŊŅ Đ´Đž Ņ‚ĐžŅ‡Đēи Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅâ€Ļ", "maintenance_title": "ĐĸиĐŧŅ‡Đ°ŅĐžĐ˛Đž ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊĐž", "make": "Đ’Đ¸Ņ€ĐžĐąĐŊиĐē", - "manage_geolocation": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅĐŧ", - "manage_media_access_rationale": "ĐĻĐĩĐš Đ´ĐžĐˇĐ˛Ņ–Đģ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ Đ´ĐģŅ ĐŊаĐģĐĩĐļĐŊĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐŊŅ Ņ„Đ°ĐšĐģŅ–Đ˛ Đ´Đž ĐēĐžŅˆĐ¸Đēа Ņ‚Đ° Ņ—Ņ… Đ˛Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ С ĐŊŅŒĐžĐŗĐž.", + "manage_geolocation": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩĐŧ", + "manage_media_access_rationale": "ĐĻĐĩĐš Đ´ĐžĐˇĐ˛Ņ–Đģ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ, Ņ‰ĐžĐą ĐŊаĐģĐĩĐļĐŊĐž ĐŋĐĩŅ€ĐĩĐŧŅ–Ņ‰ŅƒĐ˛Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ Đ´Đž ĐēĐžŅˆĐ¸Đēа Ņ‚Đ° Đ˛Ņ–Đ´ĐŊОвĐģŅŽĐ˛Đ°Ņ‚Đ¸ Ņ—Ņ… С ĐŊŅŒĐžĐŗĐž.", "manage_media_access_settings": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "manage_media_access_subtitle": "ДозвоĐģŅŒŅ‚Đĩ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich ĐēĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧĐĩĐ´Ņ–Đ°Ņ„Đ°ĐšĐģаĐŧи Ņ‚Đ° ĐŋĐĩŅ€ĐĩĐŧŅ–Ņ‰ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ—Ņ….", + "manage_media_access_subtitle": "Đ”Đ°ĐšŅ‚Đĩ СĐŧĐžĐŗŅƒ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich ĐēĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧĐĩĐ´Ņ–Đ°Ņ„Đ°ĐšĐģаĐŧи Ņ‚Đ° ĐŋĐĩŅ€ĐĩĐŧŅ–Ņ‰ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ—Ņ….", "manage_media_access_title": "Đ”ĐžŅŅ‚ŅƒĐŋ Đ´Đž ĐēĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŧĐĩĐ´Ņ–Đ°", "manage_shared_links": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐŋŅ–ĐģҌĐŊиĐŧи ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧи", - "manage_sharing_with_partners": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐŋŅ–ĐģҌĐŊиĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐžĐŧ С ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°Đŧи", + "manage_sharing_with_partners": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐŋŅ–ĐģҌĐŊиĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐžĐŧ Ņ–Đˇ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°Đŧи", "manage_the_app_settings": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", "manage_your_account": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ОйĐģŅ–ĐēОвиĐŧ СаĐŋĐ¸ŅĐžĐŧ", "manage_your_api_keys": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐēĐģŅŽŅ‡Đ°Đŧи API", "manage_your_devices": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐžĐ˛Đ°ĐŊиĐŧи ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅĐŧи", - "manage_your_oauth_connection": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋŅ–Đ´ĐēĐģŅŽŅ‡ĐĩĐŊĐžĐŗĐž OAuth", + "manage_your_oauth_connection": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋŅ–Đ´'Ņ”Đ´ĐŊаĐŊĐŊŅĐŧ OAuth", "map": "МаĐŋа", - "map_assets_in_bounds": "{count, plural, =0 {НĐĩĐŧĐ°Ņ” Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš ҃ Ņ†Ņ–Đš ĐŧҖҁ҆ĐĩĐ˛ĐžŅŅ‚Ņ–} one {# Ņ„ĐžŅ‚Đž} few {# Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—} many {# Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš} other {# Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš}}", - "map_cannot_get_user_location": "НĐĩ ĐŧĐžĐļ҃ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "map_assets_in_bounds": "{count, plural, =0 {НĐĩĐŧĐ°Ņ” Ņ„ĐžŅ‚Đž ҃ Ņ†Ņ–Đš ĐŧҖҁ҆ĐĩĐ˛ĐžŅŅ‚Ņ–} one {# Ņ„ĐžŅ‚Đž} few {# Ņ„ĐžŅ‚Đž} many {# Ņ„ĐžŅ‚Đž} 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_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_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_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_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": "Đ’Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊŅ– Ņ„Đ°ĐšĐģи", + "matching_assets": "Đ’Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "media_type": "ĐĸиĐŋ ĐŧĐĩĐ´Ņ–Đ°", "memories": "ĐĄĐŋĐžĐŗĐ°Đ´Đ¸", "memories_all_caught_up": "ĐĻĐĩ Đ˛ŅĐĩ ĐŊа ŅŅŒĐžĐŗĐžĐ´ĐŊŅ–", "memories_check_back_tomorrow": "Đ—Đ°Đ˛Ņ–Ņ‚Đ°ĐšŅ‚Đĩ ĐˇĐ°Đ˛Ņ‚Ņ€Đ°, Ņ‰ĐžĐą ĐŋĐžĐąĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐąŅ–ĐģҌ҈Đĩ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", - "memories_setting_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ вĐŧŅ–ŅŅ‚Ņƒ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", - "memories_start_over": "ĐŸĐžŅ‡Đ°Ņ‚Đ¸ СаĐŊОвО", + "memories_setting_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ вĐŧŅ–ŅŅ‚ĐžĐŧ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", + "memories_start_over": "ĐŸĐžŅ‡Đ°Ņ‚Đ¸ СĐŊĐžĐ˛Ņƒ", "memories_swipe_to_close": "ЗĐŧĐ°Ņ…ĐŊŅ–Ņ‚ŅŒ Đ˛ĐŗĐžŅ€Ņƒ, Ņ‰ĐžĐą СаĐēŅ€Đ¸Ņ‚Đ¸", "memory": "ĐĄĐŋĐžĐŗĐ°Đ´", - "memory_lane_title": "АĐģĐĩŅ ĐĄĐŋĐžĐŗĐ°Đ´Ņ–Đ˛ {title}", + "memory_lane_title": "АĐģĐĩŅ ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛ {title}", "menu": "МĐĩĐŊŅŽ", "merge": "Об'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸", "merge_people": "Об'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", "merge_people_limit": "Ви ĐŧĐžĐļĐĩŅ‚Đĩ Ой'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Đ´Đž 5 ОйĐģĐ¸Ņ‡ ОдĐŊĐžŅ‡Đ°ŅĐŊĐž", "merge_people_prompt": "Ви Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Ой'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Ņ†Đ¸Ņ… ĐģŅŽĐ´ĐĩĐš? ĐĻŅ Đ´Ņ–Ņ ĐŊĐĩĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊа.", - "merge_people_successfully": "ĐŖŅĐŋŅ–ŅˆĐŊĐĩ Ой'Ņ”Đ´ĐŊаĐŊĐŊŅ ĐģŅŽĐ´ĐĩĐš", - "merged_people_count": "Об'Ņ”Đ´ĐŊаĐŊĐž {count, plural, one {# ĐžŅĐžĐąĐ°} few {# ĐžŅĐžĐąĐ¸} many {# ĐžŅŅ–Đą} other {# ĐģŅŽĐ´ĐĩĐš}}", - "minimize": "ĐœŅ–ĐŊŅ–ĐŧŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸", + "merge_people_successfully": "Đ›ŅŽĐ´ĐĩĐš Ой'Ņ”Đ´ĐŊаĐŊĐž", + "merged_people_count": "Об'Ņ”Đ´ĐŊаĐŊĐž {count, plural, one {# ĐģŅŽĐ´Đ¸ĐŊ҃} few {# ĐģŅŽĐ´Đ¸ĐŊи} many {# ĐģŅŽĐ´ĐĩĐš} other {# ĐģŅŽĐ´ĐĩĐš}}", + "minimize": "Đ—ĐŗĐžŅ€ĐŊŅƒŅ‚Đ¸", "minute": "ĐĨвиĐģиĐŊа", "minutes": "ĐĨвиĐģиĐŊи", - "mirror_horizontal": "Đ“ĐžŅ€Đ¸ĐˇĐžĐŊŅ‚Đ°ĐģҌĐŊиК", - "mirror_vertical": "ВĐĩŅ€Ņ‚Đ¸ĐēаĐģҌĐŊиК", + "mirror_horizontal": "По ĐŗĐžŅ€Đ¸ĐˇĐžĐŊŅ‚Đ°ĐģŅ–", + "mirror_vertical": "По вĐĩŅ€Ņ‚Đ¸ĐēаĐģŅ–", "missing": "Đ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–", "mobile_app": "ĐœĐžĐąŅ–ĐģҌĐŊиК ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē", - "mobile_app_download_onboarding_note": "ЗаваĐŊŅ‚Đ°ĐļŅ‚Đĩ ҁ҃ĐŋŅƒŅ‚ĐŊŅ–Đš ĐŧĐžĐąŅ–ĐģҌĐŊиК ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē, ҁĐēĐžŅ€Đ¸ŅŅ‚Đ°Đ˛ŅˆĐ¸ŅŅŒ ĐŊавĐĩĐ´ĐĩĐŊиĐŧи ĐŊиĐļ҇Đĩ ĐžĐŋŅ†Ņ–ŅĐŧи", + "mobile_app_download_onboarding_note": "ЗаваĐŊŅ‚Đ°ĐļŅ‚Đĩ ĐŧĐžĐąŅ–ĐģҌĐŊиК ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ОдĐŊиĐŧ Ņ–Đˇ ĐŊавĐĩĐ´ĐĩĐŊĐ¸Ņ… ĐŊиĐļ҇Đĩ ҁĐŋĐžŅĐžĐąŅ–Đ˛", "model": "МодĐĩĐģҌ", "month": "ĐœŅ–ŅŅŅ†ŅŒ", - "monthly_title_text_date_format": "ММММ Ņ€", + "monthly_title_text_date_format": "MMMM y", "more": "Đ‘Ņ–ĐģҌ҈Đĩ", "move": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸", "move_down": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ вĐŊиС", - "move_off_locked_folder": "Đ’Đ¸ĐšŅ‚Đ¸ С ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", + "move_off_locked_folder": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ С ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", "move_to": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž", - "move_to_device_trash": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ в ĐēĐžŅˆĐ¸Đē ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", - "move_to_lock_folder_action_prompt": "{count} дОдаĐŊĐž Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", + "move_to_device_trash": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž ĐēĐžŅˆĐ¸Đēа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ", + "move_to_lock_folder_action_prompt": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ дОдаĐŊĐž Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ дОдаĐŊĐž Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ дОдаĐŊĐž Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ дОдаĐŊĐž Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи}}", "move_to_locked_folder": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ´Đž ĐžŅĐžĐąĐ¸ŅŅ‚ĐžŅ— ĐŋаĐŋĐēи", - "move_to_locked_folder_confirmation": "ĐĻŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐąŅƒĐ´Đĩ видаĐģĐĩĐŊĐž ĐˇŅ– Đ˛ŅŅ–Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ Ņ– Ņ—Ņ… ĐŧĐžĐļĐŊа ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ в ĐžŅĐžĐąĐ¸ŅŅ‚Ņ–Đš ĐŋаĐŋ҆Җ", + "move_to_locked_folder_confirmation": "ĐĻŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐąŅƒĐ´Đĩ виĐģŅƒŅ‡ĐĩĐŊĐž С ŅƒŅŅ–Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ Ņ– Ņ—Ņ… ĐŧĐžĐļĐŊа ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‚Đ¸ ĐģĐ¸ŅˆĐĩ в ĐžŅĐžĐąĐ¸ŅŅ‚Ņ–Đš ĐŋаĐŋ҆Җ", "move_up": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ĐŗĐžŅ€Ņƒ", - "moved_to_archive": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} в Đ°Ņ€Ņ…Ņ–Đ˛", - "moved_to_library": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} в ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "moved_to_archive": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", + "moved_to_library": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} Đ´Đž ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "moved_to_trash": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа", - "multiselect_grid_edit_date_time_err_read_only": "НĐĩĐŧĐžĐļĐģивО Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "multiselect_grid_edit_gps_err_read_only": "НĐĩĐŧĐžĐļĐģивО Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŗĐĩĐžĐģĐžĐēĐ°Ņ†Ņ–ŅŽ Ņ„Đ°ĐšĐģŅ–Đ˛ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°ŅŽ", - "mute_memories": "ĐŸŅ€Đ¸ĐŗĐģŅƒŅˆĐ¸Ņ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", + "multiselect_grid_edit_date_time_err_read_only": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Ņƒ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", + "multiselect_grid_edit_gps_err_read_only": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ Ņ€ĐĩĐ´Đ°ĐŗŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ, ĐŋŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž", + "mute_memories": "ВиĐŧĐēĐŊŅƒŅ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", "my_albums": "ĐœĐžŅ— аĐģŅŒĐąĐžĐŧи", "name": "ІĐŧ'Ņ", "name_or_nickname": "ІĐŧ'Ņ айО ĐŋҁĐĩвдОĐŊŅ–Đŧ", "name_required": "ІĐŧ'Ņ ОйОв'ŅĐˇĐēОвĐĩ", "navigate": "ĐĐ°Đ˛Ņ–ĐŗĐ°Ņ†Ņ–Ņ", - "navigate_to_time": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž Đ§Đ°ŅŅƒ", - "network_requirement_photos_upload": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ҁ҂ҖĐģҌĐŊиĐēĐžĐ˛Ņ– даĐŊŅ– Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Ņ„ĐžŅ‚Đž", - "network_requirement_videos_upload": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ҁ҂ҖĐģҌĐŊиĐēĐžĐ˛Ņ– даĐŊŅ– Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž", + "navigate_to_time": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž Ņ‡Đ°ŅŅƒ", + "network_requirement_photos_upload": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧĐžĐąŅ–ĐģҌĐŊŅ– даĐŊŅ– Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Ņ„ĐžŅ‚Đž", + "network_requirement_videos_upload": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧĐžĐąŅ–ĐģҌĐŊŅ– даĐŊŅ– Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž", "network_requirements": "ВиĐŧĐžĐŗĐ¸ Đ´Đž ĐŧĐĩŅ€ĐĩĐļŅ–", - "network_requirements_updated": "ВиĐŧĐžĐŗĐ¸ Đ´Đž ĐŧĐĩŅ€ĐĩĐļŅ– СĐŧŅ–ĐŊиĐģĐ¸ŅŅ, ҇ĐĩŅ€ĐŗĐ° Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ĐžŅ‡Đ¸Ņ‰ĐĩĐŊа", - "networking_settings": "МĐĩŅ€ĐĩĐļĐĩĐ˛Ņ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "networking_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ Đ°Đ´Ņ€ĐĩŅĐ¸ ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ", - "never": "ĐŊŅ–ĐēĐžĐģи", + "network_requirements_updated": "ВиĐŧĐžĐŗĐ¸ Đ´Đž ĐŧĐĩŅ€ĐĩĐļŅ– СĐŧŅ–ĐŊĐĩĐŊĐž, ҇ĐĩŅ€ĐŗŅƒ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ ҁĐēиĐŊŅƒŅ‚Đž", + "networking_settings": "МĐĩŅ€ĐĩĐļа", + "networking_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅĐŧи Đ°Đ´Ņ€ĐĩŅĐ¸ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", + "never": "ĐŅ–ĐēĐžĐģи", "new_album": "Новий аĐģŅŒĐąĐžĐŧ", "new_api_key": "Новий ĐēĐģŅŽŅ‡ API", "new_date_range": "Новий Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", @@ -1585,36 +1589,36 @@ "next": "ДаĐģŅ–", "next_memory": "ĐĐ°ŅŅ‚ŅƒĐŋĐŊиК ҁĐŋĐžĐŗĐ°Đ´", "no": "ĐŅ–", - "no_actions_added": "ПоĐēи Ņ‰Đž ĐļОдĐŊĐ¸Ņ… Đ´Ņ–Đš ĐŊĐĩ дОдаĐŊĐž", + "no_actions_added": "Đ”Ņ–Đš ҉Đĩ ĐŊĐĩ дОдаĐŊĐž", "no_albums_found": "АĐģŅŒĐąĐžĐŧи ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", - "no_albums_message": "ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ, Ņ‰ĐžĐą ҃ĐŋĐžŅ€ŅĐ´ĐēŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐ˛ĐžŅ— Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "no_albums_with_name_yet": "ĐĄŅ…ĐžĐļĐĩ, ҃ Đ˛Đ°Ņ ҉Đĩ ĐŊĐĩĐŧĐ°Ņ” аĐģŅŒĐąĐžĐŧŅ–Đ˛ С Ņ‚Đ°ĐēĐžŅŽ ĐŊĐ°ĐˇĐ˛ĐžŅŽ.", + "no_albums_message": "ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ, Ņ‰ĐžĐą ҃ĐŋĐžŅ€ŅĐ´ĐēŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐ˛ĐžŅ— Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", + "no_albums_with_name_yet": "ĐĄŅ…ĐžĐļĐĩ, ҃ Đ˛Đ°Ņ ҉Đĩ ĐŊĐĩĐŧĐ°Ņ” аĐģŅŒĐąĐžĐŧŅ–Đ˛ Ņ–Đˇ Ņ‚Đ°ĐēĐžŅŽ ĐŊĐ°ĐˇĐ˛ĐžŅŽ.", "no_albums_yet": "ĐĄŅ…ĐžĐļĐĩ, ҃ Đ˛Đ°Ņ ҉Đĩ ĐŊĐĩĐŧĐ°Ņ” ĐļОдĐŊĐžĐŗĐž аĐģŅŒĐąĐžĐŧ҃.", - "no_archived_assets_message": "Đ—Đ°Đ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, Ņ‰ĐžĐą ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Ņ—Ņ… ҃ Đ˛Đ°ŅˆĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņ– Ņ„ĐžŅ‚Đž", - "no_assets_message": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ŅĐ˛ĐžŅ” ĐŋĐĩŅ€ŅˆĐĩ Ņ„ĐžŅ‚Đž", - "no_assets_to_show": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–", + "no_archived_assets_message": "ĐŅ€Ņ…Ņ–Đ˛ŅƒĐšŅ‚Đĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, Ņ‰ĐžĐą ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Ņ—Ņ… С ĐžŅĐŊОвĐŊĐžŅ— ҁ҂ҀҖ҇Đēи", + "no_assets_message": "ĐĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ŅĐ˛ĐžŅ” ĐŋĐĩŅ€ŅˆĐĩ Ņ„ĐžŅ‚Đž", + "no_assets_to_show": "НĐĩĐŧĐ°Ņ” ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ Đ´ĐģŅ ĐŋĐžĐēĐ°ĐˇŅƒ", "no_cast_devices_found": "ĐŸŅ€Đ¸ŅŅ‚Ņ€ĐžŅ— Đ´ĐģŅ Ņ‚Ņ€Đ°ĐŊҁĐģŅŅ†Ņ–Ņ— ĐŊĐĩ СĐŊаКдĐĩĐŊĐž", - "no_checksum_local": "КоĐŊŅ‚Ņ€ĐžĐģҌĐŊа ҁ҃Đŧа ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа – ĐŊĐĩĐŧĐžĐļĐģивО ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– Ņ„Đ°ĐšĐģи", - "no_checksum_remote": "КоĐŊŅ‚Ņ€ĐžĐģҌĐŊа ҁ҃Đŧа ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа – ĐŊĐĩĐŧĐžĐļĐģивО ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊиК Ņ„Đ°ĐšĐģ", - "no_configuration_needed": "НĐĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊа ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–Ņ", + "no_checksum_local": "КоĐŊŅ‚Ņ€ĐžĐģҌĐŊа ҁ҃Đŧа ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа — ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "no_checksum_remote": "КоĐŊŅ‚Ņ€ĐžĐģҌĐŊа ҁ҃Đŧа ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа — ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "no_configuration_needed": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŊĐĩ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐĩ", "no_devices": "НĐĩĐŧĐ°Ņ” Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—Đ˛", "no_duplicates_found": "Đ”ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛ ĐŊĐĩ Đ˛Đ¸ŅĐ˛ĐģĐĩĐŊĐž.", - "no_exif_info_available": "Đ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž exif", - "no_explore_results_message": "ЗаваĐŊŅ‚Đ°ĐļŅƒĐšŅ‚Đĩ ĐąŅ–ĐģҌ҈Đĩ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš, Ņ‰ĐžĐą ĐŊĐ°ŅĐžĐģОдĐļŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ Đ˛Đ°ŅˆĐžŅŽ ĐēĐžĐģĐĩĐēŅ†Ņ–Ņ”ŅŽ.", - "no_favorites_message": "Đ”ĐžĐ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž в ĐžĐąŅ€Đ°ĐŊĐĩ, Ņ‰ĐžĐą ŅˆĐ˛Đ¸Đ´ĐēĐž СĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚Đ¸ ĐŊаКĐēŅ€Đ°Ņ‰Ņ–", + "no_exif_info_available": "Đ’Ņ–Đ´ŅŅƒŅ‚ĐŊŅ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Exif", + "no_explore_results_message": "ВиваĐŊŅ‚Đ°ĐļŅƒĐšŅ‚Đĩ ĐąŅ–ĐģҌ҈Đĩ Ņ„ĐžŅ‚Đž, Ņ‰ĐžĐą Đ´ĐžŅĐģŅ–Đ´Đ¸Ņ‚Đ¸ ŅĐ˛ĐžŅŽ ĐēĐžĐģĐĩĐēŅ†Ņ–ŅŽ.", + "no_favorites_message": "Đ”ĐžĐ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ҃ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐĩ, Ņ‰ĐžĐą ŅˆĐ˛Đ¸Đ´ĐēĐž СĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚Đ¸ ĐŊаКĐēŅ€Đ°Ņ‰Ņ–", "no_filters_added": "Đ¤Ņ–ĐģŅŒŅ‚Ņ€Đ¸ ҉Đĩ ĐŊĐĩ дОдаĐŊĐž", - "no_libraries_message": "ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ СОвĐŊŅ–ŅˆĐŊŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃ Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš Ņ– Đ˛Ņ–Đ´ĐĩĐž", - "no_local_assets_found": "З Ņ†Ņ–Ņ”ŅŽ ĐēĐžĐŊŅ‚Ņ€ĐžĐģҌĐŊĐžŅŽ ҁ҃ĐŧĐžŅŽ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž ĐģĐžĐēаĐģҌĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "no_location_set": "ĐœŅ–ŅŅ†ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ ĐŊĐĩ Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž", - "no_locked_photos_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_remote_assets_found": "З Ņ†Ņ–Ņ”ŅŽ ĐēĐžĐŊŅ‚Ņ€ĐžĐģҌĐŊĐžŅŽ ҁ҃ĐŧĐžŅŽ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "no_results": "НĐĩĐŧĐ°Ņ” Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Ņ–Đ˛", "no_results_description": "ĐĄĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐ¸ĐŊĐžĐŊŅ–Đŧ айО ĐąŅ–ĐģҌ҈ ĐˇĐ°ĐŗĐ°ĐģҌĐŊĐĩ ĐēĐģŅŽŅ‡ĐžĐ˛Đĩ ҁĐģОвО", - "no_shared_albums_message": "ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ, Ņ‰ĐžĐą Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅĐŧи Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž С ĐģŅŽĐ´ŅŒĐŧи ҃ Đ˛Đ°ŅˆŅ–Đš ĐŧĐĩŅ€ĐĩĐļŅ–", + "no_shared_albums_message": "ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ аĐģŅŒĐąĐžĐŧ, Ņ‰ĐžĐą Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž С ĐģŅŽĐ´ŅŒĐŧи ҃ Đ˛Đ°ŅˆŅ–Đš ĐŧĐĩŅ€ĐĩĐļŅ–", "no_uploads_in_progress": "НĐĩĐŧĐ°Ņ” аĐēŅ‚Đ¸Đ˛ĐŊĐ¸Ņ… виваĐŊŅ‚Đ°ĐļĐĩĐŊҌ", "none": "ЖодĐĩĐŊ", "not_allowed": "НĐĩ дОСвОĐģĐĩĐŊĐž", @@ -1623,141 +1627,141 @@ "not_selected": "НĐĩ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž", "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": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ҁĐŋĐžĐ˛Ņ–Ņ‰ĐĩĐŊĐŊŅ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊĐžŅŽ ĐŋĐžŅˆŅ‚ĐžŅŽ", + "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", - "obtainium_configurator_instructions": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ Obtainium Đ´ĐģŅ Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ Ņ‚Đ° ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Android ĐąĐĩСĐŋĐžŅĐĩŅ€ĐĩĐ´ĐŊŅŒĐž С Ņ€ĐĩĐģŅ–ĐˇŅƒ Immich ĐŊа GitHub. ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ ĐēĐģŅŽŅ‡ API Ņ‚Đ° вийĐĩŅ€Ņ–Ņ‚ŅŒ Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚, Ņ‰ĐžĐą ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ Obtainium", + "obtainium_configurator_instructions": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ Obtainium Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ Ņ‚Đ° ĐžĐŊОвĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Android ĐąĐĩСĐŋĐžŅĐĩŅ€ĐĩĐ´ĐŊŅŒĐž С Ņ€ĐĩĐģŅ–ĐˇŅƒ Immich ĐŊа GitHub. ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ ĐēĐģŅŽŅ‡ API Ņ‚Đ° вийĐĩŅ€Ņ–Ņ‚ŅŒ Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚, Ņ‰ĐžĐą ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ Obtainium", "ocr": "OCR", "official_immich_resources": "ĐžŅ„Ņ–Ņ†Ņ–ĐšĐŊŅ– Ņ€ĐĩŅŅƒŅ€ŅĐ¸ Immich", "offline": "НĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊиК", "offset": "Đ—ŅŅƒĐ˛", "ok": "ОĐē", - "oldest_first": "ĐĄĐŋĐžŅ‡Đ°Ņ‚Đē҃ ĐŊĐ°ĐšŅŅ‚Đ°Ņ€ŅˆŅ–", + "oldest_first": "ĐĄĐŋĐžŅ‡Đ°Ņ‚Đē҃ ĐŊаКдавĐŊŅ–ŅˆŅ–", "on_this_device": "На Ņ†ŅŒĐžĐŧ҃ ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "onboarding": "ВвĐĩĐ´ĐĩĐŊĐŊŅ", + "onboarding": "ĐŸĐžŅ‡Đ°Ņ‚ĐēОвĐĩ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", "onboarding_locale_description": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ йаĐļаĐŊ҃ ĐŧĐžĐ˛Ņƒ. Ви СĐŧĐžĐļĐĩŅ‚Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ҆Đĩ ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", - "onboarding_privacy_description": "ĐĐ°ŅŅ‚ŅƒĐŋĐŊŅ– (ĐŊĐĩĐžĐąĐžĐ˛â€™ŅĐˇĐēĐžĐ˛Ņ–) Ņ„ŅƒĐŊĐē҆Җҗ СаĐģĐĩĐļĐ°Ņ‚ŅŒ Đ˛Ņ–Đ´ СОвĐŊŅ–ŅˆĐŊŅ–Ņ… ҁĐĩŅ€Đ˛Ņ–ŅŅ–Đ˛ Ņ– ĐŧĐžĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ виĐŧĐēĐŊĐĩĐŊŅ– ĐąŅƒĐ´ŅŒ-ĐēĐžĐģи в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", + "onboarding_privacy_description": "ĐĐ°ŅŅ‚ŅƒĐŋĐŊŅ– (ĐŊĐĩОйОв'ŅĐˇĐēĐžĐ˛Ņ–) Ņ„ŅƒĐŊĐē҆Җҗ СаĐģĐĩĐļĐ°Ņ‚ŅŒ Đ˛Ņ–Đ´ СОвĐŊŅ–ŅˆĐŊŅ–Ņ… ҁĐģ҃ĐļĐą, Ņ– Ņ—Ņ… ĐŧĐžĐļĐŊа виĐŧĐēĐŊŅƒŅ‚Đ¸ ĐąŅƒĐ´ŅŒ-ĐēĐžĐģи в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", "onboarding_server_welcome_description": "НаĐģĐ°ŅˆŅ‚ŅƒĐšĐŧĐž Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ С йаСОвиĐŧи ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Đŧи.", - "onboarding_theme_description": "ОбĐĩŅ€Ņ–Ņ‚ŅŒ Ņ‚ĐĩĐŧ҃. Ви ĐŧĐžĐļĐĩŅ‚Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ—Ņ— ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", + "onboarding_theme_description": "ОбĐĩŅ€Ņ–Ņ‚ŅŒ Ņ‚ĐĩĐŧ҃ ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ Đ´ĐģŅ Đ˛Đ°ŅˆĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. Ви СĐŧĐžĐļĐĩŅ‚Đĩ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ Ņ—Ņ— ĐŋŅ–ĐˇĐŊŅ–ŅˆĐĩ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", "onboarding_user_welcome_description": "ĐŸĐžŅ‡ĐŊĐĩĐŧĐž!", "onboarding_welcome_user": "Đ›Đ°ŅĐēавО ĐŋŅ€ĐžŅĐ¸ĐŧĐž, {user}", "online": "Đ”ĐžŅŅ‚ŅƒĐŋĐŊиК", - "only_favorites": "Đ›Đ¸ŅˆĐĩ ĐžĐąŅ€Đ°ĐŊŅ–", + "only_favorites": "Đ›Đ¸ŅˆĐĩ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐĩ", "open": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸", "open_calendar": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ ĐēаĐģĐĩĐŊĐ´Đ°Ņ€", "open_in_browser": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ в ĐąŅ€Đ°ŅƒĐˇĐĩҀҖ", "open_in_map_view": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ ĐŊа ĐŧаĐŋŅ–", "open_in_openstreetmap": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ в OpenStreetMap", - "open_the_search_filters": "Đ’Ņ–Đ´ĐēŅ€Đ¸ĐšŅ‚Đĩ ҄ҖĐģŅŒŅ‚Ņ€Đ¸ ĐŋĐžŅˆŅƒĐē҃", - "options": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", + "open_the_search_filters": "Đ’Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸ ҄ҖĐģŅŒŅ‚Ņ€Đ¸ ĐŋĐžŅˆŅƒĐē҃", + "options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸", "or": "айО", "organize_into_albums": "ĐŖĐŋĐžŅ€ŅĐ´ĐēŅƒĐ˛Đ°Ņ‚Đ¸ в аĐģŅŒĐąĐžĐŧи", - "organize_into_albums_description": "ПоĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐŊĐ°ŅĐ˛ĐŊŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— в аĐģŅŒĐąĐžĐŧи, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅŽŅ‡Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ—", - "organize_your_library": "ĐžŅ€ĐŗĐ°ĐŊŅ–ĐˇŅƒĐšŅ‚Đĩ ŅĐ˛ĐžŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", + "organize_into_albums_description": "ПоĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ ĐŊĐ°ŅĐ˛ĐŊŅ– Ņ„ĐžŅ‚Đž в аĐģŅŒĐąĐžĐŧи Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐž Đ´Đž ĐŋĐžŅ‚ĐžŅ‡ĐŊĐ¸Ņ… ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ—", + "organize_your_library": "ĐŖĐŋĐžŅ€ŅĐ´ĐēŅƒĐšŅ‚Đĩ ŅĐ˛ĐžŅŽ ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐē҃", "original": "ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ", "other": "ІĐŊ҈Đĩ", "other_devices": "ІĐŊŅˆŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", - "other_entities": "ІĐŊŅˆŅ– Ņ„Đ°ĐšĐģи", + "other_entities": "ІĐŊŅˆŅ– Ой'Ņ”ĐēŅ‚Đ¸", "other_variables": "ІĐŊŅˆŅ– СĐŧŅ–ĐŊĐŊŅ–", "owned": "ВĐģĐ°ŅĐŊŅ–", "owner": "ВĐģĐ°ŅĐŊиĐē", "page": "ĐĄŅ‚ĐžŅ€Ņ–ĐŊĐēа", "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_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_select_partner": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°", + "partner_page_shared_to_title": "Đ”ĐžŅŅ‚ŅƒĐŋ ĐŊадаĐŊĐž", "partner_page_stop_sharing_content": "{partner} ĐąŅ–ĐģҌ҈Đĩ ĐŊĐĩ ĐŧĐ°Ņ‚Đ¸ĐŧĐĩ Đ´ĐžŅŅ‚ŅƒĐŋ҃ Đ´Đž Đ˛Đ°ŅˆĐ¸Ņ… Ņ„ĐžŅ‚Đž.", - "partner_sharing": "ĐĄĐŋŅ–ĐģҌĐŊĐĩ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ", + "partner_sharing": "ĐĄĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ Ņ–Đˇ ĐŋĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ°Đŧи", "partners": "ĐŸĐ°Ņ€Ņ‚ĐŊĐĩŅ€Đ¸", "password": "ĐŸĐ°Ņ€ĐžĐģҌ", "password_does_not_match": "ĐŸĐ°Ņ€ĐžĐģŅ– ĐŊĐĩ ĐˇĐąŅ–ĐŗĐ°ŅŽŅ‚ŅŒŅŅ", "password_required": "ĐŸĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ ĐŋĐ°Ņ€ĐžĐģҌ", - "password_reset_success": "ĐŸĐ°Ņ€ĐžĐģҌ ĐąŅƒĐģĐž ҃ҁĐŋŅ–ŅˆĐŊĐž ҁĐēиĐŊŅƒŅ‚Đž", + "password_reset_success": "ĐŸĐ°Ņ€ĐžĐģҌ ҁĐēиĐŊŅƒŅ‚Đž", "past_durations": { - "days": "ĐŸŅ€ĐžĐšŅˆĐģĐž {days, plural, one {Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}", - "hours": "За ĐžŅŅ‚Đ°ĐŊĐŊŅ– {hours, plural, one {ĐŗĐžĐ´Đ¸ĐŊ҃} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊи}}", - "years": "ĐŸŅ€ĐžĐšŅˆĐģĐž {years, plural, one {ҀҖĐē} few {# Ņ€ĐžĐēи} many {# Ņ€ĐžĐēŅ–Đ˛} other {# Ņ€ĐžĐē҃}}" + "days": "За {days, plural, one {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Đš # Đ´ĐĩĐŊҌ} few {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # Đ´ĐŊŅ–} many {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # Đ´ĐŊŅ–Đ˛} other {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # Đ´ĐŊŅ–Đ˛}}", + "hours": "За {hours, plural, one {ĐžŅŅ‚Đ°ĐŊĐŊŅŽ # ĐŗĐžĐ´Đ¸ĐŊ҃} few {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # ĐŗĐžĐ´Đ¸ĐŊи} many {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # ĐŗĐžĐ´Đ¸ĐŊ} other {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # ĐŗĐžĐ´Đ¸ĐŊ}}", + "years": "За {years, plural, one {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Đš # ҀҖĐē} few {ĐžŅŅ‚Đ°ĐŊĐŊŅ– # Ņ€ĐžĐēи} many {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # Ņ€ĐžĐēŅ–Đ˛} other {ĐžŅŅ‚Đ°ĐŊĐŊŅ–Ņ… # Ņ€ĐžĐēŅ–Đ˛}}" }, "path": "ШĐģŅŅ…", "pattern": "ШайĐģĐžĐŊ", - "pause": "ĐŸĐ°ŅƒĐˇĐ°", + "pause": "ĐŸŅ€Đ¸ĐˇŅƒĐŋиĐŊĐ¸Ņ‚Đ¸", "pause_memories": "ĐŸŅ€Đ¸ĐˇŅƒĐŋиĐŊĐ¸Ņ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", "paused": "ĐŸŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊĐž", - "pending": "На Ņ€ĐžĐˇĐŗĐģŅĐ´Ņ–", + "pending": "В ĐžŅ‡Ņ–ĐēŅƒĐ˛Đ°ĐŊĐŊŅ–", "people": "Đ›ŅŽĐ´Đ¸", - "people_edits_count": "Đ’Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗĐžĐ˛Đ°ĐŊĐž {count, plural, one {# ĐžŅĐžĐąŅƒ} few {# ĐžŅĐžĐąĐ¸} many {# ĐžŅŅ–Đą} other {# ĐģŅŽĐ´ĐĩĐš}}", - "people_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš Ņ– Đ˛Ņ–Đ´ĐĩĐž, ĐˇĐŗŅ€ŅƒĐŋОваĐŊĐ¸Ņ… Са ĐģŅŽĐ´ŅŒĐŧи", - "people_selected": "{count, plural, one {# ĐžĐąŅ€Đ°ĐŊа ĐžŅĐžĐąĐ°} few {# Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– ĐžŅĐžĐąĐ¸} many {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… ĐžŅŅ–Đą} other {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… ĐžŅŅ–Đą}}", + "people_edits_count": "Đ’Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗĐžĐ˛Đ°ĐŊĐž {count, plural, one {# ĐģŅŽĐ´Đ¸ĐŊ҃} few {# ĐģŅŽĐ´Đ¸ĐŊи} many {# ĐģŅŽĐ´ĐĩĐš} other {# ĐģŅŽĐ´ĐĩĐš}}", + "people_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ Ņ„ĐžŅ‚Đž Ņ– Đ˛Ņ–Đ´ĐĩĐž, ĐˇĐŗŅ€ŅƒĐŋОваĐŊĐ¸Ņ… Са ĐģŅŽĐ´ŅŒĐŧи", + "people_selected": "{count, plural, one {Đ’Đ¸ĐąŅ€Đ°ĐŊĐž # ĐģŅŽĐ´Đ¸ĐŊ҃} few {Đ’Đ¸ĐąŅ€Đ°ĐŊĐž # ĐģŅŽĐ´Đ¸ĐŊи} many {Đ’Đ¸ĐąŅ€Đ°ĐŊĐž # ĐģŅŽĐ´ĐĩĐš} other {Đ’Đ¸ĐąŅ€Đ°ĐŊĐž # ĐģŅŽĐ´ĐĩĐš}}", "people_sidebar_description": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа ĐģŅŽĐ´ĐĩĐš ҃ ĐąŅ–Ņ‡ĐŊŅ–Đš ĐŋаĐŊĐĩĐģŅ–", - "permanent_deletion_warning": "ПоĐŋĐĩŅ€ĐĩĐ´ĐļĐĩĐŊĐŊŅ ĐŋŅ€Đž видаĐģĐĩĐŊĐŊŅ", - "permanent_deletion_warning_setting_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐļĐĩĐŊĐŊŅ ĐŋŅ€Đ¸ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŧ҃ видаĐģĐĩĐŊĐŊŅ– Ņ„Đ°ĐšĐģŅ–Đ˛", + "permanent_deletion_warning": "ПоĐŋĐĩŅ€ĐĩĐ´ĐļĐĩĐŊĐŊŅ ĐŋŅ€Đž ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐĩ видаĐģĐĩĐŊĐŊŅ", + "permanent_deletion_warning_setting_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐļĐĩĐŊĐŊŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐžĐŗĐž видаĐģĐĩĐŊĐŊŅ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "permanently_delete": "ВидаĐģĐ¸Ņ‚Đ¸ ĐŊаСавĐļди", - "permanently_delete_assets_count": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "permanently_delete_assets_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŊаСавĐļди видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {҆ĐĩĐš Ņ„Đ°ĐšĐģ?} few {҆Җ # Ņ„Đ°ĐšĐģи?} many {҆Җ # Ņ„Đ°ĐšĐģŅ–Đ˛?} other {҆Җ # Ņ„Đ°ĐšĐģŅ–Đ˛?}} ĐĻĐĩ Ņ‚Đ°ĐēĐžĐļ видаĐģĐ¸Ņ‚ŅŒ {count, plural, one {ĐšĐžĐŗĐž С} few {Ņ—Ņ… С} many {Ņ—Ņ… С} other {Ņ—Ņ… С}} аĐģŅŒĐąĐžĐŧ҃(Ņ–Đ˛).", - "permanently_deleted_asset": "ФаКĐģ видаĐģĐĩĐŊĐž ĐŊаСавĐļди", - "permanently_deleted_assets_count": "ВидаĐģĐĩĐŊĐž ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "permission": "ДозвоĐģи", - "permission_empty": "ДозвоĐģи ĐŊĐĩ ĐŋОвиĐŊĐŊŅ– ĐąŅƒŅ‚Đ¸ ĐŋĐžŅ€ĐžĐļĐŊŅ–Đŧи", + "permanently_delete_assets_count": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "permanently_delete_assets_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐŊаСавĐļди видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚? Đ™ĐžĐŗĐž} few {҆Җ # ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸? Đ‡Ņ…} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛? Đ‡Ņ…} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛? Đ‡Ņ…}} Ņ‚Đ°ĐēĐžĐļ ĐąŅƒĐ´Đĩ видаĐģĐĩĐŊĐž С {count, plural, one {ĐšĐžĐŗĐž} few {Ņ—Ņ…ĐŊŅ–Ņ…} many {Ņ—Ņ…ĐŊŅ–Ņ…} other {Ņ—Ņ…ĐŊŅ–Ņ…}} аĐģŅŒĐąĐžĐŧŅ–Đ˛.", + "permanently_deleted_asset": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ видаĐģĐĩĐŊĐž ĐŊаСавĐļди", + "permanently_deleted_assets_count": "ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "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_denied": "Đ”ĐžŅŅ‚ŅƒĐŋ ĐˇĐ°ĐąĐžŅ€ĐžĐŊĐĩĐŊĐž. ЊОй виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Immich, ĐŊĐ°Đ´Đ°ĐšŅ‚Đĩ дОСвОĐģи Đ´Đž ÂĢĐ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐžÂģ в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", "permission_onboarding_permission_granted": "Đ”ĐžŅŅ‚ŅƒĐŋ ĐŊадаĐŊĐž! Đ’ŅĐĩ ĐŗĐžŅ‚ĐžĐ˛Đž.", - "permission_onboarding_permission_limited": "Đ”ĐžŅŅ‚ŅƒĐŋ ОйĐŧĐĩĐļĐĩĐŊĐž. ЊОйи дОСвОĐģĐ¸Ņ‚Đ¸ Immich ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ‚Đ° ĐēĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ–Ņ”ŅŽ ĐŗĐ°ĐģĐĩŅ€ĐĩŅ”ŅŽ, ĐŊĐ°Đ´Đ°ĐšŅ‚Đĩ дОСвОĐģи ĐŊа Ņ„ĐžŅ‚Đž Đš Đ˛Ņ–Đ´ĐĩĐž в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", + "permission_onboarding_permission_limited": "Đ”ĐžŅŅ‚ŅƒĐŋ ОйĐŧĐĩĐļĐĩĐŊĐž. ЊОй Đ´Đ°Ņ‚Đ¸ СĐŧĐžĐŗŅƒ Immich ŅŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊŅ– ĐēĐžĐŋŅ–Ņ— Ņ‚Đ° ĐēĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ–Ņ”ŅŽ ĐŗĐ°ĐģĐĩŅ€ĐĩŅ”ŅŽ, ĐŊĐ°Đ´Đ°ĐšŅ‚Đĩ дОСвОĐģи ĐŊа Ņ„ĐžŅ‚Đž Đš Đ˛Ņ–Đ´ĐĩĐž в ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ….", "permission_onboarding_request": "Đ—Đ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ Immich ĐŋĐžŅ‚Ņ€Ņ–ĐąĐĩĐŊ Đ´ĐžĐˇĐ˛Ņ–Đģ Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ Đ˛Đ°ŅˆĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž.", "person": "Đ›ŅŽĐ´Đ¸ĐŊа", - "person_age_months": "{months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", - "person_age_year_months": "1 ҀҖĐē, {months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", - "person_age_years": "{years, plural, one {# ҀҖĐē} few {# Ņ€ĐžĐēи} many {# Ņ€ĐžĐēŅ–Đ˛} other {# Ņ€ĐžĐēŅ–Đ˛}}", + "person_age_months": "Đ’Ņ–Đē: {months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", + "person_age_year_months": "Đ’Ņ–Đē: 1 ҀҖĐē, {months, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", + "person_age_years": "Đ’Ņ–Đē: {years, plural, one {# ҀҖĐē} few {# Ņ€ĐžĐēи} many {# Ņ€ĐžĐēŅ–Đ˛} other {# Ņ€ĐžĐēŅ–Đ˛}}", "person_birthdate": "Đ”Đ°Ņ‚Đ° ĐŊĐ°Ņ€ĐžĐ´ĐļĐĩĐŊĐŊŅ: {date}", "person_hidden": "{name}{hidden, select, true { (ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°ĐŊĐž)} other {}}", - "person_recognized": "ĐžŅĐžĐąŅƒ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐģи", - "person_selected": "ĐžĐąŅ€Đ°ĐŊа ĐžŅĐžĐąĐ°", - "photo_shared_all_users": "Đ’Đ¸ĐŗĐģŅĐ´Đ°Ņ” Ņ‚Đ°Đē, Ņ‰Đž ви ĐŋĐžĐ´Ņ–ĐģиĐģĐ¸ŅŅ ŅĐ˛ĐžŅ—Đŧи Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅĐŧи С ŅƒŅŅ–Đŧа ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи айО ҃ Đ˛Đ°Ņ ĐŊĐĩĐŧĐ°Ņ” ĐļОдĐŊĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°, С ŅĐēиĐŧ ĐŧĐžĐļĐŊа ĐŋĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ.", + "person_recognized": "Đ›ŅŽĐ´Đ¸ĐŊ҃ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊĐž", + "person_selected": "Đ›ŅŽĐ´Đ¸ĐŊ҃ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž", + "photo_shared_all_users": "ĐĄŅ…ĐžĐļĐĩ, ви вĐļĐĩ ĐŋĐžĐ´Ņ–ĐģиĐģĐ¸ŅŅ Ņ„ĐžŅ‚Đž С ŅƒŅŅ–Đŧа ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°Đŧи, айО ĐŊĐĩĐŧĐ°Ņ” С ĐēиĐŧ Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ.", "photos": "Đ¤ĐžŅ‚Đž", "photos_and_videos": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "photos_count": "{count, plural, one {{count, number} Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ} few {{count, number} Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—} many {{count, number} Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš} other {{count, number} Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš}}", - "photos_from_previous_years": "Đ¤ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— ĐŧиĐŊ҃ĐģĐ¸Ņ… Ņ€ĐžĐēŅ–Đ˛ ҃ ҆ĐĩĐš Đ´ĐĩĐŊҌ", - "photos_only": "ĐĸŅ–ĐģҌĐēи Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—", - "pick_a_location": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐŧҖҁ҆Đĩ Ņ€ĐžĐˇŅ‚Đ°ŅˆŅƒĐ˛Đ°ĐŊĐŊŅ", - "pick_custom_range": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēиК Đ´Ņ–Đ°ĐŋаСОĐŊ", - "pick_date_range": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", - "pin_code_changed_successfully": "PIN-ĐēОд ҃ҁĐŋŅ–ŅˆĐŊĐž СĐŧŅ–ĐŊĐĩĐŊĐž", - "pin_code_reset_successfully": "PIN-ĐēОд ҃ҁĐŋŅ–ŅˆĐŊĐž ҁĐēиĐŊŅƒŅ‚Đž", - "pin_code_setup_successfully": "PIN-ĐēОд ҃ҁĐŋŅ–ŅˆĐŊĐž ĐŊаĐģĐ°ŅˆŅ‚ĐžĐ˛Đ°ĐŊĐž", + "photos_count": "{count, plural, one {{count, number} Ņ„ĐžŅ‚Đž} few {{count, number} Ņ„ĐžŅ‚Đž} many {{count, number} Ņ„ĐžŅ‚Đž} other {{count, number} Ņ„ĐžŅ‚Đž}}", + "photos_from_previous_years": "Đ¤ĐžŅ‚Đž ĐŧиĐŊ҃ĐģĐ¸Ņ… Ņ€ĐžĐēŅ–Đ˛", + "photos_only": "Đ›Đ¸ŅˆĐĩ Ņ„ĐžŅ‚Đž", + "pick_a_location": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐŧҖҁ҆Đĩ", + "pick_custom_range": "Đ”ĐžĐ˛Ņ–ĐģҌĐŊиК Đ´Ņ–Đ°ĐŋаСОĐŊ", + "pick_date_range": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", + "pin_code_changed_successfully": "PIN-ĐēОд СĐŧŅ–ĐŊĐĩĐŊĐž", + "pin_code_reset_successfully": "PIN-ĐēОд ҁĐēиĐŊŅƒŅ‚Đž", + "pin_code_setup_successfully": "PIN-ĐēОд ĐŊаĐģĐ°ŅˆŅ‚ĐžĐ˛Đ°ĐŊĐž", "pin_verification": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēа PIN-ĐēĐžĐ´Ņƒ", "place": "ĐœŅ–ŅŅ†Đĩ", "places": "ĐœŅ–ŅŅ†Ņ", - "places_count": "{count, plural, one {{count, number} ĐœŅ–ŅŅ†Đĩ} few {{count, number} ĐœŅ–ŅŅ†Ņ} many {{count, number} ĐœŅ–ŅŅ†ŅŒ} other {{count, number} ĐœŅ–ŅŅ†ŅŒ}}", + "places_count": "{count, plural, one {{count, number} ĐŧҖҁ҆Đĩ} few {{count, number} ĐŧŅ–ŅŅ†Ņ} many {{count, number} ĐŧŅ–ŅŅ†ŅŒ} other {{count, number} ĐŧŅ–ŅŅ†ŅŒ}}", "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": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋŅ€ĐžĐšĐ´Ņ–Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ†Ņ–ŅŽ", + "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": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸", + "preferences_settings_subtitle": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ҃ĐŋОдОйаĐŊĐŊŅĐŧи ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", + "preferences_settings_title": "ĐŖĐŋОдОйаĐŊĐŊŅ", "preparing": "ĐŸŅ–Đ´ĐŗĐžŅ‚ĐžĐ˛Đēа", - "preset": "ПĐĩŅ€ĐĩĐ´Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ", + "preset": "ĐŸŅ€ĐĩҁĐĩŅ‚", "preview": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´", - "previous": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ”", + "previous": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš", "previous_memory": "ПоĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš ҁĐŋĐžĐŗĐ°Đ´", "previous_or_next_day": "ДĐĩĐŊҌ вĐŋĐĩŅ€ĐĩĐ´/ĐŊаСад", "previous_or_next_month": "ĐœŅ–ŅŅŅ†ŅŒ вĐŋĐĩŅ€ĐĩĐ´/ĐŊаСад", @@ -1769,526 +1773,530 @@ "profile_drawer_app_logs": "Đ–ŅƒŅ€ĐŊаĐģ", "profile_drawer_client_server_up_to_date": "КĐģŅ–Ņ”ĐŊŅ‚ Ņ‚Đ° ҁĐĩŅ€Đ˛ĐĩŅ€ — аĐēŅ‚ŅƒĐ°ĐģҌĐŊŅ–", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "Đ ĐĩĐļиĐŧ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž. ЊОй Đ˛Đ¸ĐšŅ‚Đ¸, Đ´ĐžĐ˛ĐŗĐž ĐŊĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐžĐē Đ°Đ˛Đ°Ņ‚Đ°Ņ€Đ° ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°.", + "profile_drawer_readonly_mode": "Đ ĐĩĐļиĐŧ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž. ЊОй Đ˛Đ¸ĐšŅ‚Đ¸, ŅƒŅ‚Ņ€Đ¸ĐŧŅƒĐšŅ‚Đĩ СĐŊĐ°Ņ‡ĐžĐē Đ°Đ˛Đ°Ņ‚Đ°Ņ€Đ°.", "profile_image_of_user": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ {user}", - "profile_picture_set": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ Đ˛ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž.", + "profile_picture_set": "Đ—ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐŋŅ€ĐžŅ„Ņ–ĐģŅŽ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž.", "public_album": "ĐŸŅƒĐąĐģҖ҇ĐŊиК аĐģŅŒĐąĐžĐŧ", - "public_share": "ĐŸŅƒĐąĐģҖ҇ĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ", - "purchase_account_info": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēа", + "public_share": "ĐŸŅƒĐąĐģҖ҇ĐŊиК ҁĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ", + "purchase_account_info": "ĐŸŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐē", "purchase_activated_subtitle": "Đ”ŅĐēŅƒŅ”ĐŧĐž Са ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐē҃ Immich Ņ‚Đ° ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊĐžĐŗĐž СайĐĩСĐŋĐĩ҇ĐĩĐŊĐŊŅ С Đ˛Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸Đŧ ĐēОдОĐŧ", "purchase_activated_time": "АĐēŅ‚Đ¸Đ˛ĐžĐ˛Đ°ĐŊĐž {date}", - "purchase_activated_title": "Đ’Đ°Ņˆ ĐēĐģŅŽŅ‡ ĐąŅƒĐģĐž ҃ҁĐŋŅ–ŅˆĐŊĐž аĐēŅ‚Đ¸Đ˛ĐžĐ˛Đ°ĐŊĐž", + "purchase_activated_title": "Đ’Đ°Ņˆ ĐēĐģŅŽŅ‡ аĐēŅ‚Đ¸Đ˛ĐžĐ˛Đ°ĐŊĐž", "purchase_button_activate": "АĐēŅ‚Đ¸Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸", "purchase_button_buy": "ĐšŅƒĐŋĐ¸Ņ‚Đ¸", "purchase_button_buy_immich": "ĐšŅƒĐŋĐ¸Ņ‚Đ¸ Immich", - "purchase_button_never_show_again": "ĐŅ–ĐēĐžĐģи ĐąŅ–ĐģҌ҈Đĩ ĐŊĐĩ ĐŋĐžĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸", + "purchase_button_never_show_again": "Đ‘Ņ–ĐģҌ҈Đĩ ĐŊĐĩ ĐŋĐžĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸", "purchase_button_reminder": "ĐĐ°ĐŗĐ°Đ´Đ°Ņ‚Đ¸ ҇ĐĩŅ€ĐĩС 30 Đ´ĐŊŅ–Đ˛", - "purchase_button_remove_key": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡", - "purchase_button_select": "ĐžĐąŅ€Đ°Ņ‚Đ¸", - "purchase_failed_activation": "НĐĩ вдаĐģĐžŅŅ аĐēŅ‚Đ¸Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸! Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ŅĐ˛ĐžŅŽ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ Đ´ĐģŅ ĐžŅ‚Ņ€Đ¸ĐŧаĐŊĐŊŅ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐžĐŗĐž ĐēĐģŅŽŅ‡Đ° ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ!", - "purchase_individual_description_1": "ДĐģŅ Ņ–ĐŊĐ´Đ¸Đ˛Ņ–Đ´ŅƒĐ°ĐģҌĐŊĐžĐŗĐž виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ", - "purchase_individual_description_2": "ĐĄŅ‚Đ°Ņ‚ŅƒŅ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēи", + "purchase_button_remove_key": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡", + "purchase_button_select": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸", + "purchase_failed_activation": "НĐĩ вдаĐģĐžŅŅ аĐēŅ‚Đ¸Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸! ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Ņ‚Đĩ ĐĩĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊ҃ ĐŋĐžŅˆŅ‚Ņƒ — Ņ‚Đ°Đŧ ĐŧĐ°Ņ” ĐąŅƒŅ‚Đ¸ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊиК ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ!", + "purchase_individual_description_1": "ДĐģŅ ОдĐŊĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "purchase_individual_description_2": "ĐĄŅ‚Đ°Ņ‚ŅƒŅ ĐŋŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐēа", "purchase_individual_title": "ІĐŊĐ´Đ¸Đ˛Ņ–Đ´ŅƒĐ°ĐģҌĐŊиК", "purchase_input_suggestion": "ĐœĐ°Ņ”Ņ‚Đĩ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ? ВвĐĩĐ´Ņ–Ņ‚ŅŒ ĐēĐģŅŽŅ‡ ĐŊиĐļ҇Đĩ", - "purchase_license_subtitle": "ĐšŅƒĐŋŅ–Ņ‚ŅŒ Immich, Ņ‰ĐžĐą ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŋОдаĐģŅŒŅˆĐ¸Đš Ņ€ĐžĐˇĐ˛Đ¸Ņ‚ĐžĐē ҁĐĩŅ€Đ˛Ņ–ŅŅƒ", - "purchase_lifetime_description": "НазавĐļди", + "purchase_license_subtitle": "ĐšŅƒĐŋŅ–Ņ‚ŅŒ Immich, Ņ‰ĐžĐą ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŋОдаĐģŅŒŅˆĐ¸Đš Ņ€ĐžĐˇĐ˛Đ¸Ņ‚ĐžĐē ĐŋŅ€ĐžŅ”ĐēŅ‚Ņƒ", + "purchase_lifetime_description": "БĐĩĐˇŅŅ‚Ņ€ĐžĐēОва Đē҃ĐŋŅ–Đ˛ĐģŅ", "purchase_option_title": "ВАРІАНĐĸИ ĐšĐŖĐŸĐ†Đ’Đ›Đ†", - "purchase_panel_info_1": "Đ ĐžĐˇŅ€ĐžĐąĐēа Immich виĐŧĐ°ĐŗĐ°Ņ” ĐąĐ°ĐŗĐ°Ņ‚Đž Ņ‡Đ°ŅŅƒ Ņ‚Đ° ĐˇŅƒŅĐ¸ĐģҌ. Ми ĐŧĐ°Ņ”ĐŧĐž ŅˆŅ‚Đ°Ņ‚ĐŊĐ¸Ņ… Ņ–ĐŊĐļĐĩĐŊĐĩŅ€Ņ–Đ˛, ŅĐēŅ– ĐŋŅ€Đ°Ņ†ŅŽŅŽŅ‚ŅŒ ĐŊад Ņ‚Đ¸Đŧ, Ņ‰ĐžĐą ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ ĐšĐžĐŗĐž ŅĐēĐžĐŧĐžĐŗĐ° ĐēŅ€Đ°Ņ‰Đ¸Đŧ. ĐĐ°ŅˆĐ° ĐŧŅ–ŅŅ–Ņ — ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊĐĩ СайĐĩСĐŋĐĩ҇ĐĩĐŊĐŊŅ С Đ˛Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸Đŧ ĐēОдОĐŧ Ņ‚Đ° ĐĩŅ‚Đ¸Ņ‡ĐŊŅ– ĐąŅ–ĐˇĐŊĐĩҁ-ĐŋŅ€Đ°ĐēŅ‚Đ¸Đēи ŅŅ‚Ņ–ĐšĐēиĐŧ Đ´ĐļĐĩŅ€ĐĩĐģĐžĐŧ Đ´ĐžŅ…ĐžĐ´Ņƒ Đ´ĐģŅ Ņ€ĐžĐˇŅ€ĐžĐąĐŊиĐēŅ–Đ˛ Ņ– ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐĩĐēĐžŅĐ¸ŅŅ‚ĐĩĐŧ҃, Ņ‰Đž ĐŋОваĐļĐ°Ņ” ĐēĐžĐŊŅ„Ņ–Đ´ĐĩĐŊŅ†Ņ–ĐšĐŊŅ–ŅŅ‚ŅŒ, С Ņ€ĐĩаĐģҌĐŊиĐŧи аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Đ°Đŧи ĐĩĐēҁĐŋĐģŅƒĐ°Ņ‚Đ°Ņ‚ĐžŅ€ŅŅŒĐēиĐŧ Ņ…ĐŧĐ°Ņ€ĐŊиĐŧ ҁĐĩŅ€Đ˛Ņ–ŅĐ°Đŧ.", - "purchase_panel_info_2": "ĐžŅĐēŅ–ĐģҌĐēи Đŧи ĐˇĐžĐąĐžĐ˛â€™ŅĐˇŅƒŅ”ĐŧĐžŅŅ ĐŊĐĩ Đ´ĐžĐ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐģĐ°Ņ‚ĐŊŅ– ОйĐŧĐĩĐļĐĩĐŊĐŊŅ, Ņ†Ņ ĐŋĐžĐē҃ĐŋĐēа ĐŊĐĩ ĐŊĐ°Đ´Đ°ŅŅ‚ŅŒ ваĐŧ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Ņ–Đš в Immich. Ми ĐŋĐžĐēĐģĐ°Đ´Đ°Ņ”ĐŧĐžŅŅ ĐŊа Ņ‚Đ°ĐēĐ¸Ņ… ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛, ŅĐē ви, Ņ‰ĐžĐą ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋОдаĐģŅŒŅˆĐ¸Đš Ņ€ĐžĐˇĐ˛Đ¸Ņ‚ĐžĐē Immich.", + "purchase_panel_info_1": "Đ ĐžĐˇŅ€ĐžĐąĐēа Immich ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒŅ” ĐąĐ°ĐŗĐ°Ņ‚Đž Ņ‡Đ°ŅŅƒ Ņ‚Đ° ĐˇŅƒŅĐ¸ĐģҌ. Ми ĐŧĐ°Ņ”ĐŧĐž ŅˆŅ‚Đ°Ņ‚ĐŊĐ¸Ņ… Ņ–ĐŊĐļĐĩĐŊĐĩŅ€Ņ–Đ˛, ŅĐēŅ– ĐŋŅ€Đ°Ņ†ŅŽŅŽŅ‚ŅŒ ĐŊад Ņ‚Đ¸Đŧ, Ņ‰ĐžĐą ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ ĐšĐžĐŗĐž ŅĐēĐžĐŧĐžĐŗĐ° ĐēŅ€Đ°Ņ‰Đ¸Đŧ. ĐĐ°ŅˆĐ° ĐŧŅ–ŅŅ–Ņ — ĐˇŅ€ĐžĐąĐ¸Ņ‚Đ¸ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŊĐĩ СайĐĩСĐŋĐĩ҇ĐĩĐŊĐŊŅ С Đ˛Ņ–Đ´ĐēŅ€Đ¸Ņ‚Đ¸Đŧ ĐēОдОĐŧ Ņ‚Đ° ĐĩŅ‚Đ¸Ņ‡ĐŊŅ– ĐąŅ–ĐˇĐŊĐĩҁ-ĐŋŅ€Đ°ĐēŅ‚Đ¸Đēи ŅŅ‚Ņ–ĐšĐēиĐŧ Đ´ĐļĐĩŅ€ĐĩĐģĐžĐŧ Đ´ĐžŅ…ĐžĐ´Ņƒ Đ´ĐģŅ Ņ€ĐžĐˇŅ€ĐžĐąĐŊиĐēŅ–Đ˛ Ņ– ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐĩĐēĐžŅĐ¸ŅŅ‚ĐĩĐŧ҃, Ņ‰Đž ĐŋОваĐļĐ°Ņ” ĐēĐžĐŊŅ„Ņ–Đ´ĐĩĐŊŅ†Ņ–ĐšĐŊŅ–ŅŅ‚ŅŒ, С Ņ€ĐĩаĐģҌĐŊиĐŧи аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Đ°Đŧи ĐĩĐēҁĐŋĐģŅƒĐ°Ņ‚Đ°Ņ‚ĐžŅ€ŅŅŒĐēиĐŧ Ņ…ĐŧĐ°Ņ€ĐŊиĐŧ ҁĐģ҃ĐļйаĐŧ.", + "purchase_panel_info_2": "ĐžŅĐēŅ–ĐģҌĐēи Đŧи Đ˛ĐˇŅĐģи ĐŊа ҁĐĩĐąĐĩ СОйОв'ŅĐˇĐ°ĐŊĐŊŅ ĐŊĐĩ Đ´ĐžĐ´Đ°Đ˛Đ°Ņ‚Đ¸ ĐŋĐģĐ°Ņ‚ĐŊŅ– ОйĐŧĐĩĐļĐĩĐŊĐŊŅ, Ņ†Ņ Đē҃ĐŋŅ–Đ˛ĐģŅ ĐŊĐĩ ĐŊĐ°Đ´Đ°ŅŅ‚ŅŒ ваĐŧ Đ´ĐžĐ´Đ°Ņ‚ĐēĐžĐ˛Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Ņ–Đš в Immich. ПодаĐģŅŒŅˆĐ¸Đš Ņ€ĐžĐˇĐ˛Đ¸Ņ‚ĐžĐē Immich СаĐģĐĩĐļĐ¸Ņ‚ŅŒ Đ˛Ņ–Đ´ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēи Ņ‚Đ°ĐēĐ¸Ņ… ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛, ŅĐē ви.", "purchase_panel_title": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ ĐŋŅ€ĐžŅ”ĐēŅ‚", "purchase_per_server": "На ҁĐĩŅ€Đ˛ĐĩŅ€", "purchase_per_user": "На ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "purchase_remove_product_key": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ", - "purchase_remove_product_key_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ?", - "purchase_remove_server_product_key": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ Đ´ĐģŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", - "purchase_remove_server_product_key_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ Đ´ĐģŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°?", + "purchase_remove_product_key": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ", + "purchase_remove_product_key_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ?", + "purchase_remove_server_product_key": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ Đ´ĐģŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", + "purchase_remove_server_product_key_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐēĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ Đ´ĐģŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°?", "purchase_server_description_1": "ДĐģŅ Đ˛ŅŅŒĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", - "purchase_server_description_2": "ĐĄŅ‚Đ°Ņ‚ŅƒŅ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēи", + "purchase_server_description_2": "ĐĄŅ‚Đ°Ņ‚ŅƒŅ ĐŋŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐēа", "purchase_server_title": "ĐĄĐĩŅ€Đ˛ĐĩŅ€", "purchase_settings_server_activated": "КĐģŅŽŅ‡ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Ņƒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐēĐĩŅ€ŅƒŅ”Ņ‚ŅŒŅŅ адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€ĐžĐŧ", - "query_asset_id": "ІдĐĩĐŊŅ‚Đ¸Ņ„Ņ–ĐēĐ°Ņ‚ĐžŅ€ Ņ„Đ°ĐšĐģ҃ СаĐŋĐ¸Ņ‚Ņƒ", + "query_asset_id": "ЗаĐŋĐ¸Ņ‚ Са ID ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", "queue_status": "ĐŖ ҇ĐĩŅ€ĐˇŅ– {count} С {total}", - "rate_asset": "ĐžŅ†Ņ–ĐŊĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", - "rating": "Đ—ĐžŅ€ŅĐŊиК Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", - "rating_clear": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", - "rating_count": "{count, plural, one {# ĐˇŅ–Ņ€Đēа} few {# ĐˇŅ–Ņ€Đēи} many {# ĐˇŅ–Ņ€ĐžĐē} other {# ĐˇŅ–Ņ€ĐžĐē}}", - "rating_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ EXIF ĐŊа Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ĐšĐŊŅ–Đš ĐŋаĐŊĐĩĐģŅ–", - "reaction_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ Ņ€ĐĩаĐē҆Җҗ", - "read_changelog": "ĐŸŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚Đ¸ СĐŧŅ–ĐŊи в ĐžĐŊОвĐģĐĩĐŊĐŊŅ–", + "rate_asset": "ĐžŅ†Ņ–ĐŊĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "rating": "Đ—Ņ–Ņ€ĐēОвиК Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", + "rating_clear": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", + "rating_count": "{count, plural, =0 {БĐĩС Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗŅƒ} one {# ĐˇŅ–Ņ€Đēа} few {# ĐˇŅ–Ņ€Đēи} many {# ĐˇŅ–Ņ€ĐžĐē} other {# ĐˇŅ–Ņ€ĐžĐē}}", + "rating_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ Exif ĐŊа Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ĐšĐŊŅ–Đš ĐŋаĐŊĐĩĐģŅ–", + "reaction_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ Ņ€ĐĩаĐē҆Җҗ", + "read_changelog": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐļŅƒŅ€ĐŊаĐģ СĐŧŅ–ĐŊ", "readonly_mode_disabled": "Đ ĐĩĐļиĐŧ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ виĐŧĐēĐŊĐĩĐŊĐž", - "readonly_mode_enabled": "Đ ĐĩĐļиĐŧ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ Đ˛Đ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", + "readonly_mode_enabled": "Đ ĐĩĐļиĐŧ ĐģĐ¸ŅˆĐĩ Đ´ĐģŅ Ņ‡Đ¸Ņ‚Đ°ĐŊĐŊŅ ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž", "ready_for_upload": "Đ“ĐžŅ‚ĐžĐ˛Đž Đ´Đž виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "reassign": "ПĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸", - "reassigned_assets_to_existing_person": "ПĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} {name, select, null {ҖҁĐŊŅƒŅŽŅ‡Ņ–Đš ĐžŅĐžĐąŅ–} other {{name}}}", - "reassigned_assets_to_new_person": "ПĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} ĐŊĐžĐ˛Ņ–Đš ĐžŅĐžĐąŅ–", - "reassing_hint": "ĐŸŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐžĐąŅ€Đ°ĐŊŅ– Ņ„Đ°ĐšĐģи ҖҁĐŊŅƒŅŽŅ‡Ņ–Đš ĐžŅĐžĐąŅ–", + "reassigned_assets_to_existing_person": "ПĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} {name, select, null {ĐŊĐ°ŅĐ˛ĐŊŅ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–} other {{name}}}", + "reassigned_assets_to_new_person": "ПĐĩŅ€ĐĩĐŋŅ€Đ¸ĐˇĐŊĐ°Ņ‡ĐĩĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} ĐŊĐžĐ˛Ņ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–", + "reassing_hint": "ĐŸŅ€Đ¸ĐˇĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐŊĐ°ŅĐ˛ĐŊŅ–Đš ĐģŅŽĐ´Đ¸ĐŊŅ–", "recent": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž", "recent_albums": "ĐžŅŅ‚Đ°ĐŊĐŊŅ– аĐģŅŒĐąĐžĐŧи", "recent_searches": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊŅ– ĐŋĐžŅˆŅƒĐēĐžĐ˛Ņ– СаĐŋĐ¸Ņ‚Đ¸", "recently_added": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž дОдаĐŊŅ–", - "recently_added_page_title": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊŅ–", - "recently_taken": "НĐĩдавĐŊĐž ĐˇŅ€ĐžĐąĐģĐĩĐŊĐž", - "recently_taken_page_title": "НĐĩдавĐŊĐž ĐˇŅ€ĐžĐąĐģĐĩĐŊŅ–", + "recently_added_page_title": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž дОдаĐŊŅ–", + "recently_taken": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž СĐŊŅŅ‚Ņ–", + "recently_taken_page_title": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊĐž СĐŊŅŅ‚Ņ–", "refresh": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸", "refresh_encoded_videos": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ СаĐēОдОваĐŊŅ– Đ˛Ņ–Đ´ĐĩĐž", "refresh_faces": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", "refresh_metadata": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊŅ–", "refresh_thumbnails": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸", - "refreshed": "ОĐŊОвĐģĐĩĐŊиК", - "refreshes_every_file": "ĐŸĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž Ņ‡Đ¸Ņ‚Đ°Ņ” Đ˛ŅŅ– ҖҁĐŊŅƒŅŽŅ‡Ņ– Ņ‚Đ° ĐŊĐžĐ˛Ņ– Ņ„Đ°ĐšĐģи", + "refreshed": "ОĐŊОвĐģĐĩĐŊĐž", + "refreshes_every_file": "ĐŸĐžĐ˛Ņ‚ĐžŅ€ĐŊĐž ĐˇŅ‡Đ¸Ņ‚ŅƒŅ” Đ˛ŅŅ– ĐŊĐ°ŅĐ˛ĐŊŅ– Ņ‚Đ° ĐŊĐžĐ˛Ņ– Ņ„Đ°ĐšĐģи", "refreshing_encoded_video": "ОĐŊОвĐģĐĩĐŊĐŊŅ СаĐēОдОваĐŊĐžĐŗĐž Đ˛Ņ–Đ´ĐĩĐž", "refreshing_faces": "ОĐŊОвĐģĐĩĐŊĐŊŅ ОйĐģĐ¸Ņ‡", "refreshing_metadata": "ОĐŊОвĐģĐĩĐŊĐŊŅ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐ¸Ņ…", "regenerating_thumbnails": "ĐŸĐžĐ˛Ņ‚ĐžŅ€ĐŊĐĩ ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€", - "remote": "На ҁĐĩŅ€Đ˛ĐĩҀҖ", - "remote_assets": "Đ’Ņ–Đ´Đ´Đ°ĐģĐĩĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž", - "remote_media_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊĐ¸Ņ… ĐŧĐĩĐ´Ņ–Đ°Ņ„Đ°ĐšĐģŅ–Đ˛", + "remote": "Đ’Ņ–Đ´Đ´Đ°ĐģĐĩĐŊиК", + "remote_assets": "Đ’Ņ–Đ´Đ´Đ°ĐģĐĩĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", + "remote_media_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ Đ˛Ņ–Đ´Đ´Đ°ĐģĐĩĐŊĐ¸Ņ… ĐŧĐĩĐ´Ņ–Đ°", "remove": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸", - "remove_assets_album_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} С аĐģŅŒĐąĐžĐŧ҃?", - "remove_assets_shared_link_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}} С Ņ†ŅŒĐžĐŗĐž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ?", - "remove_assets_title": "ВидаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи?", - "remove_custom_date_range": "ВидаĐģĐ¸Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēиК Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", - "remove_deleted_assets": "ВидаĐģĐĩĐŊĐŊŅ Đ°Đ˛Ņ‚ĐžĐŊĐžĐŧĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", - "remove_from_album": "ВидаĐģĐ¸Ņ‚Đ¸ С аĐģŅŒĐąĐžĐŧ҃", - "remove_from_album_action_prompt": "{count} видаĐģĐĩĐŊĐž С аĐģŅŒĐąĐžĐŧ҃", - "remove_from_favorites": "ВидаĐģĐ¸Ņ‚Đ¸ С ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", + "remove_assets_album_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} С аĐģŅŒĐąĐžĐŧ҃?", + "remove_assets_shared_link_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ виĐģŅƒŅ‡Đ¸Ņ‚Đ¸ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}} С Ņ†ŅŒĐžĐŗĐž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ?", + "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_memory": "ВидаĐģĐĩĐŊиК ҁĐŋĐžĐŗĐ°Đ´", - "removed_photo_from_memory": "Đ¤ĐžŅ‚Đž видаĐģĐĩĐŊĐĩ ĐˇŅ– ҁĐŋĐžĐŗĐ°Đ´Ņƒ", - "removed_tagged_assets": "ВидаĐģĐĩĐŊĐž Ņ‚ĐĩĐŗ Ņ–Đˇ {count, plural, one {# Ņ„Đ°ĐšĐģ҃} few {# Ņ„Đ°ĐšĐģŅ–Đ˛} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "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, one {ВиĐģŅƒŅ‡ĐĩĐŊĐž # С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} few {ВиĐģŅƒŅ‡ĐĩĐŊĐž # С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} many {ВиĐģŅƒŅ‡ĐĩĐŊĐž # С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž} other {ВиĐģŅƒŅ‡ĐĩĐŊĐž # С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž}}", + "removed_memory": "ВиĐģŅƒŅ‡ĐĩĐŊĐž ҁĐŋĐžĐŗĐ°Đ´", + "removed_photo_from_memory": "ВиĐģŅƒŅ‡ĐĩĐŊĐž Ņ„ĐžŅ‚Đž ĐˇŅ– ҁĐŋĐžĐŗĐ°Đ´Ņƒ", + "removed_tagged_assets": "ВиĐģŅƒŅ‡ĐĩĐŊĐž Ņ‚ĐĩĐŗ Ņ–Đˇ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "rename": "ПĐĩŅ€ĐĩĐšĐŧĐĩĐŊŅƒĐ˛Đ°Ņ‚Đ¸", - "repair": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐŊŅ", - "repair_no_results_message": "НĐĩĐ˛Ņ–Đ´ŅŅ‚ĐĩĐļŅƒĐ˛Đ°ĐŊŅ– Ņ‚Đ° Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊŅ– Ņ‚ŅƒŅ‚", - "replace_with_upload": "ЗаĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŊа виваĐŊŅ‚Đ°ĐļĐĩĐŊĐĩ", + "repair": "ВиĐŋŅ€Đ°Đ˛Đ¸Ņ‚Đ¸", + "repair_no_results_message": "НĐĩĐ˛Ņ–Đ´ŅŅ‚ĐĩĐļŅƒĐ˛Đ°ĐŊŅ– Ņ‚Đ° Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ– Ņ„Đ°ĐšĐģи С'ŅĐ˛ĐģŅŅ‚ŅŒŅŅ Ņ‚ŅƒŅ‚", + "replace_with_upload": "ЗаĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ виваĐŊŅ‚Đ°ĐļĐĩĐŊиĐŧ", "repository": "Đ ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Ņ–Đš", - "require_password": "ВиĐŧĐ°ĐŗĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "require_user_to_change_password_on_first_login": "ВиĐŧĐ°ĐŗĐ°Ņ‚Đ¸ Đ˛Ņ–Đ´ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° СĐŧŅ–ĐŊŅŽĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ ĐŋŅ€Đ¸ ĐŋĐĩŅ€ŅˆĐžĐŧ҃ Đ˛Ņ…ĐžĐ´Ņ–", - "rescan": "ПĐĩŅ€ĐĩҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", + "require_password": "ЗаĐŋĐ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", + "require_user_to_change_password_on_first_login": "Зобов'ŅĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐĩŅ€ŅˆĐžĐŗĐž Đ˛Ņ…ĐžĐ´Ņƒ", + "rescan": "ПĐĩŅ€ĐĩҁĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸", "reset": "ĐĄĐēиĐŊŅƒŅ‚Đ¸", "reset_password": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", "reset_people_visibility": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ видиĐŧŅ–ŅŅ‚ŅŒ ĐģŅŽĐ´ĐĩĐš", "reset_pin_code": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ PIN-ĐēОд", "reset_pin_code_description": "Đ¯ĐēŅ‰Đž ви ĐˇĐ°ĐąŅƒĐģи ŅĐ˛Ņ–Đš PIN-ĐēОд, ви ĐŧĐžĐļĐĩŅ‚Đĩ СвĐĩŅ€ĐŊŅƒŅ‚Đ¸ŅŅ Đ´Đž адĐŧŅ–ĐŊŅ–ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ° ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, Ņ‰ĐžĐą ҁĐēиĐŊŅƒŅ‚Đ¸ ĐšĐžĐŗĐž", - "reset_pin_code_success": "PIN-ĐēОд ҃ҁĐŋŅ–ŅˆĐŊĐž ҁĐēиĐŊŅƒŅ‚Đž", + "reset_pin_code_success": "PIN-ĐēОд ҁĐēиĐŊŅƒŅ‚Đž", "reset_pin_code_with_password": "Ви СавĐļди ĐŧĐžĐļĐĩŅ‚Đĩ ҁĐēиĐŊŅƒŅ‚Đ¸ ŅĐ˛Ņ–Đš PIN-ĐēОд Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ ĐŋĐ°Ņ€ĐžĐģŅ", - "reset_sqlite": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐąĐ°ĐˇŅƒ даĐŊĐ¸Ņ… SQLite", + "reset_sqlite": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ ĐąĐ°ĐˇŅƒ даĐŊĐ¸Ņ… SQLite", "reset_sqlite_clear_app_data": "ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ даĐŊŅ–", - "reset_sqlite_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ Đ˛ŅŅ– даĐŊŅ–? ĐĻĐĩ видаĐģĐ¸Ņ‚ŅŒ Đ˛ŅŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ– виКдĐĩ С виКдĐĩ С Đ˛Đ°ŅˆĐžĐŗĐž ОйĐģŅ–ĐēĐžĐ˛ĐžĐŗĐž СаĐŋĐ¸ŅŅƒŅŽ", - "reset_sqlite_confirmation_note": "ĐŖĐ˛Đ°ĐŗĐ°: ВаĐŧ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ ĐŋŅ€ĐžĐŗŅ€Đ°Đŧ҃ ĐŋҖҁĐģŅ ĐžŅ‡Đ¸ŅŅ‚Đēи.", - "reset_sqlite_done": "ДаĐŊŅ– ĐąŅƒĐģĐž ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋĐĩŅ€ĐĩСаваĐŊŅ‚Đ°ĐļŅ‚Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°Đŧ҃ Ņ– СĐŊĐžĐ˛Ņƒ ŅƒĐ˛Ņ–ĐšĐ´Ņ–Ņ‚ŅŒ ҃ ŅĐ˛Ņ–Đš ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ.", - "reset_sqlite_success": "Đ‘Đ°ĐˇŅƒ даĐŊĐ¸Ņ… SQLite ҃ҁĐŋŅ–ŅˆĐŊĐž ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž", - "reset_to_default": "ĐĄĐēиĐŊŅƒŅ‚Đ¸ Đ´Đž ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Са СаĐŧĐžĐ˛Ņ‡ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ", - "resolution": "Đ ĐžĐˇĐ´Ņ–ĐģҌĐŊа Đ—Đ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŒ", + "reset_sqlite_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ даĐŊŅ– ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃? ĐŖŅŅ– ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐąŅƒĐ´Đĩ видаĐģĐĩĐŊĐž, а ҁĐĩаĐŊҁ — СавĐĩŅ€ŅˆĐĩĐŊĐž.", + "reset_sqlite_confirmation_note": "ĐŖĐ˛Đ°ĐŗĐ°: ВаĐŧ ĐŋĐžŅ‚Ņ€Ņ–ĐąĐŊĐž ĐąŅƒĐ´Đĩ ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē ĐŋҖҁĐģŅ ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐŊŅ.", + "reset_sqlite_done": "ДаĐŊŅ– ĐąŅƒĐģĐž ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Ņ–Ņ‚ŅŒ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē Ņ– СĐŊĐžĐ˛Ņƒ ŅƒĐ˛Ņ–ĐšĐ´Ņ–Ņ‚ŅŒ ҃ ŅĐ˛Ņ–Đš ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ.", + "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": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊиК Ņ„Đ°ĐšĐģ", + "restored_asset": "Đ’Ņ–Đ´ĐŊОвĐģĐĩĐŊĐž ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", "resume": "ĐŸŅ€ĐžĐ´ĐžĐ˛ĐļĐ¸Ņ‚Đ¸", "resume_paused_jobs": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ {count, plural, one {# ĐŋŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊĐĩ СавдаĐŊĐŊŅ} few {# ĐŋŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊŅ– СавдаĐŊĐŊŅ} many {# ĐŋŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊĐ¸Ņ… СавдаĐŊҌ} other {# ĐŋŅ€Đ¸ĐˇŅƒĐŋиĐŊĐĩĐŊĐ¸Ņ… СавдаĐŊҌ}}", "retry_upload": "ĐŸĐžĐ˛Ņ‚ĐžŅ€Đ¸Ņ‚Đ¸ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "review_duplicates": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", - "review_large_files": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ вĐĩĐģиĐēĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛", + "review_large_files": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ вĐĩĐģиĐēŅ– Ņ„Đ°ĐšĐģи", "role": "Đ ĐžĐģҌ", "role_editor": "Đ ĐĩдаĐēŅ‚ĐžŅ€", - "role_viewer": "ГĐģŅĐ´Đ°Ņ‡", - "running": "АĐēŅ‚Đ¸Đ˛ĐŊиК", + "role_viewer": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡", + "running": "ВиĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ", "save": "ЗбĐĩŅ€ĐĩĐŗŅ‚Đ¸", "save_to_gallery": "ЗбĐĩŅ€ĐĩĐŗŅ‚Đ¸ в ĐŗĐ°ĐģĐĩŅ€ĐĩŅŽ", "saved": "ЗбĐĩŅ€ĐĩĐļĐĩĐŊĐž", - "saved_api_key": "ЗбĐĩŅ€ĐĩĐļĐĩĐŊŅ– ĐēĐģŅŽŅ‡Ņ– API", + "saved_api_key": "КĐģŅŽŅ‡ API СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", "saved_profile": "ĐŸŅ€ĐžŅ„Ņ–ĐģҌ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", "saved_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", - "say_something": "ĐĄĐēаĐļŅ–Ņ‚ŅŒ Ņ‰Đž-ĐŊĐĩĐąŅƒĐ´ŅŒ", + "say_something": "НаĐŋĐ¸ŅˆŅ–Ņ‚ŅŒ Ņ‰ĐžŅŅŒ", "scaffold_body_error_occurred": "ВиĐŊиĐēĐģа ĐŋĐžĐŧиĐģĐēа", - "scan": "ĐĄĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", + "scaffold_body_error_unrecoverable": "ВиĐŊиĐēĐģа ĐēŅ€Đ¸Ņ‚Đ¸Ņ‡ĐŊа ĐŋĐžĐŧиĐģĐēа. ĐĐ°Đ´Ņ–ŅˆĐģŅ–Ņ‚ŅŒ ĐžĐŋĐ¸Ņ ĐŋĐžĐŧиĐģĐēи Ņ‚Đ° ҁ҂ĐĩĐē виĐēĐģиĐēŅ–Đ˛ ĐŊа Discord айО GitHub, Ņ‰ĐžĐą Đŧи ĐŧĐžĐŗĐģи Đ´ĐžĐŋĐžĐŧĐžĐŗŅ‚Đ¸. Đ¯ĐēŅ‰Đž ваĐŧ ĐŋĐžŅ€Đ°Đ´Đ¸Đģи, ви ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ даĐŊŅ– ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ ĐŊиĐļ҇Đĩ.", + "scan": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸", "scan_all_libraries": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", "scan_library": "ĐĄĐēаĐŊŅƒĐ˛Đ°Ņ‚Đ¸", "scan_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", "scanning": "ĐĄĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ", - "scanning_for_album": "ĐĄĐēаĐŊŅƒĐ˛Đ°ĐŊĐŊŅ аĐģŅŒĐąĐžĐŧ҃...", + "scanning_for_album": "ĐŸĐžŅˆŅƒĐē аĐģŅŒĐąĐžĐŧ҃â€Ļ", "search": "ĐŸĐžŅˆŅƒĐē", - "search_albums": "Đ¨ŅƒĐēĐ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", + "search_albums": "ĐŸĐžŅˆŅƒĐē аĐģŅŒĐąĐžĐŧŅ–Đ˛", "search_by_context": "ĐŸĐžŅˆŅƒĐē Са ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚ĐžĐŧ", "search_by_description": "ĐŸĐžŅˆŅƒĐē Са ĐžĐŋĐ¸ŅĐžĐŧ", - "search_by_description_example": "ĐŸĐžŅ…Ņ–Đ´ĐŊиК Đ´ĐĩĐŊҌ ҃ ХаĐŋŅ–", - "search_by_filename": "ĐŸĐžŅˆŅƒĐē Са ĐŊĐ°ĐˇĐ˛ĐžŅŽ айО Ņ€ĐžĐˇŅˆĐ¸Ņ€ĐĩĐŊĐŊŅĐŧ Ņ„Đ°ĐšĐģ҃", + "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_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_interval": "{start} — {end}", "search_filter_date_title": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", "search_filter_display_option_not_in_album": "НĐĩ в аĐģŅŒĐąĐžĐŧŅ–", - "search_filter_display_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", + "search_filter_display_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "search_filter_filename": "ĐŸĐžŅˆŅƒĐē Са ĐŊĐ°ĐˇĐ˛ĐžŅŽ Ņ„Đ°ĐšĐģ҃", - "search_filter_location": "ĐœŅ–ŅŅ†ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", - "search_filter_location_title": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐŧҖҁ҆ĐĩСĐŊĐ°Ņ…ĐžĐ´ĐļĐĩĐŊĐŊŅ", + "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_filter_star_rating": "Đ—ĐžŅ€ŅĐŊиК Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ", - "search_filter_tags_title": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Ņ‚ĐĩĐŗĐ¸", - "search_for": "Đ¨ŅƒĐēĐ°Ņ‚Đ¸ Đ´ĐģŅ", - "search_for_existing_person": "ĐŸĐžŅˆŅƒĐē ҖҁĐŊŅƒŅŽŅ‡ĐžŅ— ĐžŅĐžĐąĐ¸", + "search_filter_star_rating": "Đ ĐĩĐšŅ‚Đ¸ĐŊĐŗ ĐˇŅ–Ņ€ĐēаĐŧи", + "search_filter_tags_title": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ Ņ‚ĐĩĐŗĐ¸", + "search_for": "Đ¨ŅƒĐēĐ°Ņ‚Đ¸", + "search_for_existing_person": "ĐŸĐžŅˆŅƒĐē ĐŊĐ°ŅĐ˛ĐŊĐžŅ— ĐģŅŽĐ´Đ¸ĐŊи", "search_no_more_result": "Đ‘Ņ–ĐģҌ҈Đĩ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Ņ–Đ˛ ĐŊĐĩĐŧĐ°Ņ”", "search_no_people": "НĐĩĐŧĐ°Ņ” ĐģŅŽĐ´ĐĩĐš", - "search_no_people_named": "НĐĩĐŧĐ°Ņ” ĐžŅŅ–Đą С Ņ–ĐŧĐĩĐŊĐĩĐŧ \"{name}\"", + "search_no_people_named": "НĐĩĐŧĐ°Ņ” ĐģŅŽĐ´ĐĩĐš С Ņ–ĐŧĐĩĐŊĐĩĐŧ ÂĢ{name}Âģ", "search_no_result": "Đ ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Ņ–Đ˛ ĐŊĐĩ СĐŊаКдĐĩĐŊĐž, ҁĐŋŅ€ĐžĐąŅƒĐšŅ‚Đĩ Ņ–ĐŊŅˆĐ¸Đš СаĐŋĐ¸Ņ‚ айО ĐēĐžĐŧĐąŅ–ĐŊĐ°Ņ†Ņ–ŅŽ", - "search_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐŋĐžŅˆŅƒĐē҃", + "search_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐŋĐžŅˆŅƒĐē҃", "search_page_categories": "ĐšĐ°Ņ‚ĐĩĐŗĐžŅ€Ņ–Ņ—", - "search_page_motion_photos": "Đ–Đ¸Đ˛Ņ– Ņ„ĐžŅ‚Đž", - "search_page_no_objects": "НĐĩĐŧĐ°Ņ” Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ— ĐŋŅ€Đž Ņ„Đ°ĐšĐģи", - "search_page_no_places": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž ĐŧŅ–ŅŅ†Ņ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊа", + "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_view_all_button": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ Đ˛ŅĐĩ", "search_page_your_activity": "Đ’Đ°ŅˆŅ– Đ´Ņ–Ņ—", "search_page_your_map": "Đ’Đ°ŅˆĐ° ĐŧаĐŋа", - "search_people": "Đ¨ŅƒĐēĐ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", + "search_people": "ĐŸĐžŅˆŅƒĐē ĐģŅŽĐ´ĐĩĐš", "search_places": "ĐŸĐžŅˆŅƒĐē ĐŧŅ–ŅŅ†ŅŒ", - "search_rating": "ĐŸĐžŅˆŅƒĐē Са Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗĐžĐŧ...", + "search_rating": "ĐŸĐžŅˆŅƒĐē Са Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗĐžĐŧâ€Ļ", "search_result_page_new_search_hint": "Новий ĐŋĐžŅˆŅƒĐē", - "search_settings": "ĐŸĐžŅˆŅƒĐē ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "search_state": "ĐŸĐžŅˆŅƒĐē Ņ€ĐĩĐŗŅ–ĐžĐŊ҃...", - "search_suggestion_list_smart_search_hint_1": "Đ ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐē ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž Са СаĐŧĐžĐ˛Ņ‡ŅƒĐ˛Đ°ĐŊĐŊŅĐŧ, Đ´ĐģŅ ĐŋĐžŅˆŅƒĐē҃ Са ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ. ", + "search_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ĐŋĐžŅˆŅƒĐē҃", + "search_state": "ĐŸĐžŅˆŅƒĐē Ņ€ĐĩĐŗŅ–ĐžĐŊ҃â€Ļ", + "search_suggestion_list_smart_search_hint_1": "Đ ĐžĐˇŅƒĐŧĐŊиК ĐŋĐžŅˆŅƒĐē ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž Ņ‚Đ¸ĐŋОвО, Đ´ĐģŅ ĐŋĐžŅˆŅƒĐē҃ Са ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊиĐŧи виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐšŅ‚Đĩ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ ", "search_suggestion_list_smart_search_hint_2": "m:Đ˛Đ°Ņˆ-ĐŋĐžŅˆŅƒĐēОвиК-Ņ‚ĐĩŅ€ĐŧŅ–ĐŊ", - "search_tags": "ĐŸĐžŅˆŅƒĐē Ņ‚ĐĩĐŗŅ–Đ˛...", - "search_timezone": "ĐŸĐžŅˆŅƒĐē Ņ‡Đ°ŅĐžĐ˛ĐžĐŗĐž ĐŋĐžŅŅŅƒ...", + "search_tags": "ĐŸĐžŅˆŅƒĐē Ņ‚ĐĩĐŗŅ–Đ˛â€Ļ", + "search_timezone": "ĐŸĐžŅˆŅƒĐē Ņ‡Đ°ŅĐžĐ˛ĐžĐŗĐž ĐŋĐžŅŅŅƒâ€Ļ", "search_type": "ĐĸиĐŋ ĐŋĐžŅˆŅƒĐē҃", "search_your_photos": "ĐŸĐžŅˆŅƒĐē ҁĐĩŅ€ĐĩĐ´ Đ˛Đ°ŅˆĐ¸Ņ… Ņ„ĐžŅ‚Đž", - "searching_locales": "ĐĸŅ€Đ¸Đ˛Đ°Ņ” ĐŋĐžŅˆŅƒĐē ĐŋĐĩŅ€ĐĩĐēĐģĐ°Đ´Ņ–Đ˛...", + "searching_locales": "ĐŸĐžŅˆŅƒĐē ĐģĐžĐēаĐģĐĩĐšâ€Ļ", "second": "ĐĄĐĩĐē҃ĐŊда", "see_all_people": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ Đ˛ŅŅ–Ņ… ĐģŅŽĐ´ĐĩĐš", "select": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸", "select_album": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", - "select_album_cover": "ĐžĐąŅ€Đ°Ņ‚Đ¸ ОйĐēĐģадиĐŊĐē҃ аĐģŅŒĐąĐžĐŧ҃", + "select_album_cover": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ОйĐēĐģадиĐŊĐē҃ аĐģŅŒĐąĐžĐŧ҃", "select_albums": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", "select_all": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Đ˛ŅĐĩ", "select_all_duplicates": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Đ˛ŅŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", "select_all_in": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Đ˛ŅĐĩ в {group}", "select_avatar_color": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐēĐžĐģŅ–Ņ€ Đ°Đ˛Đ°Ņ‚Đ°Ņ€Đ°", "select_count": "{count, plural, one {Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ #} few {Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ #} many {Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ #} other {Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ #}}", - "select_cutoff_date": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐēŅ–ĐŊ҆ĐĩĐ˛Ņƒ Đ´Đ°Ņ‚Ņƒ", - "select_face": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ОйĐģĐ¸Ņ‡Ņ‡Ņ", - "select_featured_photo": "ĐžĐąŅ€Đ°Ņ‚Đ¸ ĐžĐąŅ€Đ°ĐŊĐĩ Ņ„ĐžŅ‚Đž", - "select_from_computer": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ С ĐēĐžĐŧĐŋ'ŅŽŅ‚ĐĩŅ€Đ°", - "select_keep_all": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ Đ˛ŅĐĩ ĐžĐąŅ€Đ°ĐŊĐĩ", + "select_cutoff_date": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐēŅ–ĐŊ҆ĐĩĐ˛Ņƒ Đ´Đ°Ņ‚Ņƒ", + "select_face": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "select_featured_photo": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐŗĐžĐģОвĐŊĐĩ Ņ„ĐžŅ‚Đž", + "select_from_computer": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ С ĐēĐžĐŧĐŋ'ŅŽŅ‚ĐĩŅ€Đ°", + "select_keep_all": "ЗаĐģĐ¸ŅˆĐ¸Ņ‚Đ¸ Đ˛ŅŅ– Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", "select_library_owner": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ вĐģĐ°ŅĐŊиĐēа ĐąŅ–ĐąĐģŅ–ĐžŅ‚ĐĩĐēи", - "select_new_face": "ĐžĐąŅ€Đ°Ņ‚Đ¸ ĐŊОвĐĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "select_new_face": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐŊОвĐĩ ОйĐģĐ¸Ņ‡Ņ‡Ņ", "select_people": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", - "select_person": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐžŅĐžĐąŅƒ", - "select_person_to_tag": "ВибĐĩŅ€Ņ–Ņ‚ŅŒ ĐģŅŽĐ´Đ¸ĐŊ҃ Đ´ĐģŅ ĐŋОСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ", + "select_person": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", + "select_person_to_tag": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃ Đ´ĐģŅ ĐŋОСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ", "select_photos": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž", - "select_trash_all": "ВидаĐģĐ¸Ņ‚Đ¸ Đ˛ŅĐĩ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐĩ", + "select_trash_all": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ŅŅ– Đ´Đž ĐēĐžŅˆĐ¸Đēа", "select_user_for_sharing_page_err_album": "НĐĩ вдаĐģĐžŅŅ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧ", - "selected": "ĐžĐąŅ€Đ°ĐŊĐž", - "selected_count": "{count, plural, one {# ĐžĐąŅ€Đ°ĐŊиК} few {# ĐžĐąŅ€Đ°ĐŊŅ–} many {# ĐžĐąŅ€Đ°ĐŊĐ¸Ņ…} other {# ĐžĐąŅ€Đ°ĐŊĐ¸Ņ…}}", - "selected_gps_coordinates": "Đ’Đ¸ĐąŅ€Đ°ĐŊŅ– ĐēĐžĐžŅ€Đ´Đ¸ĐŊĐ°Ņ‚Đ¸", + "selected": "Đ’Đ¸ĐąŅ€Đ°ĐŊĐž", + "selected_count": "{count, plural, one {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} few {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} many {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž} other {# Đ˛Đ¸ĐąŅ€Đ°ĐŊĐž}}", + "selected_gps_coordinates": "Đ’Đ¸ĐąŅ€Đ°ĐŊŅ– GPS-ĐēĐžĐžŅ€Đ´Đ¸ĐŊĐ°Ņ‚Đ¸", "send_message": "ĐĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸ ĐŋĐžĐ˛Ņ–Đ´ĐžĐŧĐģĐĩĐŊĐŊŅ", - "send_welcome_email": "ĐĐ°Đ´Ņ–ŅˆĐģŅ–Ņ‚ŅŒ Đ˛Ņ–Ņ‚Đ°ĐģҌĐŊиК ĐģĐ¸ŅŅ‚", - "server_endpoint": "ĐĐ´Ņ€ĐĩŅĐ° ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ", + "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_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_navigation_title": "ĐĐ°Đ˛Ņ–ĐŗĐ°Ņ†Ņ–Ņ ĐŋĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅŅ…", - "setting_image_viewer_help": "ПовĐŊĐžĐĩĐēŅ€Đ°ĐŊĐŊиК ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡ ҁĐŋĐžŅ‡Đ°Ņ‚Đē҃ СаваĐŊŅ‚Đ°ĐļŅƒŅ” ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Đ´ĐģŅ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ в ĐŊĐ¸ĐˇŅŒĐēŅ–Đš Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊŅ–Đš ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ–, ĐŋĐžŅ‚Ņ–Đŧ СаваĐŊŅ‚Đ°ĐļŅƒŅ” ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ в СĐŧĐĩĐŊ҈ĐĩĐŊŅ–Đš Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊŅ–Đš ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ– Đ˛Ņ–Đ´ĐŊĐžŅĐŊĐž ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ҃ (ŅĐēŅ‰Đž вĐēĐģŅŽŅ‡ĐĩĐŊĐž) Ņ– ĐˇŅ€ĐĩŅˆŅ‚ĐžŅŽ СаваĐŊŅ‚Đ°ĐļŅƒŅ” ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ (ŅĐēŅ‰Đž вĐēĐģŅŽŅ‡ĐĩĐŊĐž).", - "setting_image_viewer_original_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Đ´ĐģŅ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ С ĐŋОвĐŊĐžŅŽ Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅŽ ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŽ (вĐĩĐģиĐēĐĩ!). ВиĐŧĐēĐŊŅƒŅ‚Đ¸, Ņ‰ĐžĐą СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ даĐŊĐ¸Ņ… (ŅĐē ҇ĐĩŅ€ĐĩС ĐŧĐĩŅ€ĐĩĐļ҃, Ņ‚Đ°Đē Ņ– ĐŊа ĐēĐĩŅˆŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ).", + "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_navigation_enable_subtitle": "Đ¯ĐēŅ‰Đž ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž, ви ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´Đ¸Ņ‚Đ¸ Đ´Đž ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅŒĐžĐŗĐž айО ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ, ĐŊĐ°Ņ‚Đ¸ŅĐēĐ°ŅŽŅ‡Đ¸ ĐŊа ĐēŅ€Đ°ĐšĐŊŅŽ ĐģŅ–Đ˛Ņƒ айО ĐŋŅ€Đ°Đ˛Ņƒ Ņ‡Đ˛ĐĩŅ€Ņ‚ŅŒ ĐĩĐēŅ€Đ°ĐŊа.", + "setting_image_navigation_enable_title": "ĐĸĐžŅ€ĐēĐŊŅ–Ņ‚ŅŒŅŅ, Ņ‰ĐžĐą ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", + "setting_image_navigation_title": "ĐĐ°Đ˛Ņ–ĐŗĐ°Ņ†Ņ–Ņ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅĐŧи", + "setting_image_viewer_help": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´Đ°Ņ‡ ҁĐŋĐžŅ‡Đ°Ņ‚Đē҃ СаваĐŊŅ‚Đ°ĐļŅƒŅ” ĐŧаĐģ҃ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Ņƒ, ĐŋĐžŅ‚Ņ–Đŧ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´ ҁĐĩŅ€ĐĩĐ´ĐŊŅŒĐžŅ— Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅ— ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ– (ŅĐēŅ‰Đž ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž) Ņ– ĐˇŅ€ĐĩŅˆŅ‚ĐžŅŽ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ (ŅĐēŅ‰Đž ŅƒĐ˛Ņ–ĐŧĐēĐŊĐĩĐŊĐž).", + "setting_image_viewer_original_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą СаваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐĩ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ С ĐŋОвĐŊĐžŅŽ Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅŽ ĐˇĐ´Đ°Ņ‚ĐŊŅ–ŅŅ‚ŅŽ (вĐĩĐģиĐēĐĩ!). ВиĐŧĐēĐŊŅ–Ņ‚ŅŒ, Ņ‰ĐžĐą СĐŧĐĩĐŊŅˆĐ¸Ņ‚Đ¸ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ даĐŊĐ¸Ņ… (ŅĐē ҇ĐĩŅ€ĐĩС ĐŧĐĩŅ€ĐĩĐļ҃, Ņ‚Đ°Đē Ņ– в ĐēĐĩŅˆŅ– ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅŽ).", "setting_image_viewer_original_title": "ЗаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐĩ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", - "setting_image_viewer_preview_subtitle": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Đ´ĐģŅ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ҁĐĩŅ€ĐĩĐ´ĐŊŅŒĐžŅ— Ņ€ĐžĐˇĐ´Ņ–ĐģҌĐŊĐžŅ— ĐˇĐ´Đ°Ņ‚ĐŊĐžŅŅ‚Ņ–. ВиĐŧĐēĐŊŅƒŅ‚Đ¸, Ņ‰ĐžĐą СаваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ айО виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ҂ҖĐģҌĐēи ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Ņƒ.", + "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_failures_grace_period": "ĐĄĐŋĐžĐ˛Ņ–Ņ‰Đ°Ņ‚Đ¸ ĐŋŅ€Đž ĐŋĐžĐŧиĐģĐēи Ņ„ĐžĐŊĐžĐ˛ĐžĐŗĐž Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ: {duration}", + "setting_notifications_notify_hours": "{count, plural, one {# ĐŗĐžĐ´Đ¸ĐŊа} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊ}}", "setting_notifications_notify_immediately": "ĐŊĐĩĐŗĐ°ĐšĐŊĐž", - "setting_notifications_notify_minutes": "{count} Ņ…Đ˛Đ¸ĐģиĐŊ", + "setting_notifications_notify_minutes": "{count, plural, one {# Ņ…Đ˛Đ¸ĐģиĐŊа} few {# Ņ…Đ˛Đ¸ĐģиĐŊи} many {# Ņ…Đ˛Đ¸ĐģиĐŊ} other {# Ņ…Đ˛Đ¸ĐģиĐŊ}}", "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_notifications_notify_seconds": "{count, plural, one {# ҁĐĩĐē҃ĐŊда} few {# ҁĐĩĐē҃ĐŊди} many {# ҁĐĩĐē҃ĐŊĐ´} other {# ҁĐĩĐē҃ĐŊĐ´}}", + "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_subtitle": "ĐŸŅ–Đ´ Ņ‡Đ°Ņ ĐŋĐžŅ‚ĐžĐēĐžĐ˛ĐžĐŗĐž Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž Ņ–Đˇ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģ, ĐŊĐ°Đ˛Ņ–Ņ‚ŅŒ ŅĐēŅ‰Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐĩ Ņ‚Ņ€Đ°ĐŊҁĐēĐžĐ´ŅƒĐ˛Đ°ĐŊĐŊŅ. МоĐļĐĩ ĐŋŅ€Đ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ Đ´Đž ĐąŅƒŅ„ĐĩŅ€Đ¸ĐˇĐ°Ņ†Ņ–Ņ—. Đ’Ņ–Đ´ĐĩĐž, Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐģĐžĐēаĐģҌĐŊĐž, Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ŅŽŅŽŅ‚ŅŒŅŅ в ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊŅ–Đš ŅĐēĐžŅŅ‚Ņ–, ĐŊĐĩСаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ Ņ†ŅŒĐžĐŗĐž ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ.", "setting_video_viewer_original_video_title": "ĐŸŅ€Đ¸ĐŧŅƒŅĐžĐ˛Đž Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐžŅ€Đ¸ĐŗŅ–ĐŊаĐģҌĐŊĐĩ Đ˛Ņ–Đ´ĐĩĐž", "settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "settings_require_restart": "ПĐĩŅ€ĐĩСаваĐŊŅ‚Đ°ĐļŅ‚Đĩ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐžĐē Đ´ĐģŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°ĐŊĐŊŅ Ņ†ŅŒĐžĐŗĐž ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", - "settings_saved": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ СйĐĩŅ€ĐĩĐļĐĩĐŊŅ–", + "settings_require_restart": "ПĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Ņ–Ņ‚ŅŒ Immich, Ņ‰ĐžĐą ĐˇĐ°ŅŅ‚ĐžŅŅƒĐ˛Đ°Ņ‚Đ¸ ҆Đĩ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ", + "settings_saved": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ СйĐĩŅ€ĐĩĐļĐĩĐŊĐž", "setup_pin_code": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ PIN-ĐēОд", - "share": "ĐŸĐžŅˆĐ¸Ņ€Đ¸Ņ‚Đ¸", - "share_action_prompt": "{count} Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ĐŊĐ°Đ´Ņ–ŅĐģаĐŊĐž", + "share": "ĐŸĐžĐ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ", + "share_action_prompt": "НадаĐŊĐž ҁĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "share_add_photos": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž", - "share_assets_selected": "{count} ĐžĐąŅ€Đ°ĐŊĐž", - "share_dialog_preparing": "ĐŸŅ–Đ´ĐŗĐžŅ‚ĐžĐ˛Đēа...", + "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_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_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_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_days": "{count, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}", "shared_link_edit_expire_after_option_hour": "1 ĐŗĐžĐ´Đ¸ĐŊ҃", - "shared_link_edit_expire_after_option_hours": "{count} ĐŗĐžĐ´Đ¸ĐŊ", + "shared_link_edit_expire_after_option_hours": "{count, plural, one {# ĐŗĐžĐ´Đ¸ĐŊ҃} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊ}}", "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_expire_after_option_minutes": "{count, plural, one {# Ņ…Đ˛Đ¸ĐģиĐŊ҃} few {# Ņ…Đ˛Đ¸ĐģиĐŊи} many {# Ņ…Đ˛Đ¸ĐģиĐŊ} other {# Ņ…Đ˛Đ¸ĐģиĐŊ}}", + "shared_link_edit_expire_after_option_months": "{count, plural, one {# ĐŧŅ–ŅŅŅ†ŅŒ} few {# ĐŧŅ–ŅŅŅ†Ņ–} many {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛} other {# ĐŧŅ–ŅŅŅ†Ņ–Đ˛}}", + "shared_link_edit_expire_after_option_year": "{count, plural, one {# ҀҖĐē} few {# Ņ€ĐžĐēи} many {# Ņ€ĐžĐēŅ–Đ˛} other {# Ņ€ĐžĐēŅ–Đ˛}}", "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_error_server_url_fetch": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ URL ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", + "shared_link_expires_day": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}", + "shared_link_expires_days": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}", + "shared_link_expires_hour": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# ĐŗĐžĐ´Đ¸ĐŊ҃} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊ}}", + "shared_link_expires_hours": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# ĐŗĐžĐ´Đ¸ĐŊ҃} few {# ĐŗĐžĐ´Đ¸ĐŊи} many {# ĐŗĐžĐ´Đ¸ĐŊ} other {# ĐŗĐžĐ´Đ¸ĐŊ}}", + "shared_link_expires_minute": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# Ņ…Đ˛Đ¸ĐģиĐŊ҃} few {# Ņ…Đ˛Đ¸ĐģиĐŊи} many {# Ņ…Đ˛Đ¸ĐģиĐŊ} other {# Ņ…Đ˛Đ¸ĐģиĐŊ}}", + "shared_link_expires_minutes": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# Ņ…Đ˛Đ¸ĐģиĐŊ҃} few {# Ņ…Đ˛Đ¸ĐģиĐŊи} many {# Ņ…Đ˛Đ¸ĐģиĐŊ} other {# Ņ…Đ˛Đ¸ĐģиĐŊ}}", "shared_link_expires_never": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ∞", - "shared_link_expires_second": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count} ҁĐĩĐē҃ĐŊĐ´Ņƒ", - "shared_link_expires_seconds": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count} ҁĐĩĐē҃ĐŊĐ´", + "shared_link_expires_second": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# ҁĐĩĐē҃ĐŊĐ´Ņƒ} few {# ҁĐĩĐē҃ĐŊди} many {# ҁĐĩĐē҃ĐŊĐ´} other {# ҁĐĩĐē҃ĐŊĐ´}}", + "shared_link_expires_seconds": "ЗаĐēŅ–ĐŊŅ‡ŅƒŅ”Ņ‚ŅŒŅŅ ҇ĐĩŅ€ĐĩС {count, plural, one {# ҁĐĩĐē҃ĐŊĐ´Ņƒ} few {# ҁĐĩĐē҃ĐŊди} many {# ҁĐĩĐē҃ĐŊĐ´} other {# ҁĐĩĐē҃ĐŊĐ´}}", "shared_link_individual_shared": "ІĐŊĐ´Đ¸Đ˛Ņ–Đ´ŅƒĐ°ĐģҌĐŊиК ҁĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ", - "shared_link_info_chip_metadata": "EXIF", + "shared_link_info_chip_metadata": "Exif", "shared_link_manage_links": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐŋŅ–ĐģҌĐŊиĐŧи ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧи", - "shared_link_options": "ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… ĐŋĐžŅĐ¸ĐģаĐŊҌ", - "shared_link_password_description": "ВиĐŧĐ°ĐŗĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ Đ´ĐģŅ Đ´ĐžŅŅ‚ŅƒĐŋ҃ Đ´Đž Ņ†ŅŒĐžĐŗĐž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", + "shared_link_options": "Đ’Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… ĐŋĐžŅĐ¸ĐģаĐŊҌ", + "shared_link_password_description": "ЗаĐŋĐ¸Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ, Ņ‰ĐžĐą ĐžŅ‚Ņ€Đ¸ĐŧĐ°Ņ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž Ņ†ŅŒĐžĐŗĐž ҁĐŋŅ–ĐģҌĐŊĐžĐŗĐž ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "shared_links": "ĐĄĐŋŅ–ĐģҌĐŊŅ– ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "shared_links_description": "Đ”Ņ–ĐģŅ–Ņ‚ŅŒŅŅ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Са ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧ", - "shared_photos_and_videos_count": "{assetCount, plural, other {# ҁĐŋŅ–ĐģҌĐŊŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž.}}", - "shared_with_me": "Đ”ĐžŅŅ‚ŅƒĐŋĐŊŅ– ĐŧĐĩĐŊŅ–", + "shared_photos_and_videos_count": "{assetCount, plural, one {# ҁĐŋŅ–ĐģҌĐŊĐĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž} few {# ҁĐŋŅ–ĐģҌĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž} many {# ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž} other {# ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž}}", + "shared_with_me": "ĐĄĐŋŅ–ĐģҌĐŊŅ– ĐˇŅ– ĐŧĐŊĐžŅŽ", "shared_with_partner": "ĐĄĐŋŅ–ĐģҌĐŊĐž С {partner}", - "sharing": "ĐĄĐŋŅ–ĐģҌĐŊŅ–", - "sharing_enter_password": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ввĐĩĐ´Ņ–Ņ‚ŅŒ ĐŋĐ°Ņ€ĐžĐģҌ Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´Ņƒ ҆ҖҔҗ ŅŅ‚ĐžŅ€Ņ–ĐŊĐēи.", + "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": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ аĐģŅŒĐąĐžĐŧ҃", + "shift_to_permanent_delete": "ĐŊĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ ⇧, Ņ‰ĐžĐą видаĐģĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ ĐŊаСавĐļди", + "show_album_options": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ҃", "show_albums": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", "show_all_people": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Đ˛ŅŅ–Ņ… ĐģŅŽĐ´ĐĩĐš", "show_and_hide_people": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Ņ‚Đ° ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", "show_file_location": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Ņ€ĐžĐˇŅ‚Đ°ŅˆŅƒĐ˛Đ°ĐŊĐŊŅ Ņ„Đ°ĐšĐģ҃", "show_gallery": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŗĐ°ĐģĐĩŅ€ĐĩŅŽ", "show_hidden_people": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°ĐŊĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš", - "show_in_timeline": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŊа Ņ‡Đ°ŅĐžĐ˛Ņ–Đš ҈ĐēаĐģŅ–", - "show_in_timeline_setting_description": "ПоĐēĐ°ĐˇŅƒĐšŅ‚Đĩ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Ņ†ŅŒĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ҃ ŅĐ˛ĐžŅ—Đš ҁ҂ҀҖ҇҆Җ", + "show_in_timeline": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ в Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ—", + "show_in_timeline_setting_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Ņ†ŅŒĐžĐŗĐž ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° ҃ Đ˛Đ°ŅˆŅ–Đš Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ—", "show_keyboard_shortcuts": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ҁĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ ĐēĐģĐ°Đ˛Ņ–Ņˆ", "show_metadata": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊŅ–", "show_or_hide_info": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ айО ĐŋŅ€Đ¸Ņ…ĐžĐ˛Đ°Ņ‚Đ¸ Ņ–ĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–ŅŽ", "show_password": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "show_person_options": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐģŅŽĐ´Đ¸ĐŊи", - "show_progress_bar": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Ņ–ĐŊдиĐēĐ°Ņ‚ĐžŅ€ ĐŋŅ€ĐžĐŗŅ€Đĩҁ҃", + "show_person_options": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊи", + "show_progress_bar": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Ņ–ĐŊдиĐēĐ°Ņ‚ĐžŅ€ ĐŋĐžŅŅ‚ŅƒĐŋ҃", "show_schema": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ҁ҅ĐĩĐŧ҃", - "show_search_options": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ ĐŋĐžŅˆŅƒĐē҃", + "show_search_options": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Đ˛Đ°Ņ€Ņ–Đ°ĐŊŅ‚Đ¸ ĐŋĐžŅˆŅƒĐē҃", "show_shared_links": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊŅ– ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", - "show_slideshow_transition": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩŅ…Ņ–Đ´ ҁĐģаКд-ŅˆĐžŅƒ", - "show_supporter_badge": "ЗĐŊĐ°Ņ‡ĐžĐē ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēи", - "show_supporter_badge_description": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ СĐŊĐ°Ņ‡ĐžĐē ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēи", + "show_slideshow_transition": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩŅ…Ņ–Đ´ ҁĐģаКд-ŅˆĐžŅƒ", + "show_supporter_badge": "ЗĐŊĐ°Ņ‡ĐžĐē ĐŋŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐēа", + "show_supporter_badge_description": "ПоĐēĐ°ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ СĐŊĐ°Ņ‡ĐžĐē ĐŋŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐēа", "show_text_recognition": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ", "show_text_search_menu": "ПоĐēĐ°ĐˇĐ°Ņ‚Đ¸ ĐŧĐĩĐŊŅŽ Ņ‚ĐĩĐēŅŅ‚ĐžĐ˛ĐžĐŗĐž ĐŋĐžŅˆŅƒĐē҃", "shuffle": "ПĐĩŅ€ĐĩĐŧŅ–ŅˆĐ°Ņ‚Đ¸", "sidebar": "Đ‘Ņ–Ņ‡ĐŊа ĐŋаĐŊĐĩĐģҌ", - "sidebar_display_description": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐˇĐ¸Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´ ҃ ĐąŅ–Ņ‡ĐŊŅ–Đš ĐŋаĐŊĐĩĐģŅ–", - "sign_out": "Đ’Đ¸Ņ…Ņ–Đ´", + "sidebar_display_description": "Đ’Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐ°Ņ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ ĐŊа ĐŋĐĩŅ€ĐĩĐŗĐģŅĐ´ ҃ ĐąŅ–Ņ‡ĐŊŅ–Đš ĐŋаĐŊĐĩĐģŅ–", + "sign_out": "Đ’Đ¸ĐšŅ‚Đ¸", "sign_up": "Đ—Đ°Ņ€ĐĩŅ”ŅŅ‚Ņ€ŅƒĐ˛Đ°Ņ‚Đ¸ŅŅ", "size": "РОСĐŧŅ–Ņ€", "skip_to_content": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž вĐŧŅ–ŅŅ‚Ņƒ", "skip_to_folders": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž ĐŋаĐŋĐžĐē", "skip_to_tags": "ПĐĩŅ€ĐĩĐšŅ‚Đ¸ Đ´Đž Ņ‚ĐĩĐŗŅ–Đ˛", - "slideshow": "ĐĄĐģĐ°ĐšĐ´ŅˆĐžŅƒ", - "slideshow_repeat": "ĐŸĐžĐ˛Ņ‚ĐžŅ€Đ¸Ņ‚Đ¸ ҁĐģаКд-ŅˆĐžŅƒ", + "slideshow": "ĐĄĐģаКд-ŅˆĐžŅƒ", + "slideshow_repeat": "ĐŸĐžĐ˛Ņ‚ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ҁĐģаКд-ŅˆĐžŅƒ", "slideshow_repeat_description": "ПовĐĩŅ€ĐŊĐĩĐŊĐŊŅ Đ´Đž ĐŋĐžŅ‡Đ°Ņ‚Đē҃ ĐŋҖҁĐģŅ СавĐĩŅ€ŅˆĐĩĐŊĐŊŅ ҁĐģаКд-ŅˆĐžŅƒ", "slideshow_settings": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ ҁĐģаКд-ŅˆĐžŅƒ", - "sort_albums_by": "ĐĄĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи Са...", + "sort_albums_by": "ĐĄĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи Саâ€Ļ", "sort_created": "Đ”Đ°Ņ‚Đ° ŅŅ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ", - "sort_items": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ Ņ„Đ°ĐšĐģŅ–Đ˛", + "sort_items": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "sort_modified": "Đ”Đ°Ņ‚Đ° СĐŧŅ–ĐŊи", "sort_newest": "НайĐŊĐžĐ˛Ņ–ŅˆĐĩ Ņ„ĐžŅ‚Đž", - "sort_oldest": "ĐĄŅ‚Đ°Ņ€Ņ– Ņ„ĐžŅ‚Đž", + "sort_oldest": "ĐĐ°ĐšŅŅ‚Đ°Ņ€Ņ–ŅˆĐĩ Ņ„ĐžŅ‚Đž", "sort_people_by_similarity": "ĐĄĐžŅ€Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš Са ŅŅ…ĐžĐļŅ–ŅŅ‚ŅŽ", - "sort_recent": "НĐĩŅ‰ĐžĐ´Đ°Đ˛ĐŊŅ–", - "sort_title": "Đ—Đ°ĐŗĐžĐģОвОĐē", + "sort_recent": "ĐĐ°ĐšŅĐ˛Ņ–ĐļŅ–ŅˆĐĩ Ņ„ĐžŅ‚Đž", + "sort_title": "Назва", "source": "ДĐļĐĩŅ€ĐĩĐģĐž", - "stack": "ĐŖ ŅŅ‚ĐžĐŋĐē҃", - "stack_action_prompt": "Đ—ĐŗŅ€ŅƒĐŋОваĐŊĐž: {count}", + "stack": "Đ—ĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸", + "stack_action_prompt": "{count} ĐˇĐŗŅ€ŅƒĐŋОваĐŊĐž", "stack_duplicates": "Đ“Ņ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", "stack_select_one_photo": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ОдĐŊĐĩ ĐžŅĐŊОвĐŊĐĩ Ņ„ĐžŅ‚Đž Đ´ĐģŅ ĐŗŅ€ŅƒĐŋи", - "stack_selected_photos": "Đ—ĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ ĐžĐąŅ€Đ°ĐŊŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—", - "stacked_assets_count": "Đ—ĐŗŅ€ŅƒĐŋОваĐŊĐž {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "stack_selected_photos": "Đ—ĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– Ņ„ĐžŅ‚Đž", + "stacked_assets_count": "Đ—ĐŗŅ€ŅƒĐŋОваĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "stacktrace": "ĐĄŅ‚ĐĩĐē виĐēĐģиĐēŅ–Đ˛", - "start": "ĐĄŅ‚Đ°Ņ€Ņ‚", + "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": "ĐŸŅ€Đ¸ĐŋиĐŊĐ¸Ņ‚Đ¸ Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ ŅĐ˛ĐžŅ—Đŧи Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–ŅĐŧи С Ņ†Đ¸Đŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐŧ", + "stop_motion_photo": "Đ—ŅƒĐŋиĐŊĐ¸Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Ņ„ĐžŅ‚Đž", + "stop_photo_sharing": "ĐŸŅ€Đ¸ĐŋиĐŊĐ¸Ņ‚Đ¸ ҁĐŋŅ–ĐģҌĐŊиК Đ´ĐžŅŅ‚ŅƒĐŋ Đ´Đž Đ˛Đ°ŅˆĐ¸Ņ… Ņ„ĐžŅ‚Đž?", + "stop_photo_sharing_description": "{partner} ĐąŅ–ĐģҌ҈Đĩ ĐŊĐĩ ĐŧĐ°Ņ‚Đ¸ĐŧĐĩ Đ´ĐžŅŅ‚ŅƒĐŋ҃ Đ´Đž Đ˛Đ°ŅˆĐ¸Ņ… Ņ„ĐžŅ‚Đž.", + "stop_sharing_photos_with_user": "ĐŸŅ€Đ¸ĐŋиĐŊĐ¸Ņ‚Đ¸ Đ´Ņ–ĐģĐ¸Ņ‚Đ¸ŅŅ ŅĐ˛ĐžŅ—Đŧи Ņ„ĐžŅ‚Đž С Ņ†Đ¸Đŧ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡ĐĩĐŧ", "storage": "ĐĄŅ…ĐžĐ˛Đ¸Ņ‰Đĩ", - "storage_label": "ĐœŅ–Ņ‚Đēа Đ´ĐģŅ СйĐĩŅ€Ņ–ĐŗĐ°ĐŊĐŊŅ", - "storage_quota": "ĐžĐąŅŅĐŗ ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", + "storage_label": "ĐœŅ–Ņ‚Đēа ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", + "storage_quota": "ĐšĐ˛ĐžŅ‚Đ° ŅŅ…ĐžĐ˛Đ¸Ņ‰Đ°", "storage_usage": "{used} С {available} виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐž", - "submit": "ĐŸŅ–Đ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚Đ¸", - "success": "ĐŖŅĐŋŅ–ŅˆĐŊĐž", + "submit": "ĐĐ°Đ´Ņ–ŅĐģĐ°Ņ‚Đ¸", + "success": "Đ“ĐžŅ‚ĐžĐ˛Đž", "suggestions": "ĐŸŅ€ĐžĐŋĐžĐˇĐ¸Ņ†Ņ–Ņ—", "sunrise_on_the_beach": "ĐĄĐ˛Ņ–Ņ‚Đ°ĐŊĐžĐē ĐŊа ĐŋĐģŅĐļŅ–", "support": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēа", "support_and_feedback": "ĐŸŅ–Đ´Ņ‚Ņ€Đ¸ĐŧĐēа Ņ‚Đ° ĐˇĐ˛ĐžŅ€ĐžŅ‚ĐŊиК Св'ŅĐˇĐžĐē", - "support_third_party_description": "Đ’Đ°ŅˆŅƒ ŅƒŅŅ‚Đ°ĐŊОвĐē҃ Immich ĐąŅƒĐģĐž ҃ĐŋаĐēОваĐŊĐž ҂ҀĐĩŅ‚ŅŒĐžŅŽ ŅŅ‚ĐžŅ€ĐžĐŊĐžŅŽ. ĐŸŅ€ĐžĐąĐģĐĩĐŧи, С ŅĐēиĐŧи ви ŅŅ‚Đ¸ĐēĐ°Ņ”Ņ‚ĐĩҁҌ, ĐŧĐžĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ виĐēĐģиĐēаĐŊŅ– Ņ†Đ¸Đŧ ĐŋаĐēĐĩŅ‚ĐžĐŧ, Ņ‚ĐžĐŧ҃ ҁĐŋĐžŅ‡Đ°Ņ‚Đē҃ СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž ĐŊĐ¸Ņ… Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ, виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅŽŅ‡Đ¸ ĐŊавĐĩĐ´ĐĩĐŊŅ– ĐŊиĐļ҇Đĩ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ.", + "support_third_party_description": "Đ’Đ°ŅˆŅƒ ĐˇĐąŅ–Ņ€Đē҃ Immich ĐąŅƒĐģĐž ĐŋŅ–Đ´ĐŗĐžŅ‚ĐžĐ˛ĐģĐĩĐŊĐž ŅŅ‚ĐžŅ€ĐžĐŊĐŊŅ–Đŧ Ņ€ĐžĐˇŅ€ĐžĐąĐŊиĐēĐžĐŧ. ĐŸŅ€ĐžĐąĐģĐĩĐŧи ĐŧĐžĐļŅƒŅ‚ŅŒ ĐąŅƒŅ‚Đ¸ виĐēĐģиĐēаĐŊŅ– Ņ†Đ¸Đŧ ĐŋаĐēĐĩŅ‚ĐžĐŧ, Ņ‚ĐžĐŧ҃ ҁĐŋĐĩŅ€ŅˆŅƒ СвĐĩŅ€ĐŊŅ–Ņ‚ŅŒŅŅ Đ´Đž ĐšĐžĐŗĐž Đ°Đ˛Ņ‚ĐžŅ€Đ° Са ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅĐŧи ĐŊиĐļ҇Đĩ.", "supporter": "ĐŸŅ€Đ¸Ņ…Đ¸ĐģҌĐŊиĐē", "swap_merge_direction": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŊаĐŋŅ€ŅĐŧĐžĐē Ой'Ņ”Đ´ĐŊаĐŊĐŊŅ", "sync": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸", "sync_albums": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ аĐģŅŒĐąĐžĐŧи", - "sync_albums_manual_subtitle": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– СаваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ҃ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– аĐģŅŒĐąĐžĐŧи Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", + "sync_albums_manual_subtitle": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛ŅŅ– виваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž ҃ Đ˛Đ¸ĐąŅ€Đ°ĐŊŅ– аĐģŅŒĐąĐžĐŧи Đ´ĐģŅ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊĐžĐŗĐž ĐēĐžĐŋŅ–ŅŽĐ˛Đ°ĐŊĐŊŅ", "sync_local": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ ĐŊа ĐŋŅ€Đ¸ŅŅ‚Ņ€ĐžŅ—", "sync_remote": "ХиĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇŅƒĐ˛Đ°Ņ‚Đ¸ С ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ", "sync_status": "ĐĄŅ‚Đ°ĐŊ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ—", "sync_status_subtitle": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ Ņ‚Đ° ĐēĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ ŅĐ¸ŅŅ‚ĐĩĐŧĐžŅŽ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐ°Ņ†Ņ–Ņ—", - "sync_upload_album_setting_subtitle": "ĐĄŅ‚Đ˛ĐžŅ€ŅŽĐšŅ‚Đĩ Ņ‚Đ° виваĐŊŅ‚Đ°ĐļŅƒĐšŅ‚Đĩ ŅĐ˛ĐžŅ— Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ— Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ Immich", + "sync_upload_album_setting_subtitle": "ĐĄŅ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ Ņ‚Đ° виваĐŊŅ‚Đ°ĐļŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐ˛ĐžŅ— Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Đ´Đž Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… аĐģŅŒĐąĐžĐŧŅ–Đ˛ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ Immich", "tag": "ĐĸĐĩĐŗ", "tag_assets": "Đ”ĐžĐ´Đ°Ņ‚Đ¸ Ņ‚ĐĩĐŗĐ¸", "tag_created": "ĐĄŅ‚Đ˛ĐžŅ€ĐĩĐŊĐž Ņ‚ĐĩĐŗ: {tag}", - "tag_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Đš Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, ĐˇĐŗŅ€ŅƒĐŋОваĐŊĐ¸Ņ… Са ĐģĐžĐŗŅ–Ņ‡ĐŊиĐŧи Ņ‚ĐĩĐŧаĐŧи Ņ‚ĐĩĐŗŅ–Đ˛", - "tag_not_found_question": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŊĐ°ĐšŅ‚Đ¸ Ņ‚ĐĩĐŗ? ĐĄŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ ĐŊОвиК Ņ‚ĐĩĐŗ.", - "tag_people": "ĐĸĐĩĐŗ ĐģŅŽĐ´ĐĩĐš", + "tag_face": "ĐĸĐĩĐŗ ОйĐģĐ¸Ņ‡Ņ‡Ņ", + "tag_feature_description": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž, ĐˇĐŗŅ€ŅƒĐŋОваĐŊĐ¸Ņ… Са ĐģĐžĐŗŅ–Ņ‡ĐŊиĐŧи Ņ‚ĐĩĐŧаĐŧи Ņ‚ĐĩĐŗŅ–Đ˛", + "tag_not_found_question": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŊĐ°ĐšŅ‚Đ¸ Ņ‚ĐĩĐŗ? ĐĄŅ‚Đ˛ĐžŅ€Ņ–Ņ‚ŅŒ ĐŊОвиК Ņ‚ĐĩĐŗ.", + "tag_people": "ПозĐŊĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐģŅŽĐ´ĐĩĐš", "tag_updated": "ОĐŊОвĐģĐĩĐŊĐž Ņ‚ĐĩĐŗ: {tag}", - "tagged_assets": "ПозĐŊĐ°Ņ‡ĐĩĐŊĐž Ņ‚ĐĩĐŗĐžĐŧ {count, plural, one {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "tagged_assets": "ПозĐŊĐ°Ņ‡ĐĩĐŊĐž Ņ‚ĐĩĐŗĐžĐŧ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "tags": "ĐĸĐĩĐŗĐ¸", - "tap_to_run_job": "ĐĸĐžŅ€ĐēĐŊŅ–Ņ‚ŅŒŅŅ, Ņ‰ĐžĐą СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đ¸ СавдаĐŊĐŊŅ", + "tap_to_run_job": "ĐĸĐžŅ€ĐēĐŊŅ–Ņ‚ŅŒŅŅ, Ņ‰ĐžĐą виĐēĐžĐŊĐ°Ņ‚Đ¸ СавдаĐŊĐŊŅ", "template": "ШайĐģĐžĐŊ", "text_recognition": "РОСĐŋŅ–ĐˇĐŊаваĐŊĐŊŅ Ņ‚ĐĩĐēŅŅ‚Ņƒ", - "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": "ĐĸĐĩĐŧа ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ", + "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_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": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ‚Ņ€Đ¸ĐĩŅ‚Đ°ĐŋĐŊĐĩ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", + "theme_setting_theme_subtitle": "НаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅ Ņ‚ĐĩĐŧи ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃", + "theme_setting_three_stage_loading_subtitle": "ĐĸŅ€Đ¸ĐĩŅ‚Đ°ĐŋĐŊĐĩ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ ĐŋŅ–Đ´Đ˛Đ¸Ņ‰Đ¸Ņ‚Đ¸ ŅˆĐ˛Đ¸Đ´ĐēŅ–ŅŅ‚ŅŒ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ, аĐģĐĩ СĐŊĐ°Ņ‡ĐŊĐž ĐˇĐąŅ–ĐģŅŒŅˆĐ¸Ņ‚ŅŒ ĐŊаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŊа ĐŧĐĩŅ€ĐĩĐļ҃", + "theme_setting_three_stage_loading_title": "ĐĸŅ€Đ¸ĐĩŅ‚Đ°ĐŋĐŊĐĩ СаваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "then": "ĐĸĐžĐ´Ņ–", - "they_will_be_merged_together": "ВоĐŊи ĐąŅƒĐ´ŅƒŅ‚ŅŒ Ой'Ņ”Đ´ĐŊаĐŊŅ– Ņ€Đ°ĐˇĐžĐŧ", + "they_will_be_merged_together": "Đ‡Ņ… ĐąŅƒĐ´Đĩ Ой'Ņ”Đ´ĐŊаĐŊĐž", "third_party_resources": "ĐĄŅ‚ĐžŅ€ĐžĐŊĐŊŅ– Ņ€ĐĩŅŅƒŅ€ŅĐ¸", "time": "Đ§Đ°Ņ", - "time_based_memories": "ĐĄĐŋĐžĐŗĐ°Đ´Đ¸, Ņ‰Đž ĐąĐ°ĐˇŅƒŅŽŅ‚ŅŒŅŅ ĐŊа Ņ‡Đ°ŅŅ–", + "time_based_memories": "ĐĄĐŋĐžĐŗĐ°Đ´Đ¸ Са Đ´Đ°Ņ‚ĐžŅŽ", "time_based_memories_duration": "ĐšŅ–ĐģҌĐēŅ–ŅŅ‚ŅŒ ҁĐĩĐē҃ĐŊĐ´ Đ´ĐģŅ Đ˛Ņ–Đ´ĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ ĐēĐžĐļĐŊĐžĐŗĐž ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ.", "timeline": "ĐĨŅ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ", "timezone": "Đ§Đ°ŅĐžĐ˛Đ¸Đš ĐŋĐžŅŅ", "to_archive": "ĐŅ€Ņ…Ņ–Đ˛", "to_change_password": "ЗĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ ĐŋĐ°Ņ€ĐžĐģҌ", - "to_favorite": "ĐžĐąŅ€Đ°ĐŊĐĩ", + "to_favorite": "Đ’Đ¸ĐąŅ€Đ°ĐŊĐĩ", "to_login": "Đ’Ņ…Ņ–Đ´", "to_multi_select": "Đ´ĐģŅ ĐŧĐŊĐžĐļиĐŊĐŊĐžĐŗĐž Đ˛Đ¸ĐąĐžŅ€Ņƒ", - "to_parent": "ПовĐĩŅ€ĐŊŅƒŅ‚Đ¸ŅŅŒ ĐŊаСад", + "to_parent": "До ĐąĐ°Ņ‚ŅŒĐēŅ–Đ˛ŅŅŒĐēĐžŅ— ĐŋаĐŋĐēи", "to_select": "Đ˛Đ¸ĐąŅ€Đ°Ņ‚Đ¸", "to_trash": "ĐšĐžŅˆĐ¸Đē", "toggle_settings": "ПĐĩŅ€ĐĩĐŧиĐēаĐŊĐŊŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊҌ", - "toggle_theme_description": "ПĐĩŅ€ĐĩĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ‚ĐĩĐŧ҃", + "toggle_theme_description": "ПĐĩŅ€ĐĩĐŧĐēĐŊŅƒŅ‚Đ¸ Ņ‚ĐĩĐŧ҃ ĐžŅ„ĐžŅ€ĐŧĐģĐĩĐŊĐŊŅ", "total": "ĐŖŅŅŒĐžĐŗĐž", "total_usage": "Đ—Đ°ĐŗĐ°ĐģҌĐŊĐĩ виĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ", "trash": "ĐšĐžŅˆĐ¸Đē", "trash_action_prompt": "{count} ĐŋĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊĐž Đ´Đž ĐēĐžŅˆĐ¸Đēа", - "trash_all": "ВидаĐģĐ¸Ņ‚Đ¸ Đ˛ŅĐĩ", - "trash_count": "ВидаĐģĐ¸Ņ‚Đ¸ {count, number}", - "trash_delete_asset": "ĐŖ ĐšĐžŅˆĐ¸Đē/ВидаĐģĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģ", + "trash_all": "ПĐĩŅ€ĐĩĐŧŅ–ŅŅ‚Đ¸Ņ‚Đ¸ Đ˛ŅĐĩ Đ´Đž ĐēĐžŅˆĐ¸Đēа", + "trash_count": "ĐšĐžŅˆĐ¸Đē {count, number}", + "trash_delete_asset": "ĐŖ ĐēĐžŅˆĐ¸Đē/ВидаĐģĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", "trash_emptied": "ĐšĐžŅˆĐ¸Đē ĐžŅ‡Đ¸Ņ‰ĐĩĐŊĐž", - "trash_no_results_message": "ĐĸŅƒŅ‚ С'ŅĐ˛ĐģŅŅ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ видаĐģĐĩĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž.", + "trash_no_results_message": "Đ¤ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž С ĐēĐžŅˆĐ¸Đēа С'ŅĐ˛ĐģŅŅ‚Đ¸ĐŧŅƒŅ‚ŅŒŅŅ Ņ‚ŅƒŅ‚.", "trash_page_delete_all": "ВидаĐģĐ¸Ņ‚Đ¸ ҃ҁĐĩ", - "trash_page_empty_trash_dialog_content": "Ви Ņ…ĐžŅ‡ĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē? ĐĻŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊŅ– С Immich", + "trash_page_empty_trash_dialog_content": "ĐĨĐžŅ‡ĐĩŅ‚Đĩ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ ĐēĐžŅˆĐ¸Đē? ĐĻŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ĐąŅƒĐ´Đĩ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž С Immich", "trash_page_info": "ПĐĩŅ€ĐĩĐŧҖ҉ĐĩĐŊŅ– Đ´Đž ĐēĐžŅˆĐ¸Đēа Ņ„Đ°ĐšĐģи ĐąŅƒĐ´Đĩ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž ҇ĐĩŅ€ĐĩС {days} Đ´ĐŊŅ–Đ˛", - "trash_page_no_assets": "ВидаĐģĐĩĐŊŅ– Ņ„ĐžŅ‚Đž Ņ‚Đ° Đ˛Ņ–Đ´ĐĩĐž Đ˛Ņ–Đ´ŅŅƒŅ‚ĐŊŅ–", + "trash_page_no_assets": "НĐĩĐŧĐ°Ņ” ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ҃ ĐēĐžŅˆĐ¸Đē҃", "trash_page_restore_all": "Đ’Ņ–Đ´ĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ҃ҁĐĩ", - "trash_page_select_assets_btn": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", + "trash_page_select_assets_btn": "Đ’Đ¸ĐąŅ€Đ°Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸", "trash_page_title": "ĐšĐžŅˆĐ¸Đē ({count})", - "trashed_items_will_be_permanently_deleted_after": "ВидаĐģĐĩĐŊŅ– Ņ„Đ°ĐšĐģи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊŅ– ҇ĐĩŅ€ĐĩС {days, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}.", + "trashed_items_will_be_permanently_deleted_after": "ЕĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ ҃ ĐēĐžŅˆĐ¸Đē҃ ĐąŅƒĐ´Đĩ ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž видаĐģĐĩĐŊĐž ҇ĐĩŅ€ĐĩС {days, plural, one {# Đ´ĐĩĐŊҌ} few {# Đ´ĐŊŅ–} many {# Đ´ĐŊŅ–Đ˛} other {# Đ´ĐŊŅ–Đ˛}}.", "trigger": "ĐĸŅ€Đ¸ĐŗĐĩŅ€", - "trigger_asset_uploaded": "ФаКĐģ дОдаĐŊĐž", - "trigger_asset_uploaded_description": "ЗаĐŋ҃ҁĐēĐ°Ņ”Ņ‚ŅŒŅŅ ĐŋŅ–Đ´ Ņ‡Đ°Ņ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŊĐžĐ˛ĐžĐŗĐž Ņ„Đ°ĐšĐģ҃", + "trigger_asset_uploaded": "ЕĐģĐĩĐŧĐĩĐŊŅ‚ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐž", + "trigger_asset_uploaded_description": "ĐĄĐŋŅ€Đ°Ņ†ŅŒĐžĐ˛ŅƒŅ”, ĐēĐžĐģи виваĐŊŅ‚Đ°ĐļĐĩĐŊĐž ĐŊОвиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", "trigger_description": "ĐŸĐžĐ´Ņ–Ņ, ŅĐēа СаĐŋ҃ҁĐēĐ°Ņ” Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", - "trigger_person_recognized": "ĐžŅĐžĐąĐ° Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊа", + "trigger_person_recognized": "Đ›ŅŽĐ´Đ¸ĐŊ҃ Ņ€ĐžĐˇĐŋŅ–ĐˇĐŊаĐŊĐž", "trigger_person_recognized_description": "ĐĄĐŋŅ€Đ°Ņ†ŅŒĐžĐ˛ŅƒŅ”, ĐēĐžĐģи Đ˛Đ¸ŅĐ˛ĐģŅŅ”Ņ‚ŅŒŅŅ ĐģŅŽĐ´Đ¸ĐŊа", "trigger_type": "ĐĸиĐŋ Ņ‚Ņ€Đ¸ĐŗĐĩŅ€Đ°", - "troubleshoot": "ВиĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊŅ ĐŊĐĩĐŋĐžĐģадОĐē", + "troubleshoot": "ĐŖŅŅƒĐŊĐĩĐŊĐŊŅ ĐŊĐĩĐŋĐžĐģадОĐē", "type": "ĐĸиĐŋ", - "unable_to_change_pin_code": "НĐĩĐŧĐžĐļĐģивО СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ PIN-ĐēОд", + "unable_to_change_pin_code": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ СĐŧŅ–ĐŊĐ¸Ņ‚Đ¸ PIN-ĐēОд", "unable_to_check_version": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đ¸Ņ‚Đ¸ вĐĩŅ€ŅŅ–ŅŽ ĐˇĐ°ŅŅ‚ĐžŅŅƒĐŊĐē҃ айО ҁĐĩŅ€Đ˛ĐĩŅ€Đ°", - "unable_to_setup_pin_code": "НĐĩĐŧĐžĐļĐģивО ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ PIN-ĐēОд", - "unarchive": "Đ ĐžĐˇĐ°Ņ€Ņ…Ņ–Đ˛ŅƒĐ˛Đ°Ņ‚Đ¸", - "unarchive_action_prompt": "{count, plural, one {# Ņ„Đ°ĐšĐģ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} few {# Ņ„Đ°ĐšĐģи виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} other {# Ņ„Đ°ĐšĐģŅ–Đ˛ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ}}", - "unarchived_count": "{count, plural, other {ПовĐĩŅ€ĐŊŅƒŅ‚Đž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ #}}", + "unable_to_setup_pin_code": "НĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°Ņ‚Đ¸ PIN-ĐēОд", + "unarchive": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ", + "unarchive_action_prompt": "{count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ виĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ}}", + "unarchived_count": "{count, plural, one {ВиĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ #} few {ВиĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ #} many {ВиĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ #} other {ВиĐģŅƒŅ‡ĐĩĐŊĐž С Đ°Ņ€Ņ…Ņ–Đ˛Ņƒ #}}", "undo": "ĐĄĐēĐ°ŅŅƒĐ˛Đ°Ņ‚Đ¸", - "unfavorite": "ВидаĐģĐ¸Ņ‚Đ¸ С ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", - "unfavorite_action_prompt": "{count} виĐģŅƒŅ‡ĐĩĐŊĐž С ĐžĐąŅ€Đ°ĐŊĐžĐŗĐž", - "unhide_person": "РОСĐēŅ€Đ¸Ņ‚Đ¸ ĐžŅĐžĐąŅƒ", + "unfavorite": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "unfavorite_action_prompt": "{count} виĐģŅƒŅ‡ĐĩĐŊĐž С Đ˛Đ¸ĐąŅ€Đ°ĐŊĐžĐŗĐž", + "unhide_person": "РОСĐēŅ€Đ¸Ņ‚Đ¸ ĐģŅŽĐ´Đ¸ĐŊ҃", "unknown": "НĐĩĐ˛Ņ–Đ´ĐžĐŧĐž", "unknown_country": "НĐĩĐ˛Ņ–Đ´ĐžĐŧа ĐēŅ€Đ°Ņ—ĐŊа", "unknown_date": "НĐĩĐ˛Ņ–Đ´ĐžĐŧа Đ´Đ°Ņ‚Đ°", @@ -2296,130 +2304,133 @@ "unlimited": "БĐĩС ОйĐŧĐĩĐļĐĩĐŊҌ", "unlink_motion_video": "Đ’Ņ–Đ´'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ Ņ€ŅƒŅ…ĐžĐŧĐĩ Đ˛Ņ–Đ´ĐĩĐž", "unlink_oauth": "Đ’Ņ–Đ´'Ņ”Đ´ĐŊĐ°Ņ‚Đ¸ OAuth", - "unlinked_oauth_account": "Đ’Ņ–Đ´'Ņ”Đ´ĐŊаĐŊиК ОйĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth", - "unmute_memories": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ĐˇĐ˛ŅƒĐē ҁĐŋĐžĐŗĐ°Đ´Ņ–Đ˛", + "unlinked_oauth_account": "ОбĐģŅ–ĐēОвиК СаĐŋĐ¸Ņ OAuth Đ˛Ņ–Đ´'Ņ”Đ´ĐŊаĐŊĐž", + "unmute_memories": "ĐŖĐ˛Ņ–ĐŧĐēĐŊŅƒŅ‚Đ¸ ҁĐŋĐžĐŗĐ°Đ´Đ¸", "unnamed_album": "АĐģŅŒĐąĐžĐŧ ĐąĐĩС ĐŊаСви", - "unnamed_album_delete_confirmation": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž йаĐļĐ°Ņ”Ņ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš аĐģŅŒĐąĐžĐŧ?", + "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 {# Ņ„Đ°ĐšĐģ} few {# Ņ„Đ°ĐšĐģи} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "unselect_all": "ЗĐŊŅŅ‚Đ¸ Đ˛Đ¸ĐąŅ–Ņ€ С ŅƒŅŅ–Ņ…", + "unselect_all_duplicates": "ЗĐŊŅŅ‚Đ¸ Đ˛Đ¸ĐąŅ–Ņ€ С ŅƒŅŅ–Ņ… Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛", + "unselect_all_in": "ЗĐŊŅŅ‚Đ¸ Đ˛Đ¸ĐąŅ–Ņ€ ҃ {group}", + "unstack": "Đ ĐžĐˇĐŗŅ€ŅƒĐŋŅƒĐ˛Đ°Ņ‚Đ¸", + "unstack_action_prompt": "{count} — Ņ€ĐžĐˇĐŗŅ€ŅƒĐŋОваĐŊĐž", + "unstacked_assets_count": "Đ ĐžĐˇĐŗŅ€ŅƒĐŋОваĐŊĐž {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", "unsupported_field_type": "НĐĩĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒĐ˛Đ°ĐŊиК Ņ‚Đ¸Đŋ ĐŋĐžĐģŅ", + "unsupported_file_type": "ФаКĐģ {file} ĐŊĐĩ Đ˛Đ´Đ°Ņ”Ņ‚ŅŒŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸, ĐžŅĐēŅ–ĐģҌĐēи Ņ‚Đ¸Đŋ Ņ„Đ°ĐšĐģ҃ {type} ĐŊĐĩ ĐŋŅ–Đ´Ņ‚Ņ€Đ¸ĐŧŅƒŅ”Ņ‚ŅŒŅŅ.", "untagged": "БĐĩС Ņ‚ĐĩĐŗŅ–Đ˛", - "untitled_workflow": "БĐĩĐˇŅ–ĐŧĐĩĐŊĐŊиК Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", + "untitled_workflow": "БĐĩĐˇŅ–ĐŧĐĩĐŊĐŊа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ", "up_next": "ĐĐ°ŅŅ‚ŅƒĐŋĐŊĐĩ", - "update_location_action_prompt": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ Ņ€ĐžĐˇŅ‚Đ°ŅˆŅƒĐ˛Đ°ĐŊĐŊŅ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… ĐžĐąâ€™Ņ”ĐēŅ‚Ņ–Đ˛ ({count}) Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ:", + "update_location_action_prompt": "ОĐŊĐžĐ˛Đ¸Ņ‚Đ¸ ĐŧҖҁ҆Đĩ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ({count}) Са Đ´ĐžĐŋĐžĐŧĐžĐŗĐžŅŽ:", "updated_at": "ОĐŊОвĐģĐĩĐŊĐž", "updated_password": "ĐŸĐ°Ņ€ĐžĐģҌ ĐžĐŊОвĐģĐĩĐŊĐž", "upload": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸", - "upload_concurrency": "ĐŸĐ°Ņ€Đ°ĐģĐĩĐģҌĐŊŅ–ŅŅ‚ŅŒ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", + "upload_concurrency": "ОдĐŊĐžŅ‡Đ°ŅĐŊŅ– виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", "upload_details": "ДĐĩŅ‚Đ°ĐģŅ– виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", - "upload_dialog_info": "БаĐļĐ°Ņ”Ņ‚Đĩ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛ ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ?", - "upload_dialog_title": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ Ņ„Đ°ĐšĐģи", - "upload_error_with_count": "ПоĐŧиĐģĐēа виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ Đ´ĐģŅ {count, plural, one {# Ņ„Đ°ĐšĐģ҃} few {# Ņ„Đ°ĐšĐģŅ–Đ˛} many {# Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Ņ„Đ°ĐšĐģŅ–Đ˛}}", - "upload_errors": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ СавĐĩŅ€ŅˆĐĩĐŊĐž С {count, plural, one {# ĐŋĐžĐŧиĐģĐēĐžŅŽ} few {# ĐŋĐžĐŧиĐģĐēаĐŧи} many {# ĐŋĐžĐŧиĐģĐēаĐŧи} other {# ĐŋĐžĐŧиĐģĐēаĐŧи}}, ĐžĐŊĐžĐ˛Ņ–Ņ‚ŅŒ ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃, Ņ‰ĐžĐą ĐŋĐžĐąĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– виваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– Ņ„Đ°ĐšĐģи.", + "upload_dialog_info": "ĐĨĐžŅ‡ĐĩŅ‚Đĩ ŅŅ‚Đ˛ĐžŅ€Đ¸Ņ‚Đ¸ Ņ€ĐĩСĐĩŅ€Đ˛ĐŊ҃ ĐēĐžĐŋŅ–ŅŽ Đ˛Đ¸ĐąŅ€Đ°ĐŊĐ¸Ņ… ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛ ĐŊа ҁĐĩŅ€Đ˛ĐĩҀҖ?", + "upload_dialog_title": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "upload_error_with_count": "НĐĩ вдаĐģĐžŅŅ виваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ {count, plural, one {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} few {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸} many {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛} other {# ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛}}", + "upload_errors": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ СавĐĩŅ€ŅˆĐĩĐŊĐž С {count, plural, one {# ĐŋĐžĐŧиĐģĐēĐžŅŽ} few {# ĐŋĐžĐŧиĐģĐēаĐŧи} many {# ĐŋĐžĐŧиĐģĐēаĐŧи} other {# ĐŋĐžĐŧиĐģĐēаĐŧи}}, ĐžĐŊĐžĐ˛Ņ–Ņ‚ŅŒ ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃, Ņ‰ĐžĐą ĐŋĐžĐąĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– виваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸.", "upload_finished": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ СавĐĩŅ€ŅˆĐĩĐŊĐž", - "upload_progress": "ЗаĐģĐ¸ŅˆĐ¸ĐģĐžŅŅŒ {remaining, number} - ОĐŋŅ€Đ°Ņ†ŅŒĐžĐ˛Đ°ĐŊĐž {processed, number}/{total, number}", - "upload_skipped_duplicates": "ĐŸŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž {count, plural, one {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊиК Ņ„Đ°ĐšĐģ} few {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊŅ– Ņ„Đ°ĐšĐģи} many {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛} other {# Đ´ŅƒĐąĐģŅŒĐžĐ˛Đ°ĐŊĐ¸Ņ… Ņ„Đ°ĐšĐģŅ–Đ˛}}", + "upload_progress": "ЗаĐģĐ¸ŅˆĐ¸ĐģĐžŅŅ {remaining, number} - ОĐŋŅ€Đ°Ņ†ŅŒĐžĐ˛Đ°ĐŊĐž {processed, number}/{total, number}", + "upload_skipped_duplicates": "ĐŸŅ€ĐžĐŋŅƒŅ‰ĐĩĐŊĐž {count, plural, one {# Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚} few {# Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸} many {# Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛} other {# Đ´ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Ņ–Đ˛}}", "upload_status_duplicates": "Đ”ŅƒĐąĐģŅ–ĐēĐ°Ņ‚Đ¸", "upload_status_errors": "ПоĐŧиĐģĐēи", "upload_status_uploaded": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐž", - "upload_success": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ҃ҁĐŋŅ–ŅˆĐŊĐĩ. ОĐŊĐžĐ˛Ņ–Ņ‚ŅŒ ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃, Ņ‰ĐžĐą ĐŋĐžĐąĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– виваĐŊŅ‚Đ°ĐļĐĩĐŊŅ– Ņ„Đ°ĐšĐģи.", + "upload_success": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐž. ОĐŊĐžĐ˛Ņ–Ņ‚ŅŒ ŅŅ‚ĐžŅ€Ņ–ĐŊĐē҃, Ņ‰ĐžĐą ĐŋĐžĐąĐ°Ņ‡Đ¸Ņ‚Đ¸ ĐŊĐžĐ˛Ņ– ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ¸.", "upload_to_immich": "ВиваĐŊŅ‚Đ°ĐļĐ¸Ņ‚Đ¸ в Immich ({count})", "uploading": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", - "uploading_media": "ВиĐēĐžĐŊŅƒŅ”Ņ‚ŅŒŅŅ виваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ", + "uploading_media": "ВиваĐŊŅ‚Đ°ĐļĐĩĐŊĐŊŅ ĐŧĐĩĐ´Ņ–Đ°", "url": "URL", "usage": "ВиĐēĐžŅ€Đ¸ŅŅ‚Đ°ĐŊĐŊŅ", "use_biometric": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐąŅ–ĐžĐŧĐĩŅ‚Ņ€Ņ–ŅŽ", "use_browser_locale": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐģĐžĐēаĐģҌ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°", + "use_browser_locale_description": "Đ¤ĐžŅ€ĐŧĐ°Ņ‚ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´Đ°Ņ‚Đ¸, Ņ‡Đ°Ņ Ņ‚Đ° Ņ‡Đ¸ŅĐģа Đ˛Ņ–Đ´ĐŋĐžĐ˛Ņ–Đ´ĐŊĐž Đ´Đž ĐģĐžĐēаĐģŅ– Đ˛Đ°ŅˆĐžĐŗĐž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°", "use_current_connection": "ВиĐēĐžŅ€Đ¸ŅŅ‚Đ°Ņ‚Đ¸ ĐŋĐžŅ‚ĐžŅ‡ĐŊĐĩ С'Ņ”Đ´ĐŊаĐŊĐŊŅ", - "use_custom_date_range": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ†ŅŒĐēиК Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", + "use_custom_date_range": "ĐĐ°Ņ‚ĐžĐŧŅ–ŅŅ‚ŅŒ виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ Đ´ĐžĐ˛Ņ–ĐģҌĐŊиК Đ´Ņ–Đ°ĐŋаСОĐŊ Đ´Đ°Ņ‚", "user": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡", "user_has_been_deleted": "ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ° видаĐģĐĩĐŊĐž.", - "user_id": "ID ĐšĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "user_liked": "{user} вĐŋОдОйав {type, select, photo {҆Đĩ Ņ„ĐžŅ‚Đž} video {҆Đĩ Đ˛Ņ–Đ´ĐĩĐž} asset {҆ĐĩĐš Ņ„Đ°ĐšĐģ} other {҆Đĩ}}", + "user_id": "ID ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", + "user_liked": "{user} вĐŋОдОйав(-Đģа) {type, select, photo {҆Đĩ Ņ„ĐžŅ‚Đž} video {҆Đĩ Đ˛Ņ–Đ´ĐĩĐž} asset {҆ĐĩĐš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚} other {҆Đĩ}}", "user_pin_code_settings": "PIN-ĐēОд", "user_pin_code_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°ĐŊĐŊŅ PIN-ĐēОдОĐŧ", "user_privacy": "КоĐŊŅ„Ņ–Đ´ĐĩĐŊŅ†Ņ–ĐšĐŊŅ–ŅŅ‚ŅŒ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "user_purchase_settings": "ĐŸŅ€Đ¸Đ´ĐąĐ°Ņ‚Đ¸", - "user_purchase_settings_description": "КĐĩŅ€ŅƒĐ˛Đ°Ņ‚Đ¸ Đ˛Đ°ŅˆĐžŅŽ ĐŋĐžĐē҃ĐŋĐēĐžŅŽ", + "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 {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°} few {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–} many {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛} other {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛}} дОдаĐŊĐž Đ´Đž аĐģŅŒĐąĐžĐŧ҃", + "users_added_to_album_count": "{count, plural, one {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°} few {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛} many {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛} other {# ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛}} дОдаĐŊĐž Đ´Đž аĐģŅŒĐąĐžĐŧ҃", "utilities": "ĐŖŅ‚Đ¸ĐģŅ–Ņ‚Đ¸", "validate": "ПĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đ¸Ņ‚Đ¸", "validate_endpoint_error": "Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ввĐĩĐ´Ņ–Ņ‚ŅŒ Đ´Ņ–ĐšŅĐŊ҃ URL-Đ°Đ´Ņ€Đĩҁ҃", "validation_error": "ПоĐŧиĐģĐēа ĐŋĐĩŅ€ĐĩĐ˛Ņ–Ņ€Đēи", "variables": "ЗĐŧŅ–ĐŊĐŊŅ–", "version": "ВĐĩŅ€ŅŅ–Ņ", - "version_announcement_closing": "ĐĸĐ˛Ņ–Đš Đ´Ņ€ŅƒĐŗ, АĐģĐĩĐēҁ", - "version_announcement_message": "ĐŸŅ€Đ¸Đ˛Ņ–Ņ‚! Đ”ĐžŅŅ‚ŅƒĐŋĐŊа ĐŊОва вĐĩŅ€ŅŅ–Ņ Immich. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋŅ€Đ¸Đ´Ņ–ĐģŅ–Ņ‚ŅŒ Ņ‚Ņ€ĐžŅ…Đ¸ Ņ‡Đ°ŅŅƒ Đ´ĐģŅ ОСĐŊаКОĐŧĐģĐĩĐŊĐŊŅ С ĐŋŅ€Đ¸ĐŧŅ–Ņ‚ĐēаĐŧи Đ´Đž виĐŋ҃ҁĐē҃, Ņ‰ĐžĐą ĐŋĐĩŅ€ĐĩĐēĐžĐŊĐ°Ņ‚Đ¸ŅŅ, Ņ‰Đž Đ˛Đ°ŅˆĐ° ŅƒŅŅ‚Đ°ĐŊОвĐēа ĐžĐŊОвĐģĐĩĐŊа Ņ– ҃ĐŊиĐēĐŊŅƒŅ‚Đ¸ ĐŧĐžĐļĐģĐ¸Đ˛Đ¸Ņ… ĐŋĐžĐŧиĐģĐžĐē ҃ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…, ĐžŅĐžĐąĐģивО ŅĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ WatchTower айО ĐąŅƒĐ´ŅŒ-ŅĐēиК Ņ–ĐŊŅˆĐ¸Đš ĐŧĐĩŅ…Đ°ĐŊŅ–ĐˇĐŧ, ŅĐēиК Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐžĐŊОвĐģŅŽŅ” Đ˛Đ°Ņˆ ĐĩĐēСĐĩĐŧĐŋĐģŅŅ€ Immich.", + "version_announcement_closing": "Đ’Đ°Ņˆ Đ´Ņ€ŅƒĐŗ, АĐģĐĩĐēҁ", + "version_announcement_message": "ĐŸŅ€Đ¸Đ˛Ņ–Ņ‚! Đ”ĐžŅŅ‚ŅƒĐŋĐŊа ĐŊОва вĐĩŅ€ŅŅ–Ņ Immich. Đ‘ŅƒĐ´ŅŒ ĐģĐ°ŅĐēа, ĐŋŅ€Đ¸Đ´Ņ–ĐģŅ–Ņ‚ŅŒ Ņ‚Ņ€ĐžŅ…Đ¸ Ņ‡Đ°ŅŅƒ Ņ‰ĐžĐą ОСĐŊаКОĐŧĐ¸Ņ‚Đ¸ŅŅ С ĐŋŅ€Đ¸ĐŧŅ–Ņ‚ĐēаĐŧи Đ´Đž виĐŋ҃ҁĐē҃, Ņ‰ĐžĐą ĐŋĐĩŅ€ĐĩĐēĐžĐŊĐ°Ņ‚Đ¸ŅŅ, Ņ‰Đž Đ˛Đ°ŅˆŅƒ ŅƒŅŅ‚Đ°ĐŊОвĐē҃ ĐžĐŊОвĐģĐĩĐŊĐž Đš ҃ĐŊиĐēĐŊŅƒŅ‚Đ¸ ĐŧĐžĐļĐģĐ¸Đ˛Đ¸Ņ… ĐŋĐžĐŧиĐģĐžĐē ҃ ĐŊаĐģĐ°ŅˆŅ‚ŅƒĐ˛Đ°ĐŊĐŊŅŅ…, ĐžŅĐžĐąĐģивО ŅĐēŅ‰Đž ви виĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒŅ”Ņ‚Đĩ WatchTower айО ĐąŅƒĐ´ŅŒ-ŅĐēиК Ņ–ĐŊŅˆĐ¸Đš ĐŧĐĩŅ…Đ°ĐŊŅ–ĐˇĐŧ, ŅĐēиК Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐŊĐž ĐžĐŊОвĐģŅŽŅ” Đ˛Đ°Ņˆ ĐĩĐēСĐĩĐŧĐŋĐģŅŅ€ Immich.", "version_history": "Đ†ŅŅ‚ĐžŅ€Ņ–Ņ вĐĩŅ€ŅŅ–Đš", - "version_history_item": "Đ’ŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž {version} {date}", + "version_history_item": "ĐŖŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž {version} — {date}", "video": "Đ’Ņ–Đ´ĐĩĐž", "video_hover_setting": "Đ’Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Đ¸ Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŊавĐĩĐ´ĐĩĐŊĐŊŅ ĐēŅƒŅ€ŅĐžŅ€Ņƒ ĐŧĐ¸ŅˆŅ–", - "video_hover_setting_description": "Đ’Ņ–Đ´Ņ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ€Đ¸ ĐŊавĐĩĐ´ĐĩĐŊĐŊŅ– ĐēŅƒŅ€ŅĐžŅ€Đ° ĐŊа Ņ„Đ°ĐšĐģ. ĐĐ°Đ˛Ņ–Ņ‚ŅŒ ŅĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧĐžĐļĐĩ ĐąŅƒŅ‚Đ¸ СаĐŋŅƒŅ‰ĐĩĐŊĐž, ĐŊĐ°Đ˛Ņ–Đ˛ŅˆĐ¸ ĐēŅƒŅ€ŅĐžŅ€ ĐŊа ĐŋŅ–ĐēŅ‚ĐžĐŗŅ€Đ°Đŧ҃ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ.", + "video_hover_setting_description": "Đ’Ņ–Đ´Ņ‚Đ˛ĐžŅ€ŅŽĐ˛Đ°Ņ‚Đ¸ ĐŧŅ–ĐŊŅ–Đ°Ņ‚ŅŽŅ€Ņƒ Đ˛Ņ–Đ´ĐĩĐž ĐŋŅ–Đ´ Ņ‡Đ°Ņ ĐŊавĐĩĐ´ĐĩĐŊĐŊŅ ĐēŅƒŅ€ŅĐžŅ€Đ° ĐŊа ĐĩĐģĐĩĐŧĐĩĐŊŅ‚. ĐĐ°Đ˛Ņ–Ņ‚ŅŒ ŅĐēŅ‰Đž виĐŧĐēĐŊĐĩĐŊĐž, Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ ĐŧĐžĐļĐŊа Ņ€ĐžĐˇĐŋĐžŅ‡Đ°Ņ‚Đ¸, ĐŊĐ°Đ˛Ņ–Đ˛ŅˆĐ¸ ĐēŅƒŅ€ŅĐžŅ€ ĐŊа ĐŋŅ–ĐēŅ‚ĐžĐŗŅ€Đ°Đŧ҃ Đ˛Ņ–Đ´Ņ‚Đ˛ĐžŅ€ĐĩĐŊĐŊŅ.", "videos": "Đ’Ņ–Đ´ĐĩĐž", - "videos_count": "{count, plural, one {# Đ’Ņ–Đ´ĐĩĐž} few {# Đ’Ņ–Đ´ĐĩĐž} many {# Đ’Ņ–Đ´ĐĩĐž} other {# Đ’Ņ–Đ´ĐĩĐž}}", - "videos_only": "ĐĸŅ–ĐģҌĐēи Đ˛Ņ–Đ´ĐĩĐž", + "videos_count": "{count, plural, one {# Đ˛Ņ–Đ´ĐĩĐž} few {# Đ˛Ņ–Đ´ĐĩĐž} many {# Đ˛Ņ–Đ´ĐĩĐž} other {# Đ˛Ņ–Đ´ĐĩĐž}}", + "videos_only": "Đ›Đ¸ŅˆĐĩ Đ˛Ņ–Đ´ĐĩĐž", "view": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´", "view_album": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ аĐģŅŒĐąĐžĐŧ", - "view_all": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ŅƒŅŅ–", + "view_all": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ Đ˛ŅĐĩ", "view_all_users": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ Đ˛ŅŅ–Ņ… ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Ņ–Đ˛", - "view_asset_owners": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ вĐģĐ°ŅĐŊиĐēŅ–Đ˛ Ņ„Đ°ĐšĐģŅ–Đ˛", + "view_asset_owners": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ вĐģĐ°ŅĐŊиĐēŅ–Đ˛ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Ņ–Đ˛", "view_details": "ДĐĩŅ‚Đ°ĐģҌĐŊŅ–ŅˆĐĩ", "view_in_timeline": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ в Ņ…Ņ€ĐžĐŊĐžĐģĐžĐŗŅ–Ņ—", "view_link": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "view_links": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŋĐžŅĐ¸ĐģаĐŊĐŊŅ", "view_name": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸", - "view_next_asset": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊиК Ņ„Đ°ĐšĐģ", - "view_previous_asset": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš Ņ„Đ°ĐšĐģ", + "view_next_asset": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŊĐ°ŅŅ‚ŅƒĐŋĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "view_previous_asset": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐŋĐžĐŋĐĩŅ€ĐĩĐ´ĐŊŅ–Đš ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", "view_qr_code": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ QR-ĐēОд", - "view_similar_photos": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ŅŅ…ĐžĐļŅ– Ņ„ĐžŅ‚ĐžĐŗŅ€Đ°Ņ„Ņ–Ņ—", - "view_stack": "ПĐĩŅ€ĐĩĐŗĐģŅĐ´ ҁ҂ĐĩĐē҃", + "view_similar_photos": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ŅŅ…ĐžĐļŅ– Ņ„ĐžŅ‚Đž", + "view_stack": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ҁ҂ĐĩĐē", "view_user": "ПĐĩŅ€ĐĩĐŗĐģŅĐŊŅƒŅ‚Đ¸ ĐēĐžŅ€Đ¸ŅŅ‚ŅƒĐ˛Đ°Ņ‡Đ°", - "viewer_remove_from_stack": "ВидаĐģĐ¸Ņ‚Đ¸ ĐˇŅ– ҁ҂ĐĩĐē҃", - "viewer_stack_use_as_main_asset": "ВиĐēĐžŅ€Đ¸ŅŅ‚ĐžĐ˛ŅƒĐ˛Đ°Ņ‚Đ¸ ŅĐē ĐžŅĐŊОвĐŊиК Ņ„Đ°ĐšĐģ", - "viewer_unstack": "Đ ĐžĐˇŅ–ĐąŅ€Đ°Ņ‚Đ¸ ҁ҂ĐĩĐē", - "visibility_changed": "ВидиĐŧŅ–ŅŅ‚ŅŒ СĐŧŅ–ĐŊĐĩĐŊĐž Đ´ĐģŅ {count, plural, one {# ĐžŅĐžĐąĐ¸} few {# ĐžŅŅ–Đą} many {# ĐžŅŅ–Đą} other {# ĐžŅŅ–Đą}}", + "viewer_remove_from_stack": "ВиĐģŅƒŅ‡Đ¸Ņ‚Đ¸ ĐˇŅ– ҁ҂ĐĩĐē҃", + "viewer_stack_use_as_main_asset": "ВиĐēĐžŅ€Đ¸ŅŅ‚Đ°Ņ‚Đ¸ ŅĐē ĐžŅĐŊОвĐŊиК ĐĩĐģĐĩĐŧĐĩĐŊŅ‚", + "viewer_unstack": "Đ ĐžĐˇĐąĐ¸Ņ‚Đ¸ ҁ҂ĐĩĐē", + "visibility": "ВидиĐŧŅ–ŅŅ‚ŅŒ", + "visibility_changed": "ВидиĐŧŅ–ŅŅ‚ŅŒ СĐŧŅ–ĐŊĐĩĐŊĐž Đ´ĐģŅ {count, plural, one {# ĐģŅŽĐ´Đ¸ĐŊи} few {# ĐģŅŽĐ´ĐĩĐš} many {# ĐģŅŽĐ´ĐĩĐš} other {# ĐģŅŽĐ´ĐĩĐš}}", "visual": "Đ’Ņ–ĐˇŅƒĐ°ĐģҌĐŊиК", "visual_builder": "Đ’Ņ–ĐˇŅƒĐ°ĐģҌĐŊиК ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ‚ĐžŅ€", "waiting": "ĐŖ ҇ĐĩŅ€ĐˇŅ–", - "waiting_count": "ĐžŅ‡Ņ–ĐēŅƒŅŽŅ‚ŅŒ: {count}", + "waiting_count": "ĐŖ ҇ĐĩŅ€ĐˇŅ–: {count}", "warning": "ПоĐŋĐĩŅ€ĐĩĐ´ĐļĐĩĐŊĐŊŅ", "week": "ĐĸиĐļĐ´ĐĩĐŊҌ", "welcome": "Đ›Đ°ŅĐēавО ĐŋŅ€ĐžŅĐ¸ĐŧĐž", "welcome_to_immich": "Đ›Đ°ŅĐēавО ĐŋŅ€ĐžŅĐ¸ĐŧĐž Đ´Đž Immich", "width": "Đ¨Đ¸Ņ€Đ¸ĐŊа", "wifi_name": "Назва Wi-Fi", - "workflow_delete_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ ҆ĐĩĐš Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ?", - "workflow_deleted": "Đ ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ видаĐģĐĩĐŊĐž", - "workflow_description": "ОĐŋĐ¸Ņ Ņ€ĐžĐąĐžŅ‡ĐžĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁ҃", - "workflow_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Ņ€ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ", - "workflow_json": "Đ ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ JSON", - "workflow_json_help": "Đ’Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗŅƒĐšŅ‚Đĩ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ Ņ€ĐžĐąĐžŅ‡ĐžĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁ҃ ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– JSON. ЗĐŧŅ–ĐŊи ĐąŅƒĐ´ŅƒŅ‚ŅŒ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐžĐ˛Đ°ĐŊŅ– С Đ˛Ņ–ĐˇŅƒĐ°ĐģҌĐŊиĐŧ ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ‚ĐžŅ€ĐžĐŧ.", - "workflow_name": "Назва Ņ€ĐžĐąĐžŅ‡ĐžĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁ҃", + "workflow_delete_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ видаĐģĐ¸Ņ‚Đ¸ Ņ†ŅŽ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ?", + "workflow_deleted": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ видаĐģĐĩĐŊĐž", + "workflow_description": "ОĐŋĐ¸Ņ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", + "workflow_info": "ІĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Ņ–Ņ ĐŋŅ€Đž Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ", + "workflow_json": "JSON Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", + "workflow_json_help": "Đ’Ņ–Đ´Ņ€ĐĩĐ´Đ°ĐŗŅƒĐšŅ‚Đĩ ĐēĐžĐŊŅ„Ņ–ĐŗŅƒŅ€Đ°Ņ†Ņ–ŅŽ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ— ҃ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ– JSON. ЗĐŧŅ–ĐŊи ĐąŅƒĐ´Đĩ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊŅ–ĐˇĐžĐ˛Đ°ĐŊĐž С Đ˛Ņ–ĐˇŅƒĐ°ĐģҌĐŊиĐŧ ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ‚ĐžŅ€ĐžĐŧ.", + "workflow_name": "Назва Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", "workflow_navigation_prompt": "Ви вĐŋĐĩвĐŊĐĩĐŊŅ–, Ņ‰Đž Ņ…ĐžŅ‡ĐĩŅ‚Đĩ Đ˛Đ¸ĐšŅ‚Đ¸ ĐąĐĩС СйĐĩŅ€ĐĩĐļĐĩĐŊĐŊŅ СĐŧŅ–ĐŊ?", - "workflow_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ Ņ€ĐžĐąĐžŅ‡ĐžĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁ҃", - "workflow_update_success": "Đ ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ ҃ҁĐŋŅ–ŅˆĐŊĐž ĐžĐŊОвĐģĐĩĐŊĐž", - "workflow_updated": "Đ ĐžĐąĐžŅ‡Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁ ĐžĐŊОвĐģĐĩĐŊĐž", - "workflows": "Đ ĐžĐąĐžŅ‡Ņ– ĐŋŅ€ĐžŅ†ĐĩŅĐ¸", - "workflows_help_text": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ— виĐēĐžĐŊŅƒŅŽŅ‚ŅŒ Đ´Ņ–Ņ— С Ņ„Đ°ĐšĐģаĐŧи СаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ Ņ‚Ņ€Đ¸ĐŗĐĩŅ€Ņ–Đ˛ Ņ– ҃ĐŧОв", + "workflow_summary": "ЗвĐĩĐ´ĐĩĐŊĐŊŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", + "workflow_update_success": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ ĐžĐŊОвĐģĐĩĐŊĐž", + "workflow_updated": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–ŅŽ ĐžĐŊОвĐģĐĩĐŊĐž", + "workflows": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ—", + "workflows_help_text": "ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Ņ–Ņ— виĐēĐžĐŊŅƒŅŽŅ‚ŅŒ Đ´Ņ–Ņ— С ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°Đŧи СаĐģĐĩĐļĐŊĐž Đ˛Ņ–Đ´ Ņ‚Ņ€Đ¸ĐŗĐĩŅ€Ņ–Đ˛ Ņ– ҄ҖĐģŅŒŅ‚Ņ€Ņ–Đ˛", "wrong_pin_code": "НĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊиК PIN-ĐēОд", "year": "Đ Ņ–Đē", "years_ago": "{years, plural, one {# ҀҖĐē} few {# Ņ€ĐžĐēи} many {# Ņ€ĐžĐēŅ–Đ˛} other {# Ņ€ĐžĐēŅ–Đ˛}} Ņ‚ĐžĐŧ҃", "yes": "ĐĸаĐē", "you_dont_have_any_shared_links": "ĐŖ Đ˛Đ°Ņ ĐŊĐĩĐŧĐ°Ņ” ҁĐŋŅ–ĐģҌĐŊĐ¸Ņ… ĐŋĐžŅĐ¸ĐģаĐŊҌ", "your_wifi_name": "Назва Đ˛Đ°ŅˆĐžŅ— Wi-Fi ĐŧĐĩŅ€ĐĩĐļŅ–", - "zero_to_clear_rating": "ĐŊĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ 0, Ņ‰ĐžĐą ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ Ņ„Đ°ĐšĐģ҃", + "zero_to_clear_rating": "ĐŊĐ°Ņ‚Đ¸ŅĐŊŅ–Ņ‚ŅŒ 0, Ņ‰ĐžĐą ҁĐēиĐŊŅƒŅ‚Đ¸ Ņ€ĐĩĐšŅ‚Đ¸ĐŊĐŗ ĐĩĐģĐĩĐŧĐĩĐŊŅ‚Đ°", "zoom_image": "Đ—ĐąŅ–ĐģŅŒŅˆĐ¸Ņ‚Đ¸ ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊĐŊŅ", "zoom_to_bounds": "Đ—ĐąŅ–ĐģŅŒŅˆĐ¸Ņ‚Đ¸ ĐŧĐ°ŅŅˆŅ‚Đ°Đą Đ´Đž ĐŧĐĩĐļ" } diff --git a/i18n/vi.json b/i18n/vi.json index e9d5fb4006..5c3ace5da0 100644 --- a/i18n/vi.json +++ b/i18n/vi.json @@ -441,7 +441,7 @@ "user_successfully_removed": "Ngưáģi dÚng {email} Ä‘ÃŖ đưáģŖc xÃŗa thành công.", "users_page_description": "Trang quáēŖn tráģ‹ ngưáģi dÚng", "version_check_enabled_description": "Báē­t kiáģƒm tra phiÃĒn báēŖn", - "version_check_implications": "Tính năng kiáģƒm tra phiÃĒn báēŖn yÃĒu cáē§u káēŋt náģ‘i thưáģng xuyÃĒn đáēŋn github.com", + "version_check_implications": "Tính năng kiáģƒm tra phiÃĒn báēŖn yÃĒu cáē§u káēŋt náģ‘i thưáģng xuyÃĒn đáēŋn {server}", "version_check_settings": "Kiáģƒm tra phiÃĒn báēŖn", "version_check_settings_description": "Báē­t/táē¯t thông bÃĄo phiÃĒn báēŖn máģ›i", "video_conversion_job": "Chuyáģƒn mÃŖ video", @@ -537,10 +537,10 @@ "app_bar_signout_dialog_content": "BáēĄn cÃŗ muáģ‘n đăng xuáēĨt?", "app_bar_signout_dialog_ok": "CÃŗ", "app_bar_signout_dialog_title": "Đăng xuáēĨt", - "app_download_links": "LiÃĒn káēŋt táēŖi app", - "app_settings": "App", - "app_stores": "Cáģ­a hàng app", - "app_update_available": "ÄÃŖ cÃŗ báēŖn cáē­p nháē­t app", + "app_download_links": "LiÃĒn káēŋt táēŖi áģŠng dáģĨng", + "app_settings": "áģ¨ng dáģĨng", + "app_stores": "Cáģ­a hàng áģŠng dáģĨng", + "app_update_available": "ÄÃŖ cÃŗ báēŖn cáē­p nháē­t áģŠng dáģĨng", "appears_in": "XuáēĨt hiáģ‡n trong", "apply_count": "Áp dáģĨng ({count, number})", "archive": "Lưu tráģ¯", @@ -617,7 +617,7 @@ "back_close_deselect": "Quay láēĄi, Ä‘Ãŗng, hoáēˇc báģ cháģn", "background_backup_running_error": "Sao lưu náģn hiáģ‡n đang cháēĄy, không tháģƒ báē¯t đáē§u sao lưu tháģ§ công", "background_location_permission": "Quyáģn truy cáē­p váģ‹ trí khi cháēĄy náģn", - "background_location_permission_content": "Đáģƒ chuyáģƒn đáģ•i máēĄng khi cháēĄy áģŸ cháēŋ đáģ™ náģn, Immich *luôn* pháēŖi cÃŗ quyáģn truy cáē­p váģ‹ trí chính xÃĄc đáģƒ cÃŗ tháģƒ Ä‘áģc tÃĒn máēĄng Wi-Fi", + "background_location_permission_content": "Đáģƒ chuyáģƒn đáģ•i máēĄng khi cháēĄy áģŸ cháēŋ đáģ™ náģn, Immich pháēŖi *luôn* cÃŗ quyáģn truy cáē­p váģ‹ trí chính xÃĄc đáģƒ cÃŗ tháģƒ Ä‘áģc tÃĒn máēĄng Wi-Fi", "background_options": "TÚy cháģn náģn", "backup": "Sao lưu", "backup_album_selection_page_albums_device": "Album trÃĒn thiáēŋt báģ‹ ({count})", @@ -637,8 +637,8 @@ "backup_background_service_in_progress_notification": "Đang sao lưu táģ‡p cáģ§a báēĄnâ€Ļ", "backup_background_service_upload_failure_notification": "TáēŖi lÃĒn {filename} tháēĨt báēĄi", "backup_controller_page_albums": "Album sao lưu", - "backup_controller_page_background_app_refresh_disabled_content": "Báē­t làm máģ›i app trong náģn táēĄi Cài đáēˇt > Cài đáēˇt chung > Làm máģ›i app trong náģn đáģƒ dÚng sao lưu náģn.", - "backup_controller_page_background_app_refresh_disabled_title": "Làm máģ›i app trong náģn báģ‹ vô hiáģ‡u hoÃĄ", + "backup_controller_page_background_app_refresh_disabled_content": "Báē­t làm máģ›i áģŠng dáģĨng trong náģn táēĄi Cài đáēˇt > Cài đáēˇt chung > Làm máģ›i áģŠng dáģĨng trong náģn đáģƒ dÚng sao lưu náģn.", + "backup_controller_page_background_app_refresh_disabled_title": "Làm máģ›i áģŠng dáģĨng trong náģn báģ‹ vô hiáģ‡u hoÃĄ", "backup_controller_page_background_app_refresh_enable_button_text": "Đi táģ›i cài đáēˇt", "backup_controller_page_background_battery_info_link": "Hưáģ›ng dáēĢn tôi", "backup_controller_page_background_battery_info_message": "Đáģƒ cÃŗ tráēŖi nghiáģ‡m sao lưu náģn táģ‘t nháēĨt, vui lÃ˛ng vô hiáģ‡u hÃŗa báēĨt káģŗ táģ‘i ưu hÃŗa pin nào đang háēĄn cháēŋ hoáēĄt đáģ™ng náģn cáģ§a Immich.\n\nVÃŦ điáģu này pháģĨ thuáģ™c vào thiáēŋt báģ‹, vui lÃ˛ng tham kháēŖo thông tin cáē§n thiáēŋt cáģ§a nhà sáēŖn xuáēĨt thiáēŋt báģ‹ cáģ§a báēĄn.", @@ -647,7 +647,7 @@ "backup_controller_page_background_charging": "Cháģ‰ khi đang sáēĄc", "backup_controller_page_background_configure_error": "CáēĨu hÃŦnh dáģ‹ch váģĨ náģn tháēĨt báēĄi", "backup_controller_page_background_delay": "TrÃŦ hoÃŖn sao lưu táģ‡p máģ›i: {duration}", - "backup_controller_page_background_description": "Báē­t dáģ‹ch váģĨ náģn đáģƒ táģą Ä‘áģ™ng sao lưu táģ‡p máģ›i mà không cáē§n máģŸ app", + "backup_controller_page_background_description": "Báē­t dáģ‹ch váģĨ náģn đáģƒ táģą Ä‘áģ™ng sao lưu táģ‡p máģ›i mà không cáē§n máģŸ áģŠng dáģĨng", "backup_controller_page_background_is_off": "Sao lưu táģą Ä‘áģ™ng trong náģn đang táē¯t", "backup_controller_page_background_is_on": "Sao lưu táģą Ä‘áģ™ng trong náģn đang báē­t", "backup_controller_page_background_turn_off": "Táē¯t dáģ‹ch váģĨ náģn", @@ -657,7 +657,7 @@ "backup_controller_page_backup_selected": "ÄÃŖ cháģn: ", "backup_controller_page_backup_sub": "áēĸnh và video Ä‘ÃŖ sao lưu", "backup_controller_page_created": "TáēĄo vào: {date}", - "backup_controller_page_desc_backup": "Báē­t sao lưu khi app hoáēĄt đáģ™ng đáģƒ táģą Ä‘áģ™ng sao lưu táģ‡p máģ›i lÃĒn mÃĄy cháģ§ khi máģŸ app.", + "backup_controller_page_desc_backup": "Báē­t sao lưu khi áģŠng dáģĨng hoáēĄt đáģ™ng đáģƒ táģą Ä‘áģ™ng sao lưu táģ‡p máģ›i lÃĒn mÃĄy cháģ§ khi máģŸ áģŠng dáģĨng.", "backup_controller_page_excluded": "ÄÃŖ báģ qua: ", "backup_controller_page_failed": "TháēĨt báēĄi ({count})", "backup_controller_page_filename": "TÃĒn táģ‡p: {filename} [{size}]", @@ -668,12 +668,12 @@ "backup_controller_page_remainder_sub": "Sáģ‘ lưáģŖng áēŖnh và video Ä‘ÃŖ cháģn chưa đưáģŖc sao lưu", "backup_controller_page_server_storage": "Dung lưáģŖng mÃĄy cháģ§", "backup_controller_page_start_backup": "Báē¯t đáē§u sao lưu", - "backup_controller_page_status_off": "Sao lưu táģą Ä‘áģ™ng khi app hoáēĄt đáģ™ng đang táē¯t", - "backup_controller_page_status_on": "Sao lưu táģą Ä‘áģ™ng khi app hoáēĄt đáģ™ng đang báē­t", + "backup_controller_page_status_off": "Sao lưu táģą Ä‘áģ™ng khi áģŠng dáģĨng hoáēĄt đáģ™ng đang táē¯t", + "backup_controller_page_status_on": "Sao lưu táģą Ä‘áģ™ng khi áģŠng dáģĨng hoáēĄt đáģ™ng đang báē­t", "backup_controller_page_storage_format": "ÄÃŖ dÚng {used} cáģ§a {total}", "backup_controller_page_to_backup": "CÃĄc album cáē§n đưáģŖc sao lưu", "backup_controller_page_total_sub": "TáēĨt cáēŖ áēŖnh và video không trÚng láē­p táģĢ cÃĄc album đưáģŖc cháģn", - "backup_controller_page_turn_off": "Táē¯t sao lưu khi app hoáēĄt đáģ™ng", + "backup_controller_page_turn_off": "Táē¯t sao lưu khi áģŠng dáģĨng hoáēĄt đáģ™ng", "backup_controller_page_turn_on": "Báē­t sao lưu khi máģŸ app", "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", @@ -704,16 +704,16 @@ "bulk_trash_duplicates_confirmation": "BáēĄn cÃŗ cháē¯c muáģ‘n đưa {count, plural, one {# táģ‡p trÚng láēˇp} other {# táģ‡p trÚng láēˇp}} vào thÚng rÃĄc? Điáģu này sáēŊ giáģ¯ láēĄi áēŖnh cháēĨt lưáģŖng nháēĨt cáģ§a máģ—i nhÃŗm và đưa táēĨt cáēŖ cÃĄc báēŖn trÚng láēˇp khÃĄc vào thÚng rÃĄc.", "buy": "Mua Immich", "cache_settings_clear_cache_button": "XÃŗa báģ™ nháģ› Ä‘áģ‡m", - "cache_settings_clear_cache_button_title": "XÃŗa báģ™ nháģ› Ä‘áģ‡m cáģ§a app. Điáģu này sáēŊ áēŖnh hưáģŸng đáēŋn hiáģ‡u suáēĨt cáģ§a app đáēŋn khi báģ™ nháģ› Ä‘áģ‡m đưáģŖc táēĄo láēĄi.", + "cache_settings_clear_cache_button_title": "XÃŗa báģ™ nháģ› Ä‘áģ‡m cáģ§a áģŠng dáģĨng. Điáģu này sáēŊ áēŖnh hưáģŸng đáēŋn hiáģ‡u suáēĨt cáģ§a áģŠng dáģĨng đáēŋn khi báģ™ nháģ› Ä‘áģ‡m đưáģŖc táēĄo láēĄi.", "cache_settings_duplicated_assets_clear_button": "XÓA", - "cache_settings_duplicated_assets_subtitle": "áēĸnh và video không đưáģŖc phÊp hiáģƒn tháģ‹ trÃĒn app", + "cache_settings_duplicated_assets_subtitle": "áēĸnh và video không đưáģŖc phÊp hiáģƒn tháģ‹ trÃĒn áģŠng dáģĨng", "cache_settings_duplicated_assets_title": "Táģ‡p báģ‹ trÚng ({count})", "cache_settings_statistics_album": "áēĸnh thu nháģ thư viáģ‡n", "cache_settings_statistics_full": "áēĸnh đáē§y đáģ§", "cache_settings_statistics_shared": "áēĸnh thu nháģ album chia sáēģ", "cache_settings_statistics_thumbnail": "áēĸnh thu nháģ", "cache_settings_statistics_title": "MáģŠc sáģ­ dáģĨng báģ™ nháģ› Ä‘áģ‡m", - "cache_settings_subtitle": "Kiáģƒm soÃĄt hành vi báģ™ nháģ› Ä‘áģ‡m cáģ§a app Immich", + "cache_settings_subtitle": "Kiáģƒm soÃĄt hành vi báģ™ nháģ› Ä‘áģ‡m cáģ§a Immich", "cache_settings_tile_subtitle": "Kiáģƒm soÃĄt cÃĄch xáģ­ lÃŊ lưu tráģ¯ cáģĨc báģ™", "cache_settings_tile_title": "Lưu tráģ¯ cáģĨc báģ™", "cache_settings_title": "Cài đáēˇt báģ™ nháģ› Ä‘áģ‡m", @@ -871,8 +871,8 @@ "current_pin_code": "MÃŖ PIN hiáģ‡n táēĄi", "current_server_address": "Đáģ‹a cháģ§ mÃĄy cháģ§ hiáģ‡n táēĄi", "custom_date": "Thiáēŋt láē­p ngày tÚy cháģ‰nh", - "custom_locale": "Ngôn ngáģ¯ và khu váģąc", - "custom_locale_description": "Đáģ‹nh dáēĄng ngày và sáģ‘ dáģąa trÃĒn ngôn ngáģ¯ và khu váģąc", + "custom_locale": "Khu váģąc tÚy cháģ‰nh", + "custom_locale_description": "Đáģ‹nh dáēĄng ngày, tháģi gian và sáģ‘ dáģąa trÃĒn ngôn ngáģ¯ và khu váģąc Ä‘ÃŖ cháģn", "custom_url": "URL tÚy cháģ‰nh", "cutoff_date_description": "Giáģ¯ láēĄi áēŖnh trong vÃ˛ngâ€Ļ", "cutoff_day": "{count, plural, one {ngày} other {ngày}}", @@ -880,7 +880,7 @@ "daily_title_text_date": "E, dd MMM", "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Táģ‘i", - "dark_theme": "Đáģ•i giao diáģ‡n", + "dark_theme": "Chuyáģƒn sang cháģ§ Ä‘áģ táģ‘i", "date": "Ngày", "date_after": "Ngày sau", "date_and_time": "Ngày và giáģ", @@ -891,10 +891,6 @@ "day": "Ngày", "days": "Ngày", "deduplicate_all": "XÃŗa táēĨt cáēŖ máģĨc trÚng láēˇp", - "deduplication_criteria_1": "Kích cáģĄ áēŖnh theo byte", - "deduplication_criteria_2": "Sáģ‘ lưáģŖng dáģ¯ liáģ‡u EXIF", - "deduplication_info": "Thông tin loáēĄi báģ dáģ¯ liáģ‡u trÚng láēˇp", - "deduplication_info_description": "Đáģƒ táģą Ä‘áģ™ng cháģn trưáģ›c và loáēĄi báģ cÃĄc táģ‡p trÚng láēˇp hàng loáēĄt, chÃēng tôi sáēŊ xem xÊt dáģąa trÃĒn:", "delete": "XÃŗa", "delete_action_confirmation_message": "BáēĄn cÃŗ cháē¯c muáģ‘n xÃŗa táģ‡p này? Thao tÃĄc này sáēŊ chuyáģƒn táģ‡p vào thÚng rÃĄc cáģ§a mÃĄy cháģ§ và sáēŊ háģi báēĄn cÃŗ muáģ‘n xÃŗa nÃŗ cáģĨc báģ™ không", "delete_action_prompt": "{count} Ä‘ÃŖ xÃŗa", @@ -1003,8 +999,8 @@ "editor_discard_edits_confirm": "Báģ thay đáģ•i", "editor_discard_edits_prompt": "BáēĄn cÃŗ nháģ¯ng thay đáģ•i chưa đưáģŖc lưu. BáēĄn cÃŗ cháē¯c cháē¯n muáģ‘n háģ§y báģ chÃēng không?", "editor_discard_edits_title": "Háģ§y thay đáģ•i?", - "editor_edits_applied_error": "Láģ—i khi ÃĄp dáģĨng thay đáģ•i", - "editor_edits_applied_success": "Thay đáģ•i đưáģŖc ÃĄp dáģĨng thành công", + "editor_edits_applied_error": "Không tháģƒ ÃĄp dáģĨng cháģ‰nh sáģ­a", + "editor_edits_applied_success": "Cháģ‰nh sáģ­a đưáģŖc ÃĄp dáģĨng thành công", "editor_flip_horizontal": "Láē­t ngang", "editor_flip_vertical": "Láē­t dáģc", "editor_orientation": "Đáģ‹nh hưáģ›ng", @@ -1072,7 +1068,7 @@ "failed_to_update_notification_status": "Cáē­p nháē­t tráēĄng thÃĄi thông bÃĄo tháēĨt báēĄi", "incorrect_email_or_password": "Email hoáēˇc máē­t kháēŠu không chính xÃĄc", "library_folder_already_exists": "Đưáģng dáēĢn nháē­p này Ä‘ÃŖ táģ“n táēĄi.", - "page_not_found": "Không tÃŦm tháēĨy trang :/", + "page_not_found": "Không tÃŦm tháēĨy trang", "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.", "quota_higher_than_disk_size": "BáēĄn Ä‘ÃŖ đáēˇt háēĄn máģŠc cao hÆĄn dung lưáģŖng áģ• Ä‘ÄŠa", @@ -1206,7 +1202,7 @@ "feature_photo_updated": "ÄÃŖ cáē­p nháē­t áēŖnh náģ•i báē­t", "features": "Tính năng", "features_in_development": "Tính năng đang đưáģŖc phÃĄt triáģƒn", - "features_setting_description": "QuáēŖn lÃŊ cÃĄc tính năng app", + "features_setting_description": "QuáēŖn lÃŊ cÃĄc tính năng áģŠng dáģĨng", "file_name_or_extension": "TÃĒn hoáēˇc pháē§n máģŸ ráģ™ng táē­p tin", "file_name_text": "TÃĒn táģ‡p", "file_name_with_value": "TÃĒn táģ‡p: {file_name}", @@ -1284,7 +1280,7 @@ "home_page_delete_remote_err_local": "Táģ‡p trÃĒn thiáēŋt báģ‹ trong láģąa cháģn xÃŗa táģĢ xa, báģ qua", "home_page_favorite_err_local": "Không tháģƒ thích táģ‡p trÃĒn thiáēŋt báģ‹, báģ qua", "home_page_favorite_err_partner": "Không tháģƒ thích táģ‡p cáģ§a ngưáģi thÃĸn, báģ qua", - "home_page_first_time_notice": "Náēŋu đÃĸy là láē§n đáē§u báēĄn dÚng app, hÃŖy cháģn máģ™t album sao lưu đáģƒ dÃ˛ng tháģi gian cÃŗ tháģƒ hiáģƒn tháģ‹ áēŖnh và video cáģ§a báēĄn", + "home_page_first_time_notice": "Náēŋu đÃĸy là láē§n đáē§u báēĄn dÚng áģŠng dáģĨng, hÃŖy cháģn máģ™t album sao lưu đáģƒ dÃ˛ng tháģi gian cÃŗ tháģƒ hiáģƒn tháģ‹ áēŖnh và video cáģ§a báēĄn", "home_page_locked_error_local": "Không tháģƒ di chuyáģƒn táģ‡p trÃĒn thiáēŋt báģ‹ Ä‘áēŋn thư máģĨc KhÃŗa, báģ qua", "home_page_locked_error_partner": "Không tháģƒ di chuyáģƒn táģ‡p cáģ§a ngưáģi thÃĸn đáēŋn thư máģĨc KhÃŗa, báģ qua", "home_page_share_err_local": "Không tháģƒ chia sáēģ táģ‡p trÃĒn thiáēŋt báģ‹ qua liÃĒn káēŋt, báģ qua", @@ -1399,7 +1395,7 @@ "local_id": "ID cáģĨc báģ™", "local_media_summary": "Mô táēŖ phÆ°ÆĄng tiáģ‡n trÃĒn thiáēŋt báģ‹", "local_network": "MáēĄng náģ™i báģ™", - "local_network_sheet_info": "App 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", + "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", @@ -1475,11 +1471,11 @@ "manage_geolocation": "QuáēŖn lÃŊ đáģ‹a điáģƒm", "manage_media_access_rationale": "Đáģƒ cÃŗ tháģƒ di chuyáģƒn táģ‡p vào thÚng rÃĄc và khôi pháģĨc chÃēng táģĢ Ä‘Ãŗ.", "manage_media_access_settings": "MáģŸ cài đáēˇt", - "manage_media_access_subtitle": "Cho phÊp app [Immich] quáēŖn lÃŊ và di chuyáģƒn táģ‡p.", + "manage_media_access_subtitle": "Cho phÊp áģŠng dáģĨng [Immich] quáēŖn lÃŊ và di chuyáģƒn táģ‡p.", "manage_media_access_title": "QuáēŖn lÃŊ phÆ°ÆĄng tiáģ‡n", "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 app", + "manage_the_app_settings": "QuáēŖn lÃŊ cài đáēˇt áģŠng dáģĨng", "manage_your_account": "QuáēŖn lÃŊ tài khoáēŖn cáģ§a báēĄn", "manage_your_api_keys": "QuáēŖn lÃŊ cÃĄc khÃŗa API cáģ§a báēĄn", "manage_your_devices": "QuáēŖn lÃŊ cÃĄc thiáēŋt báģ‹ Ä‘ÃŖ đăng nháē­p cáģ§a báēĄn", @@ -1494,7 +1490,7 @@ "map_marker_for_images": "ÄÃĄnh dáēĨu báēŖn đáģ“ cho áēŖnh cháģĨp táēĄi {city}, {country}", "map_marker_with_image": "ÄÃĄnh dáēĨu báēŖn đáģ“ váģ›i áēŖnh", "map_no_location_permission_content": "Cáē§n quyáģn truy cáē­p váģ‹ trí đáģƒ hiáģƒn tháģ‹ táģ‡p táģĢ váģ‹ trí hiáģ‡n táēĄi cáģ§a báēĄn. BáēĄn cÃŗ muáģ‘n cho phÊp ngay bÃĸy giáģ không?", - "map_no_location_permission_title": "App không đưáģŖc phÊp truy cáē­p váģ‹ trí", + "map_no_location_permission_title": "áģ¨ng dáģĨng không đưáģŖc phÊp truy cáē­p váģ‹ trí", "map_settings": "Cài đáēˇt báēŖn đáģ“", "map_settings_dark_mode": "Cháēŋ đáģ™ táģ‘i", "map_settings_date_range_option_day": "Trong vÃ˛ng 24 giáģ qua", @@ -1649,6 +1645,7 @@ "only_favorites": "Cháģ‰ lưáģŖt thích", "open": "MáģŸ", "open_calendar": "Hiáģ‡n tháģ‹ láģ‹ch", + "open_in_browser": "MáģŸ trong trÃŦnh duyáģ‡t", "open_in_map_view": "MáģŸ trong báēŖn đáģ“", "open_in_openstreetmap": "MáģŸ trong OpenStreetMap", "open_the_search_filters": "MáģŸ báģ™ láģc tÃŦm kiáēŋm", @@ -1749,7 +1746,7 @@ "play_transcoded_video": "PhÃĄt video Ä‘ÃŖ chuyáģƒn mÃŖ", "please_auth_to_access": "Vui lÃ˛ng xÃĄc tháģąc đáģƒ truy cáē­p", "port": "Cáģ•ng", - "preferences_settings_subtitle": "TÚy cháģ‰nh tráēŖi nghiáģ‡m app", + "preferences_settings_subtitle": "TÚy cháģ‰nh tráēŖi nghiáģ‡m áģŠng dáģĨng", "preferences_settings_title": "CÃĄ nhÃĸn hÃŗa", "preparing": "Đang chuáēŠn báģ‹", "preset": "MáēĢu cÃŗ sáēĩn", @@ -1763,7 +1760,7 @@ "primary": "Chính", "privacy": "BáēŖo máē­t", "profile": "Háģ“ sÆĄ", - "profile_drawer_app_logs": "Log", + "profile_drawer_app_logs": "Nháē­t kÃŊ", "profile_drawer_client_server_up_to_date": "MÃĄy khÃĄch và mÃĄy cháģ§ Ä‘ÃŖ cáē­p nháē­t", "profile_drawer_github": "GitHub", "profile_drawer_readonly_mode": "ÄÃŖ báē­t cháēŋ đáģ™ cháģ‰-xem. NháēĨn giáģ¯ áēŖnh đáēĄi diáģ‡n ngưáģi dÚng đáģƒ táē¯t.", @@ -1808,7 +1805,7 @@ "rate_asset": "Asset ÄÃĄnh giÃĄ", "rating": "Xáēŋp háēĄng sao", "rating_clear": "XÃŗa xáēŋp háēĄng", - "rating_count": "{count, plural, one {# sao} other {# sao}}", + "rating_count": "{count, plural, =0 {Chưa xáēŋp háēĄng} one {# sao} other {# sao}}", "rating_description": "Hiáģƒn tháģ‹ xáēŋp háēĄng EXIF trong báēŖng thông tin", "reaction_options": "TÚy cháģn pháēŖn áģŠng", "read_changelog": "Đáģc nháē­t kÃŊ thay đáģ•i", @@ -1881,7 +1878,10 @@ "reset_pin_code_success": "Đáēˇt láēĄi mÃŖ PIN thành công", "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_sqlite": "Đáēˇt láēĄi cÆĄ sáģŸ dáģ¯ liáģ‡u SQLite", - "reset_sqlite_confirmation": "BáēĄn cÃŗ cháē¯c muáģ‘n đáēˇt láēĄi cÆĄ sáģŸ dáģ¯ liáģ‡u SQLite? BáēĄn sáēŊ cáē§n đăng xuáēĨt và đăng nháē­p láēĄi đáģƒ Ä‘áģ“ng báģ™ láēĄi dáģ¯ liáģ‡u", + "reset_sqlite_clear_app_data": "XÃŗa dáģ¯ liáģ‡u", + "reset_sqlite_confirmation": "BáēĄn cÃŗ cháē¯c muáģ‘n xÃŗa dáģ¯ liáģ‡u áģŠng dáģĨng không? Thao tÃĄc này sáēŊ xÃŗa táēĨt cáēŖ cài đáēˇt và đăng xuáēĨt báēĄn kháģi áģŠng dáģĨng.", + "reset_sqlite_confirmation_note": "Lưu ÃŊ: BáēĄn cáē§n kháģŸi đáģ™ng láēĄi áģŠng dáģĨng sau khi xÃŗa.", + "reset_sqlite_done": "Dáģ¯ liáģ‡u áģŠng dáģĨng Ä‘ÃŖ đưáģŖc xÃŗa. Vui lÃ˛ng kháģŸi đáģ™ng láēĄi Immich và đăng nháē­p láēĄi.", "reset_sqlite_success": "ÄÃŖ thiáēŋt láē­p láēĄi cÆĄ sáģŸ dáģ¯ liáģ‡u SQLite thành công", "reset_to_default": "Đáēˇt láēĄi váģ máēˇc đáģ‹nh", "resolution": "Đáģ™ phÃĸn giáēŖi", @@ -2006,7 +2006,7 @@ "send_message": "Gáģ­i tin nháē¯n", "send_welcome_email": "Gáģ­i email chào máģĢng", "server_endpoint": "Đáģ‹a cháģ‰ mÃĄy cháģ§", - "server_info_box_app_version": "PhiÃĒn báēŖn app", + "server_info_box_app_version": "PhiÃĒn báēŖn áģŠng dáģĨng", "server_info_box_server_url": "URL mÃĄy cháģ§", "server_offline": "MÃĄy cháģ§ ngoáēĄi tuyáēŋn", "server_online": "PhiÃĒn báēŖn", @@ -2228,7 +2228,7 @@ "theme_setting_primary_color_title": "Màu cháģ§ Ä‘áēĄo", "theme_setting_system_primary_color_title": "DÚng màu háģ‡ tháģ‘ng", "theme_setting_system_theme_switch": "Táģą Ä‘áģ™ng (Giáģ‘ng thiáēŋt báģ‹)", - "theme_setting_theme_subtitle": "Cháģn cài đáēˇt giao diáģ‡n app", + "theme_setting_theme_subtitle": "Cháģn cài đáēˇt giao diáģ‡n áģŠng dáģĨng", "theme_setting_three_stage_loading_subtitle": "TáēŖi ba giai đoáēĄn cÃŗ tháģƒ tăng táģ‘c đáģ™ táēŖi áēŖnh nhưng sáēŊ táģ‘n dáģ¯ liáģ‡u máēĄng Ä‘ÃĄng káģƒ", "theme_setting_three_stage_loading_title": "Báē­t táēŖi ba giai đoáēĄn", "then": "Tiáēŋp theo", @@ -2276,7 +2276,7 @@ "troubleshoot": "Kháē¯c pháģĨc sáģą cáģ‘", "type": "LoáēĄi", "unable_to_change_pin_code": "Thay đáģ•i mÃŖ PIN tháēĨt báēĄi", - "unable_to_check_version": "Không tháģƒ kiáģƒm tra phiÃĒn báēŖn app hoáēˇc mÃĄy cháģ§", + "unable_to_check_version": "Không tháģƒ kiáģƒm tra phiÃĒn báēŖn áģŠng dáģĨng hoáēˇc mÃĄy cháģ§", "unable_to_setup_pin_code": "Thiáēŋt láē­p mÃŖ PIN tháēĨt báēĄi", "unarchive": "Báģ lưu tráģ¯", "unarchive_action_prompt": "{count} Ä‘ÃŖ báģ kháģi Lưu tráģ¯", @@ -2332,6 +2332,8 @@ "url": "URL", "usage": "Sáģ­ dáģĨng", "use_biometric": "DÚng sinh tráē¯c háģc", + "use_browser_locale": "DÚng ngôn ngáģ¯ trÃŦnh duyáģ‡t", + "use_browser_locale_description": "Đáģ‹nh dáēĄng ngày, tháģi gian và sáģ‘ dáģąa trÃĒn ngôn ngáģ¯ trÃŦnh duyáģ‡t", "use_current_connection": "DÚng káēŋt náģ‘i hiáģ‡n táēĄi", "use_custom_date_range": "Cháģn khoáēŖng tháģi gian tÚy cháģ‰nh", "user": "Ngưáģi dÚng", diff --git a/i18n/yue_Hant.json b/i18n/yue_Hant.json index ab1ff60fef..19666b0af5 100644 --- a/i18n/yue_Hant.json +++ b/i18n/yue_Hant.json @@ -86,18 +86,21 @@ "export_config_as_json_description": "å°‡į›Žå‰å˜…įŗģįĩąč¨­åŽšä¸‹čŧ‰į‚ē JSON æĒ”æĄˆ", "external_libraries_page_description": "įŽĄį†å¤–éƒ¨åĒ’éĢ”åēĢ嘅頁éĸ", "face_detection": "äēēéĸåĩæ¸Ŧ", - "face_detection_description": "į”¨æŠŸå™¨å­¸įŋ’åšŸæœå°‹į›¸ä¸­å˜…ã€‚", + "face_detection_description": "äŊŋį”¨æŠŸå™¨å­¸įŋ’åĩæ¸Ŧé …į›Žä¸­å˜…č‡‰å­”ã€‚å°æ–ŧåŊąį‰‡īŧŒåĒäŋ‚æœƒåˆ†æžį¸Žåœ–ã€‚ã€Œé‡æ–°æ•´į†ã€æœƒé‡æ–°č™•į†æ‰€æœ‰å˜…é …į›Žīŧ›ã€Œé‡č¨­ã€å°ąæœƒéĄå¤–æ¸…é™¤į›Žå‰å˜…č‡‰å­”čŗ‡æ–™īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€æœƒå°‡å°šæœĒč™•į†å˜…é …į›ŽåŠ å…Ĩåēåˆ—ã€‚åŽŒæˆã€Œč‡‰å­”åĩæ¸Ŧ」垌īŧŒåĩæ¸Ŧåˆ°å˜…č‡‰å­”å°‡æœƒåŠ å…Ĩã€Œč‡‰å­”čž¨č­˜ã€æŽ’į¨‹īŧŒä¸Ļæ­¸éĄžåˆ°č€ŒåŽļæˆ–č€…æ–°å˜…äēēį‰Šįž¤įĩ„。", + "facial_recognition_job_description": "將åĩæ¸Ŧåˆ°å˜…č‡‰å­”æ­¸éĄžį‚ēäēēį‰Šã€‚æ­¤æ­ĨéŠŸæœƒåœ¨č‡‰å­”åĩæ¸ŦåŽŒæˆåžŒåŸˇčĄŒã€‚ã€Œé‡č¨­ã€æœƒé‡æ–°å°æ‰€æœ‰å˜…č‡‰å­”é€˛čĄŒåˆ†įž¤īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€å°ąæœƒå°‡æœĒ指洞äēēį‰Šå˜…č‡‰å­”åŠ å…Ĩåēåˆ—。", "failed_job_command": "åŸˇčĄŒ{job}äģģ務嘅{command}指äģ¤å¤ąæ•—", "force_delete_user_warning": "č­Ļ告īŧšå‘ĸ個會įĢ‹åŗåˆĒ除ᔍæˆļ同埋äŊĸ所有嘅æĒ”æĄˆã€‚å‘ĸ個äŋ‚į„Ąæŗ•æ’¤éŠˇå˜…å‹•äŊœīŧŒč€Œä¸”åˆĒ除嘅æĒ”æĄˆå°‡å†‡čžĻæŗ•åžŠåŽŸã€‚", "image_format": "æ ŧåŧ", "image_format_description": "WebP æ ŧåŧį›¸å˜…æĒ”æĄˆæœƒæ¯” JPEG į´°īŧŒäŊ†äŋ‚ᎍįĸŧ嘅速åēĻæœƒæ…ĸå•˛ã€‚", "image_fullsize_description": "厞åˆĒ除元數據嘅全å°ē坏ᛏīŧŒå–ēæ”žå¤§į›¸å˜…æ™‚å€™į”¨å˜…", "image_fullsize_enabled": "å•Ÿį”¨å…¨å°ēå¯¸å˜…åœ–į‰‡į”Ÿæˆ", - "image_fullsize_enabled_description": "į‚ē非įļ˛é å‹å–„æ ŧåŧį”Ÿæˆå¤§å°ēå¯¸åœ–į‰‡ã€‚å•Ÿį”¨", + "image_fullsize_enabled_description": "į‚ē非įļ˛é å‹å–„æ ŧåŧį”ĸį”Ÿå¤§å°ēå¯¸å˜…į›¸ã€‚å•Ÿį”¨ã€ŒååĨŊ內åĩŒé čĻŊ」嘅時候īŧŒįŗģįĩąå°‡æœƒį›´æŽĨᔍ內åĩŒå˜…預čĻŊč€Œå””é€˛čĄŒčŊ‰įĸŧ。å‘ĸå€‹č¨­åŽšå””æœƒåŊąéŸŋ JPEG į­‰įļ˛é å‹å–„æ ŧåŧã€‚", "image_fullsize_quality_description": "į”ą 1 到 100īŧŒį”Ÿæˆå…¨å°ēå¯¸åœ–į‰‡å˜…čŗĒį´ ã€‚æ•¸å€ŧčļŠé̘į•ĢčŗĒčļŠåĨŊīŧŒäŊ†äŋ‚æĒ”æĄˆæœƒæ›´åŠ å¤§ã€‚", "image_fullsize_title": "全å°ēå¯¸åœ–į‰‡č¨­åŽš", "image_prefer_embedded_preview": "偏向åĩŒå…Ĩ預čĻŊ", + "image_prefer_embedded_preview_setting_description": "å–ēå¯į”¨å˜…æ™‚å€™å°‡ RAW į›¸į‰‡ä¸­įš„å…§åĩŒé čĻŊäŊœį‚ēåŊąåƒč™•į†å˜…čŧ¸å…Ĩ來æēã€‚é›–į„ļå‘ĸå€‹č¨­åŽšå¯äģĨäģ¤åˆ°éƒ¨åˆ†į›¸į‰‡å˜…色åŊŠæ›´åŠ æē–įĸēīŧŒäŊ†é čĻŊ品čŗĒ取æąēæ–ŧį›¸æŠŸīŧŒä¸”åŊąåƒå¯čƒŊ會å‡ēįžčŧƒå¤šåŖ“į¸Žį‘•į–ĩ。", "image_prefer_wide_gamut": "傞向åģŖč‰˛åŸŸ", + "image_prefer_wide_gamut_setting_description": "äŊŋᔍ Display P3 čŖŊäŊœį¸Žåœ–īŧšå¯äģĨ更åĨŊ地äŋį•™åģŖč‰˛åŸŸåŊąåƒå˜…鎎蹔åēĻīŧŒäŊ†äŋ‚å–ēčˆŠčŖįŊŽåŒčˆŠį‰ˆį€čĻŊ器上īŧŒåŊąåƒå‘ˆįžå˜…效果可čƒŊ會有所唔同。sRGB åŊąåƒæœƒäŋį•™į‚ē sRGBīŧŒäģĨéŋå…č‰˛åŊŠåį§ģ。", "image_preview_description": "䏭ᭉå°ēå¯¸å˜…åœ–į‰‡īŧŒį”¨åšŸæĒĸčĻ–å–Žä¸€åŊąåƒåŒåŸ‹æŠŸå™¨å­¸įŋ’", "image_preview_title": "預čĻŊč¨­åŽš", "image_progressive": "逐æ­Ĩ", diff --git a/i18n/zh_Hans.json b/i18n/zh_Hans.json index 2a85e2e3b7..49dbce4035 100644 --- a/i18n/zh_Hans.json +++ b/i18n/zh_Hans.json @@ -5,7 +5,7 @@ "acknowledge": "厞įŸĨ悉", "action": "操äŊœ", "action_common_update": "更新", - "action_description": "å¯šį­›é€‰å‡ēįš„čĩ„äē§æ‰§čĄŒįš„一į섿“äŊœ", + "action_description": "å¯šį­›é€‰å‡ēįš„į…§į‰‡/视éĸ‘æ‰§čĄŒįš„ä¸€į섿“äŊœ", "actions": "操äŊœ", "active": "čŋ›čĄŒä¸­", "active_count": "æ´ģ动: {count}", @@ -18,7 +18,7 @@ "add_a_title": "æˇģ加标éĸ˜", "add_action": "æˇģ加操äŊœ", "add_action_description": "į‚šå‡ģäģĨæˇģ加čĻæ‰§čĄŒįš„æ“äŊœ", - "add_assets": "æˇģ加čĩ„äē§", + "add_assets": "æˇģåŠ éĄšį›Ž", "add_birthday": "æˇģåŠ į”Ÿæ—Ĩ", "add_endpoint": "æˇģ加įĢ¯į‚š", "add_exclusion_pattern": "æˇģåŠ æŽ’é™¤č§„åˆ™", @@ -34,13 +34,13 @@ "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_album_bottom_sheet_some_local_assets": "部分æœŦ地čĩ„äē§æ— æŗ•æˇģåŠ č‡ŗį›¸å†Œ", "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_upload_to_stack": "æˇģ加上äŧ č‡ŗå †å ", "add_url": "æˇģ加 URL", "add_workflow_step": "æˇģ加åˇĨäŊœæĩæ­ĨéǤ", "added_to_archive": "æˇģåŠ č‡ŗå­˜æĄŖ", @@ -49,9 +49,9 @@ "admin": { "add_exclusion_pattern_description": "æˇģåŠ æŽ’é™¤æ¨Ąåŧīŧˆæ”¯æŒ  * ,  ** ,  ?  通配įŦĻīŧ‰ã€‚äž‹åĻ‚īŧšåŋŊį•Ĩ \"Raw\" į›ŽåŊ•蝎ᔍ  \"**/Raw/**\" īŧ›åŋŊį•Ĩ \".tif\" 文äģļ蝎ᔍ  \"**/*.tif\" īŧ›åŋŊį•Ĩįģå¯ščˇ¯åž„蝎ᔍ  \"/path/to/ignore/**\" 。", "admin_user": "įŽĄį†å‘˜į”¨æˆˇ", - "asset_offline_description": "æœĒ扞到č¯Ĩ外部čĩ„äē§å瓿–‡äģļīŧŒåˇ˛å°†å…ļį§ģč‡ŗå›žæ”ļįĢ™ã€‚åĻ‚æžœæ–‡äģ￘¯åœ¨åē“内čĸĢį§ģ动īŧŒč¯ˇåœ¨æ—ļ间įēŋ中æŸĨ扞寚åē”įš„æ–°čĩ„äē§ã€‚åĻ‚éœ€æĸ复此čĩ„äē§īŧŒč¯ˇįĄŽäŋ Immich 可čŽŋé—Žä¸‹æ–šįš„æ–‡äģļčˇ¯åž„īŧŒåšļ重新æ‰Ģ描č¯Ĩčĩ„äē§åē“。", + "asset_offline_description": "æœĒ扞到č¯Ĩ外部čĩ„æēå瓿–‡äģļīŧŒåˇ˛å°†å…ļį§ģč‡ŗå›žæ”ļįĢ™ã€‚åĻ‚æžœæ–‡äģ￘¯åœ¨čĩ„æēåē“内čĸĢį§ģ动īŧŒč¯ˇåœ¨æ—ļ间įēŋ中æŸĨ扞寚åē”įš„æ–°æ–‡äģļ。åĻ‚éœ€æĸ复此文äģļīŧŒč¯ˇįĄŽäŋ Immich 可čŽŋé—Žä¸‹æ–šįš„æ–‡äģļčˇ¯åž„īŧŒåšļ重新æ‰Ģ描č¯Ĩčĩ„æēåē“。", "authentication_settings": "čŽ¤č¯čŽžįŊŽ", - "authentication_settings_description": "įŽĄį†å¯†į ã€OAuth 和å…ļåŽƒčŽ¤č¯čŽžįŊŽ", + "authentication_settings_description": "įŽĄį†å¯†į ã€OAuth 和å…ļäģ–čŽ¤č¯čŽžįŊŽ", "authentication_settings_disable_all": "æ‚¨įĄŽåŽščρįĻį”¨æ‰€æœ‰į™ģåŊ•æ–šåŧå—īŧŸį™ģåŊ•功čƒŊå°†åŽŒå…¨å¤ąæ•ˆã€‚", "authentication_settings_reenable": "åĻ‚éœ€é‡æ–°å¯į”¨īŧŒč¯ˇäŊŋᔍ æœåŠĄå™¨å‘Ŋäģ¤ã€‚", "background_task_job": "后台äģģåŠĄ", @@ -61,40 +61,40 @@ "backup_onboarding_1_description": "åŧ‚地备äģŊīŧŒäž‹åĻ‚å­˜å‚¨åœ¨äē‘įĢ¯æˆ–åĻ一ä¸Ēį‰Šį†äŊįŊŽã€‚", "backup_onboarding_2_description": "æœŦåœ°å¤ščŽžå¤‡å‰¯æœŦã€‚åŗåœ¨ä¸åŒčŽžå¤‡ä¸Šäŋå­˜ä¸ģ文äģļ及å…ļæœŦ地备äģŊ。", "backup_onboarding_3_description": "æ•°æŽįš„æ€ģ副æœŦ数īŧŒåŒ…åĢ原始文äģļ。䞋åĻ‚īŧš1 äģŊåŧ‚地备äģŊ和 2 äģŊæœŦ地副æœŦ。", - "backup_onboarding_description": "åģēčŽŽé‡‡į”¨ 3-2-1 备äģŊį­–į•Ĩ æĨäŋæŠ¤æ‚¨įš„æ•°æŽã€‚äŊ åē”č¯Ĩäŋį•™åˇ˛ä¸Šäŧ įš„ᅧቇ/视éĸ‘äģĨ及 Immich 数捎åē“įš„å‰¯æœŦīŧŒäģĨåŽžįŽ°å…¨éĸįš„å¤‡äģŊč§Ŗå†ŗæ–šæĄˆã€‚", + "backup_onboarding_description": "åģēčŽŽé‡‡į”¨ 3-2-1 备äģŊį­–į•Ĩ æĨäŋæŠ¤äŊ įš„æ•°æŽã€‚ä¸ēäē†åŽžįŽ°å…¨éĸįš„å¤‡äģŊæ–šæĄˆīŧŒäŊ åē”č¯Ĩ同æ—ļäŋå­˜åˇ˛ä¸Šäŧ įš„ᅧቇ/视éĸ‘副æœŦäģĨ及 Immich įš„æ•°æŽåē“。", "backup_onboarding_footer": "æœ‰å…ŗå¤‡äģŊ Immich įš„æ›´å¤šäŋĄæ¯īŧŒč¯ˇå‚阅 æ–‡æĄŖã€‚", - "backup_onboarding_parts_title": "3-2-1 备äģŊį­–į•Ĩ包æ‹Ŧīŧš", + "backup_onboarding_parts_title": "3-2-1备äģŊ原则包æ‹Ŧīŧš", "backup_onboarding_title": "备äģŊ", "backup_settings": "数捎åē“备äģŊ莞įŊŽ", "backup_settings_description": "įŽĄį†æ•°æŽåē“备äģŊ莞įŊŽã€‚", "cleared_jobs": "åˇ˛æ¸…é™¤ {job} įš„äģģåŠĄ", "config_set_by_file": "åŊ“前配įŊŽį”ąé…įŊŽæ–‡äģļčŽžåŽš", - "confirm_delete_library": "įĄŽåŽščĻåˆ é™¤čĩ„äē§åē“ \"{library}\" 吗īŧŸ", - "confirm_delete_library_assets": "įĄŽåŽščĻåˆ é™¤æ­¤čĩ„äē§åē“吗īŧŸæ­¤æ“äŊœå°†äģŽ Immich 中删除 {count, plural, one {# ä¸Ē兺联čĩ„äē§} other {全部 # ä¸Ē兺联čĩ„äē§}}īŧŒä¸”æ— æŗ•æ’¤é”€ã€‚æŗ¨æ„īŧšæ–‡äģļäģå°†äŋį•™åœ¨įŖį›˜ä¸Šã€‚", - "confirm_email_below": "ä¸ēįĄŽčŽ¤æ“äŊœīŧŒč¯ˇåœ¨ä¸‹æ–ščž“å…Ĩ \"{email}\"", + "confirm_delete_library": "įĄŽåŽščĻåˆ é™¤čĩ„æēåē“ \"{library}\" 吗īŧŸ", + "confirm_delete_library_assets": "įĄŽåŽščĻåˆ é™¤æ­¤čĩ„æēåē“吗īŧŸæ­¤æ“äŊœå°†äģŽ Immich 中删除 {count, plural, one {# ä¸Ēå…ŗč”éĄšį›Ž} other {å…ą # ä¸Ēå…ŗč”éĄšį›Ž}}īŧŒä¸”æ— æŗ•æ’¤é”€ã€‚æŗ¨æ„īŧšæ–‡äģļäģå°†äŋį•™åœ¨įŖį›˜ä¸Šã€‚", + "confirm_email_below": "ä¸ēįĄŽčŽ¤æ“äŊœīŧŒč¯ˇåœ¨ä¸‹æ–ščž“å…Ĩ“{email}”", "confirm_reprocess_all_faces": "įĄŽåŽščĻé‡æ–°å¤„į†æ‰€æœ‰äēē脏吗īŧŸæ­¤æ“äŊœå°†æ¸…除厞å‘Ŋåįš„äēēį‰Šã€‚", "confirm_user_password_reset": "įĄŽåŽščĻé‡įŊŽ {user} įš„å¯†į å—īŧŸ", "confirm_user_pin_code_reset": "įĄŽåŽščĻé‡įŊŽ {user} įš„ PIN ᠁吗īŧŸ", "copy_config_to_clipboard_description": "将åŊ“前įŗģįģŸé…įŊŽäŊœä¸ē JSON å¯ščąĄå¤åˆļ到å‰Ēč´´æŋ", "create_job": "创åģēäģģåŠĄ", - "cron_expression": "Cron 襨螞åŧ", - "cron_expression_description": "äŊŋᔍ Cron æ ŧåŧčŽžįŊŽæ‰Ģ描间隔。更多äŋĄæ¯č¯ˇå‚č€ƒ Crontab Guru į­‰įŊ‘įĢ™", - "cron_expression_presets": "Cron 襨螞åŧéĸ„莞", + "cron_expression": "Cron襨螞åŧ", + "cron_expression_description": "äŊŋᔍCronæ ŧåŧčŽžįŊŽæ‰Ģ描间隔。更多äŋĄæ¯č¯ˇå‚č€ƒ Crontab Guru į­‰įŊ‘įĢ™", + "cron_expression_presets": "Cron襨螞åŧéĸ„莞", "disable_login": "įρᔍį™ģåŊ•", "duplicate_detection_job_description": "čŋčĄŒæœē器å­Ļäš æĨæŖ€æĩ‹į›¸äŧŧ回像īŧŒæ­¤åŠŸčƒŊ䞝čĩ–äēŽæ™ēčƒŊ搜į´ĸ", - "exclusion_pattern_description": "æŽ’é™¤č§„åˆ™å…čŽ¸æ‚¨åœ¨æ‰Ģ描čĩ„äē§å瓿—ļåŋŊį•Ĩį‰šåŽšįš„æ–‡äģļ和文äģļ多。åĻ‚æžœæ‚¨æœ‰æŸäē›åŒ…åĢ不希望å¯ŧå…Ĩįš„æ–‡äģļīŧˆäž‹åĻ‚ RAW æ ŧåŧæ–‡äģļīŧ‰įš„æ–‡äģļ多īŧŒæ­¤åŠŸčƒŊå°†éžå¸¸æœ‰į”¨ã€‚", + "exclusion_pattern_description": "æŽ’é™¤č§„åˆ™å…čŽ¸æ‚¨åœ¨æ‰Ģ描čĩ„æēå瓿—ļåŋŊį•Ĩį‰šåŽšįš„æ–‡äģļ和文äģļ多。åĻ‚æžœæ‚¨æœ‰æŸäē›åŒ…åĢ不希望å¯ŧå…Ĩįš„æ–‡äģļīŧˆäž‹åĻ‚ RAW æ ŧåŧæ–‡äģļīŧ‰įš„æ–‡äģļ多īŧŒæ­¤åŠŸčƒŊå°†éžå¸¸æœ‰į”¨ã€‚", "export_config_as_json_description": "将åŊ“前įŗģįģŸé…įŊŽä¸‹čŊŊä¸ē JSON 文äģļ", - "external_libraries_page_description": "įŽĄį†å¤–éƒ¨čĩ„äē§åē“", + "external_libraries_page_description": "įŽĄį†å¤–éƒ¨čĩ„æēåē“", "face_detection": "äēēč„¸æŖ€æĩ‹", "face_detection_description": "äŊŋᔍæœē器å­Ļäš æŖ€æĩ‹åŊąåƒä¸­įš„äēē脸īŧŒå¯šäēŽč§†éĸ‘äģ…处ᐆå…ļįŧŠį•Ĩå›žã€‚â€œåˆˇæ–°â€äŧšé‡æ–°å¤„į†æ‰€æœ‰åŊąåƒīŧ›â€œé‡įŊŽâ€äŧ𿏅除åŊ“前所有äēēč„¸æ•°æŽīŧ›â€œįŧēå¤ąâ€åˆ™äģ…å°†æœĒæ›žå¤„į†čŋ‡įš„åŊąåƒåŠ å…Ĩ队列。åŊ““äēēč„¸æŖ€æĩ‹â€åŽŒæˆåŽīŧŒįŗģįģŸäŧšå°†æ–°æŖ€æĩ‹åˆ°įš„äēēč„¸æ”žå…Ĩ“äēē脏蝆åˆĢ”队列īŧŒäģĨ将å…ļåŊ’įąģåˆ°įŽ°æœ‰æˆ–æ–°åģēįš„äēēį‰Šåˆ†įģ„中。", "facial_recognition_job_description": "å°†æŖ€æĩ‹åˆ°įš„äēē脸åŊ’įąģä¸ēä¸åŒįš„äēēį‰ŠīŧŒæ­¤æ­ĨéĒ¤éœ€åœ¨â€œäēēč„¸æŖ€æĩ‹â€åŽŒæˆåŽčŋčĄŒã€‚“重įŊŽâ€äŧšīŧˆé‡æ–°īŧ‰čšįąģ所有äēēč„¸ã€‚â€œįŧēå¤ąâ€åˆ™å°†å°šæœĒįĄŽåŽšæ˜¯č°įš„äēēč„¸åŠ å…ĨåŊ’įąģ队列。", "failed_job_command": "å‘Ŋäģ¤ {command} åœ¨æ‰§čĄŒäģģåŠĄ {job} æ—ļå¤ąč´Ĩ", - "force_delete_user_warning": "č­Ļ告īŧšæ­¤æ“äŊœå°†įĢ‹åŗåˆ é™¤č¯Ĩį”¨æˆˇåŠå…ļ所有čĩ„äē§ã€‚此操äŊœä¸å¯æ’¤é”€īŧŒä¸”æ–‡äģļæ— æŗ•æĸ复。", + "force_delete_user_warning": "č­Ļ告īŧšæ­¤æ“äŊœå°†įĢ‹åŗåˆ é™¤č¯Ĩį”¨æˆˇåŠå…ļ所有文äģļ。此操äŊœä¸å¯æ’¤é”€īŧŒä¸”æ–‡äģļæ— æŗ•æĸ复。", "image_format": "æ ŧåŧ", - "image_format_description": "WebP æ ŧåŧįš„æ–‡äģļäŊ“į§¯æ¯” JPEG 更小īŧŒäŊ†įŧ–į é€ŸåēĻ螃æ…ĸ。", + "image_format_description": "WebPæ ŧåŧįš„æ–‡äģļäŊ“į§¯æ¯”JPEG更小īŧŒäŊ†įŧ–į é€ŸåēĻ螃æ…ĸ。", "image_fullsize_description": "厞å‰ĨįĻģå…ƒæ•°æŽįš„å…¨å°ē寸回像īŧŒæ”žå¤§æŸĨįœ‹æ—ļäŊŋᔍ", "image_fullsize_enabled": "吝ᔍ免å°ēå¯¸å›žåƒį”Ÿæˆ", - "image_fullsize_enabled_description": "ä¸ē非įŊ‘éĄĩ友åĨŊæ ŧåŧį”Ÿæˆå…¨å°ēå¯¸å›žåƒã€‚å¯į”¨â€œäŧ˜å…ˆäŊŋᔍåĩŒå…Ĩåŧéĸ„č§ˆâ€åŽīŧŒå°†į›´æŽĨäŊŋᔍåĩŒå…Ĩåŧéĸ„č§ˆč€Œæ— éœ€čŊŦæĸã€‚æ­¤čŽžįŊŽä¸åŊąå“ JPEG į­‰įŊ‘éĄĩ友åĨŊæ ŧåŧã€‚", + "image_fullsize_enabled_description": "ä¸ē非įŊ‘éĄĩ友åĨŊæ ŧåŧį”Ÿæˆå…¨å°ēå¯¸å›žåƒã€‚å¯į”¨â€œäŧ˜å…ˆäŊŋᔍåĩŒå…Ĩåŧéĸ„č§ˆâ€åŽīŧŒå°†į›´æŽĨäŊŋᔍåĩŒå…Ĩåŧéĸ„č§ˆč€Œæ— éœ€čŊŦæĸã€‚æ­¤čŽžįŊŽä¸åŊąå“JPEGį­‰įŊ‘éĄĩ友åĨŊæ ŧåŧã€‚", "image_fullsize_quality_description": "全å°ēå¯¸å›žåƒč´¨é‡īŧˆ1-100īŧ‰ã€‚æ•°å€ŧčļŠé̘į”ģč´¨čļŠåĨŊīŧŒäŊ†į”Ÿæˆįš„æ–‡äģļ也čļŠå¤§ã€‚", "image_fullsize_title": "全å°ēå¯¸å›žåƒčŽžįŊŽ", "image_prefer_embedded_preview": "äŧ˜å…ˆäŊŋᔍåĩŒå…Ĩåŧéĸ„č§ˆ", @@ -115,29 +115,29 @@ "image_thumbnail_quality_description": "įŧŠį•Ĩå›žč´¨é‡īŧˆ1-100īŧ‰ã€‚æ•°å€ŧčļŠé̘į”ģč´¨čļŠåĨŊīŧŒäŊ†į”Ÿæˆįš„æ–‡äģļčļŠå¤§īŧŒä¸”可čƒŊ降äŊŽåē”į”¨å“åē”速åēĻ。", "image_thumbnail_title": "įŧŠį•Ĩå›žčŽžįŊŽ", "import_config_from_json_description": "通čŋ‡ä¸Šäŧ  JSON 配įŊŽæ–‡äģļå¯ŧå…ĨįŗģįģŸé…įŊŽ", - "job_concurrency": "{job} åšļ发数", + "job_concurrency": "{job}åšļ发数", "job_created": "äģģåŠĄåˇ˛åˆ›åģē", "job_not_concurrency_safe": "č¯ĨäģģåŠĄä¸æ”¯æŒåšļ发操äŊœã€‚", "job_settings": "äģģåŠĄčŽžįŊŽ", "job_settings_description": "įŽĄį†äģģåŠĄåšļ发数", - "jobs_delayed": "{jobCount, plural, other {# ä¸ĒåģļčŋŸ}}", + "jobs_delayed": "{jobCount, plural, other {#ä¸ĒåģļčŋŸ}}", "jobs_failed": "{jobCount, plural, other {# ä¸Ēå¤ąč´Ĩ}}", "jobs_over_time": "äģģåŠĄåŠ¨æ€", - "library_created": "åˇ˛åˆ›åģēčĩ„äē§åē“īŧš{library}", - "library_deleted": "čĩ„äē§åē“åˇ˛åˆ é™¤", - "library_details": "čĩ„äē§åē“č¯Ļ情", + "library_created": "åˇ˛åˆ›åģēčĩ„æēåē“īŧš{library}", + "library_deleted": "čĩ„æēåē“åˇ˛åˆ é™¤", + "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_settings": "外部čĩ„æēåē“", + "library_settings_description": "įŽĄį†å¤–éƒ¨čĩ„æēåē“莞įŊŽ", + "library_tasks_description": "æ‰Ģ描外部čĩ„æēåē“äģĨæŸĨ扞新åĸžå’Œå˜æ›´įš„æ–‡äģļ", + "library_updated": "čĩ„æēåē“åˇ˛æ›´æ–°", + "library_watching_enable_description": "į›‘æŽ§å¤–éƒ¨čĩ„æēåē“įš„æ–‡äģļ变更", + "library_watching_settings": "čĩ„æēåē“į›‘æŽ§ [厞éĒŒæ€§åŠŸčƒŊ]", "library_watching_settings_description": "č‡ĒåŠ¨į›‘æŽ§æ–‡äģļ变更", "logging_enable_description": "吝ᔍæ—Ĩåŋ—čްåŊ•", "logging_level_description": "å¯į”¨åŽīŧŒæ‰€é‡‡į”¨įš„æ—Ĩåŋ—įē§åˆĢ。", @@ -149,11 +149,11 @@ "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": "CLIPæ¨Ąåž‹", "machine_learning_clip_model_description": "在 此处 列å‡ēįš„ CLIP æ¨Ąåž‹åį§°ã€‚č¯ˇæŗ¨æ„īŧŒæ›´æ”šæ¨Ąåž‹åŽīŧŒåŋ…éĄģ重新čŋčĄŒæ‰€æœ‰å›žį‰‡įš„“æ™ēčƒŊ搜į´ĸ”äģģåŠĄã€‚", "machine_learning_duplicate_detection": "é‡å¤éĄšæŖ€æĩ‹", "machine_learning_duplicate_detection_enabled": "å¯į”¨é‡å¤éĄšæŖ€æĩ‹", - "machine_learning_duplicate_detection_enabled_description": "č‹Ĩå…ŗé—­æ­¤åŠŸčƒŊīŧŒåŽŒå…¨į›¸åŒįš„čĩ„äē§äģäŧščĸĢåŽģé‡å¤„į†ã€‚", + "machine_learning_duplicate_detection_enabled_description": "č‹Ĩå…ŗé—­æ­¤åŠŸčƒŊīŧŒåŽŒå…¨į›¸åŒįš„æ–‡äģļäģäŧščĸĢåŽģé‡å¤„į†ã€‚", "machine_learning_duplicate_detection_setting_description": "åˆŠį”¨ CLIP åĩŒå…Ĩå‘é‡č¯†åˆĢæŊœåœ¨įš„é‡å¤éĄš", "machine_learning_enabled": "吝ᔍæœē器å­Ļäš ", "machine_learning_enabled_description": "č‹Ĩå…ŗé—­æ­¤å¤„æ€ģåŧ€å…ŗīŧŒæ‰€æœ‰æœē器å­Ļäš į›¸å…ŗį‰šæ€§å°†å…¨éƒ¨åœį”¨īŧŒä¸‹æ–šå…ˇäŊ“莞įŊŽæ— æ•ˆã€‚", @@ -181,12 +181,12 @@ "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": "OCRæ¨Ąåž‹", "machine_learning_ocr_model_description": "æœåŠĄå™¨įĢ¯æ¨Ąåž‹æ¯”į§ģ动įĢ¯æ¨Ąåž‹æ›´į˛žå‡†īŧŒäŊ†å¤„ᐆ耗æ—ļ更é•ŋä¸”æ›´å į”¨å†…å­˜ã€‚", "machine_learning_settings": "æœē器å­Ļ䚠莞įŊŽ", "machine_learning_settings_description": "įŽĄį†æœē器å­Ļ䚠功čƒŊåŠį›¸å…ŗčŽžįŊŽ", "machine_learning_smart_search": "æ™ēčƒŊ搜į´ĸ", - "machine_learning_smart_search_description": "äŊŋᔍ CLIP åĩŒå…Ĩ向量čŋ›čĄŒč¯­äš‰åŒ–å›žį‰‡æœį´ĸ", + "machine_learning_smart_search_description": "äŊŋᔍCLIPåĩŒå…Ĩ向量čŋ›čĄŒč¯­äš‰åŒ–å›žį‰‡æœį´ĸ", "machine_learning_smart_search_enabled": "吝ᔍæ™ēčƒŊ搜į´ĸ", "machine_learning_smart_search_enabled_description": "č‹ĨįρᔍīŧŒå›žį‰‡å°†ä¸äŧščĸĢįŧ–᠁äģĨᔍäēŽæ™ēčƒŊ搜į´ĸ。", "machine_learning_url_description": "æœē器å­Ļäš æœåŠĄå™¨įš„ URL。č‹Ĩ提䞛多ä¸Ē URLīŧŒįŗģįģŸå°†æŒ‰äģŽå‰åž€åŽįš„éĄēåēé€ä¸Ēå°č¯•čŋžæŽĨīŧŒį›´č‡ŗæœ‰æœåŠĄå™¨æˆåŠŸå“åē”ä¸ēæ­ĸ。æœĒčƒŊ响åē”įš„æœåŠĄå™¨å°†čĸĢæš‚æ—ļåŋŊį•ĨīŧŒį›´č‡ŗå…￁ĸ复在įēŋ。", @@ -194,7 +194,7 @@ "maintenance_delete_backup_description": "此文äģļ将čĸĢæ°¸äš…删除。", "maintenance_delete_error": "删除备äģŊå¤ąč´Ĩ。", "maintenance_restore_backup": "æĸ复备äģŊ", - "maintenance_restore_backup_description": "Immich 数捎将čĸĢæ¸…除īŧŒåšļäģŽé€‰åŽšįš„å¤‡äģŊ中æĸ复。在įģ§įģ­äš‹å‰īŧŒå°†å…ˆåˆ›åģē一ä¸ĒåŊ“å‰æ•°æŽįš„å¤‡äģŊ。", + "maintenance_restore_backup_description": "Immich数捎将čĸĢæ¸…除īŧŒåšļäģŽé€‰åŽšįš„å¤‡äģŊ中æĸ复。在įģ§įģ­äš‹å‰īŧŒå°†å…ˆåˆ›åģē一ä¸ĒåŊ“å‰æ•°æŽįš„å¤‡äģŊ。", "maintenance_restore_backup_different_version": "此备äģŊæ˜¯į”ąä¸åŒį‰ˆæœŦįš„ Immich 创åģēįš„īŧ", "maintenance_restore_backup_unknown_version": "æ— æŗ•įĄŽåŽšå¤‡äģŊį‰ˆæœŦ。", "maintenance_restore_database_backup": "æĸ复数捎åē“备äģŊ", @@ -220,13 +220,13 @@ "map_reverse_geocoding_settings": "é€†åœ°į†įŧ–į čŽžįŊŽ", "map_settings": "地回", "map_settings_description": "įŽĄį†åœ°å›žčŽžįŊŽ", - "map_style_description": "style.json 地回ä¸ģéĸ˜įš„ URL", + "map_style_description": "style.json地回ä¸ģéĸ˜įš„URL", "memory_cleanup_job": "æ¸…į†å›žåŋ†æ•°æŽ", "memory_generate_job": "į”Ÿæˆå›žåŋ†", "metadata_extraction_job": "提取元数捎", - "metadata_extraction_job_description": "äģŽæ¯ä¸Ēčĩ„äē§ä¸­æå–元数捎äŋĄæ¯īŧŒäž‹åĻ‚ GPS、äēēč„¸å’Œåˆ†čž¨įŽ‡", + "metadata_extraction_job_description": "äģŽæ¯ä¸Ē文äģļ中提取元数捎äŋĄæ¯īŧŒäž‹åĻ‚GPS、äēēč„¸å’Œåˆ†čž¨įŽ‡", "metadata_faces_import_setting": "吝ᔍäēē脸å¯ŧå…Ĩ", - "metadata_faces_import_setting_description": "äģŽå›žį‰‡ EXIF 数捎和附å¸Ļ文äģļ中å¯ŧå…Ĩäēē脸äŋĄæ¯", + "metadata_faces_import_setting_description": "äģŽå›žį‰‡EXIF数捎和附å¸Ļ文äģļ中å¯ŧå…Ĩäēē脸äŋĄæ¯", "metadata_settings": "å…ƒæ•°æŽčŽžįŊŽ", "metadata_settings_description": "įŽĄį†å…ƒæ•°æŽčŽžįŊŽ", "migration_job": "čŋį§ģ", @@ -273,7 +273,7 @@ "oauth_auto_register_description": "į”¨æˆˇé€ščŋ‡ OAuth į™ģåŊ•后īŧŒč‡Ē动ä¸ēå…ļæŗ¨å†Œæ–°č´Ļæˆˇ", "oauth_button_text": "按钎文字", "oauth_client_secret_description": "æœē密åŽĸæˆˇį̝åŋ…åĄĢīŧŒæˆ–å…Ŧå…ąåŽĸæˆˇį̝č‹Ĩ不支持 PKCEīŧˆäģŖį ä礿ĸč¯æ˜Žå¯†é’Ĩīŧ‰æ—ļåŋ…åĄĢ。", - "oauth_enable_description": "äŊŋᔍ OAuth į™ģåŊ•", + "oauth_enable_description": "äŊŋᔍOAuthį™ģåŊ•", "oauth_mobile_redirect_uri": "į§ģ动įĢ¯é‡åŽšå‘ URI", "oauth_mobile_redirect_uri_override": "į§ģ动įĢ¯é‡åŽšå‘ URI čφᛖ", "oauth_mobile_redirect_uri_override_description": "åŊ“ OAuth æäž›å•†ä¸å…čŽ¸äŊŋᔍį§ģ动į̝ URIīŧˆäž‹åĻ‚ “{callback}”īŧ‰æ—ļ吝ᔍ", @@ -307,13 +307,13 @@ "require_password_change_on_login": "åŧēåˆļį”¨æˆˇéĻ–æŦĄį™ģåŊ•æ—ļäŋŽæ”šå¯†į ", "reset_settings_to_default": "å°†čŽžįŊŽé‡įŊŽä¸ēéģ˜čޤå€ŧ", "reset_settings_to_recent_saved": "å°†čŽžįŊŽé‡įŊŽä¸ē上æŦĄäŋå­˜įš„å€ŧ", - "scanning_library": "æ­Ŗåœ¨æ‰Ģ描čĩ„æ–™åē“", + "scanning_library": "æ­Ŗåœ¨æ‰Ģ描čĩ„æēåē“", "search_jobs": "搜į´ĸäģģåŠĄâ€Ļ", "send_welcome_email": "发送æŦĸčŋŽé‚Žäģļ", "server_external_domain_settings": "外部域名", "server_external_domain_settings_description": "å…Ŧåŧ€åˆ†äēĢ链æŽĨįš„åŸŸåīŧŒéœ€åŒ…åĢ http(s)://", "server_public_users": "į”¨æˆˇå…Ŧåŧ€", - "server_public_users_description": "åœ¨å°†į”¨æˆˇæˇģåŠ åˆ°å…ąäēĢį›¸å†Œæ—ļīŧŒæ‰€æœ‰į”¨æˆˇīŧˆå§“åå’Œé‚ŽįŽąīŧ‰éƒŊäŧščĸĢ列å‡ē。č‹Ĩå…ŗé—­æ­¤åŠŸčƒŊīŧŒį”¨æˆˇåˆ—čĄ¨å°†äģ…å¯šįŽĄį†å‘˜å¯č§ã€‚", + "server_public_users_description": "åœ¨å°†į”¨æˆˇæˇģåŠ č‡ŗå…ąäēĢį›¸å†Œæ—ļīŧŒäŧšåˆ—å‡ēæ‰€æœ‰į”¨æˆˇīŧˆåŒ…æ‹Ŧå§“åå’Œé‚ŽįŽąīŧ‰ã€‚č‹ĨįĻį”¨æ­¤é€‰éĄšīŧŒåˆ™äģ…įŽĄį†å‘˜å¯č§į”¨æˆˇåˆ—čĄ¨ã€‚", "server_settings": "æœåŠĄå™¨čŽžįŊŽ", "server_settings_description": "įŽĄį†æœåŠĄå™¨čŽžįŊŽ", "server_stats_page_description": "įŽĄį†æœåŠĄå™¨įģŸčŽĄéĄĩéĸ", @@ -323,21 +323,21 @@ "sidecar_job": "é™„åąžå…ƒæ•°æŽ", "sidecar_job_description": "äģŽæ–‡äģļįŗģįģŸä¸­å‘įŽ°æˆ–åŒæ­Ĩé™„åąžå…ƒæ•°æŽ", "slideshow_duration_description": "每åŧ å›žį‰‡æ˜žį¤ēįš„į§’æ•°", - "smart_search_job_description": "寚čĩ„äē§čŋčĄŒæœē器å­Ļäš äģĨ支持æ™ēčƒŊ搜į´ĸ", - "storage_template_date_time_description": "čĩ„äē§įš„创åģēæ—ļé—´æˆŗį”¨äēŽæ—Ĩ期æ—ļ间äŋĄæ¯", + "smart_search_job_description": "å¯šį…§į‰‡/视éĸ‘čŋčĄŒæœē器å­Ļäš äģĨ支持æ™ēčƒŊ搜į´ĸ", + "storage_template_date_time_description": "文äģļįš„åˆ›åģēæ—ļé—´æˆŗå°†į”¨äēŽæ—Ĩ期æ—ļ间äŋĄæ¯", "storage_template_date_time_sample": "į¤ē例æ—ļ间īŧš{date}", "storage_template_enable_description": "å¯į”¨å­˜å‚¨æ¨Ąæŋåŧ•擎", "storage_template_hash_verification_enabled": "å¯į”¨å“ˆå¸Œæ Ąénj", "storage_template_hash_verification_enabled_description": "åŧ€å¯å“ˆå¸Œæ Ąénj功čƒŊ。č‹Ĩ不清æĨšå…ŗé—­įš„后果īŧŒč¯ˇå‹ŋå…ŗé—­", "storage_template_migration": "å­˜å‚¨æ¨Ąæŋčŋį§ģ", - "storage_template_migration_description": "将åŊ“前 {template} åē”ᔍäēŽåˇ˛ä¸Šäŧ įš„čĩ„äē§", - "storage_template_migration_info": "å­˜å‚¨æ¨Ąæŋäŧšå°†æ‰€æœ‰æ–‡äģ￉Šåą•名čŊŦæĸä¸ēå°å†™ã€‚æ¨Ąæŋ更攚äģ…寚新上äŧ įš„čĩ„äē§į”Ÿæ•ˆã€‚č‹ĨčĻå°†æ¨Ąæŋ回æē¯åē”ᔍäēŽåˇ˛ä¸Šäŧ įš„čĩ„äē§īŧŒč¯ˇčŋčĄŒ {job}。", + "storage_template_migration_description": "将åŊ“前 {template} åē”ᔍäēŽåˇ˛ä¸Šäŧ įš„æ–‡äģļ", + "storage_template_migration_info": "å­˜å‚¨æ¨Ąæŋäŧšå°†æ‰€æœ‰æ–‡äģ￉Šåą•名čŊŦæĸä¸ēå°å†™ã€‚æ¨Ąæŋ更攚äģ…寚新上äŧ įš„æ–‡äģļį”Ÿæ•ˆã€‚č‹ĨčĻå°†æ¨Ąæŋ回æē¯åē”ᔍäēŽåˇ˛ä¸Šäŧ įš„æ–‡äģļīŧŒč¯ˇčŋčĄŒ {job}。", "storage_template_migration_job": "å­˜å‚¨æ¨Ąæŋčŋį§ģäģģåŠĄ", "storage_template_more_details": "æœ‰å…ŗæ­¤åŠŸčƒŊįš„æ›´å¤šč¯Ļįģ†äŋĄæ¯īŧŒč¯ˇå‚阅 å­˜å‚¨æ¨Ąæŋ 及å…ļ åĢ义", "storage_template_onboarding_description_v2": "å¯į”¨åŽīŧŒæ­¤åŠŸčƒŊå°†æ šæŽį”¨æˆˇåŽšäš‰įš„æ¨Ąæŋč‡ĒåŠ¨æ•´į†æ–‡äģļ。更多äŋĄæ¯īŧŒč¯ˇå‚阅 æ–‡æĄŖã€‚", "storage_template_path_length": "čŋ‘äŧŧčˇ¯åž„é•ŋåēĻ限åˆļīŧš{length, number}/{limit, number}", "storage_template_settings": "å­˜å‚¨æ¨Ąæŋ", - "storage_template_settings_description": "įŽĄį†ä¸Šäŧ čĩ„äē§æ–‡äģļ多į쓿ž„和文äģļ名", + "storage_template_settings_description": "įŽĄį†å­˜æ”žåˇ˛ä¸Šäŧ į…§į‰‡/视éĸ‘įš„æ–‡äģļ多į쓿ž„和文äģļ名", "storage_template_user_label": "{label}ä¸ēč¯Ĩį”¨æˆˇįš„å­˜å‚¨æ ‡į­ž", "system_settings": "įŗģįģŸčŽžįŊŽ", "tag_cleanup_job": "æ ‡į­žæ¸…į†", @@ -351,16 +351,16 @@ "template_settings": "通įŸĨæ¨Ąæŋ", "template_settings_description": "įŽĄį†é€šįŸĨįš„č‡ĒåŽšäš‰æ¨Ąæŋ", "theme_custom_css_settings": "č‡Ē厚䚉 CSS", - "theme_custom_css_settings_description": "CSS å…čŽ¸č‡Ē厚䚉 Immich į•ŒéĸčŽžčŽĄã€‚", + "theme_custom_css_settings_description": "äŊŋᔍCSSč‡Ē厚䚉Immichį•ŒéĸčŽžčŽĄã€‚", "theme_settings": "ä¸ģéĸ˜čŽžįŊŽ", "theme_settings_description": "č‡Ē厚䚉 Immich Web į•Œéĸ", "thumbnail_generation_job": "į”ŸæˆįŧŠį•Ĩ回", - "thumbnail_generation_job_description": "ä¸ē每ä¸Ēčĩ„äē§į”Ÿæˆä¸åŒå°ēå¯¸įš„įŧŠį•Ĩ回īŧŒåšļä¸ē每ä¸Ēäēēį‰Šį”ŸæˆįŧŠį•Ĩ回", + "thumbnail_generation_job_description": "ä¸ē每ä¸Ēᅧቇ/视éĸ‘į”Ÿæˆä¸åŒå°ēå¯¸įš„įŧŠį•Ĩ回īŧŒåšļä¸ē每ä¸Ēäēēį‰Šį”ŸæˆįŧŠį•Ĩ回", "transcoding_acceleration_api": "įĄŦäģļ加速 API", "transcoding_acceleration_api_description": "ᔍäēŽä¸ŽčŽžå¤‡äē¤äē’äģĨ加速čŊŦį įš„ API。č¯Ĩ莞įŊŽé‡‡į”¨â€œå°ŊåŠ›č€Œä¸ēâ€į­–į•Ĩīŧšč‹ĨįĄŦäģļåŠ é€Ÿå¤ąč´ĨīŧŒįŗģįģŸå°†č‡Ē动回退到čŊ¯äģļčŊŦį ã€‚VP9 įŧ–į įš„æ”¯æŒæƒ…å†ĩå–å†ŗäēŽæ‚¨įš„įĄŦäģļ配įŊŽã€‚", - "transcoding_acceleration_nvenc": "NVENCīŧˆéœ€čρ NVIDIA æ˜žåĄīŧ‰", - "transcoding_acceleration_qsv": "Quick Syncīŧˆéœ€čρ Intel 7äģŖåŠäģĨä¸Šįš„ CPUīŧ‰", - "transcoding_acceleration_rkmpp": "RKMPPīŧˆäģ…适ᔍäēŽ Rockchip SOCsīŧ‰", + "transcoding_acceleration_nvenc": "NVENCīŧˆéœ€čρNVIDIAæ˜žåĄīŧ‰", + "transcoding_acceleration_qsv": "Quick Syncīŧˆéœ€čρIntel 7äģŖåŠäģĨä¸Šįš„CPUīŧ‰", + "transcoding_acceleration_rkmpp": "RKMPPīŧˆäģ…适ᔍäēŽRockchip SOCsīŧ‰", "transcoding_acceleration_vaapi": "视éĸ‘加速 API", "transcoding_accepted_audio_codecs": "æ”¯æŒįš„éŸŗéĸ‘įŧ–᠁æ ŧåŧ", "transcoding_accepted_audio_codecs_description": "选拊无需čŊŦį įš„éŸŗéĸ‘įŧ–᠁æ ŧåŧã€‚äģ…åœ¨į‰šåŽšįš„čŊŦ᠁᭖į•Ĩä¸‹į”Ÿæ•ˆã€‚", @@ -370,11 +370,11 @@ "transcoding_accepted_video_codecs_description": "选拊无需čŊŦį įš„č§†éĸ‘įŧ–᠁æ ŧåŧã€‚äģ…åœ¨į‰šåŽšįš„čŊŦ᠁᭖į•Ĩä¸‹į”Ÿæ•ˆã€‚", "transcoding_advanced_options_description": "å¤§å¤šæ•°į”¨æˆˇä¸éœ€čĻæ›´æ”šįš„é€‰éĄš", "transcoding_audio_codec": "韺éĸ‘įŧ–᠁æ ŧåŧ", - "transcoding_audio_codec_description": "Opus æ˜¯éŸŗč´¨æœ€éĢ˜įš„é€‰éĄšīŧŒäŊ†åœ¨č€æ—§čŽžå¤‡æˆ–čŊ¯äģļä¸Šįš„å…ŧåŽšæ€§čžƒåˇŽã€‚", + "transcoding_audio_codec_description": "Opusæ˜¯éŸŗč´¨æœ€éĢ˜įš„é€‰éĄšīŧŒäŊ†åœ¨č€æ—§čŽžå¤‡æˆ–čŊ¯äģļä¸Šįš„å…ŧåŽšæ€§čžƒåˇŽã€‚", "transcoding_bitrate_description": "视éĸ‘į įŽ‡é̘äēŽæœ€å¤§é™åˆļīŧŒæˆ–æ ŧåŧä¸åœ¨æŽĨå—åˆ—čĄ¨ä¸­", "transcoding_codecs_learn_more": "č‹Ĩčρäē†č§Ŗæ­¤å¤„äŊŋį”¨įš„æœ¯č¯­č¯Ļ情īŧŒč¯ˇæŸĨ阅 FFmpeg æ–‡æĄŖä¸­įš„ H.264 įŧ–į ã€HEVC įŧ–᠁ 和 VP9 įŧ–į ã€‚", "transcoding_constant_quality_mode": "æ’åŽšč´¨é‡æ¨Ąåŧ", - "transcoding_constant_quality_mode_description": "ICQ 比 CQP 效果更åĨŊīŧŒäŊ†éƒ¨åˆ†įĄŦäģļåŠ é€ŸčŽžå¤‡ä¸æ”¯æŒæ­¤æ¨Ąåŧã€‚吝ᔍč¯Ĩé€‰éĄšåŽīŧŒåœ¨åŸēäēŽč´¨é‡įš„įŧ–᠁䏭将äŧ˜å…ˆäŊŋį”¨æŒ‡åŽšįš„æ¨Ąåŧã€‚į”ąäēŽ NVENCīŧˆNVIDIA æ˜žåĄįŧ–᠁噍īŧ‰ä¸æ”¯æŒ ICQīŧŒå› æ­¤č¯Ĩ莞įŊŽå¯šå…ļ无效。", + "transcoding_constant_quality_mode_description": "ICQ比CQP效果更åĨŊīŧŒäŊ†éƒ¨åˆ†įĄŦäģļåŠ é€ŸčŽžå¤‡ä¸æ”¯æŒæ­¤æ¨Ąåŧã€‚吝ᔍč¯Ĩé€‰éĄšåŽīŧŒåœ¨åŸēäēŽč´¨é‡įš„įŧ–᠁䏭将äŧ˜å…ˆäŊŋį”¨æŒ‡åŽšįš„æ¨Ąåŧã€‚į”ąäēŽNVENCīŧˆNVIDIAæ˜žåĄįŧ–᠁噍īŧ‰ä¸æ”¯æŒICQīŧŒå› æ­¤č¯Ĩ莞įŊŽå¯šå…ļ无效。", "transcoding_constant_rate_factor": "æ’åŽšį įŽ‡įŗģ数īŧˆ-crfīŧ‰", "transcoding_constant_rate_factor_description": "视éĸ‘č´¨é‡į­‰įē§ã€‚典型å€ŧä¸ēīŧšH.264 äŊŋᔍ 23īŧŒHEVC äŊŋᔍ 28īŧŒVP9 äŊŋᔍ 31īŧŒAV1 äŊŋᔍ 35。数å€ŧčļŠäŊŽč´¨é‡čļŠåĨŊīŧŒäŊ†į”Ÿæˆįš„æ–‡äģļ也čļŠå¤§ã€‚", "transcoding_disabled_description": "不čŊŦ᠁äģģäŊ•视éĸ‘īŧŒå¯čƒŊäŧšå¯ŧč‡´éƒ¨åˆ†åŽĸæˆˇįĢ¯æ— æŗ•æ’­æ”ž", @@ -394,7 +394,7 @@ "transcoding_policy": "čŊŦ᠁᭖į•Ĩ", "transcoding_policy_description": "莞įŊŽč§†éĸ‘čŊŦ᠁æ—ļæœē", "transcoding_preferred_hardware_device": "éϖ选įĄŦäģļčŽžå¤‡", - "transcoding_preferred_hardware_device_description": "äģ…适ᔍäēŽ VAAPI 和 QSVã€‚čŽžįŊŽį”¨äēŽįĄŦäģļčŊŦį įš„ DRI čŽžå¤‡čŠ‚į‚šã€‚", + "transcoding_preferred_hardware_device_description": "äģ…适ᔍäēŽVAAPI和QSVã€‚čŽžįŊŽį”¨äēŽįĄŦäģļčŊŦį įš„DRIčŽžå¤‡čŠ‚į‚šã€‚", "transcoding_preset_preset": "éĸ„莞īŧˆ-presetīŧ‰", "transcoding_preset_preset_description": "压įŧŠé€ŸåēĻ。éĸ„čŽžé€ŸåēĻč…ĸīŧŒį”Ÿæˆįš„æ–‡äģļčļŠå°īŧ›åœ¨čŽžåŽšį‰šåŽšį įŽ‡æ—ļīŧŒčŋ˜čƒŊ提升į”ģč´¨ã€‚VP9 įŧ–᠁噍äŧšåŋŊį•Ĩīŧˆä¸æ”¯æŒīŧ‰é̘äēŽâ€œfaster”速åēĻįš„é€‰éĄšã€‚", "transcoding_reference_frames": "å‚č€ƒå¸§", @@ -405,7 +405,7 @@ "transcoding_target_resolution": "į›Žæ ‡åˆ†čž¨įŽ‡", "transcoding_target_resolution_description": "更éĢ˜įš„åˆ†čž¨įŽ‡č™Ŋį„ļčƒŊäŋį•™æ›´å¤šį”ģéĸįģ†čŠ‚īŧŒäŊ†äŧšåģļé•ŋįŧ–᠁æ—ļ间、åĸžå¤§æ–‡äģļäŊ“᧝īŧŒåšļ可čƒŊå¯ŧ致åē”į”¨å“åē”变æ…ĸ。", "transcoding_temporal_aq": "æ—ļ间域č‡Ē适åē”量化", - "transcoding_temporal_aq_description": "äģ…适ᔍäēŽ NVENC。æ—ļ间域č‡Ē适åē”量化可提升é̘įģ†čŠ‚ã€äŊŽčŋåЍåœēæ™¯įš„į”ģč´¨ã€‚å¯čƒŊä¸Žčžƒæ—§įš„čŽžå¤‡ä¸å…ŧ厚。", + "transcoding_temporal_aq_description": "äģ…适ᔍäēŽNVENC。æ—ļ间域č‡Ē适åē”量化可提升é̘įģ†čŠ‚ã€äŊŽčŋåЍåœēæ™¯įš„į”ģč´¨ã€‚å¯čƒŊä¸Žčžƒæ—§įš„čŽžå¤‡ä¸å…ŧ厚。", "transcoding_threads": "įēŋį¨‹æ•°", "transcoding_threads_description": "数å€ŧčļŠé̘īŧŒįŧ–į é€ŸåēĻčļŠåŋĢīŧŒäŊ†åœ¨čŋčĄŒæ—ļäŧšå‡å°‘æœåŠĄå™¨å¤„į†å…ļäģ–äģģåŠĄįš„äŊ™é‡ã€‚č¯Ĩ数å€ŧ不åē”čļ…čŋ‡ CPU æ ¸åŋƒæ•°ã€‚莞ä¸ē 0 可最大化čĩ„æēåˆŠį”¨įŽ‡ã€‚", "transcoding_tone_mapping": "č‰˛č°ƒæ˜ å°„", @@ -415,7 +415,7 @@ "transcoding_two_pass_encoding": "ä猿ŦĄįŧ–᠁", "transcoding_two_pass_encoding_setting_description": "采ᔍ䏤æŦĄįŧ–į æ¨ĄåŧäģĨį”Ÿæˆč´¨é‡æ›´äŧ˜įš„视éĸ‘。åŊ“åŧ€å¯æœ€å¤§į įއ限åˆļæ—ļīŧˆH.264 和 HEVC įŧ–᠁æ ŧåŧåŋ…éĄģåŧ€å¯æ­¤é€‰éĄšæ‰čƒŊį”Ÿæ•ˆīŧ‰īŧŒč¯Ĩæ¨ĄåŧäŧšäžæŽæœ€å¤§į įŽ‡čŽžåŽšä¸€ä¸Ēį įŽ‡čŒƒå›´īŧŒåšļåŋŊį•Ĩ CRF 莞įŊŽã€‚寚äēŽ VP9 įŧ–᠁īŧŒč‹Ĩå…ŗé—­æœ€å¤§į įŽ‡é™åˆļīŧŒåˆ™å¯äģĨäŊŋᔍ CRF 莞įŊŽã€‚", "transcoding_video_codec": "视éĸ‘įŧ–᠁æ ŧåŧ", - "transcoding_video_codec_description": "VP9 įŧ–į æ•ˆįŽ‡é̘īŧŒä¸”在įŊ‘éĄĩį̝å…ŧ厚性åĨŊīŧŒäŊ†čŊŦ᠁耗æ—ļ螃é•ŋ。HEVCīŧˆH.265īŧ‰æ€§čƒŊä¸Žäš‹į›¸äŧŧīŧŒäŊ†åœ¨įŊ‘éĄĩįĢ¯įš„å…ŧåŽšæ€§čžƒåˇŽã€‚H.264 å…ŧ厚性极åšŋ且čŊŦį é€ŸåēĻåŋĢīŧŒäŊ†į”Ÿæˆįš„æ–‡äģļäŊ“᧝čĻå¤§åž—å¤šã€‚AV1 æ˜¯æ•ˆįŽ‡æœ€éĢ˜įš„įŧ–᠁æ ŧåŧīŧŒäŊ†åœ¨æ—§čŽžå¤‡ä¸Šįŧē䚏支持。", + "transcoding_video_codec_description": "VP9įŧ–į æ•ˆįŽ‡é̘īŧŒä¸”在įŊ‘éĄĩį̝å…ŧ厚性åĨŊīŧŒäŊ†čŊŦ᠁耗æ—ļ螃é•ŋ。HEVCīŧˆH.265īŧ‰æ€§čƒŊä¸Žäš‹į›¸äŧŧīŧŒäŊ†åœ¨įŊ‘éĄĩįĢ¯įš„å…ŧåŽšæ€§čžƒåˇŽã€‚H.264å…ŧ厚性极åšŋ且čŊŦį é€ŸåēĻåŋĢīŧŒäŊ†į”Ÿæˆįš„æ–‡äģļäŊ“᧝čĻå¤§åž—å¤šã€‚AV1æ˜¯æ•ˆįŽ‡æœ€éĢ˜įš„įŧ–᠁æ ŧåŧīŧŒäŊ†åœ¨æ—§čŽžå¤‡ä¸Šįŧē䚏支持。", "trash_enabled_description": "å¯į”¨å›žæ”ļįĢ™åŠŸčƒŊ", "trash_number_of_days": "äŋį•™å¤Šæ•°", "trash_number_of_days_description": "文äģļ在回æ”ļį̙䏭äŋį•™å¤šå°‘夊后čĸĢæ°¸äš…删除", @@ -425,11 +425,11 @@ "unlink_all_oauth_accounts_description": "在čŋį§ģåˆ°æ–°æœåŠĄå•†äš‹å‰īŧŒč¯ˇčŽ°åž—č§Ŗé™¤æ‰€æœ‰ OAuth č´Ļæˆˇįš„å…ŗč”ã€‚", "unlink_all_oauth_accounts_prompt": "æ‚¨įĄŽåŽščĻč§Ŗé™¤æ‰€æœ‰ OAuth č´Ļæˆˇįš„å…ŗč”å—īŧŸæ­¤æ“äŊœå°†é‡įŊŽæ¯ä¸Ēį”¨æˆˇįš„čēĢäģŊčŽ¤č¯ IDīŧŒä¸”æ— æŗ•æ’¤é”€ã€‚", "user_cleanup_job": "į”¨æˆˇæ¸…į†", - "user_delete_delay": "{user}įš„č´ĻæˆˇåŠčĩ„äē§å°†åœ¨{delay, plural, one {#夊} other {#夊}}后čĸĢ厉排永䚅删除。", + "user_delete_delay": "{user}įš„č´ĻæˆˇåŠčĩ„äē§å°†åœ¨{delay, plural, one {#夊} other {#夊}}后čĸĢæ°¸äš…删除。", "user_delete_delay_settings": "åģᅵŸåˆ é™¤", - "user_delete_delay_settings_description": "į§ģ除后多少夊īŧŒæ°¸äš…åˆ é™¤į”¨æˆˇįš„č´ĻæˆˇåŠčĩ„äē§ã€‚į”¨æˆˇåˆ é™¤äģģåŠĄå°†åœ¨åˆå¤œčŋčĄŒīŧŒäģĨæŖ€æŸĨ是åĻæœ‰åž…åˆ é™¤įš„į”¨æˆˇã€‚æ­¤čŽžįŊŽįš„æ›´æ”šå°†åœ¨ä¸‹æŦĄäģģåŠĄæ‰§čĄŒæ—ļį”Ÿæ•ˆã€‚", - "user_delete_immediately": "{user}įš„č´ĻæˆˇåŠčĩ„äē§å°†čĸĢįĢ‹åŗåŽ‰æŽ’æ°¸äš…åˆ é™¤ã€‚", - "user_delete_immediately_checkbox": "å°†į”¨æˆˇåŠå…ļčĩ„äē§åŠ å…ĨįĢ‹åŗåˆ é™¤é˜Ÿåˆ—", + "user_delete_delay_settings_description": "į§ģé™¤åŽæ°¸äš…åˆ é™¤į”¨æˆˇįš„č´ĻæˆˇåŠæ–‡äģļįš„å¤Šæ•°ã€‚į”¨æˆˇåˆ é™¤äģģåŠĄå°†åœ¨æˇąå¤œæŖ€æŸĨåž…åˆ é™¤įš„į”¨æˆˇã€‚æ­¤čŽžįŊŽįš„æ›´æ”šå°†åœ¨ä¸‹æŦĄäģģåŠĄæ‰§čĄŒæ—ļį”Ÿæ•ˆã€‚", + "user_delete_immediately": "{user}įš„č´ĻæˆˇåŠčĩ„äē§å°†čĸĢįĢ‹åŗæ°¸äš…åˆ é™¤ã€‚", + "user_delete_immediately_checkbox": "å°†į”¨æˆˇåŠå…ļ文äģļ加å…ĨįĢ‹åŗåˆ é™¤é˜Ÿåˆ—", "user_details": "į”¨æˆˇč¯Ļ情", "user_management": "į”¨æˆˇįŽĄį†", "user_password_has_been_reset": "į”¨æˆˇįš„å¯†į åˇ˛é‡įŊŽīŧš", @@ -441,7 +441,7 @@ "user_successfully_removed": "į”¨æˆˇ {email} åˇ˛æˆåŠŸåˆ é™¤ã€‚", "users_page_description": "įŽĄį†į”¨æˆˇéĄĩéĸ", "version_check_enabled_description": "æŖ€æŸĨčŊ¯äģļæ–°į‰ˆæœŦ", - "version_check_implications": "į‰ˆæœŦæŖ€æŸĨ功čƒŊ䞝čĩ–äēŽä¸Ž github.com įš„åŽšæœŸé€šäŋĄ", + "version_check_implications": "į‰ˆæœŦæŖ€æŸĨ功čƒŊ䞝čĩ–äēŽä¸Ž {server} įš„åŽšæœŸé€šäŋĄ", "version_check_settings": "æ–°į‰ˆæœŦæŖ€æŸĨ", "version_check_settings_description": "吝ᔍ/įĻį”¨æ–°į‰ˆæœŦ通įŸĨ", "video_conversion_job": "čŊŦ᠁视éĸ‘", @@ -454,10 +454,10 @@ "advanced_settings_clear_image_cache": "清įŠē回像įŧ“å­˜", "advanced_settings_clear_image_cache_error": "æ— æŗ•æ¸…įŠē回像įŧ“å­˜", "advanced_settings_clear_image_cache_success": "æˆåŠŸæ¸…į† {size}", - "advanced_settings_enable_alternate_media_filter_subtitle": "äŊŋį”¨æ­¤é€‰éĄšå¯æ šæŽå…ļäģ–æĄäģļį­›é€‰åŒæ­ĨæœŸé—´įš„åĒ’äŊ“。äģ…在åē”į”¨æ— æŗ•æŖ€æĩ‹åˆ°æ‰€æœ‰į›¸å†Œæ—ļå°č¯•æ­¤é€‰éĄšã€‚", + "advanced_settings_enable_alternate_media_filter_subtitle": "äŊŋį”¨æ­¤é€‰éĄšå¯æ šæŽæ›ŋäģŖæ ‡å‡†åœ¨åŒæ­Ĩ期间čŋ‡æģ¤åĒ’äŊ“。äģ…åŊ“åē”į”¨æ— æŗ•æŖ€æĩ‹æ‰€æœ‰į›¸å†Œæ—ļīŧŒæ‰å°č¯•äŊŋį”¨æ­¤é€‰éĄšã€‚", "advanced_settings_enable_alternate_media_filter_title": "[厞éĒŒæ€§] äŊŋį”¨å¤‡į”¨čŽžå¤‡į›¸å†Œį­›é€‰æ–šåŧ", "advanced_settings_log_level_title": "æ—Ĩåŋ—į­‰įē§: {level}", - "advanced_settings_prefer_remote_subtitle": "éƒ¨åˆ†čŽžå¤‡č¯ģ取æœŦ地čĩ„æēįŧŠį•Ĩå›žįš„é€ŸåēĻæžæ…ĸ。åŧ€å¯æ­¤čŽžįŊŽå¯æ”šä¸ē加čŊŊčŋœį¨‹å›žį‰‡ã€‚", + "advanced_settings_prefer_remote_subtitle": "éƒ¨åˆ†čŽžå¤‡č¯ģ取æœŦ地文äģļįŧŠį•Ĩå›žįš„é€ŸåēĻæžæ…ĸ。åŧ€å¯æ­¤čŽžįŊŽå¯æ”šä¸ē加čŊŊčŋœį¨‹å›žį‰‡ã€‚", "advanced_settings_prefer_remote_title": "äŧ˜å…ˆäŊŋᔍčŋœį¨‹å›žį‰‡", "advanced_settings_proxy_headers_subtitle": "厚䚉 Immich 每æŦĄįŊ‘įģœč¯ˇæą‚åē”附å¸Ļįš„äģŖį†å¤´äŋĄæ¯", "advanced_settings_proxy_headers_title": "č‡Ē厚䚉äģŖį†å¤´äŋĄæ¯ [厞éĒŒæ€§]", @@ -474,8 +474,8 @@ "age_year_months": "1垁{months, plural, one {#ä¸Ē月} other {#ä¸Ē月}}", "age_years": "{years, plural, other {#垁}}", "album": "į›¸å†Œ", - "album_added": "į›¸å†Œæˇģ加成功", - "album_added_notification_setting_description": "åŊ“您čĸĢæˇģåŠ åˆ°å…ąäēĢį›¸å†Œæ—ļīŧŒæŽĨæ”ļé‚ŽįŽąé€šįŸĨ", + "album_added": "į›¸å†Œåˇ˛æˇģ加", + "album_added_notification_setting_description": "åŊ“您čĸĢæˇģåŠ åˆ°å…ąäēĢį›¸å†Œæ—ļīŧŒé€ščŋ‡é‚Žäģļ通įŸĨ", "album_cover_updated": "封éĸåˇ˛æ›´æ–°", "album_delete_confirmation": "įĄŽåŽščĻåˆ é™¤į›¸å†Œ “{album}” 吗īŧŸ", "album_delete_confirmation_description": "åĻ‚æžœæ­¤į›¸å†Œåˇ˛čĸĢå…ąäēĢīŧŒå…ļäģ–į”¨æˆˇäšŸå°†æ— æŗ•å†čŽŋ闎厃。", @@ -491,10 +491,10 @@ "album_remove_user_confirmation": "įĄŽåŽščρį§ģ除 “{user}” 吗īŧŸ", "album_search_not_found": "æœĒ扞到与搜į´ĸæĄäģļåŒšé…įš„į›¸å†Œ", "album_selected": "į›¸å†Œåˇ˛é€‰ä¸­", - "album_share_no_users": "įœ‹čĩˇæĨæ‚¨åˇ˛å°†æ­¤į›¸å†Œå…ąäēĢį왿‰€æœ‰į”¨æˆˇīŧŒæˆ–č€…æ‚¨æ˛Ąæœ‰å¯å…ąäēĢįš„į”¨æˆˇã€‚", + "album_share_no_users": "æ‚¨åˇ˛å°†æ­¤į›¸å†Œå…ąäēĢį왿‰€æœ‰į”¨æˆˇīŧŒæˆ–æ˛Ąæœ‰å¯å…ąäēĢįš„į”¨æˆˇã€‚", "album_summary": "į›¸å†ŒæĻ‚č§ˆ", "album_updated": "į›¸å†Œåˇ˛æ›´æ–°", - "album_updated_setting_description": "åŊ“å…ąäēĢį›¸å†Œæœ‰æ–°å†…åŽšæ—ļīŧŒæŽĨæ”ļ邮äģļ通įŸĨ", + "album_updated_setting_description": "åŊ“å…ąäēĢį›¸å†Œæœ‰æ–°å†…åŽšæ—ļīŧŒé€ščŋ‡é‚Žäģļ通įŸĨ", "album_upload_assets": "äģŽæ‚¨įš„į”ĩ脑上äŧ æ–‡äģļåšļæˇģåŠ åˆ°į›¸å†Œ", "album_user_left": "厞退å‡ē “{album}”", "album_user_removed": "厞į§ģ除 “{user}”", @@ -508,12 +508,12 @@ "album_viewer_page_share_add_users": "邀蝎äģ–äēē", "album_with_link_access": "å…čŽ¸äģģäŊ•æ‹Ĩ有č¯Ĩ链æŽĨįš„äē翟Ĩįœ‹æ­¤į›¸å†Œä¸­įš„į…§į‰‡å’Œäēēį‰Šã€‚", "albums": "į›¸å†Œ", - "albums_count": "{count, plural, one {{count, number} ä¸Ēį›¸å†Œ} other {{count, number} ä¸Ēį›¸å†Œ}}", + "albums_count": "{count, plural, one {{count, number}ä¸Ēį›¸å†Œ} other {{count, number}ä¸Ēį›¸å†Œ}}", "albums_default_sort_order": "éģ˜čŽ¤į›¸å†ŒæŽ’åēæ–šåŧ", - "albums_default_sort_order_description": "创åģēæ–°į›¸å†Œæ—ļīŧŒåŊąåƒįš„初始排åēæ–šåŧã€‚", + "albums_default_sort_order_description": "创åģēæ–°į›¸å†Œæ—ļīŧŒčĩ„æēįš„初始排åēæ–šåŧã€‚", "albums_feature_description": "可与å…ļäģ–į”¨æˆˇå…ąäēĢįš„į…§į‰‡/内厚合集。", "albums_on_device_count": "čŽžå¤‡ä¸Šįš„į›¸å†Œīŧˆ{count} ä¸Ēīŧ‰", - "albums_selected": "{count, plural, one {# ä¸Ēį›¸å†Œåˇ˛é€‰æ‹Š} other {# ä¸Ēį›¸å†Œåˇ˛é€‰æ‹Š}}", + "albums_selected": "{count, plural, one {厞选䏭#ä¸Ēį›¸å†Œ} other {厞选䏭#ä¸Ēį›¸å†Œ}}", "all": "全部", "all_albums": "æ‰€æœ‰į›¸å†Œ", "all_people": "全部äēēį‰Š", @@ -529,10 +529,10 @@ "always_keep_photos_hint": "åŧ€å¯â€œé‡Šæ”žįŠē间”后īŧŒäģäŧšäŋį•™æ‰€æœ‰į…§į‰‡åœ¨æœŦčŽžå¤‡ä¸Šã€‚", "always_keep_videos_hint": "åŧ€å¯â€œé‡Šæ”žįŠē间”后īŧŒäģäŧšäŋį•™æ‰€æœ‰č§†éĸ‘在æœŦčŽžå¤‡ä¸Šã€‚", "anti_clockwise": "逆æ—ļ针", - "api_key": "API 密é’Ĩ", + "api_key": "API密é’Ĩ", "api_key_description": "č¯Ĩåē”ᔍ坆é’ĨåĒäŧšæ˜žį¤ē一æŦĄã€‚č¯ˇįĄŽäŋåœ¨å…ŗé—­įĒ—åŖå‰å¤åˆļ下æĨ。", - "api_key_empty": "API 密é’Ĩåį§°ä¸å¯ä¸ēįŠē", - "api_keys": "API 密é’Ĩ", + "api_key_empty": "API密é’Ĩåį§°ä¸å¯ä¸ēįŠē", + "api_keys": "API密é’Ĩ", "app_architecture_variant": "变äŊ“īŧˆæžļ构īŧ‰", "app_bar_signout_dialog_content": "æ‚¨įĄŽåŽščρ退å‡ē吗īŧŸ", "app_bar_signout_dialog_ok": "是", @@ -551,64 +551,64 @@ "archive_size": "åŊ’æĄŖå¤§å°", "archive_size_description": "配įŊŽä¸‹čŊŊįš„åŊ’æĄŖå¤§å°īŧˆGiBīŧ‰", "archived": "厞åŊ’æĄŖ", - "archived_count": "{count, plural, other {厞åŊ’æĄŖ # 饚}}", + "archived_count": "{count, plural, other {厞åŊ’æĄŖ#饚}}", "are_these_the_same_person": "čŋ™æ˜¯åŒä¸€ä¸Ēäēē吗īŧŸ", "are_you_sure_to_do_this": "įĄŽåŽščĻæ‰§čĄŒæ­¤æ“äŊœīŧŸ", "array_field_not_fully_supported": "数įģ„å­—æŽĩ需čĻæ‰‹åŠ¨čŋ›čĄŒ JSON įŧ–čž‘", - "asset_action_delete_err_read_only": "æ— æŗ•åˆ é™¤åĒč¯ģčĩ„æēīŧŒåˇ˛čˇŗčŋ‡", - "asset_action_share_err_offline": "æ— æŗ•čŽˇå–įĻģįēŋčĩ„æēīŧŒåˇ˛čˇŗčŋ‡", + "asset_action_delete_err_read_only": "æ— æŗ•åˆ é™¤åĒč¯ģéĄšį›ŽīŧŒåˇ˛čˇŗčŋ‡", + "asset_action_share_err_offline": "æ— æŗ•čŽˇå–įĻģįēŋéĄšį›ŽīŧŒåˇ˛čˇŗčŋ‡", "asset_added_to_album": "厞æˇģåŠ č‡ŗį›¸å†Œ", "asset_adding_to_album": "æ­Ŗåœ¨æˇģåŠ č‡ŗį›¸å†Œâ€Ļ", - "asset_created": "čĩ„æēåˇ˛åˆ›åģē", - "asset_description_updated": "čĩ„æēæčŋ°åˇ˛æ›´æ–°", - "asset_filename_is_offline": "čĩ„æēâ€œ{filename}â€åˇ˛įĻģįēŋ", - "asset_has_unassigned_faces": "čĩ„æēåŒ…åĢæœĒåˆ†é…įš„äēē脸", + "asset_created": "éĄšį›Žåˇ˛åˆ›åģē", + "asset_description_updated": "éĄšį›Žæčŋ°åˇ˛æ›´æ–°", + "asset_filename_is_offline": "éĄšį›Ž{filename}厞įĻģįēŋ", + "asset_has_unassigned_faces": "éĄšį›ŽåŒ…åĢæœĒåˆ†é…įš„äēē脸", "asset_hashing": "æ­Ŗåœ¨čŽĄįŽ—å“ˆå¸Œå€ŧâ€Ļ", "asset_list_group_by_sub_title": "分įģ„䞝捎", "asset_list_layout_settings_dynamic_layout_title": "åŠ¨æ€å¸ƒåą€", "asset_list_layout_settings_group_automatically": "č‡Ē动", - "asset_list_layout_settings_group_by": "čĩ„æēåˆ†įģ„䞝捎", + "asset_list_layout_settings_group_by": "ᅧቇ/视éĸ‘分įģ„䞝捎", "asset_list_layout_settings_group_by_month_day": "月äģŊ + æ—Ĩ期", "asset_list_layout_sub_title": "å¸ƒåą€", "asset_list_settings_subtitle": "ᅧቇįŊ‘æ ŧå¸ƒåą€čŽžįŊŽ", "asset_list_settings_title": "ᅧቇįŊ‘æ ŧ", - "asset_not_found_on_device_android": "čŽžå¤‡ä¸ŠæœĒ扞到č¯Ĩčĩ„æē", - "asset_not_found_on_device_ios": "čŽžå¤‡ä¸ŠæœĒ扞到č¯Ĩčĩ„æēã€‚åĻ‚æžœæ‚¨äŊŋᔍäē† iCloudīŧŒå¯čƒŊæ˜¯į”ąäēŽ iCloud 中存储äē†é”™č¯¯įš„æ–‡äģļå¯ŧ致čĩ„æēæ— æŗ•čŽŋ问", - "asset_not_found_on_icloud": "iCloud 中æœĒ扞到č¯Ĩčĩ„æēã€‚可čƒŊæ˜¯į”ąäēŽ iCloud 中存储äē†é”™č¯¯įš„æ–‡äģļå¯ŧ致čĩ„æēæ— æŗ•čŽŋ问", - "asset_offline": "čĩ„æēįĻģįēŋ", - "asset_offline_description": "įŖį›˜ä¸ŠæœĒ扞到此外部čĩ„æēã€‚蝎联įŗģæ‚¨įš„ Immich įŽĄį†å‘˜å¯ģæą‚å¸ŽåŠŠã€‚", - "asset_restored_successfully": "čĩ„æēæĸ复成功", + "asset_not_found_on_device_android": "čŽžå¤‡ä¸ŠæœĒ扞到č¯Ĩᅧቇ/视éĸ‘", + "asset_not_found_on_device_ios": "čŽžå¤‡ä¸ŠæœĒ扞到č¯Ĩᅧቇ/视éĸ‘。åĻ‚æžœæ‚¨äŊŋᔍäē† iCloudīŧŒå¯čƒŊæ˜¯į”ąäēŽ iCloud 中存储äē†é”™č¯¯įš„æ–‡äģļå¯ŧ致čĩ„æēæ— æŗ•čŽŋ问", + "asset_not_found_on_icloud": "iCloud中æœĒ扞到č¯Ĩᅧቇ/视éĸ‘。可čƒŊæ˜¯į”ąäēŽiCloud中存储äē†é”™č¯¯įš„æ–‡äģļå¯ŧ致čĩ„æēæ— æŗ•čŽŋ问", + "asset_offline": "éĄšį›ŽįĻģįēŋ", + "asset_offline_description": "įŖį›˜ä¸ŠæœĒ扞到此外部文äģļã€‚č¯ˇč”įŗģæ‚¨įš„ Immich įŽĄį†å‘˜å¯ģæą‚å¸ŽåŠŠã€‚", + "asset_restored_successfully": "文äģ￁ĸ复成功", "asset_skipped": "厞莺čŋ‡", "asset_skipped_in_trash": "在回æ”ļį̙䏭", - "asset_trashed": "čĩ„æēåˇ˛į§ģč‡ŗå›žæ”ļįĢ™", - "asset_troubleshoot": "čĩ„æēč¯Šæ–­", + "asset_trashed": "文äģļ厞į§ģč‡ŗå›žæ”ļįĢ™", + "asset_troubleshoot": "文äģļč¯Šæ–­", "asset_uploaded": "厞䏊äŧ ", "asset_uploading": "上äŧ ä¸­â€Ļ", "asset_viewer_settings_subtitle": "įŽĄį†į”ģå슿ŸĨįœ‹å™¨čŽžįŊŽ", - "asset_viewer_settings_title": "čĩ„æēæŸĨįœ‹å™¨", + "asset_viewer_settings_title": "文äģ￟Ĩįœ‹å™¨", "assets": "čĩ„æē", - "assets_added_count": "厞æˇģ加{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", + "assets_added_count": "厞æˇģ加{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}", "assets_added_to_album_count": "åˇ˛å‘į›¸å†Œæˇģ加{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", - "assets_added_to_albums_count": "厞向 {albumTotal, plural, one {# ä¸Ēį›¸å†Œ} other {# ä¸Ēį›¸å†Œ}}æˇģ加 {assetTotal, plural, one {# ä¸Ēčĩ„æē} other {# ä¸Ēčĩ„æē}}", + "assets_added_to_albums_count": "厞向 {albumTotal, plural, one {# ä¸Ēį›¸å†Œ} other {# ä¸Ēį›¸å†Œ}}æˇģ加 {assetTotal, plural, one {# ä¸Ēčĩ„æē} other {# ä¸ĒåŒģé™ĸ}}", "assets_cannot_be_added_to_album_count": "æ— æŗ•å‘į›¸å†Œæˇģ加{count, plural, one {ä¸Ēčĩ„æē} other {ä¸Ēčĩ„æē}}", "assets_cannot_be_added_to_albums": "æ— æŗ•å‘äģģäŊ•一ä¸Ēį›¸å†Œæˇģ加 {count, plural, one {ä¸Ēčĩ„æē} other {ä¸Ēčĩ„æē}}", - "assets_count": "{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", - "assets_deleted_permanently": "åˇ˛æ°¸äš…åˆ é™¤ {count} ä¸Ēčĩ„æē", - "assets_deleted_permanently_from_server": "åˇ˛æ°¸äš…į§ģ除 {count} ä¸Ēčĩ„äē§", - "assets_downloaded_failed": "{count, plural, one {厞䏋čŊŊ#ä¸Ē文äģļ - {error} ä¸Ē文äģļ下čŊŊå¤ąč´Ĩ} other {厞䏋čŊŊ#ä¸Ē文äģļ - {error} ä¸Ē文äģļ下čŊŊå¤ąč´Ĩ}}", - "assets_downloaded_successfully": "{count, plural, one {åˇ˛æˆåŠŸä¸‹čŊŊ # ä¸Ē文äģļ} other {åˇ˛æˆåŠŸä¸‹čŊŊ # ä¸Ē文äģļ}}", - "assets_moved_to_trash_count": "厞将{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}į§ģ动到回æ”ļįĢ™", - "assets_permanently_deleted_count": "åˇ˛æ°¸äš…åˆ é™¤{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", - "assets_removed_count": "厞į§ģ除{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", - "assets_removed_permanently_from_device": "厞äģŽæ‚¨įš„čŽžå¤‡ä¸­æ°¸äš…åˆ é™¤ {count} ä¸Ēčĩ„æē", - "assets_restore_confirmation": "æ‚¨įĄŽåŽščρæĸ复回æ”ļįĢ™ä¸­įš„æ‰€æœ‰čĩ„æēå—īŧŸæ­¤æ“äŊœæ— æŗ•撤销īŧč¯ˇæŗ¨æ„īŧŒäģģäŊ•įĻģįēŋčĩ„æēæ— æŗ•通čŋ‡æ­¤æ–šåŧæĸ复。", - "assets_restored_count": "厞æĸ复{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", - "assets_restored_successfully": "åˇ˛æˆåŠŸæĸ复{count}ä¸Ēčĩ„æē", - "assets_trashed": "{count} ä¸Ēčĩ„æēį§ģč‡ŗå›žæ”ļįĢ™", - "assets_trashed_count": "厞将{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}į§ģč‡ŗå›žæ”ļįĢ™", - "assets_trashed_from_server": "Immich æœåŠĄå™¨ä¸Šåˇ˛į§ģ除 {count} ä¸Ēčĩ„æē", - "assets_were_part_of_album_count": "{count, plural, one {ä¸Ēčĩ„æē} other {ä¸Ēčĩ„æē}}厞圍č¯Ĩį›¸å†Œä¸­", - "assets_were_part_of_albums_count": "{count, plural, one {ä¸Ēčĩ„æē} other {ä¸Ēčĩ„æē}} 厞存圍äēŽčŋ™äē›į›¸å†Œä¸­", + "assets_count": "{count, plural, one {#ä¸ĒéĄšį›Ž} other {#ä¸ĒéĄšį›Ž}}", + "assets_deleted_permanently": "åˇ˛æ°¸äš…åˆ é™¤ {count} ä¸Ē文äģļ", + "assets_deleted_permanently_from_server": "åˇ˛æ°¸äš…į§ģ除 {count} ä¸Ē文äģļ", + "assets_downloaded_failed": "{count, plural, one {厞䏋čŊŊ#ä¸Ē文äģļ - {error}ä¸Ē文äģļ下čŊŊå¤ąč´Ĩ} other {厞䏋čŊŊ#ä¸Ē文äģļ - {error}ä¸Ē文äģļ下čŊŊå¤ąč´Ĩ}}", + "assets_downloaded_successfully": "{count, plural, one {åˇ˛æˆåŠŸä¸‹čŊŊ#ä¸Ē文äģļ} other {åˇ˛æˆåŠŸä¸‹čŊŊ#ä¸Ē文äģļ}}", + "assets_moved_to_trash_count": "厞将{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}į§ģ动到回æ”ļįĢ™", + "assets_permanently_deleted_count": "åˇ˛æ°¸äš…åˆ é™¤{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}", + "assets_removed_count": "厞į§ģ除{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}", + "assets_removed_permanently_from_device": "厞äģŽæ‚¨įš„čŽžå¤‡ä¸­æ°¸äš…åˆ é™¤{count}ä¸Ē文äģļ", + "assets_restore_confirmation": "æ‚¨įĄŽåŽščρæĸ复回æ”ļįĢ™ä¸­įš„æ‰€æœ‰æ–‡äģļ吗īŧŸæ­¤æ“äŊœæ— æŗ•撤销īŧč¯ˇæŗ¨æ„īŧŒįĻģįēŋ文äģļæ— æŗ•通čŋ‡æ­¤æ–šåŧæĸ复。", + "assets_restored_count": "厞æĸ复{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}", + "assets_restored_successfully": "åˇ˛æˆåŠŸæĸ复{count}ä¸Ē文äģļ", + "assets_trashed": "{count}ä¸Ē文äģļį§ģč‡ŗå›žæ”ļįĢ™", + "assets_trashed_count": "厞将{count, plural, one {#ä¸Ē文äģļ} other {#ä¸Ē文äģļ}}į§ģč‡ŗå›žæ”ļįĢ™", + "assets_trashed_from_server": "厞äģŽImmichæœåŠĄå™¨ä¸Šį§ģ除{count}ä¸Ē文äģļ", + "assets_were_part_of_album_count": "{count, plural, one {ä¸ĒåŒģé™ĸ} other {ä¸Ēčĩ„æē}}厞圍č¯Ĩį›¸å†Œä¸­", + "assets_were_part_of_albums_count": "{count, plural, one {ä¸ĒéĄšį›Ž} other {ä¸ĒéĄšį›Ž}}厞存圍äēŽčŋ™äē›į›¸į°ŋ中", "authorized_devices": "åˇ˛æŽˆæƒčŽžå¤‡", "automatic_endpoint_switching_subtitle": "åœ¨å¯į”¨æ—ļ通čŋ‡æŒ‡åŽšįš„ Wi-Fi čŋ›čĄŒæœŦ地čŋžæŽĨīŧŒå…ļäģ–äŊįŊŽåˆ™äŊŋᔍæ›ŋäģŖįŊ‘įģœčŋžæŽĨ", "automatic_endpoint_switching_title": "č‡Ē动切æĸ URL", @@ -617,31 +617,31 @@ "back_close_deselect": "čŋ”å›žã€å…ŗé—­æˆ–å–æļˆé€‰æ‹Š", "background_backup_running_error": "后台备äģŊæ­Ŗåœ¨čŋčĄŒä¸­īŧŒæ— æŗ•启动手动备äģŊ", "background_location_permission": "后台厚äŊæƒé™", - "background_location_permission_content": "ä¸ēäē†åœ¨åŽå°čŋčĄŒæ—ļåŽžįŽ°įŊ‘įģœåˆ‡æĸīŧŒImmich åŋ…éĄģ始į숿‹Ĩæœ‰į˛žįĄŽäŊįŊŽčŽŋ闎权限īŧŒäģĨäžŋåē”ᔍčƒŊ够č¯ģ取 Wi-Fi įŊ‘įģœįš„åį§°", + "background_location_permission_content": "ä¸ēäē†åœ¨åŽå°čŋčĄŒæ—ļåŽžįŽ°įŊ‘įģœåˆ‡æĸīŧŒImmichåŋ…éĄģ始į숿‹Ĩæœ‰į˛žįĄŽäŊįŊŽčŽŋ闎权限īŧŒäģĨäžŋåē”ᔍčƒŊ够č¯ģ取 Wi-Fi įŊ‘įģœįš„åį§°", "background_options": "åŽå°é€‰éĄš", "backup": "备äģŊ", - "backup_album_selection_page_albums_device": "čŽžå¤‡ä¸Šįš„į›¸å†Œīŧˆ{count}īŧ‰", + "backup_album_selection_page_albums_device": "čŽžå¤‡ä¸Šįš„į›¸į°ŋīŧˆ{count}īŧ‰", "backup_album_selection_page_albums_tap": "单å‡ģ包åĢīŧŒåŒå‡ģ排除", - "backup_album_selection_page_assets_scatter": "čĩ„æēæ–‡äģļ可čƒŊåˆ†æ•Ŗåœ¨å¤šä¸Ēį›¸å†Œä¸­ã€‚å› æ­¤īŧŒåœ¨å¤‡äģŊčŋ‡į¨‹ä¸­īŧŒæ‚¨å¯äģĨ选拊包åĢæˆ–æŽ’é™¤į‰šåŽšįš„į›¸å†Œã€‚", - "backup_album_selection_page_select_albums": "é€‰æ‹Šį›¸å†Œ", + "backup_album_selection_page_assets_scatter": "čĩ„æēå¯äģĨåˆ†æ•Ŗåœ¨å¤šä¸Ēį›¸å†Œä¸­ã€‚å› æ­¤īŧŒåœ¨å¤‡äģŊčŋ‡į¨‹ä¸­īŧŒå¯äģĨ包åĢ或排除某äē›į›¸å†Œã€‚", + "backup_album_selection_page_select_albums": "é€‰æ‹Šį›¸į°ŋ", "backup_album_selection_page_selection_info": "选拊äŋĄæ¯", - "backup_album_selection_page_total_assets": "唯一čĩ„æēæ€ģ莥", - "backup_albums_sync": "备äģŊį›¸å†ŒåŒæ­Ĩ", + "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_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": "æ­Ŗåœ¨æŖ€æŸĨ新čĩ„æēâ€Ļ", + "backup_background_service_default_notification": "æ­Ŗåœ¨æŖ€æŸĨ新文äģļâ€Ļ", "backup_background_service_error_title": "备äģŊ错蝝", - "backup_background_service_in_progress_notification": "æ­Ŗåœ¨å¤‡äģŊæ‚¨įš„čĩ„æēâ€Ļ", + "backup_background_service_in_progress_notification": "æ­Ŗåœ¨å¤‡äģŊæ‚¨įš„æ–‡äģļâ€Ļ", "backup_background_service_upload_failure_notification": "“{filename}”上äŧ å¤ąč´Ĩ", - "backup_controller_page_albums": "备äģŊį›¸å†Œ", + "backup_controller_page_albums": "备äģŊᛏį°ŋ", "backup_controller_page_background_app_refresh_disabled_content": "åœ¨â€œčŽžįŊŽâ€>â€œé€šį”¨â€>“后台 App åˆˇæ–°â€ä¸­å¯į”¨æ­¤åŠŸčƒŊīŧŒäģĨäŊŋį”¨åŽå°å¤‡äģŊ。", "backup_controller_page_background_app_refresh_disabled_title": "后台 App åˆˇæ–°åˇ˛å…ŗé—­", "backup_controller_page_background_app_refresh_enable_button_text": "å‰åž€čŽžįŊŽ", "backup_controller_page_background_battery_info_link": "åą•į¤ē操äŊœæ­ĨéǤ", - "backup_controller_page_background_battery_info_message": "ä¸ēčŽˇåž—æœ€äŊŗįš„后台备äģŊäŊ“énjīŧŒč¯ˇåœ¨įŗģįģŸčŽžįŊŽä¸­įĻį”¨é’ˆå¯š Immich įš„äģģäŊ•į”ĩæą äŧ˜åŒ–限åˆļ。\n\nį”ąäēŽč¯Ĩ莞įŊŽå› čŽžå¤‡č€Œåŧ‚īŧŒč¯ˇæŸĨč¯ĸæ‚¨čŽžå¤‡åˆļé€ å•†įš„å…ˇäŊ“čĻæą‚ã€‚", + "backup_controller_page_background_battery_info_message": "ä¸ēčŽˇåž—æœ€äŊŗįš„后台备äģŊäŊ“énjīŧŒč¯ˇåœ¨įŗģįģŸčŽžįŊŽä¸­įĻį”¨é’ˆå¯šImmichįš„äģģäŊ•į”ĩæą äŧ˜åŒ–限åˆļ。\n\nį”ąäēŽč¯Ĩ莞įŊŽå› čŽžå¤‡č€Œåŧ‚īŧŒč¯ˇæŸĨč¯ĸæ‚¨čŽžå¤‡åˆļé€ å•†įš„å…ˇäŊ“čĻæą‚ã€‚", "backup_controller_page_background_battery_info_ok": "我įŸĨ道äē†", "backup_controller_page_background_battery_info_title": "į”ĩæą äŧ˜åŒ–", "backup_controller_page_background_charging": "äģ…在充į”ĩæ—ļ", @@ -652,7 +652,7 @@ "backup_controller_page_background_is_on": "后台č‡Ē动备äģŊ厞åŧ€å¯", "backup_controller_page_background_turn_off": "å…ŗé—­åŽå°æœåŠĄ", "backup_controller_page_background_turn_on": "åŧ€å¯åŽå°æœåŠĄ", - "backup_controller_page_background_wifi": "äģ…在 Wi-Fi 下", + "backup_controller_page_background_wifi": "äģ…在Wi-Fi下", "backup_controller_page_backup": "备äģŊ", "backup_controller_page_backup_selected": "厞选īŧš ", "backup_controller_page_backup_sub": "厞备äģŊįš„į…§į‰‡å’Œč§†éĸ‘", @@ -661,7 +661,7 @@ "backup_controller_page_excluded": "åˇ˛æŽ’é™¤īŧš ", "backup_controller_page_failed": "å¤ąč´Ĩīŧˆ{count}īŧ‰", "backup_controller_page_filename": "文äģļ名īŧš{filename} [{size}]", - "backup_controller_page_id": "IDīŧš{id}", + "backup_controller_page_id": "ID: {id}", "backup_controller_page_info": "备äģŊäŋĄæ¯", "backup_controller_page_none_selected": "暂æœĒ选拊", "backup_controller_page_remainder": "削äŊ™", @@ -671,14 +671,14 @@ "backup_controller_page_status_off": "æœĒåŧ€å¯å‰å°č‡Ē动备äģŊ", "backup_controller_page_status_on": "前台č‡Ē动备äģŊåˇ˛æ‰“åŧ€", "backup_controller_page_storage_format": "厞ᔍ {used}īŧˆå…ą {total}īŧ‰", - "backup_controller_page_to_backup": "垅备äģŊįš„į›¸å†Œ", - "backup_controller_page_total_sub": "包åĢæ‰€é€‰į›¸å†Œå†…å…¨éƒ¨å”¯ä¸€įš„į…§į‰‡å’Œč§†éĸ‘", + "backup_controller_page_to_backup": "垅备äģŊįš„į›¸į°ŋ", + "backup_controller_page_total_sub": "包åĢæ‰€é€‰į›¸į°ŋå†…å…¨éƒ¨å”¯ä¸€įš„į…§į‰‡å’Œč§†éĸ‘", "backup_controller_page_turn_off": "å…ŗé—­å‰å°å¤‡äģŊ", "backup_controller_page_turn_on": "åŧ€å¯å‰å°å¤‡äģŊ", "backup_controller_page_uploading_file_info": "æ­Ŗåœ¨ä¸Šäŧ æ–‡äģļäŋĄæ¯", - "backup_err_only_album": "æ— æŗ•åˆ é™¤å”¯ä¸€įš„į›¸å†Œ", + "backup_err_only_album": "æ— æŗ•åˆ é™¤å”¯ä¸€įš„į›¸į°ŋ", "backup_error_sync_failed": "同æ­Ĩå¤ąč´Ĩã€‚æ— æŗ•å¤„į†å¤‡äģŊ。", - "backup_info_card_assets": "čĩ„äē§", + "backup_info_card_assets": "į…§į‰‡å’Œč§†éĸ‘", "backup_manual_cancelled": "åˇ˛å–æļˆ", "backup_manual_in_progress": "上äŧ æ­Ŗåœ¨čŋ›čĄŒä¸­īŧŒč¯ˇį¨åŽå†č¯•", "backup_manual_success": "成功", @@ -707,10 +707,10 @@ "cache_settings_clear_cache_button_title": "æ¸…į†åē”ᔍįŧ“存。在įŧ“存重åģ翜Ÿé—´īŧŒåē”į”¨įš„čŋčĄŒé€ŸåēĻäŧšæ˜Žæ˜žå˜æ…ĸ。", "cache_settings_duplicated_assets_clear_button": "清除", "cache_settings_duplicated_assets_subtitle": "åŋŊį•Ĩåˆ—čĄ¨ä¸­įš„åĒ’äŊ“æ–‡äģļ", - "cache_settings_duplicated_assets_title": "重复čĩ„äē§īŧˆ{count}īŧ‰", + "cache_settings_duplicated_assets_title": "重复文äģļīŧˆ{count}īŧ‰", "cache_settings_statistics_album": "回åē“įŧŠį•Ĩ回", "cache_settings_statistics_full": "原回", - "cache_settings_statistics_shared": "å…ąäēĢį›¸å†ŒįŧŠį•Ĩ回", + "cache_settings_statistics_shared": "å…ąäēĢᛏį°ŋįŧŠį•Ĩ回", "cache_settings_statistics_thumbnail": "įŧŠį•Ĩ回", "cache_settings_statistics_title": "įŧ“å­˜å į”¨æƒ…å†ĩ", "cache_settings_subtitle": "įŽĄį† Immich 手æœēįĢ¯įš„įŧ“å­˜", @@ -752,25 +752,25 @@ "changed_visibility_successfully": "å¯č§įŠļ态更新成功", "charging": "充į”ĩ中", "charging_requirement_mobile_backup": "后台备äģŊ需čĻčŽžå¤‡å¤„äēŽå……į”ĩįŠļ态", - "check_corrupt_asset_backup": "æŖ€æŸĨčĩ„äē§å¤‡äģŊ是åĻ损坏", + "check_corrupt_asset_backup": "æŖ€æŸĨ文äģļ备äģŊ是åĻ损坏", "check_corrupt_asset_backup_button": "æ‰§čĄŒæŖ€æŸĨ", - "check_corrupt_asset_backup_description": "äģ…在 Wi-Fi įŽ¯åĸƒä¸‹čŋčĄŒæ­¤æŖ€æŸĨīŧŒåšļįĄŽäŋæ‰€æœ‰čĩ„æēå‡åˇ˛å¤‡äģŊ。č¯Ĩčŋ‡į¨‹å¯čƒŊ需čĻå‡ åˆ†é’Ÿæ—ļ间。", + "check_corrupt_asset_backup_description": "äģ…在Wi-FiįŽ¯åĸƒä¸‹čŋčĄŒæ­¤æŖ€æŸĨīŧŒåšļįĄŽäŋæ‰€æœ‰æ–‡äģļå‡åˇ˛å¤‡äģŊ。č¯Ĩčŋ‡į¨‹å¯čƒŊ需čĻå‡ åˆ†é’Ÿæ—ļ间。", "check_logs": "æŖ€æŸĨæ—Ĩåŋ—", "checksum": "æ ĄéĒŒå’Œ", "choose_matching_people_to_merge": "选拊čρ合åšļįš„äēēį‰Š", "city": "城市", - "cleanup_confirm_description": "Immich åˇ˛æ‰žåˆ° {count} ä¸Ē厉全备äģŊč‡ŗæœåŠĄå™¨įš„čĩ„æēīŧˆåˆ›åģēäēŽ {date} 䚋前īŧ‰ã€‚是åĻäģŽæ­¤čŽžå¤‡į§ģ除æœŦ地副æœŦīŧŸ", + "cleanup_confirm_description": "Immichåˇ˛æ‰žåˆ°{count}ä¸Ē厉全备äģŊč‡ŗæœåŠĄå™¨įš„æ–‡äģļīŧˆåˆ›åģēäēŽ{date}䚋前īŧ‰ã€‚是åĻäģŽæ­¤čŽžå¤‡į§ģ除æœŦ地副æœŦīŧŸ", "cleanup_confirm_prompt_title": "是åĻäģŽæ­¤čŽžå¤‡į§ģ除īŧŸ", - "cleanup_deleted_assets": "厞将 {count} ä¸Ēčĩ„æēį§ģč‡ŗčŽžå¤‡å›žæ”ļįĢ™", + "cleanup_deleted_assets": "厞将{count}ä¸Ē文äģļį§ģč‡ŗčŽžå¤‡å›žæ”ļįĢ™", "cleanup_deleting": "æ­Ŗåœ¨į§ģč‡ŗå›žæ”ļįĢ™...", - "cleanup_found_assets": "åˇ˛æ‰žåˆ° {count} ä¸Ē厞备äģŊįš„čĩ„æē", - "cleanup_found_assets_with_size": "åˇ˛æ‰žåˆ° {count} ä¸Ē厞备äģŊįš„čĩ„æē ({size})", - "cleanup_icloud_shared_albums_excluded": "iCloud å…ąäēĢį›¸å†Œåˇ˛æŽ’é™¤åœ¨æ‰ĢæčŒƒå›´äš‹å¤–", - "cleanup_no_assets_found": "æœĒ扞到įŦĻ合上čŋ°æĄäģļįš„čĩ„æēã€‚“释攞įŠē间”äģ…čƒŊį§ģ除厞备äģŊč‡ŗæœåŠĄå™¨įš„æ–‡äģļ", - "cleanup_preview_title": "åž…į§ģé™¤įš„čĩ„æē ({count})", - "cleanup_step3_description": "æ‰Ģ描įŦĻ合æ—Ĩ期及äŋį•™čŽžįŊŽįš„厞备äģŊčĩ„æēã€‚", - "cleanup_step4_summary": "将äģŽæœŦæœēį§ģ除 {count} ä¸Ēčĩ„æēīŧˆåˆ›åģēäēŽ {date} 䚋前īŧ‰ã€‚ᅧቇäģå¯åœ¨ Immich åē”ᔍ䏭čŽŋ闎。", - "cleanup_trash_hint": "ä¸ēåŊģåē•释攞存储įŠē间īŧŒč¯ˇæ‰“åŧ€įŗģįģŸį›¸å†Œåē”ᔍåšļ清įŠē回æ”ļįĢ™", + "cleanup_found_assets": "åˇ˛æ‰žåˆ°{count}ä¸Ē厞备äģŊįš„æ–‡äģļ", + "cleanup_found_assets_with_size": "åˇ˛æ‰žåˆ°{count}ä¸Ē厞备äģŊįš„æ–‡äģļīŧˆ{size}īŧ‰", + "cleanup_icloud_shared_albums_excluded": "iCloudå…ąäēĢᛏį°ŋåˇ˛æŽ’é™¤åœ¨æ‰ĢæčŒƒå›´äš‹å¤–", + "cleanup_no_assets_found": "æœĒ扞到įŦĻ合上čŋ°æĄäģļįš„æ–‡äģļ。“释攞įŠē间”äģ…čƒŊį§ģ除厞备äģŊč‡ŗæœåŠĄå™¨įš„æ–‡äģļ", + "cleanup_preview_title": "åž…į§ģé™¤įš„į…§į‰‡/视éĸ‘īŧˆ{count}īŧ‰", + "cleanup_step3_description": "æ‰Ģ描įŦĻ合æ—Ĩ期及äŋį•™čŽžįŊŽįš„厞备äģŊᅧቇ/视éĸ‘。", + "cleanup_step4_summary": "将äģŽæœŦ地į§ģ除{count}ä¸Ēᅧቇ/视éĸ‘īŧˆåˆ›åģēäēŽ {date} 䚋前īŧ‰ã€‚ᅧቇäģå¯åœ¨Immich App中čŽŋ闎。", + "cleanup_trash_hint": "ä¸ēåŊģåē•释攞存储įŠē间īŧŒč¯ˇæ‰“åŧ€įŗģįģŸį…§į‰‡Appåšļ清įŠē回æ”ļįĢ™", "clear": "清įŠē", "clear_all": "全部清除", "clear_all_recent_searches": "清除全部最čŋ‘搜į´ĸ莰åŊ•", @@ -786,7 +786,7 @@ "client_cert_password_title": "蝁äšĻ坆᠁", "client_cert_remove_msg": "åŽĸæˆˇį̝蝁äšĻ厞į§ģ除", "client_cert_subtitle": "äģ…æ”¯æŒ PKCS12 æ ŧåŧ (.p12, .pfx)。į™ģåŊ•åŽå°†æ— æŗ•å¯ŧå…Ĩ或į§ģ除蝁äšĻ", - "client_cert_title": "SSL åŽĸæˆˇį̝蝁äšĻ[厞éĒŒæ€§åŠŸčƒŊ]", + "client_cert_title": "SSLåŽĸæˆˇį̝蝁äšĻ [厞éĒŒæ€§åŠŸčƒŊ]", "clockwise": "éĄēæ—ļ针", "close": "å…ŗé—­", "collapse": "æ”ļčĩˇ", @@ -803,13 +803,13 @@ "comment_options": "更多", "comments_and_likes": "蝄čŽē & į‚ščĩž", "comments_are_disabled": "蝄čŽē厞兺闭", - "common_create_new_album": "创åģēæ–°į›¸å†Œ", + "common_create_new_album": "创åģēæ–°į›¸į°ŋ", "completed": "åˇ˛åŽŒæˆ", "confirm": "įĄŽčŽ¤", "confirm_admin_password": "įĄŽčŽ¤įŽĄį†å‘˜å¯†į ", "confirm_delete_face": "įĄŽåŽščρäģŽæ­¤æ–‡äģļ中删除 {name} įš„éĸ部äŋĄæ¯å—īŧŸ", "confirm_delete_shared_link": "įĄŽåŽščĻåˆ é™¤æ­¤å…ąäēĢ链æŽĨ吗īŧŸ", - "confirm_keep_this_delete_others": "堆栈中所有å…ļäģ–čĩ„æēéƒŊ将čĸĢ删除īŧŒäģ…äŋį•™æ­¤čĩ„æēã€‚įĄŽåޚčρįģ§įģ­å—īŧŸ", + "confirm_keep_this_delete_others": "å †å ä¸­é™¤æ­¤éĄšį›Žå¤–įš„æ‰€æœ‰å…ļäģ–éĄšį›ŽéƒŊ将čĸĢåˆ é™¤ã€‚įĄŽåŽščρįģ§įģ­å—īŧŸ", "confirm_new_pin_code": "įĄŽčŽ¤æ–° PIN ᠁", "confirm_password": "įĄŽčŽ¤å¯†į ", "confirm_tag_face": "是åĻ将此äēēč„¸æ ‡čŽ°ä¸ē {name}īŧŸ", @@ -819,8 +819,8 @@ "contain": "适åē”", "context": "äģĨ文搜回", "continue": "įģ§įģ­", - "control_bottom_app_bar_create_new_album": "新åģēį›¸å†Œ", - "control_bottom_app_bar_delete_from_immich": "äģŽ Immich æœåŠĄå™¨ä¸­åˆ é™¤", + "control_bottom_app_bar_create_new_album": "新åģēᛏį°ŋ", + "control_bottom_app_bar_delete_from_immich": "äģŽImmichæœåŠĄå™¨ä¸­åˆ é™¤", "control_bottom_app_bar_delete_from_local": "äģŽčŽžå¤‡ä¸­åˆ é™¤", "control_bottom_app_bar_edit_location": "įŧ–čž‘äŊįŊŽ", "control_bottom_app_bar_edit_time": "įŧ–čž‘æ—Ĩ期和æ—ļ间", @@ -840,19 +840,22 @@ "cover": "åĄĢ充", "covers": "封éĸ", "create": "创åģē", - "create_album": "创åģēį›¸å†Œ", + "create_album": "创åģēᛏį°ŋ", "create_album_page_untitled": "æœĒå‘Ŋ名", "create_api_key": "创åģē API 密é’Ĩ", "create_first_workflow": "创åģēéĻ–ä¸ĒåˇĨäŊœæĩ", - "create_library": "创åģēčĩ„æ–™åē“", + "create_library": "创åģēčĩ„æēåē“", "create_link": "创åģē链æŽĨ", "create_link_to_share": "创åģēå…ąäēĢ链æŽĨ", "create_link_to_share_description": "å…čŽ¸äģģäŊ•æ‹Ĩ有铞æŽĨįš„äē翟Ĩįœ‹æ‰€é€‰į…§į‰‡", "create_new": "新åģē", + "create_new_face": "创åģēæ–°äēē脸", "create_new_person": "创åģēæ–°äēēį‰Š", - "create_new_person_hint": "将所选čĩ„æēåˆ†é…į왿–°äēēį‰Š", + "create_new_person_hint": "å°†æ‰€é€‰į…§į‰‡/视éĸ‘分配į왿–°äēēį‰Š", "create_new_user": "新åģēį”¨æˆˇ", - "create_shared_album_page_share_add_assets": "æˇģ加čĩ„æē", + "create_person": "创åģēäēēį‰Š", + "create_person_subtitle": "ä¸ē所选äēē脸æˇģ加姓名īŧŒäģĨ创åģēåšļæ ‡čŽ°æ–°äēēį‰Š", + "create_shared_album_page_share_add_assets": "æˇģåŠ į…§į‰‡/视éĸ‘", "create_shared_album_page_share_select_photos": "é€‰æ‹Šį…§į‰‡", "create_shared_link": "创åģēå…ąäēĢ链æŽĨ", "create_tag": "创åģēæ ‡į­ž", @@ -861,11 +864,12 @@ "create_workflow": "新åģēåˇĨäŊœæĩ", "created": "åˇ˛åˆ›åģē", "created_at": "创åģēæ—ļ间", - "creating_linked_albums": "æ­Ŗåœ¨åˆ›åģēį›¸å†Œé“žæŽĨâ€Ļ", + "creating_linked_albums": "æ­Ŗåœ¨åˆ›åģēᛏį°ŋ链æŽĨâ€Ļ", "crop": "誁å‰Ē", "crop_aspect_ratio_fixed": "å›ē厚比䞋", "crop_aspect_ratio_free": "č‡Ēį”ąæ¯”äž‹", "crop_aspect_ratio_original": "原始比䞋", + "crop_aspect_ratio_square": "æ–šåŊĸ", "curated_object_page_title": "į˛žé€‰é›†", "current_device": "åŊ“å‰čŽžå¤‡", "current_pin_code": "åŊ“前 PIN ᠁", @@ -880,7 +884,7 @@ "daily_title_text_date": "MMM dd (E)", "daily_title_text_date_year": "YYYYåš´M月dæ—Ĩ (E)", "dark": "æˇąč‰˛", - "dark_theme": "切æĸæˇąč‰˛ä¸ģéĸ˜", + "dark_theme": "切æĸåˆ°æˇąč‰˛ä¸ģéĸ˜", "date": "æ—Ĩ期", "date_after": "åŧ€å§‹æ—Ĩ期", "date_and_time": "æ—Ĩ期与æ—ļ间", @@ -891,14 +895,12 @@ "day": "æ—Ĩ", "days": "夊", "deduplicate_all": "åˆ é™¤æ‰€æœ‰é‡å¤éĄš", - "deduplication_criteria_1": "回像大小īŧˆå­—节īŧ‰", - "deduplication_criteria_2": "EXIF æ•°æŽčŽĄæ•°", - "deduplication_info": "åŽģ重įģŸčŽĄ", - "deduplication_info_description": "ä¸ēäē†č‡Ē动éĸ„é€‰į´ æåšļ扚量åŽģé™¤é‡å¤éĄšīŧŒæˆ‘äģŦäŧšå‚č€ƒäģĨ下äŋĄæ¯īŧš", + "default_locale": "éģ˜čޤ蝭荀", + "default_locale_description": "æ šæŽæ‚¨įš„æĩč§ˆå™¨åŒē域æ ŧåŧåŒ–æ—Ĩ期和数字", "delete": "删除", "delete_action_confirmation_message": "æ‚¨įĄŽåŽščĻåˆ é™¤æ­¤į´ æå—īŧŸæ­¤æ“äŊœäŧšå°†č¯Ĩį´ æį§ģč‡ŗæœåŠĄå™¨įš„å›žæ”ļįĢ™īŧŒåšļ提į¤ē您是åĻ将å…ļ在æœŦåœ°čŽžå¤‡ä¸Šåˆ é™¤", "delete_action_prompt": "åˇ˛åˆ é™¤ {count} 饚", - "delete_album": "åˆ é™¤į›¸å†Œ", + "delete_album": "åˆ é™¤į›¸į°ŋ", "delete_api_key_prompt": "æ‚¨įĄŽåŽščĻåˆ é™¤æ­¤ API 密é’Ĩ吗īŧŸ", "delete_dialog_alert": "čŋ™äē›éĄšį›Žå°†äģŽ Immich æœåŠĄå™¨äģĨ及äŊ įš„čŽžå¤‡ä¸ŠčĸĢæ°¸äš…删除", "delete_dialog_alert_local": "čŋ™äē›éĄšį›Žå°†äģŽäŊ įš„čŽžå¤‡ä¸ŠčĸĢæ°¸äš…į§ģ除īŧŒäŊ†äžį„ļäŧšäŋį•™åœ¨ Immich æœåŠĄå™¨ä¸Š", @@ -909,14 +911,14 @@ "delete_duplicates_confirmation": "æ‚¨įĄŽåŽščĻæ°¸äš…åˆ é™¤čŋ™äē›é‡å¤éĄšå—īŧŸ", "delete_face": "删除č¯Ĩäēē脸", "delete_key": "删除密é’Ĩ", - "delete_library": "删除čĩ„æ–™åē“", + "delete_library": "删除čĩ„æēåē“", "delete_link": "删除铞æŽĨ", - "delete_local_action_prompt": "{count} éĄšåˇ˛åœ¨æœŦ地删除", + "delete_local_action_prompt": "{count}éĄšåˇ˛åœ¨æœŦ地删除", "delete_local_dialog_ok_backed_up_only": "äģ…åˆ é™¤åˇ˛å¤‡äģŊįš„éĄšį›Ž", "delete_local_dialog_ok_force": "åŧēåˆļ删除", - "delete_others": "删除å…ļ厃", + "delete_others": "删除å…ļäģ–", "delete_permanently": "永䚅删除", - "delete_permanently_action_prompt": "{count} éĄšåˇ˛æ°¸äš…åˆ é™¤", + "delete_permanently_action_prompt": "{count}éĄšåˇ˛æ°¸äš…åˆ é™¤", "delete_shared_link": "åˆ é™¤å…ąäēĢ链æŽĨ", "delete_shared_link_dialog_title": "åˆ é™¤å…ąäēĢ链æŽĨ", "delete_tag": "åˆ é™¤æ ‡į­ž", @@ -933,7 +935,7 @@ "disable": "įρᔍ", "disabled": "įρᔍ", "disallow_edits": "įρæ­ĸįŧ–čž‘", - "discord": "Discord į¤žåŒē", + "discord": "Discord", "discover": "å‘įŽ°", "discovered_devices": "åˇ˛å‘įŽ°įš„čŽžå¤‡", "dismiss_all_errors": "åŋŊį•Ĩæ‰€æœ‰é”™č¯¯", @@ -970,10 +972,10 @@ "downloading_media": "æ­Ŗåœ¨ä¸‹čŊŊåĒ’äŊ“æ–‡äģļ", "drop_files_to_upload": "随意拖攞文äģļäģĨ上äŧ ", "duplicates": "é‡å¤éĄš", - "duplicates_description": "č¯ˇé€ä¸€æ ‡čŽ°æ¯įģ„ä¸­įš„é‡å¤æ–‡äģļ", + "duplicates_description": "č¯ˇé€ä¸€æ ‡čŽ°æ¯įģ„ä¸­įš„é‡å¤æ–‡äģļ。", "duration": "æ—ļé•ŋ", "edit": "įŧ–čž‘", - "edit_album": "įŧ–čž‘į›¸å†Œ", + "edit_album": "įŧ–čž‘į›¸į°ŋ", "edit_avatar": "įŧ–čž‘å¤´åƒ", "edit_birthday": "įŧ–čž‘į”Ÿæ—Ĩ", "edit_date": "įŧ–čž‘æ—Ĩ期", @@ -1007,7 +1009,7 @@ "editor_edits_applied_success": "įŧ–čž‘åˇ˛æˆåŠŸåē”ᔍ", "editor_flip_horizontal": "æ°´åšŗįŋģčŊŦ", "editor_flip_vertical": "åž‚į›´įŋģčŊŦ", - "editor_handle_corner": "{corner, select, top_left {åˇĻ上角} top_right {åŗä¸Šč§’} bottom_left {åˇĻ下角} bottom_right {åŗä¸‹č§’} other {某ä¸Ē}} 角čŊįš„æŽ§åˆļ手柄", + "editor_handle_corner": "{corner, select, top_left {åˇĻ上角} top_right {åŗä¸Šč§’} bottom_left {åˇĻ下角} bottom_right {åŗä¸‹č§’} other {某ä¸Ē}}角čŊįš„æŽ§åˆļ手柄", "editor_handle_edge": "{edge, select, top {éĄļ部} bottom {åē•部} left {åˇĻäž§} right {åŗäž§} other {某ä¸Ē}} čžšįŧ˜įš„æŽ§åˆļ手柄", "editor_orientation": "斚向", "editor_reset_all_changes": "čŋ˜åŽŸæ›´æ”š", @@ -1017,7 +1019,7 @@ "email_notifications": "邮äģļ通įŸĨ", "empty_folder": "此文äģļ多ä¸ēįŠē", "empty_trash": "清įŠē回æ”ļįĢ™", - "empty_trash_confirmation": "įĄŽåŽščĻæ¸…įŠē回æ”ļį̙吗īŧŸæ­¤æ“äŊœå°†æ°¸äš…删除回æ”ļįĢ™ä¸­įš„æ‰€æœ‰čĩ„æēã€‚\nč¯Ĩ操äŊœæ— æŗ•撤销īŧ", + "empty_trash_confirmation": "įĄŽåŽščĻæ¸…įŠē回æ”ļį̙吗īŧŸæ­¤æ“äŊœå°†æ°¸äš…删除回æ”ļįĢ™ä¸­įš„æ‰€æœ‰į…§į‰‡/视éĸ‘。\nč¯Ĩ操äŊœæ— æŗ•撤销īŧ", "enable": "吝ᔍ", "enable_backup": "吝ᔍ备äģŊ", "enable_biometric_auth_description": "č¯ˇčž“å…Ĩæ‚¨įš„ PIN ᠁äģĨå¯į”¨į”Ÿį‰Šč¯†åˆĢčŽ¤č¯", @@ -1028,49 +1030,49 @@ "enter_your_pin_code": "输å…Ĩæ‚¨įš„ PIN ᠁", "enter_your_pin_code_subtitle": "输å…ĨäŊ įš„ PIN ᠁äģĨčŽŋé—Žé”åŽšįš„æ–‡äģļ多", "error": "错蝝", - "error_change_sort_album": "æ›´æ”šį›¸å†ŒæŽ’åēéĄēåēå¤ąč´Ĩ", - "error_delete_face": "删除č¯Ĩčĩ„äē§ä¸­įš„äēē脸æ—ļå‡ē错", + "error_change_sort_album": "æ›´æ”šį›¸į°ŋ排åēéĄēåēå¤ąč´Ĩ", + "error_delete_face": "删除č¯Ĩᅧቇ/视éĸ‘ä¸­įš„äēē脸æ—ļå‡ē错", "error_getting_places": "čŽˇå–åœ°į‚šäŋĄæ¯æ—ļå‡ē错", - "error_loading_albums": "加čŊŊį›¸å†Œæ—ļå‡ē错", + "error_loading_albums": "加čŊŊᛏį°ŋæ—ļå‡ē错", "error_loading_image": "加čŊŊå›žį‰‡æ—ļå‡ē错", "error_loading_partners": "加čŊŊ协äŊœč€…æ—ļå‡ē错īŧš{error}", - "error_retrieving_asset_information": "čŽˇå–čĩ„æēäŋĄæ¯æ—ļå‡ē错", + "error_retrieving_asset_information": "čŽˇå–éĄšį›ŽäŋĄæ¯æ—ļå‡ē错", "error_saving_image": "错蝝īŧš{error}", "error_tag_face_bounding_box": "æ ‡čŽ°äēē脸æ—ļå‡ē错 - æ— æŗ•čŽˇå–čžšį•ŒæĄ†åæ ‡", "error_title": "错蝝 - å‡ēįŽ°äē†é—Žéĸ˜", - "error_while_navigating": "莺čŊŦ到čĩ„æēæ—ļå‡ē错", + "error_while_navigating": "莺čŊŦåˆ°į…§į‰‡/视éĸ‘æ—ļå‡ē错", "errors": { - "cannot_navigate_next_asset": "æ— æŗ•čˇŗčŊŦ到下一ä¸Ēčĩ„æē", - "cannot_navigate_previous_asset": "æ— æŗ•čˇŗčŊŦ到上一ä¸Ēčĩ„æē", + "cannot_navigate_next_asset": "æ— æŗ•čˇŗčŊŦ到下一ä¸Ēᅧቇ/视éĸ‘", + "cannot_navigate_previous_asset": "æ— æŗ•čˇŗčŊŦ到上一ä¸Ēᅧቇ/视éĸ‘", "cant_apply_changes": "æ— æŗ•åē”į”¨æ›´æ”š", "cant_change_activity": "æ— æŗ• {enabled, select, true {įρᔍ} other {吝ᔍ}} æ´ģ动", - "cant_change_asset_favorite": "æ— æŗ•æ›´æ”ščĩ„æēįš„æ”ļ藏įŠļ态", - "cant_change_metadata_assets_count": "æ— æŗ•äŋŽæ”š{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}įš„å…ƒæ•°æŽ", + "cant_change_asset_favorite": "æ— æŗ•æ›´æ”šį…§į‰‡/视éĸ‘įš„æ”ļ藏įŠļ态", + "cant_change_metadata_assets_count": "æ— æŗ•äŋŽæ”š{count, plural, one {#ä¸Ē} other {#ä¸Ē}}ᅧቇ/视éĸ‘įš„å…ƒæ•°æŽ", "cant_get_faces": "æ— æŗ•čŽˇå–äēē脸", "cant_get_number_of_comments": "æ— æŗ•čŽˇå–č¯„čŽē数量", "cant_search_people": "æ— æŗ•æœį´ĸäēēį‰Š", "cant_search_places": "æ— æŗ•æœį´ĸåœ°į‚š", - "error_adding_assets_to_album": "æˇģ加čĩ„æēåˆ°į›¸å†Œæ—ļå‡ē错", - "error_adding_users_to_album": "æˇģåŠ į”¨æˆˇåˆ°į›¸å†Œæ—ļå‡ē错", + "error_adding_assets_to_album": "æˇģåŠ į…§į‰‡/视éĸ‘åˆ°į›¸į°ŋæ—ļå‡ē错", + "error_adding_users_to_album": "æˇģåŠ į”¨æˆˇåˆ°į›¸į°ŋæ—ļå‡ē错", "error_deleting_shared_user": "åˆ é™¤å…ąäēĢį”¨æˆˇæ—ļå‡ē错", - "error_downloading": "下čŊŊ“{filename}”æ—ļå‡ē错", + "error_downloading": "下čŊŊ{filename}æ—ļå‡ē错", "error_hiding_buy_button": "éšč—č´­äš°æŒ‰é’Žæ—ļå‡ē错", - "error_removing_assets_from_album": "į§ģé™¤į›¸å†Œčĩ„æēæ—ļå‡ē错īŧŒč¯ˇæŖ€æŸĨ控åˆļ台äģĨčŽˇå–æ›´å¤šč¯Ļ情", - "error_selecting_all_assets": "全选čĩ„æēæ—ļå‡ē错", + "error_removing_assets_from_album": "äģŽį›¸į°ŋ中į§ģ除ᅧቇ/视éĸ‘æ—ļå‡ē错īŧŒč¯ˇæŖ€æŸĨ控åˆļ台äģĨčŽˇå–æ›´å¤šč¯Ļ情", + "error_selecting_all_assets": "免选ᅧቇ/视éĸ‘æ—ļå‡ē错", "exclusion_pattern_already_exists": "æ­¤æŽ’é™¤æ¨Ąåŧåˇ˛å­˜åœ¨ã€‚", - "failed_to_create_album": "创åģēį›¸å†Œå¤ąč´Ĩ", + "failed_to_create_album": "创åģēᛏį°ŋå¤ąč´Ĩ", "failed_to_create_shared_link": "创åģēå…ąäēĢ链æŽĨå¤ąč´Ĩ", "failed_to_edit_shared_link": "įŧ–čž‘å…ąäēĢ链æŽĨå¤ąč´Ĩ", "failed_to_get_people": "čŽˇå–äēēį‰Šåˆ—čĄ¨å¤ąč´Ĩ", - "failed_to_keep_this_delete_others": "äŋį•™æ­¤čĩ„æēåšļ删除å…ļäģ–čĩ„æēå¤ąč´Ĩ", - "failed_to_load_asset": "加čŊŊčĩ„æēå¤ąč´Ĩ", - "failed_to_load_assets": "加čŊŊčĩ„æēå¤ąč´Ĩ", + "failed_to_keep_this_delete_others": "åˆ é™¤é™¤æ­¤éĄšį›Žå¤–įš„å…ļäģ–éĄšį›Žå¤ąč´Ĩ", + "failed_to_load_asset": "加čŊŊᅧቇ/视éĸ‘å¤ąč´Ĩ", + "failed_to_load_assets": "加čŊŊᅧቇ/视éĸ‘å¤ąč´Ĩ", "failed_to_load_notifications": "加čŊŊ通įŸĨå¤ąč´Ĩ", "failed_to_load_people": "加čŊŊäēēį‰Šå¤ąč´Ĩ", "failed_to_remove_product_key": "į§ģ除äē§å“å¯†é’Ĩå¤ąč´Ĩ", "failed_to_reset_pin_code": "重įŊŽ PIN į å¤ąč´Ĩ", - "failed_to_stack_assets": "堆叠čĩ„æēå¤ąč´Ĩ", - "failed_to_unstack_assets": "取æļˆå †å čĩ„æēå¤ąč´Ĩ", + "failed_to_stack_assets": "å †å į…§į‰‡/视éĸ‘å¤ąč´Ĩ", + "failed_to_unstack_assets": "取æļˆå †å į…§į‰‡/视éĸ‘å¤ąč´Ĩ", "failed_to_update_notification_status": "更新通įŸĨįŠļæ€å¤ąč´Ĩ", "incorrect_email_or_password": "é‚ŽįŽąæˆ–å¯†į é”™č¯¯", "library_folder_already_exists": "č¯Ĩå¯ŧå…Ĩčˇ¯åž„åˇ˛å­˜åœ¨ã€‚", @@ -1079,18 +1081,18 @@ "profile_picture_transparent_pixels": "å¤´åƒä¸æ”¯æŒé€æ˜ŽčƒŒæ™¯īŧŒč¯ˇæ”žå¤§æˆ–į§ģåŠ¨å›žį‰‡ã€‚", "quota_higher_than_disk_size": "äŊ čŽžįŊŽįš„配éĸčļ…čŋ‡äē†įŖį›˜æ€ģ大小", "something_went_wrong": "å‡ē错äē†", - "unable_to_add_album_users": "æ— æŗ•å‘į›¸å†ŒæˇģåŠ į”¨æˆˇ", - "unable_to_add_assets_to_shared_link": "æ— æŗ•å‘åˆ†äēĢ链æŽĨæˇģ加čĩ„æē", + "unable_to_add_album_users": "æ— æŗ•å‘į›¸į°ŋæˇģåŠ į”¨æˆˇ", + "unable_to_add_assets_to_shared_link": "æ— æŗ•å‘åˆ†äēĢ链æŽĨæˇģåŠ į…§į‰‡/视éĸ‘", "unable_to_add_comment": "æ— æŗ•æˇģåŠ č¯„čŽē", "unable_to_add_exclusion_pattern": "æ— æŗ•æˇģåŠ æŽ’é™¤č§„åˆ™", "unable_to_add_partners": "æ— æŗ•æˇģ加协äŊœč€…", - "unable_to_add_remove_archive": "æ— æŗ•{archived, select, true {äģŽåŊ’æĄŖä¸­į§ģ除} other {æˇģ加čĩ„æēåˆ°åŊ’æĄŖ}}", - "unable_to_add_remove_favorites": "æ— æŗ•{favorite, select, true {æˇģ加čĩ„æēåˆ°æ”ļ藏} other {äģŽæ”ļ藏中į§ģ除}}", + "unable_to_add_remove_archive": "æ— æŗ•{archived, select, true {äģŽåŊ’æĄŖä¸­į§ģ除} other {æˇģåŠ į…§į‰‡/视éĸ‘到åŊ’æĄŖ}}", + "unable_to_add_remove_favorites": "æ— æŗ•{favorite, select, true {æˇģåŠ į…§į‰‡/视éĸ‘到æ”ļ藏} other {äģŽæ”ļ藏中į§ģ除}}", "unable_to_archive_unarchive": "æ— æŗ•{archived, select, true {åŊ’æĄŖ} other {取æļˆåŊ’æĄŖ}}", - "unable_to_change_album_user_role": "æ— æŗ•æ›´æ”šį›¸å†Œį”¨æˆˇįš„č§’č‰˛", + "unable_to_change_album_user_role": "æ— æŗ•æ›´æ”šį›¸į°ŋį”¨æˆˇįš„č§’č‰˛", "unable_to_change_date": "æ— æŗ•æ›´æ”šæ—Ĩ期", "unable_to_change_description": "æ— æŗ•äŋŽæ”šæčŋ°", - "unable_to_change_favorite": "æ— æŗ•æ›´æ”ščĩ„æēįš„æ”ļ藏įŠļ态", + "unable_to_change_favorite": "æ— æŗ•æ›´æ”šį…§į‰‡/视éĸ‘įš„æ”ļ藏įŠļ态", "unable_to_change_location": "æ— æŗ•æ›´æ”šäŊįŊŽ", "unable_to_change_password": "æ— æŗ•äŋŽæ”šå¯†į ", "unable_to_change_visibility": "æ— æŗ•äŋŽæ”š{count, plural, one {#ä¸Ēäēē} other {#ä¸Ēäēē}}įš„å¯č§æ€§čŽžįŊŽ", @@ -1102,9 +1104,9 @@ "unable_to_create_api_key": "æ— æŗ•åˆ›åģēæ–°įš„ API 密é’Ĩ", "unable_to_create_library": "æ— æŗ•åˆ›åģēåē“", "unable_to_create_user": "æ— æŗ•åˆ›åģēį”¨æˆˇ", - "unable_to_delete_album": "æ— æŗ•åˆ é™¤į›¸å†Œ", - "unable_to_delete_asset": "æ— æŗ•åˆ é™¤čĩ„æē", - "unable_to_delete_assets": "删除čĩ„æē æ—ļå‡ē错", + "unable_to_delete_album": "æ— æŗ•åˆ é™¤į›¸į°ŋ", + "unable_to_delete_asset": "æ— æŗ•åˆ é™¤į…§į‰‡/视éĸ‘", + "unable_to_delete_assets": "åˆ é™¤į…§į‰‡/视éĸ‘æ—ļå‡ē错", "unable_to_delete_exclusion_pattern": "æ— æŗ•åˆ é™¤æŽ’é™¤č§„åˆ™", "unable_to_delete_shared_link": "æ— æŗ•åˆ é™¤å…ąäēĢ链æŽĨ", "unable_to_delete_user": "æ— æŗ•åˆ é™¤į”¨æˆˇ", @@ -1124,21 +1126,21 @@ "unable_to_login_with_oauth": "æ— æŗ•äŊŋᔍ OAuth čŋ›čĄŒį™ģåŊ•", "unable_to_play_video": "æ— æŗ•æ’­æ”žč§†éĸ‘", "unable_to_reassign_assets_existing_person": "æ— æŗ•å°†éĄšį›Žé‡æ–°åˆ†é…įģ™{name, select, null {åˇ˛å­˜åœ¨įš„äēēį‰Š} other {{name}}}", - "unable_to_reassign_assets_new_person": "æ— æŗ•é‡æ–°åˆ†é…čĩ„æēį왿–°įš„äēēį‰Š", + "unable_to_reassign_assets_new_person": "æ— æŗ•é‡æ–°åˆ†é…į…§į‰‡/视éĸ‘į왿–°įš„äēēį‰Š", "unable_to_refresh_user": "æ— æŗ•åˆˇæ–°į”¨æˆˇ", - "unable_to_remove_album_users": "æ— æŗ•äģŽį›¸å†Œä¸­į§ģé™¤į”¨æˆˇ", + "unable_to_remove_album_users": "æ— æŗ•äģŽį›¸į°ŋ中į§ģé™¤į”¨æˆˇ", "unable_to_remove_api_key": "æ— æŗ•į§ģ除 API 密é’Ĩ", - "unable_to_remove_assets_from_shared_link": "æ— æŗ•äģŽå…ąäēĢ链æŽĨ中į§ģ除čĩ„æē", + "unable_to_remove_assets_from_shared_link": "æ— æŗ•äģŽå…ąäēĢ链æŽĨ中į§ģ除ᅧቇ/视éĸ‘", "unable_to_remove_library": "æ— æŗ•į§ģ除åē“", "unable_to_remove_partner": "æ— æŗ•į§ģ除协äŊœč€…", "unable_to_remove_reaction": "æ— æŗ•åˆ é™¤å›žå¤", "unable_to_reset_password": "æ— æŗ•é‡įŊŽå¯†į ", "unable_to_reset_pin_code": "æ— æŗ•é‡įŊŽ PIN ᠁", "unable_to_resolve_duplicate": "æ— æŗ•å¤„į†é‡å¤éĄš", - "unable_to_restore_assets": "æ— æŗ•æĸ复čĩ„æē", + "unable_to_restore_assets": "æ— æŗ•æĸå¤į…§į‰‡/视éĸ‘", "unable_to_restore_trash": "æ— æŗ•čŋ˜åŽŸå›žæ”ļįĢ™", "unable_to_restore_user": "æ— æŗ•æĸå¤į”¨æˆˇ", - "unable_to_save_album": "æ— æŗ•äŋå­˜į›¸å†Œ", + "unable_to_save_album": "æ— æŗ•äŋå­˜į›¸į°ŋ", "unable_to_save_api_key": "æ— æŗ•äŋå­˜ API 密é’Ĩ", "unable_to_save_date_of_birth": "æ— æŗ•äŋå­˜å‡ēį”Ÿæ—Ĩ期", "unable_to_save_name": "æ— æŗ•æ›´æ–°äēēį‰Šåį§°", @@ -1153,8 +1155,8 @@ "unable_to_trash_asset": "æ— æŗ•į§ģč‡ŗå›žæ”ļįĢ™", "unable_to_unlink_account": "æ— æŗ•č§Ŗé™¤č´Ļåˇå…ŗč”", "unable_to_unlink_motion_video": "æ— æŗ•č§Ŗé™¤åŽžå†ĩ视éĸ‘兺联", - "unable_to_update_album_cover": "æ— æŗ•æ›´æ–°į›¸å†Œå°éĸ", - "unable_to_update_album_info": "æ— æŗ•æ›´æ–°į›¸å†ŒäŋĄæ¯", + "unable_to_update_album_cover": "æ— æŗ•æ›´æ”šį›¸į°ŋ封éĸ", + "unable_to_update_album_info": "æ— æŗ•æ›´æ”šį›¸į°ŋäŋĄæ¯", "unable_to_update_library": "æ— æŗ•æ›´æ–°å›žåē“", "unable_to_update_location": "æ— æŗ•æ›´æ–°äŊįŊŽäŋĄæ¯", "unable_to_update_settings": "æ— æŗ•æ›´æ–°čŽžįŊŽ", @@ -1184,7 +1186,7 @@ "expired": "厞čŋ‡æœŸ", "expires_date": "将äēŽ {date} čŋ‡æœŸ", "explore": "æŽĸį´ĸ", - "explorer": "čĩ„æēįŽĄį†å™¨", + "explorer": "æŽĸį´ĸ", "export": "å¯ŧå‡ē", "export_as_json": "å¯ŧå‡ēä¸ē JSON", "export_database": "å¯ŧå‡ē数捎åē“", @@ -1198,13 +1200,13 @@ "failed": "å¤ąč´Ĩ", "failed_count": "å¤ąč´Ĩ: {count}æŦĄ", "failed_to_authenticate": "čēĢäģŊéĒŒč¯å¤ąč´Ĩ", - "failed_to_load_assets": "čĩ„æēåŠ čŊŊå¤ąč´Ĩ", + "failed_to_load_assets": "ᅧቇ/视éĸ‘加čŊŊå¤ąč´Ĩ", "failed_to_load_folder": "文äģļ多加čŊŊå¤ąč´Ĩ", "favorite": "æ”ļ藏", "favorite_action_prompt": "厞æˇģ加 {count} ä¸Ē到æ”ļč—å¤š", "favorite_or_unfavorite_photo": "æ”ļč—æˆ–å–æļˆæ”ļč—į…§į‰‡", "favorites": "æ”ļč—å¤š", - "favorites_page_no_favorites": "æœĒ扞到æ”ļč—įš„čĩ„æē", + "favorites_page_no_favorites": "æœĒ扞到æ”ļč—įš„į…§į‰‡/视éĸ‘", "feature_photo_updated": "更æĸäēēį‰Šå°éĸį…§į‰‡æˆåŠŸ", "features": "功čƒŊ", "features_in_development": "åŧ€å‘ä¸­įš„åŠŸčƒŊ", @@ -1216,7 +1218,7 @@ "filename": "文äģļ名", "filetype": "文äģļįąģ型", "filter": "᭛选", - "filter_description": "į­›é€‰į›Žæ ‡čĩ„æēįš„æĄäģļ", + "filter_description": "į­›é€‰į›Žæ ‡æ–‡äģļįš„æĄäģļ", "filter_people": "᭛选äēēį‰Š", "filter_places": "į­›é€‰åœ°į‚š", "filter_tags": "į­›é€‰æ ‡į­ž", @@ -1248,7 +1250,7 @@ "gps": "有GPSäŋĄæ¯", "gps_missing": "无GPSäŋĄæ¯", "grant_permission": "授权权限", - "group_albums_by": "į›¸å†Œåˆ†įģ„䞝捎...", + "group_albums_by": "ᛏį°ŋ分įģ„䞝捎...", "group_country": "按å›ŊåŽļ分įģ„", "group_no": "不分įģ„", "group_owner": "æŒ‰æ‰€æœ‰č€…åˆ†įģ„", @@ -1268,17 +1270,17 @@ "height": "é̘åēĻ", "hi_user": "您åĨŊīŧŒ{name}īŧˆ{email}īŧ‰", "hide_all_people": "éšč—æ‰€æœ‰äēēį‰Š", - "hide_gallery": "éšč—į›¸å†Œ", + "hide_gallery": "éšč—į›¸į°ŋ", "hide_named_person": "隐藏äēēį‰Šīŧš{name}", "hide_password": "éšč—å¯†į ", "hide_person": "隐藏äēēį‰Š", "hide_schema": "éšč—æ¨Ąåŧ", "hide_text_recognition": "éšč—æ–‡æœŦ蝆åˆĢį쓿žœ", "hide_unnamed_people": "隐藏æœĒå‘Ŋåįš„äēēį‰Š", - "home_page_add_to_album_conflicts": "厞将 {added} ä¸Ē文äģᅫģåŠ åˆ°į›¸å†Œ \"{album}\" 中。å…ļ中有 {failed} ä¸Ē文äģᅵŦæĨå°ąåœ¨į›¸å†Œé‡Œäē†ã€‚", - "home_page_add_to_album_err_local": "暂æ—ļæ— æŗ•å°†æœŦ地文äģᅫģåŠ åˆ°į›¸å†ŒīŧŒæ­Ŗåœ¨čˇŗčŋ‡", - "home_page_add_to_album_success": "åˇ˛æˆåŠŸå°† {added} ä¸Ē文äģᅫģåŠ åˆ°į›¸å†Œ \"{album}\" 中。", - "home_page_album_err_partner": "暂æ—ļæ— æŗ•å°†\"寚斚\"įš„čĩ„äē§æˇģåŠ åˆ°į›¸å†Œä¸­īŧŒæ­Ŗåœ¨čˇŗčŋ‡", + "home_page_add_to_album_conflicts": "厞将 {added} ä¸Ē文äģᅫģåŠ åˆ°į›¸į°ŋ“{album}”。{failed} ä¸Ē文äģļåˇ˛å­˜åœ¨ã€‚", + "home_page_add_to_album_err_local": "暂æ—ļæ— æŗ•å°†æœŦ地文äģᅫģåŠ åˆ°į›¸į°ŋīŧŒæ­Ŗåœ¨čˇŗčŋ‡", + "home_page_add_to_album_success": "åˇ˛æˆåŠŸå°† {added} ä¸Ē文äģᅫģåŠ åˆ°į›¸į°ŋ“{album}”中。", + "home_page_album_err_partner": "暂æ—ļæ— æŗ•å°†â€œå¯šæ–šâ€įš„į…§į‰‡/视éĸ‘æˇģåŠ åˆ°į›¸į°ŋ中īŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_archive_err_local": "暂æ—ļæ— æŗ•åŊ’æĄŖæœŦ地文äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_archive_err_partner": "æ— æŗ•åŊ’æĄŖåäŊœč€…įš„æ–‡äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_building_timeline": "æ­Ŗåœ¨æž„åģēæ—ļ间įēŋ", @@ -1286,7 +1288,7 @@ "home_page_delete_remote_err_local": "æŖ€æĩ‹åˆ°åž…åˆ é™¤åˆ—čĄ¨ä¸­åŒ…åĢä熿œŦ地文äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_favorite_err_local": "暂不支持æ”ļ藏æœŦ地文äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_favorite_err_partner": "暂不支持æ”ļč—åäŊœč€…įš„æ–‡äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", - "home_page_first_time_notice": "åĻ‚æžœæ‚¨æ˜¯éĻ–æŦĄäŊŋᔍæœŦåē”ᔍīŧŒč¯ˇåŠĄåŋ…选拊一ä¸Ē备äģŊį›¸å†ŒīŧŒäģĨäžŋæ—ļ间įēŋčƒŊäģŽä¸­čŽˇå–åšļåą•į¤ēį…§į‰‡å’Œč§†éĸ‘", + "home_page_first_time_notice": "åĻ‚æžœæ‚¨æ˜¯éĻ–æŦĄäŊŋᔍæœŦåē”ᔍīŧŒč¯ˇåŠĄåŋ…选拊一ä¸Ē备äģŊᛏį°ŋīŧŒäģĨäžŋæ—ļ间įēŋčƒŊäģŽä¸­čŽˇå–åšļåą•į¤ēį…§į‰‡å’Œč§†éĸ‘", "home_page_locked_error_local": "æ— æŗ•å°†æœŦ地文äģļį§ģå…Ĩé”åŽšįš„æ–‡äģļ多īŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_locked_error_partner": "æ— æŗ•å°†åäŊœč€…įš„æ–‡äģļį§ģå…Ĩé”åŽšįš„æ–‡äģļ多īŧŒæ­Ŗåœ¨čˇŗčŋ‡", "home_page_share_err_local": "æ— æŗ•é€ščŋ‡é“žæŽĨ分äēĢæœŦ地文äģļīŧŒæ­Ŗåœ¨čˇŗčŋ‡", @@ -1313,17 +1315,17 @@ "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 å¯ŧå…Ĩ", + "immich_logo": "Immich Logo", + "immich_web_interface": "ImmichįŊ‘éĄĩį•Œéĸ", + "import_from_json": "äģŽJSONå¯ŧå…Ĩ", "import_path": "å¯ŧå…Ĩčˇ¯åž„", - "in_albums": "在{count, plural, one {# ä¸Ēį›¸å†Œ} other {# ä¸Ēį›¸å†Œ}}中", + "in_albums": "在{count, plural, one {# ä¸Ēᛏį°ŋ} other {# ä¸Ēᛏį°ŋ}}中", "in_archive": "厞åŊ’æĄŖ", "in_year": "{year}åš´", "in_year_selector": "在", "include_archived": "包æ‹Ŧ厞åŊ’æĄŖ", - "include_shared_albums": "包æ‹Ŧå…ąäēĢį›¸å†Œ", - "include_shared_partner_assets": "包æ‹Ŧ协äŊœč€…å…ąäēĢčĩ„æē", + "include_shared_albums": "包æ‹Ŧå…ąäēĢᛏį°ŋ", + "include_shared_partner_assets": "包æ‹Ŧ协äŊœč€…å…ąäēĢᅧቇ/视éĸ‘", "individual_share": "单į‹Ŧ分äēĢ", "individual_shares": "单į‹Ŧ分äēĢ", "info": "äŋĄæ¯", @@ -1336,20 +1338,20 @@ "invalid_date": "æ— æ•ˆįš„æ—Ĩ期", "invalid_date_format": "æ— æ•ˆįš„æ—Ĩ期æ ŧåŧ", "invite_people": "邀蝎äēē员", - "invite_to_album": "é‚€č¯ˇåŠ å…Ĩį›¸å†Œ", + "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_processes_queued": "{count, plural, one {{count}ä¸Ē后台äģģåŠĄåœ¨æŽ’é˜Ÿ} other {{count}ä¸Ē后台äģģåŠĄåœ¨æŽ’é˜Ÿ}}", "ios_debug_info_processing_ran_at": "处ᐆäēŽ {dateTime}", - "items_count": "{count, plural, one {#ä¸Ē} other {#ä¸Ē}}", + "items_count": "{count, plural, one {#ä¸Ē} other {#ä¸Ē}}éĄšį›Ž", "jobs": "äģģåŠĄ", "json_editor": "JSONįŧ–čž‘å™¨", "json_error": "JSON错蝝", "keep": "äŋį•™", - "keep_albums": "äŋį•™į›¸å†Œ", - "keep_albums_count": "äŋį•™ {count} {count, plural, one {ä¸Ēį›¸å†Œ} other {ä¸Ēį›¸å†Œ}}", + "keep_albums": "äŋį•™į›¸į°ŋ", + "keep_albums_count": "äŋį•™ {count} {count, plural, one {ä¸Ēᛏį°ŋ} other {ä¸Ēᛏį°ŋ}}", "keep_all": "全部äŋį•™", "keep_description": "选拊释攞įŠē间æ—ļäŋį•™åœ¨čŽžå¤‡ä¸Šįš„å†…åŽšã€‚", "keep_favorites": "äŋį•™æ”ļ藏", @@ -1357,7 +1359,7 @@ "keep_on_device_hint": "选拊čρäŋį•™åœ¨æœŦčŽžå¤‡ä¸Šįš„éĄšį›Ž", "keep_this_delete_others": "äŋį•™æ­¤éĄšīŧŒå…ļäŊ™åˆ é™¤", "keeping": "äŋį•™: {items}", - "kept_this_deleted_others": "äŋį•™č¯Ĩčĩ„æēåšļ删除 {count, plural, one {# ä¸Ēčĩ„æē} other {# ä¸Ēčĩ„æē}}", + "kept_this_deleted_others": "äŋį•™č¯Ĩᅧቇ/视éĸ‘åšļ删除{count, plural, one {# ä¸ĒéĄšį›Ž} other {# ä¸ĒéĄšį›Ž}}", "keyboard_shortcuts": "é”Žį›˜åŋĢæˇé”Ž", "language": "蝭荀", "language_no_results_subtitle": "å°č¯•č°ƒæ•´æ‚¨įš„æœį´ĸč¯", @@ -1366,45 +1368,47 @@ "language_setting_description": "é€‰æ‹Šæ‚¨įš„éϖ选蝭荀", "large_files": "大文äģļ", "last": "最后一ä¸Ē", - "last_months": "{count, plural, one {上ä¸Ē月} other {最čŋ‘ # ä¸Ē月}}", + "last_months": "{count, plural, one {上ä¸Ē月} other {最čŋ‘#ä¸Ē月}}", "last_seen": "最后上įēŋäēŽ", "latest_version": "æœ€æ–°į‰ˆæœŦ", "latitude": "įēŦåēĻ", "leave": "įĻģåŧ€", - "leave_album": "įĻģåŧ€į›¸å†Œ", + "leave_album": "įĻģåŧ€į›¸į°ŋ", "lens_model": "é•œå¤´åž‹åˇ", "let_others_respond": "å…čŽ¸äģ–äēē回复", "level": "į­‰įē§", - "library": "čĩ„æ–™åē“", + "library": "čĩ„æēåē“", "library_add_folder": "æˇģ加文äģļ多", "library_edit_folder": "įŧ–čž‘æ–‡äģļ多", - "library_options": "čĩ„æ–™åē“选饚", - "library_page_device_albums": "čŽžå¤‡ä¸Šįš„į›¸å†Œ", - "library_page_new_album": "新åģēį›¸å†Œ", - "library_page_sort_asset_count": "čĩ„æēæ•°é‡", + "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": "į›¸å†Œæ ‡éĸ˜", + "library_page_sort_title": "ᛏį°ŋ标éĸ˜", "licenses": "čŽ¸å¯č¯", "light": "æĩ…色", + "light_theme": "切æĸ到æĩ…色ä¸ģéĸ˜", "like": "į‚ščĩž", "like_deleted": "取æļˆį‚ščĩž", "link_motion_video": "链æŽĨåŠ¨æ€č§†éĸ‘", + "link_to_docs": "更多äŋĄæ¯, č¯ˇå‚č§ æ–‡æĄŖ.", "link_to_oauth": "įģ‘åޚ OAuth", "linked_oauth_account": "厞įģ‘åŽšįš„ OAuth č´Ļæˆˇ", "list": "åˆ—čĄ¨", "loading": "加čŊŊ中", "loading_search_results_failed": "加čŊŊ搜į´ĸį쓿žœå¤ąč´Ĩ", "local": "æœŦ地", - "local_asset_cast_failed": "æ— æŗ•å¤„į†å°šæœĒ上äŧ č‡ŗæœåŠĄå™¨įš„čĩ„äē§", - "local_assets": "æœŦ地čĩ„æē", + "local_asset_cast_failed": "æ— æŗ•å¤„į†å°šæœĒ上äŧ č‡ŗæœåŠĄå™¨įš„į…§į‰‡/视éĸ‘", + "local_assets": "æœŦåœ°éĄšį›Ž", "local_id": "æœŦ地 ID", "local_media_summary": "æœŦ地åĒ’äŊ“摘čρ", "local_network": "æœŦ地įŊ‘įģœ", "local_network_sheet_info": "äŊŋį”¨æŒ‡åŽšįš„ Wi-Fi įŊ‘į윿—ļīŧŒåē”į”¨å°†é€ščŋ‡æ­¤ URL čŋžæŽĨåˆ°æœåŠĄå™¨", "location": "äŊįŊŽ", "location_permission": "厚äŊæƒé™", - "location_permission_content": "ä¸ēäē†äŊŋᔍč‡Ē动切æĸ功čƒŊīŧŒImmich 需čĻčŽˇå–į˛žįĄŽäŊįŊŽæƒé™īŧŒäģĨäžŋč¯ģ取åŊ“前 Wi-Fi įŊ‘įģœįš„åį§°", + "location_permission_content": "ä¸ēäē†äŊŋᔍč‡Ē动切æĸ功čƒŊīŧŒImmich需čĻčŽˇå–į˛žįĄŽäŊįŊŽæƒé™īŧŒäģĨäžŋč¯ģ取åŊ“前 Wi-Fi įŊ‘įģœįš„åį§°", "location_picker_choose_on_map": "äģŽåœ°å›žé€‰å–", "location_picker_latitude_error": "č¯ˇčž“å…Ĩæœ‰æ•ˆįš„įēŦåēĻ", "location_picker_latitude_hint": "č¯ˇåœ¨æ­¤å¤„čž“å…ĨįēŦåēĻ", @@ -1420,7 +1424,7 @@ "logged_out_device": "厞退å‡ēčŽžå¤‡į™ģåŊ•", "login": "į™ģåŊ•", "login_disabled": "į™ģåŊ•功čƒŊ厞įρᔍ", - "login_form_api_exception": "API åŧ‚å¸¸ã€‚č¯ˇæŖ€æŸĨæœåŠĄå™¨ URL åšļé‡č¯•ã€‚", + "login_form_api_exception": "APIåŧ‚å¸¸ã€‚č¯ˇæŖ€æŸĨæœåŠĄå™¨URLåšļé‡č¯•ã€‚", "login_form_back_button_text": "čŋ”回", "login_form_email_hint": "youremail@email.com", "login_form_endpoint_hint": "http://æ‚¨įš„æœåŠĄå™¨åœ°å€:įĢ¯åŖ", @@ -1430,7 +1434,7 @@ "login_form_err_invalid_url": "æ— æ•ˆįš„URL", "login_form_err_leading_whitespace": "ä¸å…čŽ¸å‰å¯ŧįŠēæ ŧ", "login_form_err_trailing_whitespace": "ä¸å…čŽ¸å°žéšįŠēæ ŧ", - "login_form_failed_get_oauth_server_config": "äŊŋᔍ OAuth į™ģåŊ•å‡ē错īŧŒč¯ˇæŖ€æŸĨæœåŠĄå™¨åœ°å€", + "login_form_failed_get_oauth_server_config": "äŊŋᔍOAuthį™ģåŊ•å‡ē错īŧŒč¯ˇæŖ€æŸĨæœåŠĄå™¨åœ°å€", "login_form_failed_get_oauth_server_disable": "æ­¤æœåŠĄå™¨ä¸æ”¯æŒ OAuth 功čƒŊ", "login_form_failed_login": "į™ģåŊ•å¤ąč´ĨīŧŒč¯ˇæŖ€æŸĨæœåŠĄå™¨åœ°å€ã€é‚ŽįŽąå’Œå¯†į ", "login_form_handshake_exception": "ä¸ŽæœåŠĄå™¨įš„æĄæ‰‹åŧ‚常。åĻ‚æžœæ‚¨äŊŋį”¨įš„æ˜¯č‡Ēį­žåč¯äšĻīŧŒč¯ˇåœ¨čŽžįŊŽä¸­åŧ€å¯å¯šč‡Ēį­žåč¯äšĻįš„æ”¯æŒã€‚", @@ -1459,8 +1463,8 @@ "maintenance_restore_library": "æĸå¤æ‚¨įš„å›žåē“", "maintenance_restore_library_confirm": "åĻ‚æžœįĄŽčŽ¤æ— č¯¯īŧŒč¯ˇįģ§įģ­čŋ›čĄŒå¤‡äģŊæĸ复īŧ", "maintenance_restore_library_description": "æ­Ŗåœ¨æĸ复数捎åē“", - "maintenance_restore_library_folder_has_files": "{folder} 包åĢ {count} ä¸Ē文äģļ多", - "maintenance_restore_library_folder_no_files": "{folder} įŧē少文äģļīŧ", + "maintenance_restore_library_folder_has_files": "{folder}包åĢ{count}ä¸Ē文äģļ多", + "maintenance_restore_library_folder_no_files": "{folder}įŧē少文äģļīŧ", "maintenance_restore_library_folder_pass": "可č¯ģ可写", "maintenance_restore_library_folder_read_fail": "不可č¯ģ", "maintenance_restore_library_folder_write_fail": "不可写", @@ -1495,14 +1499,14 @@ "map_location_service_disabled_title": "厚äŊæœåŠĄåˇ˛įρᔍ", "map_marker_for_images": "æ ‡čŽ°{city}、{country}æ‹æ‘„į…§į‰‡įš„åœ°å›žå›žæ ‡", "map_marker_with_image": "å¸Ļéĸ„č§ˆå›žįš„åœ°å›žæ ‡čް", - "map_no_location_permission_content": "需čρäŊįŊŽæƒé™æ‰čƒŊ昞į¤ē您åŊ“前äŊįŊŽįš„čĩ„æēã€‚įŽ°åœ¨čĻå…čŽ¸å—īŧŸ", + "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_days": "{days}夊前", "map_settings_date_range_option_year": "1嚴前", - "map_settings_date_range_option_years": "{years} 嚴前", + "map_settings_date_range_option_years": "{years}嚴前", "map_settings_dialog_title": "åœ°å›žčŽžįŊŽ", "map_settings_include_show_archived": "包åĢ厞åŊ’æĄŖįš„å†…åŽš", "map_settings_include_show_partners": "包åĢ协äŊœč€…", @@ -1513,7 +1517,7 @@ "mark_as_read": "æ ‡čŽ°ä¸ē厞č¯ģ", "marked_all_as_read": "åˇ˛å…¨éƒ¨æ ‡čŽ°ä¸ē厞č¯ģ", "matches": "åŒšé…éĄš", - "matching_assets": "åŒšé…įš„čĩ„æē", + "matching_assets": "åŒšé…įš„éĄšį›Ž", "media_type": "åĒ’äŊ“įąģ型", "memories": "é‚Ŗåš´ä슿—Ĩ", "memories_all_caught_up": "åˇ˛å¤„į†åŽŒæ¯•", @@ -1549,15 +1553,15 @@ "move_to_device_trash": "į§ģč‡ŗčŽžå¤‡å›žæ”ļįĢ™", "move_to_lock_folder_action_prompt": "厞将 {count} 饚æˇģ加到锁厚文äģļ多", "move_to_locked_folder": "į§ģč‡ŗé”åŽšæ–‡äģļ多", - "move_to_locked_folder_confirmation": "čŋ™äē›į…§į‰‡å’Œč§†éĸ‘å°†äģŽæ‰€æœ‰į›¸å†Œä¸­į§ģ除īŧŒäģ…可在锁厚文äģļ多内æŸĨįœ‹", + "move_to_locked_folder_confirmation": "čŋ™äē›į…§į‰‡å’Œč§†éĸ‘å°†äģŽæ‰€æœ‰į›¸į°ŋ中į§ģ除īŧŒäģ…可在锁厚文äģļ多内æŸĨįœ‹", "move_up": "向上į§ģ动", - "moved_to_archive": "厞将 {count, plural, one {# 饚čĩ„äē§} other {# 饚čĩ„äē§}} į§ģ臺åŊ’æĄŖ", - "moved_to_library": "厞将 {count, plural, one {# 饚čĩ„äē§} other {# 饚čĩ„äē§}} į§ģ臺čĩ„æ–™åē“", + "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": "æ— æŗ•įŧ–čž‘åĒč¯ģčĩ„æēįš„æ—Ĩ期īŧŒæ­Ŗåœ¨čˇŗčŋ‡", - "multiselect_grid_edit_gps_err_read_only": "æ— æŗ•įŧ–čž‘åĒč¯ģčĩ„æēįš„äŊįŊŽäŋĄæ¯īŧŒæ­Ŗåœ¨čˇŗčŋ‡", + "multiselect_grid_edit_date_time_err_read_only": "æ— æŗ•įŧ–čž‘åĒč¯ģéĄšį›Žįš„æ—Ĩ期īŧŒæ­Ŗåœ¨čˇŗčŋ‡", + "multiselect_grid_edit_gps_err_read_only": "æ— æŗ•įŧ–čž‘åĒč¯ģéĄšį›Žįš„äŊįŊŽäŋĄæ¯īŧŒæ­Ŗåœ¨čˇŗčŋ‡", "mute_memories": "é™éŸŗå›žåŋ†", - "my_albums": "æˆ‘įš„į›¸å†Œ", + "my_albums": "æˆ‘įš„į›¸į°ŋ", "name": "åį§°", "name_or_nickname": "åį§°æˆ–æ˜ĩį§°", "name_required": "åį§°æ˜¯åŋ…åĄĢ饚", @@ -1570,7 +1574,7 @@ "networking_settings": "įŊ‘įģœčŽžįŊŽ", "networking_subtitle": "įŽĄį†æœåŠĄå™¨įĢ¯į‚ščŽžįŊŽ", "never": "永不čŋ‡æœŸ", - "new_album": "新åģēį›¸å†Œ", + "new_album": "新åģēᛏį°ŋ", "new_api_key": "新åĸž API 密é’Ĩ", "new_date_range": "æ–°įš„æ—ĨæœŸčŒƒå›´", "new_password": "æ–°å¯†į ", @@ -1586,16 +1590,16 @@ "next_memory": "下一ä¸Ē回åŋ†", "no": "åĻ", "no_actions_added": "尚æœĒæˇģ加动äŊœ", - "no_albums_found": "æœĒæ‰žåˆ°į›¸å†Œ", - "no_albums_message": "创åģēį›¸å†ŒäģĨæ•´į†æ‚¨įš„į…§į‰‡å’Œč§†éĸ‘", - "no_albums_with_name_yet": "įœ‹čĩˇæĨčŋ˜æ˛Ąæœ‰åŒåįš„į›¸å†Œã€‚", - "no_albums_yet": "įœ‹čĩˇæĨ您čŋ˜æ˛Ąæœ‰åˆ›åģēäģģäŊ•į›¸å†Œã€‚", + "no_albums_found": "æœĒæ‰žåˆ°į›¸į°ŋ", + "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_checksum_local": "æ— å¯į”¨įš„æ ĄéĒŒå’Œ — æ— æŗ•čŽˇå–æœŦåœ°éĄšį›Ž", + "no_checksum_remote": "æ— å¯į”¨įš„æ ĄéĒŒå’Œ — æ— æŗ•čŽˇå–čŋœį¨‹éĄšį›Ž", "no_configuration_needed": "无需配įŊŽ", "no_devices": "æš‚æ— åˇ˛æŽˆæƒįš„čŽžå¤‡", "no_duplicates_found": "æœĒå‘įŽ°é‡å¤å†…åŽšã€‚", @@ -1604,22 +1608,22 @@ "no_favorites_message": "æˇģ加æ”ļ藏īŧŒäģĨäžŋåŋĢ速扞到äŊ æœ€į˛žåŊŠįš„į…§į‰‡å’Œč§†éĸ‘", "no_filters_added": "尚æœĒæˇģåŠ į­›é€‰æĄäģļ", "no_libraries_message": "创åģē外部回åē“īŧŒäģĨæĩč§ˆäŊ įš„į…§į‰‡å’Œč§†éĸ‘", - "no_local_assets_found": "æœĒæ‰žåˆ°å…ˇæœ‰æ­¤æ ĄéĒŒå’Œįš„æœŦ地čĩ„æē", + "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_remote_assets_found": "æœĒæ‰žåˆ°å…ˇæœ‰æ­¤æ ĄéĒŒå’Œįš„čŋœį¨‹éĄšį›Ž", "no_results": "æœĒ扞到äģģäŊ•åŒšé…éĄš", "no_results_description": "č¯ˇå°č¯•äŊŋį”¨åŒäš‰č¯æˆ–æ›´åŽŊæŗ›įš„å…ŗé”Žč¯", - "no_shared_albums_message": "创åģēį›¸å†ŒīŧŒä¸Žį¤žäē¤åœˆå†…įš„åĨŊå‹å…ąäēĢį…§į‰‡å’Œč§†éĸ‘", + "no_shared_albums_message": "创åģēᛏį°ŋīŧŒä¸Žį¤žäē¤åœˆå†…įš„åĨŊå‹å…ąäēĢį…§į‰‡å’Œč§†éĸ‘", "no_uploads_in_progress": "暂无上äŧ äģģåŠĄ", "none": "无", "not_allowed": "ä¸å…čŽ¸", "not_available": "ä¸é€‚į”¨", - "not_in_any_album": "æœĒæ”ļåŊ•äēŽäģģäŊ•į›¸å†Œ", + "not_in_any_album": "æœĒæ”ļåŊ•äēŽäģģäŊ•ᛏį°ŋ", "not_selected": "æœĒ选拊", "notes": "å¤‡æŗ¨", "nothing_here_yet": "暂无内厚", @@ -1631,10 +1635,10 @@ "notifications": "通įŸĨ", "notifications_setting_description": "įŽĄį†é€šįŸĨ", "oauth": "OAuth", - "obtainium_configurator": "Obtainium配įŊŽå™¨", + "obtainium_configurator": "Obtainium 配įŊŽå™¨", "obtainium_configurator_instructions": "äŊŋᔍ Obtainium į›´æŽĨäģŽ Immich įš„ GitHub 发布éĄĩåŽ‰čŖ…å’Œæ›´æ–° Android åē”į”¨ã€‚č¯ˇåˆ›åģē一ä¸Ē API 密é’Ĩåšļ选拊一ä¸Ēį‰ˆæœŦīŧŒäģĨį”ŸæˆäŊ įš„ Obtainium 配įŊŽé“žæŽĨ", "ocr": "OCR", - "official_immich_resources": "Immich 厘斚čĩ„æē", + "official_immich_resources": "Immich厘斚čĩ„æē", "offline": "įĻģįēŋ", "offset": "偏į§ģ量", "ok": "įĄŽåŽš", @@ -1657,14 +1661,14 @@ "open_the_search_filters": "打åŧ€æœį´ĸ᭛选", "options": "选项", "or": "或", - "organize_into_albums": "æ•´į†åˆ°į›¸å†Œä¸­", - "organize_into_albums_description": "äŊŋᔍåŊ“å‰įš„åŒæ­Ĩ莞įŊŽīŧŒå°†įŽ°æœ‰į…§į‰‡åŊ’å…Ĩį›¸å†Œ", - "organize_your_library": "æ•´į†æ‚¨įš„čĩ„æ–™åē“", + "organize_into_albums": "æ•´į†åˆ°į›¸į°ŋ中", + "organize_into_albums_description": "äŊŋᔍåŊ“å‰įš„åŒæ­Ĩ莞įŊŽīŧŒå°†įŽ°æœ‰į…§į‰‡åŊ’å…Ĩᛏį°ŋ", + "organize_your_library": "æ•´į†æ‚¨įš„čĩ„æēåē“", "original": "åŽŸå§‹įš„", - "other": "å…ļ厃", - "other_devices": "å…ļåŽƒčŽžå¤‡", + "other": "å…ļäģ–", + "other_devices": "å…ļäģ–čŽžå¤‡", "other_entities": "å…ļäģ–厞äŊ“", - "other_variables": "å…ļ厃变量", + "other_variables": "å…ļäģ–变量", "owned": "æˆ‘įš„", "owner": "æ‰€æœ‰č€…", "page": "éĄĩéĸ", @@ -1679,7 +1683,7 @@ "partner_page_partner_add_failed": "æˇģ加åĨŊå‹å¤ąč´Ĩ", "partner_page_select_partner": "é€‰æ‹Šį›Žæ ‡", "partner_page_shared_to_title": "分äēĢįģ™", - "partner_page_stop_sharing_content": "{partner} å°†æ— æŗ•å†čŽŋé—Žæ‚¨įš„į…§į‰‡ã€‚", + "partner_page_stop_sharing_content": "{partner}å°†æ— æŗ•å†čŽŋé—Žæ‚¨įš„į…§į‰‡ã€‚", "partner_sharing": "åĨŊå‹å…ąäēĢ", "partners": "åĨŊ友", "password": "坆᠁", @@ -1700,15 +1704,15 @@ "people": "äēēį‰Š", "people_edits_count": "{count, plural, one {#ä¸Ēäēēį‰Š} other {#ä¸Ēäēēį‰Š}}厞įŧ–čž‘", "people_feature_description": "按äēēį‰Šåˆ†į섿ĩč§ˆį…§į‰‡å’Œč§†éĸ‘", - "people_selected": "{count, plural, one {厞选䏭 # äēē} other {厞选䏭 # äēē}}", + "people_selected": "{count, plural, one {厞选䏭#äēē} other {厞选䏭#äēē}}", "people_sidebar_description": "åœ¨äž§čžšæ æ˜žį¤ē“äēēį‰Šâ€é“žæŽĨ", "permanent_deletion_warning": "永䚅删除č­Ļ告", - "permanent_deletion_warning_setting_description": "永䚅删除čĩ„æēæ—ļ昞į¤ēč­Ļ告", + "permanent_deletion_warning_setting_description": "æ°¸äš…åˆ é™¤į…§į‰‡/视éĸ‘æ—ļ昞į¤ēč­Ļ告", "permanently_delete": "永䚅删除", - "permanently_delete_assets_count": "永䚅删除{count, plural, one {ä¸Ēčĩ„æē} other {ä¸Ēčĩ„æē}}", - "permanently_delete_assets_prompt": "įĄŽåŽščĻæ°¸äš…åˆ é™¤ {count, plural, one {æ­¤čĩ„æēå—īŧŸ} other {čŋ™ # ä¸Ēčĩ„æēå—īŧŸ}}čŋ™äšŸäŧšå°† {count, plural, one {å…ļ} other {厃äģŦ}}äģŽæ‰€åąžį›¸å†Œä¸­į§ģ除。", - "permanently_deleted_asset": "æ°¸äš…åˆ é™¤įš„čĩ„æē", - "permanently_deleted_assets_count": "åˇ˛æ°¸äš…åˆ é™¤{count, plural, one {#ä¸Ēčĩ„æē} other {#ä¸Ēčĩ„æē}}", + "permanently_delete_assets_count": "永䚅删除{count, plural, one {ä¸ĒéĄšį›Ž} other {ä¸ĒéĄšį›Ž}}", + "permanently_delete_assets_prompt": "įĄŽåŽščĻæ°¸äš…åˆ é™¤ {count, plural, one {æ­¤éĄšį›Žå—īŧŸ} other {čŋ™ # ä¸ĒéĄšį›Žå—īŧŸ}}čŋ™äšŸäŧšå°†{count, plural, one {å…ļ} other {厃äģŦ}}äģŽæ‰€åąžį›¸į°ŋ中į§ģ除。", + "permanently_deleted_asset": "æ°¸äš…åˆ é™¤įš„éĄšį›Ž", + "permanently_deleted_assets_count": "åˇ˛æ°¸äš…åˆ é™¤{count, plural, one {#ä¸ĒéĄšį›Ž} other {#ä¸ĒéĄšį›Ž}}", "permission": "权限", "permission_empty": "权限不čƒŊä¸ēįŠē", "permission_onboarding_back": "čŋ”回", @@ -1718,19 +1722,19 @@ "permission_onboarding_permission_denied": "权限čĸĢæ‹’įģã€‚čρäŊŋᔍ ImmichīŧŒč¯ˇåœ¨â€œčŽžįŊŽâ€ä¸­æŽˆäēˆį…§į‰‡å’Œč§†éĸ‘权限。", "permission_onboarding_permission_granted": "æƒé™åˇ˛æŽˆäēˆīŧä¸€åˆ‡å‡†å¤‡å°ąįģĒ。", "permission_onboarding_permission_limited": "权限受限。čĻčŽŠ Immich 备äģŊåšļįŽĄį†äŊ įš„æ•´ä¸Ē回åē“īŧŒč¯ˇåœ¨â€œčŽžįŊŽâ€ä¸­æŽˆäēˆį…§į‰‡å’Œč§†éĸ‘权限。", - "permission_onboarding_request": "Immich 需čĻæƒé™æ‰čƒŊæŸĨįœ‹äŊ įš„į…§į‰‡å’Œč§†éĸ‘。", + "permission_onboarding_request": "Immich需čĻæƒé™æ‰čƒŊæŸĨįœ‹äŊ įš„į…§į‰‡å’Œč§†éĸ‘。", "person": "äēēį‰Š", - "person_age_months": "{months, plural, one {# ä¸Ē月} other {# ä¸Ē月}}大", + "person_age_months": "{months, plural, one {#ä¸Ē月} other {#ä¸Ē月}}大", "person_age_year_months": "1 垁{months, plural, one {# ä¸Ē月} other {# ä¸Ē月}}大", - "person_age_years": "{years, plural, other {# 垁}}", + "person_age_years": "{years, plural, other {#垁}}", "person_birthdate": "å‡ēį”ŸäēŽ{date}", - "person_hidden": "{name}{hidden, select, true { (隐藏)} other {}}", + "person_hidden": "{name}{hidden, select, true {īŧˆéšč—īŧ‰} other {}}", "person_recognized": "厞蝆åˆĢäēēį‰Š", "person_selected": "åˇ˛é€‰æ‹Šäēēį‰Š", "photo_shared_all_users": "įœ‹čĩˇæĨäŊ åˇ˛įģä¸Žæ‰€æœ‰į”¨æˆˇå…ąäēĢäē†äŊ įš„ᅧቇīŧŒæˆ–者äŊ æ˛Ąæœ‰äģģäŊ•可äģĨå…ąäēĢįš„į”¨æˆˇã€‚", "photos": "ᅧቇ", "photos_and_videos": "ᅧቇ & 视éĸ‘", - "photos_count": "{count, plural, one {{count, number} åŧ į…§į‰‡} other {{count, number} åŧ į…§į‰‡}}", + "photos_count": "{count, plural, one {{count, number}åŧ į…§į‰‡} other {{count, number}åŧ į…§į‰‡}}", "photos_from_previous_years": "é‚Ŗåš´ä슿—Ĩ", "photos_only": "äģ…ᅧቇ", "pick_a_location": "选拊äŊįŊŽ", @@ -1742,13 +1746,13 @@ "pin_verification": "PIN᠁énj蝁", "place": "åœ°į‚š", "places": "åœ°į‚š", - "places_count": "{count, plural, one {{count, number} ä¸Ēåœ°į‚š} other {{count, number} ä¸Ēåœ°į‚š}}", + "places_count": "{count, plural, one {{count, number}ä¸Ēåœ°į‚š} other {{count, number}ä¸Ēåœ°į‚š}}", "play": "播攞", "play_memories": "æ’­æ”žé‚Ŗåš´ä슿—Ĩ", "play_motion_photo": "æ’­æ”žåŠ¨æ€å›žį‰‡", "play_or_pause_video": "æ’­æ”žæˆ–æš‚åœč§†éĸ‘", "play_original_video": "æ’­æ”žåŽŸå§‹č§†éĸ‘", - "play_original_video_setting_description": "äŧ˜å…ˆæ’­æ”žåŽŸå§‹č§†éĸ‘īŧŒč€ŒéžčŊŦ᠁视éĸ‘。åĻ‚æžœåŽŸå§‹čĩ„æēä¸å…ŧ厚īŧŒå¯čƒŊæ— æŗ•æ­Ŗå¸¸æ’­æ”žã€‚", + "play_original_video_setting_description": "äŧ˜å…ˆæ’­æ”žåŽŸå§‹č§†éĸ‘īŧŒč€ŒéžčŊŦ᠁视éĸ‘。åĻ‚æžœåŽŸå§‹č§†éĸ‘不å…ŧ厚īŧŒå¯čƒŊæ— æŗ•æ­Ŗå¸¸æ’­æ”žã€‚", "play_transcoded_video": "播攞čŊŦ᠁视éĸ‘", "please_auth_to_access": "蝎čŋ›čĄŒčēĢäģŊénj蝁äģĨčŽŋ问", "port": "įĢ¯åŖ", @@ -1772,7 +1776,7 @@ "profile_drawer_readonly_mode": "åĒč¯ģæ¨Ąåŧåˇ˛å¯į”¨ã€‚é•ŋæŒ‰į”¨æˆˇå¤´åƒå›žæ ‡é€€å‡ē。", "profile_image_of_user": "{user}įš„ä¸Ēäēēčĩ„æ–™å›žį‰‡", "profile_picture_set": "ä¸Ēäēēčĩ„æ–™å›žį‰‡åˇ˛čŽžįŊŽã€‚", - "public_album": "å…Ŧåŧ€į›¸å†Œ", + "public_album": "å…Ŧåŧ€į›¸į°ŋ", "public_share": "å…Ŧåŧ€å…ąäēĢ", "purchase_account_info": "æ”¯æŒč€…", "purchase_activated_subtitle": "感č°ĸ您寚 Immich 和åŧ€æēčŊ¯äģļįš„æ”¯æŒ", @@ -1806,9 +1810,9 @@ "purchase_server_description_2": "æ”¯æŒč€…įŠļ态", "purchase_server_title": "æœåŠĄå™¨", "purchase_settings_server_activated": "æœåŠĄå™¨äē§å“å¯†é’Ĩæ­Ŗåœ¨į”ąįŽĄį†å‘˜įŽĄį†", - "query_asset_id": "æŸĨč¯ĸčĩ„äē§ID", + "query_asset_id": "æŸĨč¯ĸéĄšį›ŽID", "queue_status": "排队中 {count}/{total}", - "rate_asset": "čĩ„äē§æ˜Ÿįē§", + "rate_asset": "éĄšį›Žæ˜Ÿįē§", "rating": "星įē§", "rating_clear": "删除星įē§", "rating_count": "{count, plural, =0 {æœĒ蝄įē§} one {# 星} other {# 星}}", @@ -1823,7 +1827,7 @@ "reassigned_assets_to_new_person": "重新指洞{count, plural, one {#ä¸ĒéĄšį›Ž} other {#ä¸ĒéĄšį›Ž}}åˆ°æ–°įš„äēēį‰Š", "reassing_hint": "æŒ‡æ´žé€‰æ‹Šįš„éĄšį›Žåˆ°åˇ˛å­˜åœ¨įš„äēēį‰Š", "recent": "最čŋ‘", - "recent_albums": "最čŋ‘įš„į›¸å†Œ", + "recent_albums": "最čŋ‘įš„į›¸į°ŋ", "recent_searches": "最čŋ‘搜į´ĸ", "recently_added": "čŋ‘期æˇģ加", "recently_added_page_title": "最čŋ‘æˇģ加", @@ -1849,8 +1853,8 @@ "remove_assets_title": "į§ģé™¤éĄšį›ŽīŧŸ", "remove_custom_date_range": "取æļˆč‡Ē厚䚉æ—ĨæœŸčŒƒå›´", "remove_deleted_assets": "åŊģåē•删除文äģļ", - "remove_from_album": "äģŽį›¸å†Œä¸­į§ģ除", - "remove_from_album_action_prompt": "äģŽį›¸å†Œä¸­į§ģ除äē† {count} 饚", + "remove_from_album": "äģŽį›¸į°ŋ中į§ģ除", + "remove_from_album_action_prompt": "äģŽį›¸į°ŋ中į§ģ除äē† {count} 饚", "remove_from_favorites": "į§ģå‡ēæ”ļ藏", "remove_from_lock_folder_action_prompt": "厞äģŽé”åŽšįš„æ–‡äģļ多中į§ģ除 {count} 饚", "remove_from_locked_folder": "äģŽé”åŽšæ–‡äģļ多中į§ģ除", @@ -1867,7 +1871,7 @@ "removed_from_favorites_count": "äģŽæ”ļ藏中į§ģ除{count, plural, other {#饚}}", "removed_memory": "åˇ˛åˆ é™¤įš„å›žåŋ†", "removed_photo_from_memory": "äģŽå›žåŋ†åŒēä¸­åˆ é™¤įš„į…§į‰‡", - "removed_tagged_assets": "äģŽ {count, plural, one {# ä¸ĒéĄšį›Ž} other {# ä¸ĒéĄšį›Ž}}ä¸­åˆ é™¤æ ‡į­ž", + "removed_tagged_assets": "äģŽ {count, plural, one {#ä¸ĒéĄšį›Ž} other {#ä¸ĒéĄšį›Ž}}ä¸­åˆ é™¤æ ‡į­ž", "rename": "重å‘Ŋ名", "repair": "äŋŽå¤", "repair_no_results_message": "æœĒ莟č¸Ē和įŧēå¤ąįš„æ–‡äģļ将在此处昞į¤ē", @@ -1895,7 +1899,7 @@ "resolved_all_duplicates": "å¤„į†æ‰€æœ‰é‡å¤éĄš", "restore": "æĸ复", "restore_all": "æĸ复全部", - "restore_trash_action_prompt": "äģŽå›žæ”ļį̙䏭æĸ复äē† {count} 饚", + "restore_trash_action_prompt": "äģŽå›žæ”ļį̙䏭æĸ复äē†{count}饚", "restore_user": "æĸå¤į”¨æˆˇ", "restored_asset": "厞æĸå¤éĄšį›Ž", "resume": "įģ§įģ­", @@ -1921,9 +1925,9 @@ "scan_library": "æ‰Ģ描", "scan_settings": "æ‰ĢæčŽžįŊŽ", "scanning": "æ‰Ģ描中", - "scanning_for_album": "æ‰Ģæį›¸å†Œä¸­...", + "scanning_for_album": "æ‰Ģæį›¸į°ŋ中...", "search": "搜į´ĸ", - "search_albums": "搜į´ĸį›¸å†Œ", + "search_albums": "搜į´ĸᛏį°ŋ", "search_by_context": "通čŋ‡æčŋ°įš„åœē景æŸĨ扞", "search_by_description": "通čŋ‡æčŋ°æŸĨ扞", "search_by_description_example": "åœ¨æ˛™åˇ´åž’æ­Ĩįš„æ—Ĩ子", @@ -1941,7 +1945,7 @@ "search_filter_date": "æ—Ĩ期", "search_filter_date_interval": "äģŽ{start}到{end}", "search_filter_date_title": "选拊æ—ĨæœŸčŒƒå›´", - "search_filter_display_option_not_in_album": "ä¸åœ¨į›¸å†Œä¸­", + "search_filter_display_option_not_in_album": "ä¸åœ¨į›¸į°ŋ中", "search_filter_display_options": "昞į¤ē选项", "search_filter_filename": "通čŋ‡æ–‡äģļ名搜į´ĸ", "search_filter_location": "äŊįŊŽ", @@ -1986,14 +1990,14 @@ "second": "į§’", "see_all_people": "æŸĨįœ‹æ‰€æœ‰äēēį‰Š", "select": "选拊", - "select_album": "é€‰æ‹Šį›¸å†Œ", - "select_album_cover": "é€‰æ‹Šį›¸å†Œå°éĸ", - "select_albums": "é€‰æ‹Šį›¸å†Œ", + "select_album": "é€‰æ‹Šį›¸į°ŋ", + "select_album_cover": "é€‰æ‹Šį›¸į°ŋ封éĸ", + "select_albums": "é€‰æ‹Šį›¸į°ŋ", "select_all": "全选", "select_all_duplicates": "é€‰æ‹Šæ‰€æœ‰é‡å¤éĄš", "select_all_in": "选拊 {group} ä¸­įš„æ‰€æœ‰å†…åŽš", "select_avatar_color": "选拊头像éĸœč‰˛", - "select_count": "{count, plural, one {选拊 # 饚} other {选拊 # 饚}}", + "select_count": "{count, plural, one {厞选䏭#饚} other {厞选䏭#饚}}", "select_cutoff_date": "选拊æˆĒæ­ĸæ—Ĩ期", "select_face": "选拊äēē脸", "select_featured_photo": "选拊ä¸Ē性头像", @@ -2006,14 +2010,14 @@ "select_person_to_tag": "选拊čĻæ ‡čŽ°įš„äēēį‰Š", "select_photos": "é€‰æ‹Šį…§į‰‡", "select_trash_all": "全部删除", - "select_user_for_sharing_page_err_album": "创åģēį›¸å†Œå¤ąč´Ĩ", + "select_user_for_sharing_page_err_album": "创åģēᛏį°ŋå¤ąč´Ĩ", "selected": "åˇ˛é€‰æ‹Š", - "selected_count": "{count, plural, other {#éĄšåˇ˛é€‰æ‹Š}}", + "selected_count": "{count, plural, other {厞选䏭#饚}}", "selected_gps_coordinates": "åˇ˛é€‰åŽšįš„GPS坐标", "send_message": "发送æļˆæ¯", "send_welcome_email": "发送æŦĸčŋŽé‚Žäģļ", "server_endpoint": "æœåŠĄå™¨ URL", - "server_info_box_app_version": "App į‰ˆæœŦ", + "server_info_box_app_version": "Appį‰ˆæœŦ", "server_info_box_server_url": "æœåŠĄå™¨åœ°å€", "server_offline": "æœåŠĄå™¨įĻģįēŋ", "server_online": "æœåŠĄå™¨åœ¨įēŋ", @@ -2024,7 +2028,7 @@ "server_update_available": "æœåŠĄå™¨æ›´æ–°å¯į”¨", "server_version": "æœåŠĄå™¨į‰ˆæœŦ", "set": "莞įŊŽ", - "set_as_album_cover": "莞ä¸ēį›¸å†Œå°éĸ", + "set_as_album_cover": "莞ä¸ēᛏį°ŋ封éĸ", "set_as_featured_photo": "莞įŊŽä¸ēį‰šč‰˛į…§į‰‡", "set_as_profile_picture": "莞ä¸ēä¸Ēäēēčĩ„æ–™å›žį‰‡", "set_date_of_birth": "莞įŊŽå‡ēį”Ÿæ—Ĩ期", @@ -2043,11 +2047,11 @@ "setting_languages_apply": "åē”ᔍ", "setting_languages_subtitle": "更攚åē”ᔍ蝭荀", "setting_notifications_notify_failures_grace_period": "后台备äģŊå¤ąč´Ĩ通įŸĨīŧš{duration}", - "setting_notifications_notify_hours": "{count} 小æ—ļ", + "setting_notifications_notify_hours": "{count}小æ—ļ", "setting_notifications_notify_immediately": "įĢ‹åŗ", - "setting_notifications_notify_minutes": "{count} 分钟", + "setting_notifications_notify_minutes": "{count}分钟", "setting_notifications_notify_never": "äģŽä¸", - "setting_notifications_notify_seconds": "{count} į§’", + "setting_notifications_notify_seconds": "{count}į§’", "setting_notifications_single_progress_subtitle": "æ¯éĄšįš„č¯Ļįģ†ä¸Šäŧ čŋ›åēĻäŋĄæ¯", "setting_notifications_single_progress_title": "昞į¤ē后台备äģŊč¯Ļįģ†čŋ›åēĻ", "setting_notifications_subtitle": "č°ƒæ•´é€šįŸĨéĻ–é€‰éĄš", @@ -2065,22 +2069,22 @@ "share": "分äēĢ", "share_action_prompt": "åˇ˛å…ąäēĢ {count} éĄšį›Ž", "share_add_photos": "æˇģåŠ éĄšį›Ž", - "share_assets_selected": "{count} åˇ˛é€‰æ‹Š", + "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_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_intent_upload_button_progress_text": "厞䏊äŧ {current} / {total}", "shared_link_app_bar_title": "å…ąäēĢ链æŽĨ", "shared_link_clipboard_copied_massage": "复åˆļ到å‰Ēč´´æŋ", "shared_link_clipboard_text": "链æŽĨīŧš{link}\n坆᠁īŧš{password}", @@ -2088,25 +2092,25 @@ "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_days": "{count}夊", "shared_link_edit_expire_after_option_hour": "1小æ—ļ", - "shared_link_edit_expire_after_option_hours": "{count} 小æ—ļ", + "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_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": "æ— æŗ•čŽˇå–æœåŠĄå™¨åœ°å€", - "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_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_expires_second": "{count}į§’åŽčŋ‡æœŸ", + "shared_link_expires_seconds": "{count}į§’åŽčŋ‡æœŸ", "shared_link_individual_shared": "ä¸Ēäēēå…ąäēĢ", "shared_link_info_chip_metadata": "EXIF", "shared_link_manage_links": "įŽĄį†å…ąäēĢ链æŽĨ", @@ -2114,20 +2118,20 @@ "shared_link_password_description": "需čĻå¯†į æ‰čƒŊčŽŋé—Žæ­¤å…ąäēĢ链æŽĨ", "shared_links": "å…ąäēĢ链æŽĨ", "shared_links_description": "通čŋ‡é“žæŽĨ分äēĢį…§į‰‡å’Œč§†éĸ‘", - "shared_photos_and_videos_count": "{assetCount, plural, other {#éĄšåˇ˛å…ąäēĢᅧቇ&视éĸ‘。}}", + "shared_photos_and_videos_count": "{assetCount, plural, other {#ä¸Ēåˇ˛å…ąäēĢᅧቇ/视éĸ‘。}}", "shared_with_me": "å…ąäēĢį왿ˆ‘", - "shared_with_partner": "与“{partner}â€å…ąäēĢ", + "shared_with_partner": "与{partner}å…ąäēĢ", "sharing": "å…ąäēĢ", "sharing_enter_password": "č¯ˇčž“å…Ĩå¯†į åŽæŸĨįœ‹æ­¤éĄĩéĸ。", - "sharing_page_album": "å…ąäēĢį›¸å†Œ", - "sharing_page_description": "创åģēå…ąäēĢį›¸å†ŒäģĨ与įŊ‘įģœä¸­įš„äēēå…ąäēĢį…§į‰‡å’Œč§†éĸ‘。", + "sharing_page_album": "å…ąäēĢᛏį°ŋ", + "sharing_page_description": "创åģēå…ąäēĢᛏį°ŋäģĨ与įŊ‘įģœä¸­įš„äēēå…ąäēĢį…§į‰‡å’Œč§†éĸ‘。", "sharing_page_empty_list": "įŠē", "sharing_sidebar_description": "åœ¨äž§čžšæ ä¸­æ˜žį¤ēâ€œå…ąäēĢ”链æŽĨ", - "sharing_silver_appbar_create_shared_album": "创åģēå…ąäēĢį›¸å†Œ", + "sharing_silver_appbar_create_shared_album": "创åģēå…ąäēĢᛏį°ŋ", "sharing_silver_appbar_share_partner": "å…ąäēĢįģ™åäŊœč€…", "shift_to_permanent_delete": "按äŊ ⇧ Shift é”Žæ°¸äš…åˆ é™¤éĄšį›Ž", - "show_album_options": "昞į¤ēį›¸å†Œé€‰éĄš", - "show_albums": "昞į¤ēį›¸å†Œ", + "show_album_options": "昞į¤ēᛏį°ŋ选项", + "show_albums": "昞į¤ēᛏį°ŋ", "show_all_people": "昞į¤ē所有äēēį‰Š", "show_and_hide_people": "昞į¤ēå’Œéšč—äēēį‰Š", "show_file_location": "昞į¤ē文äģļäŊįŊŽ", @@ -2162,7 +2166,7 @@ "slideshow_repeat": "重复åšģၝቇ", "slideshow_repeat_description": "åšģၝቇį쓿ŸåŽåžĒįŽ¯æ’­æ”ž", "slideshow_settings": "æ”žæ˜ čŽžįŊŽ", - "sort_albums_by": "į›¸å†ŒæŽ’åēäžæŽ...", + "sort_albums_by": "ᛏį°ŋ排åēäžæŽ...", "sort_created": "创åģēæ—Ĩ期", "sort_items": "éĄšį›Žæ•°é‡", "sort_modified": "äŋŽæ”šæ—Ĩ期", @@ -2171,9 +2175,9 @@ "sort_people_by_similarity": "æŒ‰į›¸äŧŧ性寚äēēį‰Ščŋ›čĄŒæŽ’åē", "sort_recent": "æœ€æ–°įš„į…§į‰‡", "sort_title": "标éĸ˜", - "source": "GitHub æēäģŖį ", + "source": "GitHubæēäģŖį ", "stack": "堆叠", - "stack_action_prompt": "{count} ä¸Ēåˇ˛å †å ", + "stack_action_prompt": "{count}ä¸Ēåˇ˛å †å ", "stack_duplicates": "å †å é‡å¤éĄšį›Ž", "stack_select_one_photo": "ä¸ē堆叠选拊一åŧ åą•į¤ē回", "stack_selected_photos": "å †å é€‰åŽšįš„į…§į‰‡", @@ -2187,7 +2191,7 @@ "stop_casting": "停æ­ĸ投攞", "stop_motion_photo": "厚æ ŧᅧቇ", "stop_photo_sharing": "停æ­ĸå…ąäēĢᅧቇīŧŸ", - "stop_photo_sharing_description": "“{partner}”将不čƒŊčŽŋé—Žæ‚¨įš„į…§į‰‡ã€‚", + "stop_photo_sharing_description": "{partner}将不čƒŊčŽŋé—Žæ‚¨įš„į…§į‰‡ã€‚", "stop_sharing_photos_with_user": "停æ­ĸä¸Žæ­¤į”¨æˆˇå…ąäēĢᅧቇ", "storage": "存储įŠē间", "storage_label": "å­˜å‚¨æ ‡į­ž", @@ -2203,16 +2207,17 @@ "supporter": "čĩžåŠŠč€…", "swap_merge_direction": "äē’æĸ合åšļ斚向", "sync": "同æ­Ĩ", - "sync_albums": "同æ­Ĩį›¸å†Œ", - "sync_albums_manual_subtitle": "将所有上äŧ įš„视éĸ‘å’Œį…§į‰‡åŒæ­Ĩåˆ°é€‰åŽšįš„å¤‡äģŊį›¸å†Œ", + "sync_albums": "同æ­Ĩᛏį°ŋ", + "sync_albums_manual_subtitle": "将所有上äŧ įš„视éĸ‘å’Œį…§į‰‡åŒæ­Ĩåˆ°é€‰åŽšįš„å¤‡äģŊᛏį°ŋ", "sync_local": "同æ­ĨæœŦ地", "sync_remote": "同æ­Ĩčŋœį¨‹", "sync_status": "同æ­ĨįŠļ态", "sync_status_subtitle": "æŸĨįœ‹å’ŒįŽĄį†åŒæ­ĨįŗģįģŸ", - "sync_upload_album_setting_subtitle": "创åģēį…§į‰‡å’Œč§†éĸ‘åšļ上äŧ åˆ° Immich ä¸Šįš„é€‰åŽšį›¸å†Œä¸­", + "sync_upload_album_setting_subtitle": "创åģēį…§į‰‡å’Œč§†éĸ‘åšļ上äŧ åˆ° Immich ä¸Šé€‰åŽšįš„į›¸į°ŋ", "tag": "æ ‡į­ž", "tag_assets": "æ ‡čŽ°éĄšį›Ž", "tag_created": "åˇ˛åˆ›åģēæ ‡į­žīŧš{tag}", + "tag_face": "æ ‡čŽ°äēē脸", "tag_feature_description": "按é€ģčž‘æ ‡į­žåˆ†įģ„åšļæĩč§ˆį…§į‰‡å’Œč§†éĸ‘", "tag_not_found_question": "æ‰žä¸åˆ°æ ‡į­žå—īŧŸåˆ›åģēæ–°æ ‡į­žã€‚", "tag_people": "å‘Ŋ名äēēį‰Š", @@ -2287,7 +2292,7 @@ "unable_to_setup_pin_code": "æ— æŗ•čŽžįŊŽPIN᠁", "unarchive": "取æļˆåŊ’æĄŖ", "unarchive_action_prompt": "厞äģŽåŊ’æĄŖä¸­į§ģ除 {count} 饚", - "unarchived_count": "{count, plural, other {取æļˆåŊ’æĄŖ # 饚}}", + "unarchived_count": "{count, plural, other {取æļˆåŊ’æĄŖ#饚}}", "undo": "撤销", "unfavorite": "取æļˆæ”ļ藏", "unfavorite_action_prompt": "厞äģŽæ”ļ藏中į§ģ除 {count} 饚", @@ -2301,22 +2306,22 @@ "unlink_oauth": "č§Ŗįģ‘ OAuth", "unlinked_oauth_account": "č§Ŗįģ‘ OAuth č´Ļæˆˇ", "unmute_memories": "取æļˆé™éŸŗå›žåŋ†", - "unnamed_album": "æœĒå‘Ŋåį›¸å†Œ", - "unnamed_album_delete_confirmation": "æ‚¨įĄŽåŽščĻåˆ é™¤č¯Ĩį›¸å†Œå—īŧŸ", + "unnamed_album": "æœĒå‘Ŋåį›¸į°ŋ", + "unnamed_album_delete_confirmation": "æ‚¨įĄŽåŽščĻåˆ é™¤č¯Ĩᛏį°ŋ吗īŧŸ", "unnamed_share": "æœĒå‘Ŋåå…ąäēĢ", "unsaved_change": "äŋŽæ”šæœĒäŋå­˜", "unselect_all": "取æļˆå…¨é€‰", "unselect_all_duplicates": "取æļˆé€‰æ‹Šæ‰€æœ‰é‡å¤éĄš", "unselect_all_in": "取æļˆé€‰æ‹Š {group} ä¸­įš„æ‰€æœ‰å†…åŽš", "unstack": "取æļˆå †å ", - "unstack_action_prompt": "{count} ä¸ĒæœĒ堆叠", + "unstack_action_prompt": "{count}ä¸ĒæœĒ堆叠", "unstacked_assets_count": "{count, plural, one {#ä¸ĒéĄšį›Ž} other {#ä¸ĒéĄšį›Ž}}åˇ˛å–æļˆå †å ", "unsupported_field_type": "ä¸æ”¯æŒįš„å­—æŽĩįąģ型", "unsupported_file_type": "不支持上äŧ æ–‡äģļ {file}īŧŒåŊ“前不支持 {type} įąģåž‹įš„æ–‡äģļ。", "untagged": "æ— æ ‡į­ž", "untitled_workflow": "无标éĸ˜åˇĨäŊœæĩ", "up_next": "下一ä¸Ē", - "update_location_action_prompt": "更新 {count} ä¸Ē所选čĩ„äē§įš„äŊįŊŽīŧš", + "update_location_action_prompt": "更新{count}ä¸Ēæ‰€é€‰éĄšį›Žįš„äŊįŊŽīŧš", "updated_at": "最后更新æ—ļ间", "updated_password": "æ›´æ–°å¯†į ", "upload": "上äŧ ", @@ -2333,7 +2338,7 @@ "upload_status_errors": "错蝝", "upload_status_uploaded": "厞䏊äŧ ", "upload_success": "上äŧ æˆåŠŸīŧŒåˆˇæ–°éĄĩéĸæŸĨįœ‹æ–°ä¸Šäŧ įš„éĄšį›Žã€‚", - "upload_to_immich": "上äŧ č‡ŗ Immichīŧˆ{count}īŧ‰", + "upload_to_immich": "上äŧ č‡ŗImmichīŧˆ{count}īŧ‰", "uploading": "æ­Ŗåœ¨ä¸Šäŧ ", "uploading_media": "文äģļ上äŧ ä¸­", "url": "URL", @@ -2346,7 +2351,7 @@ "user": "į”¨æˆˇ", "user_has_been_deleted": "æ­¤į”¨æˆˇåˇ˛čĸĢ删除。", "user_id": "į”¨æˆˇ ID", - "user_liked": "“{user}â€į‚ščĩžäē†{type, select, photo {č¯Ĩᅧቇ} video {č¯Ĩ视éĸ‘} asset {č¯ĨéĄšį›Ž} other {厃}}", + "user_liked": "{user}į‚ščĩžäē†{type, select, photo {č¯Ĩᅧቇ} video {č¯Ĩ视éĸ‘} asset {č¯ĨéĄšį›Ž} other {厃}}", "user_pin_code_settings": "PIN᠁", "user_pin_code_settings_description": "įŽĄį†äŊ įš„PIN᠁", "user_privacy": "į”¨æˆˇéšį§", @@ -2358,7 +2363,7 @@ "user_usage_stats_description": "æŸĨįœ‹å¸æˆˇäŊŋᔍįģŸčŽĄäŋĄæ¯", "username": "į”¨æˆˇå", "users": "į”¨æˆˇ", - "users_added_to_album_count": "厞将 {count, plural, one {# ä¸Ēį”¨æˆˇ} other {# ä¸Ēį”¨æˆˇ}} æˇģåŠ åˆ°į›¸å†Œ", + "users_added_to_album_count": "厞将 {count, plural, one {# ä¸Ēį”¨æˆˇ} other {# ä¸Ēį”¨æˆˇ}} æˇģåŠ åˆ°į›¸į°ŋ", "utilities": "åŽžį”¨åˇĨå…ˇ", "validate": "énj蝁", "validate_endpoint_error": "č¯ˇčž“å…Ĩæœ‰æ•ˆįš„ URL", @@ -2366,7 +2371,7 @@ "variables": "变量", "version": "į‰ˆæœŦ", "version_announcement_closing": "æ‚¨įš„æœ‹å‹īŧŒAlex", - "version_announcement_message": "Immich įŽ°åˇ˛æŽ¨å‡ēæ–°į‰ˆæœŦã€‚č¯ˇæŸĨé˜…å‘čĄŒč¯´æ˜ŽīŧŒåŠæ—ļ更新配įŊŽäģĨ防æ­ĸå‡ē错。č‹Ĩ您通čŋ‡ WatchTower 或å…ļäģ–åˇĨå…ˇč‡Ē动更新 ImmichīŧŒéœ€į‰šåˆĢæŗ¨æ„ã€‚", + "version_announcement_message": "äŊ åĨŊīŧImmich įš„æ–°į‰ˆæœŦ厞įģå‘å¸ƒã€‚č¯ˇčŠąį‚šæ—ļ间阅č¯ģå‘čĄŒč¯´æ˜ŽīŧŒäģĨįĄŽäŋäŊ įš„部įŊ˛įޝåĸƒäŋæŒæœ€æ–°īŧŒäģŽč€Œéŋ免配įŊŽé”™č¯¯ã€‚į‰šåˆĢ是åĻ‚æžœäŊ äŊŋᔍäē† WatchTower 或å…ļäģ–č‡Ē动更新æœēåˆļīŧŒčŋ™ä¸€į‚šå°¤ä¸ē重čĻã€‚", "version_history": "į‰ˆæœŦæ›´æ–°åŽ†å˛čŽ°åŊ•", "version_history_item": "在 {date} åŽ‰čŖ… {version} į‰ˆæœŦ", "video": "视éĸ‘", @@ -2376,10 +2381,10 @@ "videos_count": "{count, plural, one {#ä¸Ē视éĸ‘} other {#ä¸Ē视éĸ‘}}", "videos_only": "äģ…视éĸ‘", "view": "æŸĨįœ‹", - "view_album": "æŸĨįœ‹į›¸å†Œ", + "view_album": "æŸĨįœ‹į›¸į°ŋ", "view_all": "æŸĨįœ‹å…¨éƒ¨", "view_all_users": "æŸĨįœ‹å…¨éƒ¨į”¨æˆˇ", - "view_asset_owners": "æŸĨįœ‹čĩ„äē§æ‰€æœ‰č€…", + "view_asset_owners": "æŸĨįœ‹éĄšį›Žæ‰€æœ‰č€…", "view_details": "æŸĨįœ‹č¯Ļ情", "view_in_timeline": "在æ—ļ间čŊ´ä¸­æŸĨįœ‹", "view_link": "æŸĨįœ‹é“žæŽĨ", @@ -2392,8 +2397,9 @@ "view_stack": "æŸĨįœ‹å †å éĄšį›Ž", "view_user": "æŸĨįœ‹į”¨æˆˇ", "viewer_remove_from_stack": "äģŽå †å ä¸­į§ģ除", - "viewer_stack_use_as_main_asset": "äŊœä¸ēä¸ģéĄšį›ŽäŊŋᔍ", + "viewer_stack_use_as_main_asset": "äŊœä¸ēä¸ģį”ģ像äŊŋᔍ", "viewer_unstack": "取æļˆå †å ", + "visibility": "å¯č§æ€§", "visibility_changed": "{count, plural, one {#ä¸Ēäēēį‰Š} other {#ä¸Ēäēēį‰Š}}įš„å¯č§æ€§åˇ˛äŋŽæ”š", "visual": "å¯č§†åŒ–", "visual_builder": "å¯č§†åŒ–į”Ÿæˆå™¨", @@ -2404,7 +2410,7 @@ "welcome": "æŦĸčŋŽ", "welcome_to_immich": "æŦĸčŋŽäŊŋᔍ Immich", "width": "åŽŊåēĻ", - "wifi_name": "Wi-Fi åį§°", + "wifi_name": "Wi-Fiåį§°", "workflow_delete_prompt": "æ‚¨įĄŽåŽščĻåˆ é™¤æ­¤åˇĨäŊœæĩå—īŧŸ", "workflow_deleted": "åˇĨäŊœæĩåˇ˛åˆ é™¤", "workflow_description": "åˇĨäŊœæĩæčŋ°", @@ -2424,7 +2430,7 @@ "yes": "是", "you_dont_have_any_shared_links": "æ‚¨æ˛Ąæœ‰äģģäŊ•å…ąäēĢ链æŽĨ", "your_wifi_name": "æ‚¨įš„ Wi-Fi åį§°", - "zero_to_clear_rating": "按0清除čĩ„äē§æ˜Ÿįē§", + "zero_to_clear_rating": "按0æ¸…é™¤éĄšį›Žæ˜Ÿįē§", "zoom_image": "įŧŠæ”žå›žåƒ", "zoom_to_bounds": "įŧŠæ”žåˆ°čžšį•Œ" } diff --git a/i18n/zh_Hant.json b/i18n/zh_Hant.json index a61b03c28c..00b9629264 100644 --- a/i18n/zh_Hant.json +++ b/i18n/zh_Hant.json @@ -54,7 +54,7 @@ "authentication_settings_description": "įŽĄį†å¯†įĸŧ、OAuth 與å…ļäģ–éŠ—č­‰č¨­åŽš", "authentication_settings_disable_all": "您įĸē厚čĻåœį”¨æ‰€æœ‰į™ģå…Ĩæ–šåŧå—ŽīŧŸé€™å°‡å°Žč‡´åŽŒå…¨į„Ąæŗ•į™ģå…Ĩ。", "authentication_settings_reenable": "åĻ‚éœ€é‡æ–°å•Ÿį”¨īŧŒčĢ‹äŊŋᔍ äŧ翜å™¨æŒ‡äģ¤ã€‚", - "background_task_job": "čƒŒæ™¯åˇĨäŊœ", + "background_task_job": "čƒŒæ™¯äģģ務", "backup_database": "åģēįĢ‹čŗ‡æ–™åēĢ備äģŊ", "backup_database_enable_description": "å•Ÿį”¨čŗ‡æ–™åēĢ備äģŊ", "backup_keep_last_amount": "äŋį•™å…ˆå‰å‚™äģŊįš„æ•¸é‡", @@ -63,7 +63,7 @@ "backup_onboarding_3_description": "æ‚¨čŗ‡æ–™įš„į¸Ŋ備äģŊäģŊ數īŧŒåŒ…æ‹Ŧ原始æĒ”æĄˆåœ¨å…§ã€‚é€™åŒ…æ‹Ŧ 1 äģŊį•°åœ°å‚™äģŊ與 2 äģŊæœŦ抟副æœŦ。", "backup_onboarding_description": "åģēč­°æŽĄį”¨ 3-2-1 備äģŊį­–į•Ĩ 來äŋč­ˇæ‚¨įš„čŗ‡æ–™ã€‚æ‚¨æ‡‰äŋį•™åˇ˛ä¸Šå‚ŗįš„ᛏቇ/åŊąį‰‡å‰¯æœŦīŧŒäģĨ及 Immich čŗ‡æ–™åēĢīŧŒäģĨåģēįĢ‹åŽŒæ•´įš„å‚™äģŊæ–šæĄˆã€‚", "backup_onboarding_footer": "更多備äģŊ Immich čŗ‡č¨ŠīŧŒčĢ‹åƒč€ƒ čĒĒæ˜Žæ–‡äģļ。", - "backup_onboarding_parts_title": "éĩåžžå‚™äģŊ原則 3-2-1īŧš", + "backup_onboarding_parts_title": "3-2-1 備äģŊ包åĢīŧš", "backup_onboarding_title": "備äģŊ", "backup_settings": "čŗ‡æ–™åēĢ備äģŊč¨­åŽš", "backup_settings_description": "įŽĄį†čŗ‡æ–™åēĢ備äģŊč¨­åŽšã€‚", @@ -81,20 +81,20 @@ "cron_expression_description": "äŊŋᔍ Cron æ ŧåŧč¨­åŽšæŽƒæé–“éš”ã€‚æ›´å¤ščŗ‡č¨ŠčĢ‹åƒé–ą Crontab Guru", "cron_expression_presets": "Cron 表達åŧé č¨­å€ŧ", "disable_login": "åœį”¨į™ģå…Ĩ", - "duplicate_detection_job_description": "䞝靠æ™ēæ…§æœå°‹ã€‚å°é …į›ŽåŸˇčĄŒæŠŸå™¨å­¸įŋ’䞆åĩæ¸Ŧᛏäŧŧåœ–į‰‡", + "duplicate_detection_job_description": "é‡å°čŗ‡į”ĸåŸˇčĄŒæŠŸå™¨å­¸įŋ’äģĨåĩæ¸Ŧᛏäŧŧåœ–į‰‡ã€‚éœ€äžčŗ´ã€Œæ™ē慧搜尋」功čƒŊ", "exclusion_pattern_description": "æŽ’é™¤æ¨Ąåŧå¯čŽ“æ‚¨åœ¨æŽƒæåĒ’éĢ”åēĢæ™‚åŋŊį•Ĩį‰šåŽšæĒ”æĄˆčˆ‡čŗ‡æ–™å¤žã€‚č‹Ĩ某äē›čŗ‡æ–™å¤žåŒ…åĢæ‚¨ä¸æƒŗåŒ¯å…Ĩįš„æĒ”æĄˆīŧˆäž‹åĻ‚ RAW æĒ”īŧ‰īŧŒæ­¤åŠŸčƒŊå°‡éžå¸¸æœ‰į”¨ã€‚", "export_config_as_json_description": "å°‡į›Žå‰įŗģįĩąč¨­åŽšä¸‹čŧ‰į‚ē JSON æĒ”æĄˆ", "external_libraries_page_description": "įŽĄį†å¤–éƒ¨åĒ’éĢ”åēĢ頁éĸ", "face_detection": "臉孔åĩæ¸Ŧ", - "face_detection_description": "äŊŋį”¨æŠŸå™¨å­¸įŋ’åĩæ¸Ŧé …į›Žä¸­įš„č‡‰å­”ã€‚å°æ–ŧåŊąį‰‡īŧŒåƒ…æœƒåˆ†æžį¸Žåœ–ã€‚ã€Œé‡æ–°æ•´į†ã€æœƒé‡æ–°č™•į†æ‰€æœ‰é …į›Žīŧ›ã€Œé‡č¨­ã€å‰‡æœƒéĄå¤–æ¸…é™¤į›Žå‰įš„č‡‰å­”čŗ‡æ–™īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€æœƒå°‡å°šæœĒč™•į†įš„é …į›ŽåŠ å…Ĩåēåˆ—ã€‚åŽŒæˆã€Œč‡‰å­”åĩæ¸Ŧ」垌īŧŒåĩæ¸Ŧåˆ°įš„č‡‰å­”å°‡åŠ å…Ĩã€Œč‡‰å­”čž¨č­˜ã€æŽ’į¨‹īŧŒä¸Ļæ­¸éĄžč‡ŗįžæœ‰æˆ–æ–°įš„äēēį‰Šįž¤įĩ„。", - "facial_recognition_job_description": "將åĩæ¸Ŧåˆ°įš„č‡‰å­”æ­¸éĄžį‚ēäēēį‰Šã€‚æ­¤æ­ĨéŠŸæœƒåœ¨č‡‰å­”åĩæ¸ŦåŽŒæˆåžŒåŸˇčĄŒã€‚ã€Œé‡č¨­ã€æœƒé‡æ–°å°æ‰€æœ‰č‡‰å­”é€˛čĄŒåˆ†įž¤īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€å‰‡æœƒå°‡å°šæœĒ指洞äēēį‰Šįš„č‡‰å­”åŠ å…Ĩåēåˆ—。", + "face_detection_description": "äŊŋį”¨æŠŸå™¨å­¸įŋ’åĩæ¸Ŧé …į›Žä¸­įš„č‡‰å­”ã€‚å°æ–ŧåŊąį‰‡īŧŒåƒ…æœƒåˆ†æžį¸Žåœ–ã€‚ã€Œé‡æ–°æ•´į†ã€æœƒé‡æ–°č™•į†æ‰€æœ‰é …į›Žīŧ›ã€Œé‡č¨­ã€å‰‡æœƒéĄå¤–æ¸…é™¤į›Žå‰įš„č‡‰å­”čŗ‡æ–™īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€æœƒå°‡å°šæœĒč™•į†įš„é …į›ŽåŠ å…ĨäŊ‡åˆ—ã€‚åŽŒæˆã€Œč‡‰å­”åĩæ¸Ŧ」垌īŧŒåĩæ¸Ŧåˆ°įš„č‡‰å­”å°‡åŠ å…Ĩã€Œč‡‰å­”čž¨č­˜ã€æŽ’į¨‹īŧŒä¸Ļæ­¸éĄžč‡ŗįžæœ‰æˆ–æ–°įš„äēēį‰Šįž¤įĩ„。", + "facial_recognition_job_description": "將åĩæ¸Ŧåˆ°įš„č‡‰å­”æ­¸éĄžį‚ēäēēį‰Šã€‚æ­¤æ­ĨéŠŸæœƒåœ¨č‡‰å­”åĩæ¸ŦåŽŒæˆåžŒåŸˇčĄŒã€‚ã€Œé‡č¨­ã€æœƒé‡æ–°å°æ‰€æœ‰č‡‰å­”é€˛čĄŒåˆ†įž¤īŧ›ã€ŒåŠ å…ĨæŽ’į¨‹ã€å‰‡æœƒå°‡å°šæœĒ指洞äēēį‰Šįš„č‡‰å­”åŠ å…ĨäŊ‡åˆ—。", "failed_job_command": "{job} äģģå‹™įš„ {command} 指äģ¤åŸˇčĄŒå¤ąæ•—", "force_delete_user_warning": "č­Ļ告īŧšé€™å°‡įĢ‹åŗåˆĒ除äŊŋį”¨č€…åŠå…￉€æœ‰é …į›Žã€‚æ­¤å‹•äŊœį„Ąæŗ•垊原īŧŒä¸”į„Ąæŗ•æ‰žå›žåˇ˛åˆĒé™¤įš„æĒ”æĄˆã€‚", "image_format": "æ ŧåŧ", "image_format_description": "WebP čƒŊį”ĸį”Ÿį›¸å°æ–ŧ JPEG æ›´å°įš„æĒ”æĄˆīŧŒäŊ†įˇ¨įĸŧ速åēĻčŧƒæ…ĸ。", "image_fullsize_description": "į§ģ除中įšŧčŗ‡æ–™įš„å¤§å°ē寸åŊąåƒīŧŒåœ¨æ”žå¤§åœ–į‰‡æ™‚äŊŋᔍ", "image_fullsize_enabled": "å•Ÿį”¨å¤§å°ē寸åŊąåƒį”ĸį”Ÿ", - "image_fullsize_enabled_description": "į‚ē非įļ˛é å‹å–„æ ŧåŧį”ĸį”Ÿå¤§å°ēå¯¸į›¸į‰‡ã€‚å•Ÿį”¨ã€ŒååĨŊ內åĩŒé čĻŊ」時īŧŒįŗģįĩąå°‡į›´æŽĨäŊŋᔍ內åĩŒé čĻŊ而不進行čŊ‰įĸŧīŧŒä¸åŊąéŸŋ JPEG į­‰įļ˛é å‹å–„æ ŧåŧã€‚", + "image_fullsize_enabled_description": "į‚ē非įļ˛é į›¸åŽšæ ŧåŧį”ĸį”Ÿå¤§å°ēå¯¸į›¸į‰‡ã€‚å•Ÿį”¨ã€ŒååĨŊ內åĩŒé čĻŊ」時īŧŒįŗģįĩąå°‡į›´æŽĨäŊŋᔍ內åĩŒé čĻŊ而不進行čŊ‰įĸŧīŧŒä¸åŊąéŸŋ JPEG į­‰įļ˛é į›¸åŽšæ ŧåŧã€‚", "image_fullsize_quality_description": "大å°ē寸åŊąåƒå“čŗĒīŧŒį¯„圍į‚ē 1 到 100。數å€ŧčļŠéĢ˜å“čŗĒčļŠåĨŊīŧŒäŊ†æĒ”æĄˆä🿜ƒčļŠå¤§ã€‚", "image_fullsize_title": "大å°ē寸åŊąåƒč¨­åޚ", "image_prefer_embedded_preview": "偏åĨŊ內åĩŒé čĻŊ", @@ -104,14 +104,14 @@ "image_preview_description": "䏭ᭉå°ē寸åŊąåƒīŧˆä¸åĢ中įšŧčŗ‡æ–™īŧ‰īŧŒį”¨æ–ŧæĒĸčĻ–å–Žä¸€é …į›Žčˆ‡æŠŸå™¨å­¸įŋ’", "image_preview_quality_description": "預čĻŊ品čŗĒį¯„åœį‚ē 1 到 100。數å€ŧčļŠéĢ˜å“čŗĒčļŠåĨŊīŧŒäŊ†æĒ”æĄˆä🿜ƒæ›´å¤§īŧŒä¸Ļ可čƒŊ降äŊŽæ‡‰į”¨į¨‹åŧįš„回應速åēĻã€‚č¨­åŽšéŽäŊŽįš„æ•¸å€ŧ可čƒŊ會åŊąéŸŋ抟器學įŋ’įš„å“čŗĒ。", "image_preview_title": "預čĻŊč¨­åŽš", - "image_progressive": "逐æ­Ĩ", - "image_progressive_description": "對 JPEG åŊąåƒé€˛čĄŒæŧ¸é€˛åŧįˇ¨įĸŧīŧŒäģĨå¯Ļįžæŧ¸é€˛åŧčŧ‰å…ĨéĄ¯į¤ē。這不會åŊąéŸŋ WebP åŊąåƒã€‚", + "image_progressive": "æŧ¸é€˛åŧ", + "image_progressive_description": "對 JPEG åŊąåƒé€˛čĄŒæŧ¸é€˛åŧįˇ¨įĸŧīŧŒäģĨ達成æŧ¸é€˛åŧčŧ‰å…ĨéĄ¯į¤ē。這不會åŊąéŸŋ WebP åŊąåƒã€‚", "image_quality": "品čŗĒ", "image_resolution": "č§ŖæžåēĻ", "image_resolution_description": "čŧƒéĢ˜įš„č§ŖæžåēĻčƒŊäŋį•™æ›´å¤šį´°į¯€īŧŒäŊ†įˇ¨įĸŧæ™‚é–“æœƒæ›´é•ˇã€æĒ”æĄˆå¤§å°æœƒæ›´å¤§īŧŒä¸Ļ可čƒŊ降äŊŽæ‡‰į”¨į¨‹åŧįš„回應速åēĻ。", "image_settings": "åœ–į‰‡č¨­åŽš", "image_settings_description": "įŽĄį†į”ĸį”Ÿįš„åŊąåƒå“čŗĒčˆ‡č§ŖæžåēĻ", - "image_thumbnail_description": "į§ģ除中įšŧčŗ‡æ–™įš„å°åž‹į¸Žåœ–īŧŒäģĨᔍæ–ŧæĒĸčĻ–å¤§é‡į›¸į‰‡æ™‚äŊŋᔍīŧŒäž‹åĻ‚ä¸ģ時間čģ¸", + "image_thumbnail_description": "厞į§ģ除中įšŧčŗ‡æ–™įš„å°åž‹į¸Žåœ–īŧŒį”¨æ–ŧæĒĸčĻ–å¤šåŧĩᛏቇīŧˆåĻ‚ä¸ģ時間čģ¸īŧ‰", "image_thumbnail_quality_description": "į¸Žåœ–å“čŗĒį¯„åœį‚ē 1 到 100。數å€ŧčļŠéĢ˜å“čŗĒčļŠåĨŊīŧŒäŊ†æĒ”æĄˆä🿜ƒæ›´å¤§īŧŒä¸Ļ可čƒŊ降äŊŽæ‡‰į”¨į¨‹åŧįš„回應速åēĻ。", "image_thumbnail_title": "į¸Žåœ–č¨­åŽš", "import_config_from_json_description": "é€éŽä¸Šå‚ŗ JSON č¨­åŽšæĒ”匯å…Ĩįŗģįĩąč¨­åޚ", @@ -160,7 +160,7 @@ "machine_learning_facial_recognition": "äēē臉辨識", "machine_learning_facial_recognition_description": "åĩæ¸Ŧã€čž¨č­˜ä¸Ļå°åœ–į‰‡ä¸­įš„č‡‰å­”åˆ†éĄž", "machine_learning_facial_recognition_model": "äēēč‡‰čž¨č­˜æ¨Ąåž‹", - "machine_learning_facial_recognition_model_description": "æ¨Ąåž‹é †åēį”ąå¤§č‡ŗå°æŽ’列。čŧƒå¤§įš„æ¨Ąåž‹é€ŸåēĻčŧƒæ…ĸ且äŊ”ᔍčŧƒå¤šč¨˜æ†ļéĢ”īŧŒäŊ†æ•ˆæžœčŧƒäŊŗã€‚čĢ‹æŗ¨æ„īŧŒæ›´æ›æ¨Ąåž‹åžŒåŋ…須對所有åŊąåƒé‡æ–°åŸˇčĄŒã€Œč‡‰å­”åĩæ¸Ŧ」äģģ務。", + "machine_learning_facial_recognition_model_description": "æ¨Ąåž‹é †åēį”ąå¤§č‡ŗå°æŽ’列。čŧƒå¤§įš„æ¨Ąåž‹é€ŸåēĻčŧƒæ…ĸ且äŊ”ᔍčŧƒå¤šč¨˜æ†ļéĢ”īŧŒäŊ†įĩæžœčŧƒäŊŗã€‚čĢ‹æŗ¨æ„īŧŒæ›´æ›æ¨Ąåž‹åžŒåŋ…須對所有åŊąåƒé‡æ–°åŸˇčĄŒã€Œč‡‰å­”åĩæ¸Ŧ」äģģ務。", "machine_learning_facial_recognition_setting": "å•Ÿį”¨äēē臉辨識", "machine_learning_facial_recognition_setting_description": "č‹Ĩåœį”¨īŧŒåŊąåƒå°‡ä¸æœƒé€˛čĄŒäēēč‡‰čž¨č­˜įˇ¨įĸŧīŧŒä¸”「æŽĸį´ĸ」頁éĸįš„ã€Œäēēį‰Šã€å€åĄŠå°‡ä¸æœƒéĄ¯į¤ēäģģäŊ•內厚。", "machine_learning_max_detection_distance": "åĩæ¸Ŧ距é›ĸ上限", @@ -173,7 +173,7 @@ "machine_learning_min_recognized_faces_description": "åģēįĢ‹æ–°äēēį‰Šæ‰€éœ€įš„æœ€äŊŽåˇ˛čž¨č­˜č‡‰å­”數量。提éĢ˜æ­¤æ•¸å€ŧå¯čŽ“č‡‰å­”čž¨č­˜æ›´į˛žįĸēīŧŒäŊ†åŒæ™‚會åĸžåР臉孔æœĒčĸĢæŒ‡æ´žįĩĻäģģäŊ•äēēį‰Šįš„å¯čƒŊ性。", "machine_learning_ocr": "æ–‡å­—čž¨č­˜(OCR)", "machine_learning_ocr_description": "äŊŋį”¨æŠŸå™¨å­¸įŋ’čž¨č­˜åŊąåƒä¸­įš„æ–‡å­—", - "machine_learning_ocr_enabled": "å•Ÿį”¨OCR", + "machine_learning_ocr_enabled": "å•Ÿį”¨ OCR", "machine_learning_ocr_enabled_description": "č‹Ĩåœį”¨īŧŒåŊąåƒå°‡ä¸æœƒé€˛čĄŒæ–‡å­—čž¨č­˜ã€‚", "machine_learning_ocr_max_resolution": "æœ€å¤§č§ŖæžåēĻ", "machine_learning_ocr_max_resolution_description": "č§ŖæžåēĻé̘æ–ŧæ­¤å€ŧįš„é čĻŊåŊąåƒå°‡åœ¨äŋæŒé•ˇå¯Ŧæ¯”įš„æƒ…æŗä¸‹čĒŋ整大小。數å€ŧčļŠé̘čē–įĸēīŧŒäŊ†č™•į†æ™‚é–“æ›´é•ˇä¸”æœƒäŊ”į”¨æ›´å¤šč¨˜æ†ļéĢ”ã€‚", @@ -181,7 +181,7 @@ "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": "OCR æ¨Ąåž‹", "machine_learning_ocr_model_description": "äŧ翜å™¨æ¨Ąåž‹æ¯”čĄŒå‹•čŖįŊŽæ¨Ąåž‹æ›´æē–įĸēīŧŒäŊ†č™•į†æ™‚é–“čŧƒé•ˇä¸”會äŊ”į”¨æ›´å¤šč¨˜æ†ļéĢ”ã€‚", "machine_learning_settings": "抟器學įŋ’設åޚ", "machine_learning_settings_description": "įŽĄį†æŠŸå™¨å­¸įŋ’įš„åŠŸčƒŊå’Œč¨­åŽš", @@ -257,7 +257,7 @@ "notification_email_password_description": "ᔍæ–ŧ與é›ģ子éƒĩäģļäŧ翜å™¨éŠ—č­‰įš„å¯†įĸŧ", "notification_email_port_description": "é›ģ子éƒĩäģļäŧ翜å™¨įš„逪æŽĨ埠īŧˆäž‹åĻ‚ 25、465 或 587īŧ‰", "notification_email_secure": "SMTPS", - "notification_email_secure_description": "äŊŋᔍSMTPSīŧˆåŸēæ–ŧTLSįš„SMTPīŧ‰", + "notification_email_secure_description": "äŊŋᔍ SMTPSīŧˆåŸēæ–ŧ TLS įš„ SMTPīŧ‰", "notification_email_sent_test_email_button": "傺送æ¸ŦčŠĻé›ģ子éƒĩäģļä¸Ļå„˛å­˜", "notification_email_setting_description": "寄送é›ģ子éƒĩäģļ通įŸĨįš„č¨­åŽš", "notification_email_test_email": "傺送æ¸ŦčŠĻé›ģ子éƒĩäģļ", @@ -281,11 +281,11 @@ "oauth_role_claim_description": "æ šæ“šæ­¤åŽŖå‘Šįš„å­˜åœ¨īŧŒč‡Ē動授äēˆįŽĄį†å“ĄæŦŠé™ã€‚čŠ˛åŽŖå‘Šįš„å€ŧ可äģĨ是 'user' 或 'admin'。", "oauth_settings": "OAuth", "oauth_settings_description": "įŽĄį† OAuth į™ģå…Ĩč¨­åŽš", - "oauth_settings_more_details": "æŦ˛įž­č§Ŗæ­¤åŠŸčƒŊīŧŒčĢ‹åƒé–ą čĒĒæ˜Žæ›¸ã€‚", + "oauth_settings_more_details": "č‹ĨčĻįž­č§Ŗæ­¤åŠŸčƒŊįš„čŠŗį´°čŗ‡č¨ŠīŧŒčĢ‹åƒé–ą čĒĒæ˜Žæ–‡äģļ。", "oauth_storage_label_claim": "å„˛å­˜æ¨™įą¤åŽŖå‘Š", - "oauth_storage_label_claim_description": "č‡Ē動將äŊŋį”¨č€…įš„å„˛å­˜æ¨™įą¤åŽšį‚ēæ­¤åŽŖå‘Šäš‹å€ŧ。", + "oauth_storage_label_claim_description": "č‡Ē動將äŊŋį”¨č€…įš„å„˛å­˜æ¨™įą¤č¨­åŽšį‚ēæ­¤åŽŖå‘Šäš‹å€ŧ。", "oauth_storage_quota_claim": "å„˛å­˜é…éĄåŽŖå‘Š", - "oauth_storage_quota_claim_description": "č‡Ē動將äŊŋį”¨č€…įš„å„˛å­˜é…éĄåŽšį‚ēæ­¤åŽŖå‘Šäš‹å€ŧ。", + "oauth_storage_quota_claim_description": "č‡Ē動將äŊŋį”¨č€…įš„å„˛å­˜é…éĄč¨­åŽšį‚ēæ­¤åŽŖå‘Šäš‹å€ŧ。", "oauth_storage_quota_default": "é č¨­å„˛å­˜é…éĄīŧˆGiBīŧ‰", "oauth_storage_quota_default_description": "æœĒæäž›åŽŖå‘Šæ™‚æ‰€äŊŋį”¨įš„é…éĄīŧˆGiBīŧ‰ã€‚", "oauth_timeout": "čĢ‹æą‚é€žæ™‚", @@ -297,8 +297,8 @@ "paths_validated_successfully": "æ‰€æœ‰čˇ¯åž‘éŠ—č­‰æˆåŠŸ", "person_cleanup_job": "æ¸…į†äēēį‰Š", "queue_details": "äŊ‡åˆ—čŗ‡č¨Š", - "queues": "äģģå‹™æŽ’į¨‹", - "queues_page_description": "åēåˆ—æŽ’į¨‹įŽĄį†į•Œéĸ", + "queues": "äģģ務äŊ‡åˆ—", + "queues_page_description": "įŽĄį†å“Ąäģģ務äŊ‡åˆ—頁éĸ", "quota_size_gib": "é…éĄå¤§å°īŧˆGiBīŧ‰", "refreshing_all_libraries": "æ­Ŗåœ¨é‡æ–°æ•´į†æ‰€æœ‰åĒ’éĢ”åēĢ", "registration": "įŽĄį†č€…č¨ģ冊", @@ -320,8 +320,8 @@ "server_welcome_message": "æ­ĄčŋŽč¨Šæ¯", "server_welcome_message_description": "在į™ģå…Ĩ頁éĸéĄ¯į¤ēįš„č¨Šæ¯ã€‚", "settings_page_description": "įŽĄį†č¨­åŽšé éĸ", - "sidecar_job": "側æŽĨæĒ”æĄˆä¸­įšŧčŗ‡æ–™", - "sidecar_job_description": "åžžæĒ”æĄˆįŗģįĩąåĩæ¸Ŧ或同æ­Ĩ側æŽĨæĒ”æĄˆä¸­įšŧčŗ‡æ–™", + "sidecar_job": "附åąŦæĒ”æĄˆä¸­įšŧčŗ‡æ–™", + "sidecar_job_description": "åžžæĒ”æĄˆįŗģįĩąåĩæ¸Ŧ或同æ­Ĩ附åąŦæĒ”æĄˆä¸­įšŧčŗ‡æ–™", "slideshow_duration_description": "每åŧĩåœ–į‰‡æ”žæ˜ įš„į§’æ•¸", "smart_search_job_description": "å°é …į›ŽåŸˇčĄŒæŠŸå™¨å­¸įŋ’äģĨ支援æ™ē慧搜尋", "storage_template_date_time_description": "æĒ”æĄˆįš„åģēįĢ‹æ™‚é–“æˆŗæœƒį”¨æ–ŧæ—ĨæœŸčˆ‡æ™‚é–“čŗ‡č¨Š", @@ -411,7 +411,7 @@ "transcoding_tone_mapping": "色čĒŋ對映", "transcoding_tone_mapping_description": "在將 HDR åŊąį‰‡čŊ‰æ›į‚ē SDR 時īŧŒį›Ąé‡įļ­æŒåŽŸå§‹č§€æ„Ÿã€‚æ¯į¨Žæŧ”įŽ—æŗ•åœ¨č‰˛åŊŠã€į´°į¯€å’ŒäēŽåēĻæ–šéĸéƒŊæœ‰ä¸åŒįš„æŦŠčĄĄã€‚Hable äŋį•™į´°į¯€īŧŒMobius äŋį•™č‰˛åŊŠīŧŒReinhard äŋį•™äēŽåēĻ。", "transcoding_transcode_policy": "čŊ‰įĸŧį­–į•Ĩ", - "transcoding_transcode_policy_description": "åŊąį‰‡čŊ‰įĸŧį­–į•Ĩ。HDR åŊąį‰‡ä¸€åž‹æœƒé€˛čĄŒčŊ‰įĸŧīŧˆé™¤éžåœį”¨čŊ‰įĸŧ功čƒŊīŧ‰ã€‚", + "transcoding_transcode_policy_description": "åŊąį‰‡čŊ‰įĸŧį­–į•Ĩ。HDR åŊąį‰‡å’Œåƒį´ æ ŧåŧä¸æ˜¯ YUV 4:2:0 įš„åŊąį‰‡ä¸€åž‹æœƒé€˛čĄŒčŊ‰įĸŧīŧˆé™¤éžåœį”¨čŊ‰įĸŧ功čƒŊīŧ‰ã€‚", "transcoding_two_pass_encoding": "兊階æŽĩᎍįĸŧ", "transcoding_two_pass_encoding_setting_description": "åŸˇčĄŒå…ŠæŦĄįˇ¨įĸŧäģĨį”ĸį”Ÿå“čŗĒ更äŊŗįš„åŊąį‰‡ã€‚å•Ÿį”¨æœ€å¤§äŊå…ƒé€ŸįŽ‡æ™‚īŧˆH.264 與 HEVC åŋ…é ˆå•Ÿį”¨īŧ‰īŧŒæ­¤æ¨Ąåŧæœƒäžæœ€å¤§äŊå…ƒé€ŸįއčĒŋæ•´į¯„åœä¸ĻåŋŊį•Ĩ CRF。č‹Ĩį‚ē VP9īŧŒå‰‡å¯åœ¨åœį”¨æœ€å¤§äŊå…ƒé€ŸįŽ‡æ™‚äŊŋᔍ CRF。", "transcoding_video_codec": "åŊąį‰‡įˇ¨č§Ŗįĸŧ器", @@ -428,8 +428,8 @@ "user_delete_delay": "{user} įš„å¸ŗč™Ÿå’Œé …į›Žæœƒåœ¨ {delay, plural, one {# 夊} other {# 夊}} 垌永䚅åˆĒ除。", "user_delete_delay_settings": "åģļ垌åˆĒ除", "user_delete_delay_settings_description": "č‡Ēį§ģ除垌čĩˇįŽ—įš„å¤Šæ•¸īŧŒé€žæœŸåžŒå°‡æ°¸äš…åˆĒ除äŊŋį”¨č€…å¸ŗč™Ÿčˆ‡é …į›Žã€‚äŊŋᔍ者åˆĒ除äŊœæĨ­æœƒåœ¨æ¯æ—Ĩåˆå¤œåŸˇčĄŒīŧŒäģĨæĒĸæŸĨįŦĻ合åˆĒ除æĸäģļįš„å¸ŗč™Ÿã€‚æ­¤č¨­åŽšįš„čŽŠæ›´å°‡åœ¨ä¸‹ä¸€æŦĄåŸˇčĄŒæ™‚į”Ÿæ•ˆã€‚", - "user_delete_immediately": "{user} įš„å¸ŗč™Ÿčˆ‡é …į›Žå°‡ įĢ‹åŗ 排å…Ĩ永䚅åˆĒ除åēåˆ—。", - "user_delete_immediately_checkbox": "įĢ‹åŗå°‡äŊŋį”¨č€…čˆ‡é …į›ŽæŽ’å…Ĩ永䚅åˆĒ除åēåˆ—", + "user_delete_immediately": "{user} įš„å¸ŗč™Ÿčˆ‡é …į›Žå°‡ įĢ‹åŗ 排å…Ĩ永䚅åˆĒ除äŊ‡åˆ—。", + "user_delete_immediately_checkbox": "įĢ‹åŗå°‡äŊŋį”¨č€…čˆ‡é …į›ŽæŽ’å…Ĩ永䚅åˆĒ除äŊ‡åˆ—", "user_details": "äŊŋį”¨č€…čŠŗį´°čŗ‡č¨Š", "user_management": "äŊŋį”¨č€…įŽĄį†", "user_password_has_been_reset": "äŊŋᔍ者坆įĸŧåˇ˛é‡č¨­īŧš", @@ -441,7 +441,7 @@ "user_successfully_removed": "åˇ˛æˆåŠŸåˆĒ除äŊŋᔍ者 {email}。", "users_page_description": "įŽĄį†äŊŋᔍ者頁éĸ", "version_check_enabled_description": "å•Ÿį”¨į‰ˆæœŦæĒĸæŸĨ", - "version_check_implications": "į‰ˆæœŦæĒĸæŸĨ功čƒŊäģ°čŗ´čˆ‡ github.com įš„åŽšæœŸé€šč¨Š", + "version_check_implications": "į‰ˆæœŦæĒĸæŸĨ功čƒŊäģ°čŗ´čˆ‡ {server} įš„åŽšæœŸé€šč¨Š", "version_check_settings": "į‰ˆæœŦæĒĸæŸĨ", "version_check_settings_description": "å•Ÿį”¨ / åœį”¨æ–°į‰ˆæœŦ通įŸĨ", "video_conversion_job": "åŊąį‰‡čŊ‰įĸŧ", @@ -493,7 +493,7 @@ "album_selected": "åˇ˛é¸å–į›¸į°ŋ", "album_share_no_users": "įœ‹äž†æ‚¨čˆ‡æ‰€æœ‰äŊŋį”¨č€…å…ąäēĢäē†é€™æœŦᛏį°ŋīŧŒæˆ–æ˛’æœ‰å…ļäģ–äŊŋį”¨č€…å¯äž›åˆ†äēĢ。", "album_summary": "ᛏį°ŋ摘čρ", - "album_updated": "æ›´æ–°į›¸į°ŋ時", + "album_updated": "ᛏį°ŋåˇ˛æ›´æ–°", "album_updated_setting_description": "į•ļå…ąäēĢᛏį°ŋæœ‰æ–°é …į›Žæ™‚į”¨é›ģ子éƒĩäģļ通įŸĨ我", "album_upload_assets": "åžžæ‚¨įš„é›ģč…Ļä¸Šå‚ŗæĒ”æĄˆä¸Ļ加å…Ĩᛏį°ŋ", "album_user_left": "é›ĸ開 {album}", @@ -508,11 +508,11 @@ "album_viewer_page_share_add_users": "邀čĢ‹å…ļäģ–äēē", "album_with_link_access": "äģģäŊ•æ“æœ‰é€Ŗįĩįš„äēēįš†å¯æĒĸčĻ–æ­¤į›¸į°ŋä¸­įš„į›¸į‰‡čˆ‡äēēį‰Šã€‚", "albums": "ᛏį°ŋ", - "albums_count": "{count, plural, one {{count, number} 個ᛏį°ŋ} other {{count, number} 個ᛏį°ŋ}}", + "albums_count": "{count, plural, one {{count, number} æœŦᛏį°ŋ} other {{count, number} æœŦᛏį°ŋ}}", "albums_default_sort_order": "預荭ᛏį°ŋ排åē", "albums_default_sort_order_description": "åģēįĢ‹æ–°į›¸į°ŋ時čĻåˆå§‹åŒ–é …į›ŽæŽ’åēæ–šåŧã€‚", "albums_feature_description": "å¯å…ąäēĢįĩĻå…ļäģ–äŊŋį”¨č€…įš„é …į›Žé›†åˆã€‚", - "albums_on_device_count": "æ­¤čŖįŊŽæœ‰ ({count}) 個ᛏį°ŋ", + "albums_on_device_count": "æ­¤čŖįŊŽæœ‰ ({count}) æœŦᛏį°ŋ", "albums_selected": "{count, plural, one {åˇ˛é¸å– # æœŦᛏį°ŋ} other {åˇ˛é¸å– # æœŦᛏį°ŋ}}", "all": "全部", "all_albums": "æ‰€æœ‰į›¸į°ŋ", @@ -591,7 +591,7 @@ "assets_added_to_album_count": "厞將 {count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}加å…Ĩ臺ᛏį°ŋ", "assets_added_to_albums_count": "厞將 {assetTotal, plural, other {# å€‹é …į›Ž}} 新åĸžč‡ŗ {albumTotal, plural, other {# æœŦᛏį°ŋ}}", "assets_cannot_be_added_to_album_count": "į„Ąæŗ•å°‡ {count, plural, one {é …į›Ž} other {é …į›Ž}} 加å…Ĩ臺ᛏį°ŋ", - "assets_cannot_be_added_to_albums": "į„Ąæŗ•å°‡ {count, plural, other {# å€‹é …į›Ž}} 加å…ĨäģģäŊ•ᛏį°ŋ", + "assets_cannot_be_added_to_albums": "į„Ąæŗ•å°‡ {count, plural, one {é …į›Ž} other {é …į›Ž}} 加å…ĨäģģäŊ•ᛏį°ŋ", "assets_count": "{count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}", "assets_deleted_permanently": "åˇ˛æ°¸äš…åˆĒ除 {count} å€‹é …į›Ž", "assets_deleted_permanently_from_server": "åˇ˛åžž Immich äŧ翜å™¨ä¸­æ°¸äš…į§ģ除 {count} å€‹é …į›Ž", @@ -608,21 +608,21 @@ "assets_trashed_count": "厞將 {count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}į§ģč‡ŗåžƒåœžæĄļ", "assets_trashed_from_server": "åˇ˛åžž Immich äŧ翜å™¨å°‡ {count} å€‹é …į›Žį§ģč‡ŗåžƒåœžæĄļ", "assets_were_part_of_album_count": "{count, plural, one {čŠ˛é …į›Žåˇ˛} other {這äē›é …į›Žåˇ˛}}åœ¨į›¸į°ŋ中", - "assets_were_part_of_albums_count": "{count, plural, one {個} other {個}}é …į›Žåˇ˛čĸĢå„˛å­˜åœ¨į›¸į°ŋ中", + "assets_were_part_of_albums_count": "{count, plural, one {čŠ˛é …į›Žåˇ˛} other {這äē›é …į›Žåˇ˛}}存在æ–ŧᛏį°ŋ中", "authorized_devices": "åˇ˛æŽˆæŦŠčŖįŊŽ", "automatic_endpoint_switching_subtitle": "į•ļå¯į”¨æ™‚īŧŒé€éŽæŒ‡åŽšįš„ Wi-Fi 在æœŦæŠŸé€ŖįˇšīŧŒå…ļäģ–æƒ…æŗå‰‡äŊŋᔍæ›ŋäģŖé€Ŗįˇš", "automatic_endpoint_switching_title": "č‡Ē動 URL 切換", "autoplay_slideshow": "č‡Ē動播攞åšģį‡ˆį‰‡", "back": "上一頁", "back_close_deselect": "回上一頁、關閉ä¸Ļ取æļˆé¸å–", - "background_backup_running_error": "垌č‡ē備äģŊį›Žå‰æ­Ŗåœ¨åŸˇčĄŒīŧŒį„Ąæŗ•啟動手動備äģŊ", + "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": "éģžä¸€ä¸‹äģĨ選取īŧŒéģžå…Šä¸‹äģĨ排除", - "backup_album_selection_page_assets_scatter": "é …į›Žå¯äģĨåˆ†æ•Ŗåœ¨å¤šå€‹į›¸į°ŋ中īŧŒå› æ­¤åœ¨å‚™äģŊéŽį¨‹ä¸­å¯äģĨé¸æ“‡į´å…Ĩæˆ–æŽ’é™¤į›¸į°ŋ。", + "backup_album_selection_page_assets_scatter": "é …į›Žå¯äģĨåˆ†æ•Ŗåœ¨å¤šæœŦᛏį°ŋ中īŧŒå› æ­¤åœ¨å‚™äģŊéŽį¨‹ä¸­å¯äģĨé¸æ“‡į´å…Ĩæˆ–æŽ’é™¤į›¸į°ŋ。", "backup_album_selection_page_select_albums": "é¸å–į›¸į°ŋ", "backup_album_selection_page_selection_info": "é¸å–čŗ‡č¨Š", "backup_album_selection_page_total_assets": "į¸Ŋä¸é‡č¤‡é …į›Žæ•¸", @@ -668,13 +668,13 @@ "backup_controller_page_remainder_sub": "é¸å–é …į›Žä¸­å°šæœĒ備äģŊįš„į›¸į‰‡čˆ‡åŊąį‰‡", "backup_controller_page_server_storage": "äŧ翜å™¨å„˛å­˜įŠē間", "backup_controller_page_start_backup": "開始備äģŊ", - "backup_controller_page_status_off": "前č‡ēč‡Ē動備äģŊåˇ˛é—œé–‰", - "backup_controller_page_status_on": "前č‡ēč‡Ē動備äģŊåˇ˛é–‹å•Ÿ", + "backup_controller_page_status_off": "前景č‡Ē動備äģŊåˇ˛é—œé–‰", + "backup_controller_page_status_on": "前景č‡Ē動備äģŊåˇ˛é–‹å•Ÿ", "backup_controller_page_storage_format": "{used} / {total} 厞äŊŋᔍ", "backup_controller_page_to_backup": "čρ備äģŊįš„į›¸į°ŋ", "backup_controller_page_total_sub": "åˇ˛é¸å–į›¸į°ŋä¸­įš„æ‰€æœ‰ä¸é‡č¤‡įš„į›¸į‰‡čˆ‡åŊąį‰‡", - "backup_controller_page_turn_off": "關閉前č‡ē備äģŊ", - "backup_controller_page_turn_on": "開啟前č‡ē備äģŊ", + "backup_controller_page_turn_off": "關閉前景備äģŊ", + "backup_controller_page_turn_on": "開啟前景備äģŊ", "backup_controller_page_uploading_file_info": "ä¸Šå‚ŗä¸­įš„æĒ”æĄˆčŗ‡č¨Š", "backup_err_only_album": "不čƒŊį§ģé™¤å”¯ä¸€įš„į›¸į°ŋ", "backup_error_sync_failed": "同æ­Ĩå¤ąæ•—īŧŒį„Ąæŗ•處ᐆ備äģŊ。", @@ -685,7 +685,7 @@ "backup_manual_title": "ä¸Šå‚ŗį‹€æ…‹", "backup_options": "備äģŊ選項", "backup_options_page_title": "備äģŊ選項", - "backup_setting_subtitle": "įŽĄį†čƒŒæ™¯čˆ‡å‰č‡ēä¸Šå‚ŗč¨­åŽš", + "backup_setting_subtitle": "įŽĄį†čƒŒæ™¯čˆ‡å‰æ™¯ä¸Šå‚ŗč¨­åŽš", "backup_settings_subtitle": "įŽĄį†ä¸Šå‚ŗč¨­åŽš", "backup_upload_details_page_more_details": "éģžæ“ŠæŸĨįœ‹æ›´å¤ščŠŗį´°čŗ‡č¨Š", "backward": "į”ąčˆŠč‡ŗæ–°", @@ -751,7 +751,7 @@ "change_your_password": "čŽŠæ›´æ‚¨įš„å¯†įĸŧ", "changed_visibility_successfully": "åˇ˛æˆåŠŸčŽŠæ›´å¯čĻ‹æ€§", "charging": "充é›ģ", - "charging_requirement_mobile_backup": "垌č‡ē備äģŊčĻæą‚čŖįŊŽæ­Ŗåœ¨å……é›ģ", + "charging_requirement_mobile_backup": "čƒŒæ™¯å‚™äģŊčĻæą‚čŖįŊŽæ­Ŗåœ¨å……é›ģ", "check_corrupt_asset_backup": "æĒĸæŸĨææ¯€įš„å‚™äģŊé …į›Ž", "check_corrupt_asset_backup_button": "åŸˇčĄŒæĒĸæŸĨ", "check_corrupt_asset_backup_description": "åƒ…åœ¨åˇ˛é€Ŗįˇšč‡ŗ Wi-Fi ä¸”æ‰€æœ‰é …į›Žåˇ˛åŽŒæˆå‚™äģŊåžŒåŸˇčĄŒæ­¤æĒĸæŸĨã€‚æ­¤į¨‹åŧå¯čƒŊ需čĻæ•¸åˆ†é˜ã€‚", @@ -761,11 +761,11 @@ "city": "城市", "cleanup_confirm_description": "Immich į™ŧįžæœ‰ {count} å€‹é …į›ŽīŧˆåģēįĢ‹æ–ŧ {date} 䚋前īŧ‰åˇ˛åމ免備äģŊ臺äŧ翜å™¨ã€‚是åĻčĻåžžæ­¤čŖįŊŽä¸­åˆĒ除æœŦ抟副æœŦīŧŸ", "cleanup_confirm_prompt_title": "åžžæ­¤čŖįŊŽåˆĒ除īŧŸ", - "cleanup_deleted_assets": "厞將{count}é …į›Žį§ģåˆ°čŖįŊŽįš„垃圞æĄļčŖĄ", + "cleanup_deleted_assets": "厞將 {count} å€‹é …į›Žį§ģåˆ°čŖįŊŽįš„垃圞æĄļčŖĄ", "cleanup_deleting": "æ­Ŗåœ¨į§ģ動到垃圞æĄļ...", - "cleanup_found_assets": "扞到{count}äģļåˇ˛ä¸Šå‚ŗįš„é …į›Ž", - "cleanup_found_assets_with_size": "扞到{count}äģļīŧŒį¸Ŋå…ą({size})åˇ˛ä¸Šå‚ŗįš„é …į›Ž", - "cleanup_icloud_shared_albums_excluded": "iCloudå…ąäēĢᛏį°ŋčĸ̿ޒ除æ–ŧ搜尋䚋外", + "cleanup_found_assets": "扞到 {count} äģļåˇ˛ä¸Šå‚ŗįš„é …į›Ž", + "cleanup_found_assets_with_size": "扞到 {count} äģļīŧŒį¸Ŋå…ą ({size}) åˇ˛ä¸Šå‚ŗįš„é …į›Ž", + "cleanup_icloud_shared_albums_excluded": "iCloud å…ąäēĢᛏį°ŋčĸ̿ޒ除æ–ŧ搜尋䚋外", "cleanup_no_assets_found": "扞不到įŦĻ合上čŋ°æĸäģļįš„é …į›Žã€‚é‡‹æ”žįŠē間功čƒŊ僅čƒŊį§ģ除厞備äģŊ臺äŧ翜å™¨įš„é …į›Ž", "cleanup_preview_title": "{count} 項需čρį§ģé™¤įš„é …į›Ž", "cleanup_step3_description": "掃描įŦĻ合æ—ĨæœŸčˆ‡å„˛å­˜č¨­åŽšįš„åˇ˛å‚™äģŊé …į›Žã€‚", @@ -782,8 +782,8 @@ "client_cert_import": "匯å…Ĩ", "client_cert_import_success_msg": "厞匝å…ĨᔍæˆļįĢ¯æ†‘č­‰", "client_cert_invalid_msg": "į„Ąæ•ˆįš„æ†‘č­‰æĒ”æĄˆæˆ–å¯†įĸŧ錯čǤ", - "client_cert_password_message": "čĢ‹čŧ¸å…Ĩæ­¤č­‰æ›¸įš„å¯†įĸŧ", - "client_cert_password_title": "č­‰æ›¸å¯†įĸŧ", + "client_cert_password_message": "čĢ‹čŧ¸å…Ĩæ­¤æ†‘č­‰įš„å¯†įĸŧ", + "client_cert_password_title": "æ†‘č­‰å¯†įĸŧ", "client_cert_remove_msg": "ᔍæˆļįĢ¯æ†‘č­‰åˇ˛į§ģ除", "client_cert_subtitle": "僅支援 PKCS12 (.p12, .pfx) æ ŧåŧã€‚æ†‘č­‰åŒ¯å…Ĩ與į§ģ除僅可在į™ģå…Ĩå‰é€˛čĄŒ", "client_cert_title": "SSL ᔍæˆļįĢ¯æ†‘č­‰ [å¯Ļ銗性]", @@ -794,7 +794,7 @@ "color": "顏色", "color_theme": "色åŊŠä¸ģ題", "command": "å‘Ŋäģ¤", - "command_palette_prompt": "åŋĢ速尋扞頁éĸīŧŒå‹•äŊœæˆ–č€…æŒ‡äģ¤", + "command_palette_prompt": "åŋĢ速搜尋頁éĸ、動äŊœæˆ–指äģ¤", "command_palette_to_close": "關閉", "command_palette_to_navigate": "čŧ¸å…Ĩ", "command_palette_to_select": "選擇", @@ -837,7 +837,7 @@ "copy_password": "複čŖŊ密įĸŧ", "copy_to_clipboard": "複čŖŊ到å‰Ēč˛ŧį°ŋ", "country": "國åŽļ", - "cover": "封éĸ", + "cover": "åĄĢæģŋ", "covers": "封éĸ", "create": "åģēįĢ‹", "create_album": "åģēį̋ᛏį°ŋ", @@ -849,9 +849,12 @@ "create_link_to_share": "åģēįĢ‹åˆ†äēĢ逪įĩ", "create_link_to_share_description": "æŒæœ‰é€Ŗįĩįš„äēēįš†å¯æĒĸčĻ–æ‰€é¸é …į›Ž", "create_new": "新åĸž", + "create_new_face": "åģēįĢ‹æ–°č‡‰å­”", "create_new_person": "åģēįĢ‹æ–°äēēį‰Š", "create_new_person_hint": "å°‡é¸å–įš„é …į›ŽæŒ‡æ´žįĩĻæ–°įš„äēēį‰Š", "create_new_user": "åģēįĢ‹æ–°äŊŋᔍ者", + "create_person": "åģēįĢ‹äēēį‰Š", + "create_person_subtitle": "į‚翉€é¸č‡‰å­”æ–°åĸžåå­—äģĨåģēįĢ‹å’Œæ¨™č¨˜æ–°äēēį‰Š", "create_shared_album_page_share_add_assets": "新åĸžé …į›Ž", "create_shared_album_page_share_select_photos": "é¸å–į›¸į‰‡", "create_shared_link": "åģēįĢ‹åˆ†äēĢ逪įĩ", @@ -866,13 +869,14 @@ "crop_aspect_ratio_fixed": "厞äŋŽåžŠ", "crop_aspect_ratio_free": "į„Ąé™åˆļ", "crop_aspect_ratio_original": "原æĒ”", + "crop_aspect_ratio_square": "æ–šåŊĸ", "curated_object_page_title": "äē‹į‰Š", "current_device": "į›Žå‰čŖįŊŽ", "current_pin_code": "į›Žå‰ PIN įĸŧ", "current_server_address": "į›Žå‰įš„äŧ翜å™¨äŊå€", "custom_date": "åĻ選æ—Ĩ期", "custom_locale": "č‡Ēč¨‚åœ°å€č¨­åŽš", - "custom_locale_description": "栚據čĒžč¨€čˆ‡åœ°å€æ ŧåŧåŒ–æ—ĨæœŸčˆ‡æ•¸å­—", + "custom_locale_description": "栚據選厚čĒžč¨€čˆ‡åœ°å€æ ŧåŧåŒ–æ—ĨæœŸã€æ™‚é–“čˆ‡æ•¸å­—", "custom_url": "č‡Ē訂 URL", "cutoff_date_description": "äŋį•™æœ€čŋ‘å¤šå°‘å¤Šįš„į›¸į‰‡â€Ļ", "cutoff_day": "{count, plural, one {夊} other {夊}}", @@ -880,7 +884,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "YYYY åš´ M 月 D æ—Ĩ (E)", "dark": "æˇąč‰˛", - "dark_theme": "åˆ‡æ›æˇąč‰˛ä¸ģ題", + "dark_theme": "åˆ‡æ›č‡ŗæˇąč‰˛ä¸ģ題", "date": "æ—Ĩ期", "date_after": "čĩˇå§‹æ—Ĩ期", "date_and_time": "æ—ĨæœŸčˆ‡æ™‚é–“", @@ -891,10 +895,8 @@ "day": "æ—Ĩ", "days": "æ—Ĩ", "deduplicate_all": "åˆĒé™¤æ‰€æœ‰é‡č¤‡é …į›Ž", - "deduplication_criteria_1": "åŊąåƒå¤§å°īŧˆäģĨäŊå…ƒįĩ„į‚ēå–ŽäŊīŧ‰", - "deduplication_criteria_2": "EXIF čŗ‡æ–™æ•¸é‡", - "deduplication_info": "é‡č¤‡čŗ‡æ–™åˆĒé™¤čŗ‡č¨Š", - "deduplication_info_description": "č‹Ĩčρč‡Ēå‹•é å…ˆé¸å–é …į›Žä¸Ļ扚æŦĄį§ģé™¤é‡č¤‡é …į›ŽīŧŒæˆ‘們會æĒĸæŸĨīŧš", + "default_locale": "預設čĒžč¨€", + "default_locale_description": "äŊŋᔍäŊ įš„į€čĻŊ器區域äģĨæ ŧåŧæ—Ĩ期和數字", "delete": "åˆĒ除", "delete_action_confirmation_message": "您įĸē厚čρåˆĒé™¤æ­¤é …į›Žå—ŽīŧŸæ­¤å‹•äŊœæœƒå°‡čŠ˛é …į›Žį§ģ臺äŧ翜å™¨įš„垃圞æĄļīŧŒä¸ĻčŠĸ問您是åĻčρ圍æœŦ抟同æ­ĨåˆĒ除", "delete_action_prompt": "{count} 個厞åˆĒ除", @@ -966,11 +968,11 @@ "download_waiting_to_retry": "į­‰åž…é‡čŠĻ", "downloading": "下čŧ‰ä¸­", "downloading_asset_filename": "æ­Ŗåœ¨ä¸‹čŧ‰é …į›Ž {filename}", - "downloading_from_icloud": "æ­ŖåžžiCloud下čŧ‰", + "downloading_from_icloud": "æ­Ŗåžž iCloud 下čŧ‰", "downloading_media": "æ­Ŗåœ¨ä¸‹čŧ‰åĒ’éĢ”", "drop_files_to_upload": "將æĒ”æĄˆæ‹–æ”žåˆ°äģģäŊ•äŊįŊŽäģĨä¸Šå‚ŗ", "duplicates": "é‡č¤‡é …į›Ž", - "duplicates_description": "逐一æĒĸæŸĨæ¯å€‹įž¤įĩ„īŧŒä¸Ļ標į¤ēå…ļ中是åĻæœ‰é‡č¤‡é …į›Ž", + "duplicates_description": "逐一æĒĸæŸĨæ¯å€‹įž¤įĩ„īŧŒä¸Ļ標į¤ēå…ļ中是åĻæœ‰é‡č¤‡é …į›Žã€‚", "duration": "éĄ¯į¤ēæ™‚é•ˇ", "edit": "ᎍčŧ¯", "edit_album": "ᎍčŧ¯į›¸į°ŋ", @@ -1007,10 +1009,12 @@ "editor_edits_applied_success": "åˇ˛æˆåŠŸåĨ—ᔍᎍčŧ¯", "editor_flip_horizontal": "æ°´åšŗįŋģčŊ‰", "editor_flip_vertical": "åž‚į›´įŋģčŊ‰", + "editor_handle_corner": "{corner, select, top_left {åˇĻ上角} top_right {åŗä¸Šč§’} bottom_left {åˇĻ下角} bottom_right {åŗä¸‹č§’} other {某個}}角čŊįš„æŽ§åˆļ手柄", + "editor_handle_edge": "{edge, select, top {頂部} bottom {åē•部} left {åˇĻ側} right {åŗå´} other {某個}} é‚ŠįˇŖįš„æŽ§åˆļ手柄", "editor_orientation": "斚向", "editor_reset_all_changes": "é‡č¨­čŽŠæ›´", - "editor_rotate_left": "逆時針旋čŊ‰90åēĻ", - "editor_rotate_right": "順時針旋čŊ‰90åēĻ", + "editor_rotate_left": "逆時針旋čŊ‰ 90 åēĻ", + "editor_rotate_right": "順時針旋čŊ‰ 90 åēĻ", "email": "é›ģ子éƒĩäģļ", "email_notifications": "é›ģ子éƒĩäģļ通įŸĨ", "empty_folder": "é€™å€‹čŗ‡æ–™å¤žæ˜¯įŠēįš„", @@ -1021,7 +1025,7 @@ "enable_biometric_auth_description": "čŧ¸å…Ĩæ‚¨įš„ PIN įĸŧäģĨå•Ÿį”¨į”Ÿį‰Ščž¨č­˜éŠ—č­‰", "enabled": "åˇ˛å•Ÿį”¨", "end_date": "įĩæŸæ—Ĩ期", - "enqueued": "åˇ˛æŽ’å…Ĩåēåˆ—", + "enqueued": "åˇ˛æŽ’å…ĨäŊ‡åˆ—", "enter_wifi_name": "čŧ¸å…Ĩ Wi-Fi åį¨ą", "enter_your_pin_code": "čŧ¸å…Ĩæ‚¨įš„ PIN įĸŧ", "enter_your_pin_code_subtitle": "čŧ¸å…Ĩæ‚¨įš„ PIN įĸŧäģĨå­˜å–ã€Œåˇ˛éŽ–åŽšã€čŗ‡æ–™å¤ž", @@ -1072,7 +1076,7 @@ "failed_to_update_notification_status": "į„Ąæŗ•æ›´æ–°é€šįŸĨį‹€æ…‹", "incorrect_email_or_password": "é›ģ子éƒĩäģ￈–密įĸŧ錯čǤ", "library_folder_already_exists": "此匯å…Ĩčˇ¯åž‘åˇ˛å­˜åœ¨ã€‚", - "page_not_found": "æœĒ扞到頁éĸ :/", + "page_not_found": "æœĒ扞到頁éĸ", "paths_validation_failed": "{paths, plural, one {# å€‹čˇ¯åž‘} other {# å€‹čˇ¯åž‘}} éŠ—č­‰å¤ąæ•—", "profile_picture_transparent_pixels": "個äēēčŗ‡æ–™åœ–į‰‡ä¸čƒŊ有透明į•Ģį´ ã€‚čĢ‹æ”žå¤§ä¸Ļ/或į§ģ動åŊąåƒã€‚", "quota_higher_than_disk_size": "æ‚¨č¨­åŽšįš„é…éĄå¤§æ–ŧ᪁įĸŸåŽšé‡", @@ -1343,11 +1347,11 @@ "ios_debug_info_processing_ran_at": "æ–ŧ {dateTime} åŸˇčĄŒč™•į†", "items_count": "{count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}", "jobs": "äģģ務", - "json_editor": "JSONᎍčŧ¯å™¨", - "json_error": "JSON錯čǤ", + "json_editor": "JSON ᎍčŧ¯å™¨", + "json_error": "JSON 錯čǤ", "keep": "äŋį•™", "keep_albums": "äŋį•™į›¸į°ŋ", - "keep_albums_count": "äŋį•™{count} {count, plural, one {個ᛏį°ŋ} other {個ᛏį°ŋ}}", + "keep_albums_count": "äŋį•™{count} {count, plural, one {æœŦᛏį°ŋ} other {æœŦᛏį°ŋ}}", "keep_all": "全部äŋį•™", "keep_description": "é¸æ“‡åŸˇčĄŒé‡‹æ”žįŠē間時čρäŋį•™åœ¨čŖįŊŽä¸Šįš„é …į›Žã€‚", "keep_favorites": "äŋį•™æœ€æ„›įš„ᛏቇ", @@ -1355,7 +1359,7 @@ "keep_on_device_hint": "選擇äŋį•™åœ¨čŖįŊŽä¸Šįš„ᛏቇ", "keep_this_delete_others": "äŋį•™é€™å€‹īŧŒåˆĒ除å…ļäģ–", "keeping": "äŋį•™:{items}", - "kept_this_deleted_others": "äŋį•™é€™å€‹é …į›Žä¸ĻåˆĒ除{count, plural, one {# asset} other {# assets}}", + "kept_this_deleted_others": "äŋį•™é€™å€‹é …į›Žä¸ĻåˆĒ除{count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}", "keyboard_shortcuts": "éĩᛤåŋĢæˇéĩ", "language": "čĒžč¨€", "language_no_results_subtitle": "čŠĻ著čĒŋæ•´æ‚¨įš„æœå°‹čŠžåŊ™", @@ -1385,9 +1389,11 @@ "library_page_sort_title": "ᛏį°ŋæ¨™éĄŒ", "licenses": "授æŦŠ", "light": "æˇē色", + "light_theme": "åˆ‡æ›č‡ŗæˇē色ä¸ģ題", "like": "å–œæ­Ą", "like_deleted": "åˇ˛å–æļˆå–œæ­Ą", "link_motion_video": "逪įĩå‹•æ…‹åŊąį‰‡", + "link_to_docs": "čĢ‹åƒé–ą čĒĒæ˜Žæ–‡äģļ äģĨį˛å–æ›´å¤ščŗ‡č¨Šã€‚", "link_to_oauth": "逪įĩ OAuth", "linked_oauth_account": "厞逪įĩ OAuth å¸ŗč™Ÿ", "list": "清喎", @@ -1396,7 +1402,7 @@ "local": "æœŦ抟", "local_asset_cast_failed": "į„Ąæŗ•æŠ•æ”žæœĒä¸Šå‚ŗč‡ŗäŧ翜å™¨įš„é …į›Ž", "local_assets": "æœŦæŠŸé …į›Ž", - "local_id": "æœŦ地ID", + "local_id": "æœŦ地 ID", "local_media_summary": "æœŦ抟åĒ’éĢ”æ‘˜čρ", "local_network": "æœŦ抟įļ˛čˇ¯", "local_network_sheet_info": "į•ļäŊŋį”¨æŒ‡åŽšįš„ Wi-Fi įļ˛čˇ¯æ™‚īŧŒæ‡‰į”¨į¨‹åŧå°‡é€éŽæ­¤įļ˛å€é€Ŗįˇšč‡ŗäŧ翜å™¨", @@ -1485,14 +1491,14 @@ "manage_your_devices": "įŽĄį†åˇ˛į™ģå…Ĩįš„čŖįŊŽ", "manage_your_oauth_connection": "įŽĄį†æ‚¨įš„ OAuth 逪įĩ", "map": "地圖", - "map_assets_in_bounds": "{count, plural, one {# åŧĩᛏቇ} other {# åŧĩᛏቇ}}", + "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_marker_for_images": "在 {city}、{country} 拍攝åŊąåƒįš„åœ°åœ–æ¨™č¨˜", + "map_marker_with_image": "å¸ļ有åŊąåƒįš„åœ°åœ–æ¨™č¨˜", "map_no_location_permission_content": "需čρäŊįŊŽæŦŠé™æ‰čƒŊéĄ¯į¤ēčˆ‡æ‚¨į›Žå‰äŊįŊŽį›¸é—œįš„é …į›Žã€‚čĻįžåœ¨å°ąæŽˆäēˆäŊįŊŽæŦŠé™å—ŽīŧŸ", "map_no_location_permission_title": "æ˛’æœ‰äŊįŊŽæŦŠé™", "map_settings": "åœ°åœ–č¨­åŽš", @@ -1550,7 +1556,7 @@ "move_to_locked_folder_confirmation": "這äē›į›¸į‰‡čˆ‡åŊąį‰‡å°‡åžžæ‰€æœ‰į›¸į°ŋ中į§ģ除īŧŒä¸”僅čƒŊåžžã€Œåˇ˛éŽ–åŽšã€čŗ‡æ–™å¤žä¸­æĒĸčĻ–", "move_up": "向上į§ģ動", "moved_to_archive": "厞封存 {count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}}", - "moved_to_library": "厞į§ģ動 {count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}} 臺ᛏį°ŋ", + "moved_to_library": "厞į§ģ動 {count, plural, one {# å€‹é …į›Ž} other {# å€‹é …į›Ž}} 臺åĒ’éĢ”åēĢ", "moved_to_trash": "åˇ˛ä¸Ÿé€˛åžƒåœžæĄļ", "multiselect_grid_edit_date_time_err_read_only": "å”¯čŽ€é …į›Žįš„æ—ĨæœŸį„Ąæŗ•įˇ¨čŧ¯īŧŒåˇ˛į•Ĩ過", "multiselect_grid_edit_gps_err_read_only": "å”¯čŽ€é …į›Žįš„äŊįŊŽčŗ‡č¨Šį„Ąæŗ•ᎍčŧ¯īŧŒåˇ˛į•Ĩ過", @@ -1559,12 +1565,12 @@ "name": "åį¨ą", "name_or_nickname": "åį¨ąæˆ–æšąį¨ą", "name_required": "åį¨ąæ˜¯åŋ…åĄĢ項", - "navigate": "導čˆĒ", + "navigate": "導čĻŊ", "navigate_to_time": "莺čŊ‰č‡ŗæŒ‡åŽšæ™‚é–“", "network_requirement_photos_upload": "äŊŋį”¨čĄŒå‹•įļ˛čˇ¯æĩé‡å‚™äģŊᛏቇ", "network_requirement_videos_upload": "äŊŋį”¨čĄŒå‹•įļ˛čˇ¯æĩé‡å‚™äģŊåŊąį‰‡", "network_requirements": "įļ˛čˇ¯čĻæą‚", - "network_requirements_updated": "įļ˛čˇ¯éœ€æą‚åˇ˛čŽŠæ›´īŧŒæ­Ŗåœ¨é‡č¨­å‚™äģŊåēåˆ—", + "network_requirements_updated": "įļ˛čˇ¯éœ€æą‚åˇ˛čŽŠæ›´īŧŒæ­Ŗåœ¨é‡č¨­å‚™äģŊäŊ‡åˆ—", "networking_settings": "įļ˛čˇ¯", "networking_subtitle": "įŽĄį†äŧ翜å™¨į̝éģžč¨­åޚ", "never": "æ°¸ä¸å¤ąæ•ˆ", @@ -1588,7 +1594,7 @@ "no_albums_message": "åģēį̋ᛏį°ŋäž†æ•´į†į›¸į‰‡å’ŒåŊąį‰‡", "no_albums_with_name_yet": "įœ‹äž†é‚„æ˛’æœ‰é€™å€‹åå­—įš„į›¸į°ŋ。", "no_albums_yet": "įœ‹äž†æ‚¨é‚„æ˛’æœ‰äģģäŊ•ᛏį°ŋ。", - "no_archived_assets_message": "å°‡į›¸į‰‡čˆ‡åŊąį‰‡å°å­˜åžŒīŧŒå°ąä¸æœƒéĄ¯į¤ēåœ¨ã€Œį›¸į‰‡ã€čĻ–åœ–ä¸­", + "no_archived_assets_message": "å°‡į›¸į‰‡čˆ‡åŊąį‰‡å°å­˜åžŒīŧŒå°ąä¸æœƒéĄ¯į¤ēåœ¨ã€Œį›¸į‰‡ã€é éĸ中", "no_assets_message": "æŒ‰é€™čŖĄä¸Šå‚ŗæ‚¨įš„įŦŦ一åŧĩᛏቇ", "no_assets_to_show": "į„Ąé …į›Žåą•į¤ē", "no_cast_devices_found": "扞不到 Google Cast čŖįŊŽ", @@ -1649,6 +1655,7 @@ "only_favorites": "åƒ…éĄ¯į¤ēåˇąæ”ļ藏", "open": "開啟", "open_calendar": "打開æ—Ĩ曆", + "open_in_browser": "åœ¨į€čĻŊ器中開啟", "open_in_map_view": "開啟地圖æĒĸčĻ–", "open_in_openstreetmap": "ᔍ OpenStreetMap 開啟", "open_the_search_filters": "é–‹å•Ÿæœå°‹į¯Šé¸å™¨", @@ -1703,7 +1710,7 @@ "permanent_deletion_warning_setting_description": "在永䚅åˆĒ除æĒ”æĄˆæ™‚éĄ¯į¤ēč­Ļ告", "permanently_delete": "永䚅åˆĒ除", "permanently_delete_assets_count": "永䚅åˆĒ除 {count, plural, one {æĒ”æĄˆ} other {æĒ”æĄˆ}}", - "permanently_delete_assets_prompt": "įĸē厚čĻæ°¸äš…åˆĒ除 {count, plural, other {這 # 個æĒ”æĄˆīŧŸ}}é€™æ¨Ŗ{count, plural, one {厃} other {厃們}}䚟會垞č‡Ēåˇąæ‰€åœ¨įš„į›¸į°ŋ中æļˆå¤ąã€‚", + "permanently_delete_assets_prompt": "įĸē厚čĻæ°¸äš…åˆĒ除 {count, plural, one {這個æĒ”æĄˆīŧŸ} other {這 # 個æĒ”æĄˆīŧŸ}}é€™æ¨Ŗ{count, plural, one {厃} other {厃們}}䚟會垞č‡Ēåˇąæ‰€åœ¨įš„į›¸į°ŋ中æļˆå¤ąã€‚", "permanently_deleted_asset": "永䚅åˆĒé™¤įš„æĒ”æĄˆ", "permanently_deleted_assets_count": "永䚅åˆĒé™¤įš„ {count, plural, one {# 個æĒ”æĄˆ} other {# 個æĒ”æĄˆ}}", "permission": "æŦŠé™", @@ -1766,7 +1773,7 @@ "profile_drawer_app_logs": "į´€éŒ„", "profile_drawer_client_server_up_to_date": "ᔍæˆļįĢ¯čˆ‡äŧ翜å™¨į‰ˆæœŦįš†į‚ē最新", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "å”¯čŽ€æ¨Ąåŧåˇ˛å•Ÿį”¨ã€‚é•ˇæŒ‰äŊŋᔍ者個äēē圖į¤ēåŗå¯é€€å‡ē。", + "profile_drawer_readonly_mode": "å”¯čŽ€æ¨Ąåŧåˇ˛å•Ÿį”¨ã€‚é•ˇæŒ‰äŊŋᔍ者個äēē圖į¤ēåŗå¯é—œé–‰ã€‚", "profile_image_of_user": "{user} įš„å€‹äēēčŗ‡æ–™åœ–į‰‡", "profile_picture_set": "åˇ˛č¨­åŽšå€‹äēēčŗ‡æ–™åœ–į‰‡ã€‚", "public_album": "å…Ŧ開ᛏį°ŋ", @@ -1808,7 +1815,7 @@ "rate_asset": "é …į›ŽčŠ•åˆ†", "rating": "čŠ•æ˜Ÿ", "rating_clear": "æ¸…é™¤čŠ•į­‰", - "rating_count": "{count, plural, =0 {Unrated} other {# 星}}", + "rating_count": "{count, plural, =0 {æœĒčŠ•åˆ†} one {# 星} other {# 星}}", "rating_description": "åœ¨čŗ‡č¨Šéĸæŋä¸­éĄ¯į¤ē EXIF čŠ•į­‰", "reaction_options": "反應選項", "read_changelog": "閱čĻŊæ›´æ–°į´€éŒ„", @@ -1828,15 +1835,15 @@ "recently_taken_page_title": "最čŋ‘拍攝", "refresh": "é‡æ–°æ•´į†", "refresh_encoded_videos": "é‡æ–°æ•´į†åˇ˛įˇ¨įĸŧįš„åŊąį‰‡", - "refresh_faces": "重整éĸéƒ¨čŗ‡æ–™", + "refresh_faces": "é‡æ–°æ•´į†č‡‰å­”čŗ‡æ–™", "refresh_metadata": "é‡æ–°æ•´į†ä¸­įšŧčŗ‡æ–™", "refresh_thumbnails": "é‡æ–°æ•´į†į¸Žåœ–", "refreshed": "é‡æ–°æ•´į†åŽŒį•ĸ", "refreshes_every_file": "é‡æ–°čŽ€å–æ‰€æœ‰įžæœ‰čˆ‡æ–°åĸžæĒ”æĄˆ", "refreshing_encoded_video": "æ­Ŗåœ¨é‡æ–°æ•´į†åˇ˛įˇ¨įĸŧįš„åŊąį‰‡", - "refreshing_faces": "重整éĸéƒ¨čŗ‡æ–™ä¸­", + "refreshing_faces": "æ­Ŗåœ¨é‡æ–°æ•´į†č‡‰å­”čŗ‡æ–™", "refreshing_metadata": "æ­Ŗåœ¨é‡æ–°æ•´į†ä¸­įšŧčŗ‡æ–™", - "regenerating_thumbnails": "重新į”ĸį”Ÿį¸Žåœ–ä¸­", + "regenerating_thumbnails": "æ­Ŗåœ¨é‡æ–°į”ĸį”Ÿį¸Žåœ–", "remote": "遠į̝", "remote_assets": "遠įĢ¯é …į›Ž", "remote_media_summary": "遠į̝åĒ’éĢ”æ‘˜čρ", @@ -1865,8 +1872,8 @@ "removed_memory": "厞į§ģ除記æ†ļ", "removed_photo_from_memory": "åˇ˛åžžč¨˜æ†ļ中į§ģ除ᛏቇ", "removed_tagged_assets": "厞į§ģ除 {count, plural, one {# 個æĒ”æĄˆ} other {# 個æĒ”æĄˆ}}įš„æ¨™įą¤", - "rename": "攚名", - "repair": "įŗžæ­Ŗ", + "rename": "重新å‘Ŋ名", + "repair": "äŋŽåžŠ", "repair_no_results_message": "æœĒčĸĢčŋŊčš¤åŠéēå¤ąįš„æĒ”æĄˆæœƒéĄ¯į¤ēåœ¨é€™čŖĄ", "replace_with_upload": "į”¨ä¸Šå‚ŗįš„æĒ”æĄˆå–äģŖ", "repository": "å„˛å­˜åēĢ", @@ -1881,10 +1888,10 @@ "reset_pin_code_success": "PIN įĸŧåˇ˛æˆåŠŸé‡č¨­", "reset_pin_code_with_password": "您可隨時äŊŋį”¨æ‚¨įš„å¯†įĸŧ來重設 PIN įĸŧ", "reset_sqlite": "重設 SQLite čŗ‡æ–™åēĢ", - "reset_sqlite_clear_app_data": "清除數據", - "reset_sqlite_confirmation": "įĸē厚čĻé‡č¨­æ‰€æœ‰æ•¸æ“šå—ŽīŧŸäŊ įš„æ‰€æœ‰č¨­įŊŽå°‡čĸĢ重設īŧŒä¸”äŊ æœƒčĸĢį™ģå‡ē。", - "reset_sqlite_confirmation_note": "æŗ¨æ„īŧšäŊ éœ€čĻåœ¨æ¸…é™¤æ•¸æ“šåžŒé‡æ–°é–‹å•Ÿæ‡‰į”¨ã€‚", - "reset_sqlite_done": "æ•¸æ“šåˇ˛æ¸…é™¤ã€‚čĢ‹é‡å•ŸImmich及重新į™ģ錄。", + "reset_sqlite_clear_app_data": "æ¸…é™¤čŗ‡æ–™", + "reset_sqlite_confirmation": "įĸē厚čĻé‡č¨­æ‰€æœ‰čŗ‡æ–™å—ŽīŧŸäŊ įš„æ‰€æœ‰č¨­åŽšå°‡čĸĢ重設īŧŒä¸”äŊ æœƒčĸĢį™ģå‡ē。", + "reset_sqlite_confirmation_note": "æŗ¨æ„īŧšäŊ éœ€čĻåœ¨æ¸…é™¤čŗ‡æ–™åžŒé‡æ–°é–‹å•Ÿ App。", + "reset_sqlite_done": "čŗ‡æ–™åˇ˛æ¸…é™¤ã€‚čĢ‹é‡å•Ÿ Immich 及重新į™ģå…Ĩ。", "reset_sqlite_success": "åˇ˛æˆåŠŸé‡č¨­ SQLite čŗ‡æ–™åēĢ", "reset_to_default": "重設į‚ē預設å€ŧ", "resolution": "č§ŖæžåēĻ", @@ -1906,13 +1913,13 @@ "running": "åŸˇčĄŒä¸­", "save": "å„˛å­˜", "save_to_gallery": "å„˛å­˜åˆ°į›¸į°ŋ", - "saved": "厞äŋå­˜", + "saved": "åˇ˛å„˛å­˜", "saved_api_key": "åˇ˛å„˛å­˜ API 金鑰", "saved_profile": "åˇ˛å„˛å­˜å€‹äēēčŗ‡æ–™", "saved_settings": "åˇ˛å„˛å­˜č¨­åŽš", "say_something": "čĒĒčĒĒæ‚¨įš„æƒŗæŗ•吧", "scaffold_body_error_occurred": "į™ŧį”ŸéŒ¯čǤ", - "scaffold_body_error_unrecoverable": "į™ŧį”Ÿį„Ąæŗ•æĸåžŠįš„éŒ¯čĒ¤ã€‚čĢ‹åœ¨ Discord 或 Github 上分äēĢ錯čǤäŋĄæ¯åŠå †į–ŠčŋŊ蚤īŧŒäģĨäžŋ我們提䞛協劊。在čĸĢåģēč­°įš„æƒ…æŗä¸‹äŊ å¯äģĨ在下斚嘗čŠĻæ¸…é™¤į¨‹åŧæ•¸æ“šã€‚", + "scaffold_body_error_unrecoverable": "į™ŧį”Ÿį„Ąæŗ•æĸåžŠįš„éŒ¯čĒ¤ã€‚čĢ‹åœ¨ Discord 或 Github 上分äēĢ錯čĒ¤čŗ‡č¨ŠåŠå †į–ŠčŋŊ蚤īŧŒäģĨäžŋ我們提䞛協劊。在čĸĢåģēč­°įš„æƒ…æŗä¸‹äŊ å¯äģĨ在下斚嘗čŠĻæ¸…é™¤į¨‹åŧčŗ‡æ–™ã€‚", "scan": "掃描", "scan_all_libraries": "æŽƒææ‰€æœ‰į›¸į°ŋ", "scan_library": "掃描", @@ -1926,9 +1933,9 @@ "search_by_description_example": "åœ¨æ˛™åŖŠįš„åĨ行之æ—Ĩ", "search_by_filename": "䞝æĒ”名或副æĒ”名搜尋", "search_by_filename_example": "åĻ‚ IMG_1234.JPG 或 PNG", - "search_by_ocr": "透過OCR搜尋", + "search_by_ocr": "透過 OCR 搜尋", "search_by_ocr_example": "æ‹ŋéĩ", - "search_camera_lens_model": "蒐į´ĸéĄé ­åž‹č™Ÿ...", + "search_camera_lens_model": "æœå°‹éĄé ­åž‹č™Ÿ...", "search_camera_make": "æœå°‹į›¸æŠŸčŖŊ造商â€Ļ", "search_camera_model": "æœå°‹į›¸æŠŸåž‹č™Ÿâ€Ļ", "search_city": "搜尋城市â€Ļ", @@ -1945,7 +1952,7 @@ "search_filter_location_title": "選擇äŊįŊŽ", "search_filter_media_type": "åĒ’éĢ”éĄžåž‹", "search_filter_media_type_title": "選擇åĒ’éĢ”éĄžåž‹", - "search_filter_ocr": "透過OCR搜尋", + "search_filter_ocr": "透過 OCR 搜尋", "search_filter_people_title": "選擇äēēį‰Š", "search_filter_star_rating": "čŠ•åˆ†", "search_filter_tags_title": "é¸æ“‡æ¨™įą¤", @@ -1974,7 +1981,7 @@ "search_settings": "æœå°‹č¨­åŽš", "search_state": "搜尋地區â€Ļ", "search_suggestion_list_smart_search_hint_1": "æ™ē慧搜尋功čƒŊé č¨­åˇ˛å•Ÿį”¨īŧŒåĻ‚čĻæœå°‹ä¸­įšŧčŗ‡æ–™īŧŒčĢ‹äŊŋᔍčĒžæŗ• ", - "search_suggestion_list_smart_search_hint_2": "m:æ‚¨įš„æœå°‹é—œéĩ詞", + "search_suggestion_list_smart_search_hint_2": "m:æ‚¨įš„æœå°‹é—œéĩ字", "search_tags": "æœå°‹æ¨™įą¤...", "search_timezone": "搜尋時區â€Ļ", "search_type": "æœå°‹éĄžåž‹", @@ -2028,7 +2035,7 @@ "set_profile_picture": "č¨­åŽšå€‹äēēčŗ‡æ–™åœ–į‰‡", "set_slideshow_to_fullscreen": "äģĨ全čžĸ嚕攞映åšģį‡ˆį‰‡", "set_stack_primary_asset": "č¨­åŽšå †į–Šįš„éĻ–čĻé …į›Ž", - "setting_image_navigation_enable_subtitle": "開啟垌äģĨ觸įĸ°åąåš•åˇĻ/åŗé‚ŠįˇŖå€åŸŸįš„æ–šåŧåˆ‡æ›ä¸Š/ä¸‹åœ–į‰‡ã€‚", + "setting_image_navigation_enable_subtitle": "開啟垌äģĨ觸įĸ°čžĸåš•åˇĻ/åŗé‚ŠįˇŖå€åŸŸįš„æ–šåŧåˆ‡æ›ä¸Š/ä¸‹åœ–į‰‡ã€‚", "setting_image_navigation_enable_title": "éģžæ“Šåˆ‡æ›", "setting_image_navigation_title": "åœ–į‰‡å°Žåŧ•", "setting_image_viewer_help": "čŠŗį´°čŗ‡č¨ŠæĒĸčĻ–å™¨æœƒäžåēčŧ‰å…Ĩå°åž‹į¸Žåœ–ã€ä¸­į­‰å°ē寸預čĻŊ圖īŧˆč‹Ĩå•Ÿį”¨īŧ‰īŧŒæœ€åžŒčŧ‰å…ĨåŽŸå§‹į›¸į‰‡ã€‚", @@ -2128,7 +2135,7 @@ "show_all_people": "éĄ¯į¤ē所有äēēį‰Š", "show_and_hide_people": "éĄ¯į¤ē與隱藏äēēį‰Š", "show_file_location": "éĄ¯į¤ēæĒ”æĄˆäŊįŊŽ", - "show_gallery": "éĄ¯į¤ēį•ĢåģŠ", + "show_gallery": "éĄ¯į¤ēåĒ’éĢ”åēĢ", "show_hidden_people": "éĄ¯į¤ēéšąč—įš„äēēį‰Š", "show_in_timeline": "在時間čģ¸ä¸­éĄ¯į¤ē", "show_in_timeline_setting_description": "åœ¨æ‚¨įš„æ™‚é–“čģ¸ä¸­éĄ¯į¤ē這äŊäŊŋį”¨č€…įš„į›¸į‰‡å’ŒåŊąį‰‡", @@ -2145,7 +2152,7 @@ "show_supporter_badge": "æ”¯æŒč€…åžŊįĢ ", "show_supporter_badge_description": "éĄ¯į¤ēæ”¯æŒč€…åžŊįĢ ", "show_text_recognition": "éĄ¯į¤ēæ–‡å­—čž¨č­˜", - "show_text_search_menu": "éĄ¯į¤ēæ–‡å­—č’į´ĸ選喎", + "show_text_search_menu": "éĄ¯į¤ē文字搜尋選喎", "shuffle": "隨抟排åē", "sidebar": "側邊æŦ„", "sidebar_display_description": "在側邊æŦ„ä¸­éĄ¯į¤ē逪įĩ", @@ -2210,6 +2217,7 @@ "tag": "æ¨™įą¤", "tag_assets": "æ¨™č¨˜æĒ”æĄˆ", "tag_created": "厞åģēįĢ‹æ¨™įą¤īŧš{tag}", + "tag_face": "æ¨™č¨˜č‡‰å­”", "tag_feature_description": "äģĨ邏čŧ¯æ¨™č¨˜čĻæ—¨åˆ†éĄžį€čĻŊį›¸į‰‡å’ŒåŊąį‰‡", "tag_not_found_question": "æ‰žä¸åˆ°æ¨™įą¤īŧŸåģēįĢ‹æ–°æ¨™įą¤ã€‚", "tag_people": "æ¨™įą¤äēēį‰Š", @@ -2260,11 +2268,11 @@ "trash_all": "全部丟掉", "trash_count": "丟掉 {count, number} 個æĒ”æĄˆ", "trash_delete_asset": "將æĒ”æĄˆä¸Ÿé€˛åžƒåœžæĄļ / åˆĒ除", - "trash_emptied": "åˇ˛æ¸…įŠē回æ”ļæĄļ", + "trash_emptied": "åˇ˛æ¸…įŠē垃圞æĄļ", "trash_no_results_message": "垃圞æĄļä¸­įš„į›¸į‰‡å’ŒåŊąį‰‡å°‡éĄ¯į¤ēåœ¨é€™čŖĄã€‚", "trash_page_delete_all": "åˆĒ除全部", - "trash_page_empty_trash_dialog_content": "是åĻ清įŠē回æ”ļæĄļīŧŸé€™äē›é …į›Žå°‡čĸĢåžž Immich 中永䚅åˆĒ除", - "trash_page_info": "回æ”ļæĄļä¸­é …į›Žå°‡åœ¨ {days} 夊垌永䚅åˆĒ除", + "trash_page_empty_trash_dialog_content": "是åĻ清įŠē垃圞æĄļīŧŸé€™äē›é …į›Žå°‡čĸĢåžž Immich 中永䚅åˆĒ除", + "trash_page_info": "垃圞æĄļä¸­é …į›Žå°‡åœ¨ {days} 夊垌永䚅åˆĒ除", "trash_page_no_assets": "æšĢį„Ąåˇ˛åˆĒé™¤é …į›Ž", "trash_page_restore_all": "全部還原", "trash_page_select_assets_btn": "é¸æ“‡é …į›Ž", @@ -2277,7 +2285,7 @@ "trigger_person_recognized": "åˇ˛čž¨č­˜äēēį‰Š", "trigger_person_recognized_description": "åĩæ¸Ŧ到äēēį‰Šæ™‚č§¸į™ŧ", "trigger_type": "觸į™ŧéĄžåž‹", - "troubleshoot": "ᖑ雪觪᭔", + "troubleshoot": "į–‘é›ŖæŽ’č§Ŗ", "type": "éĄžåž‹", "unable_to_change_pin_code": "į„Ąæŗ•čŽŠæ›´ PIN įĸŧ", "unable_to_check_version": "į„Ąæŗ•æĒĸæŸĨæ‡‰į”¨į¨‹åŧæˆ–äŧ翜å™¨į‰ˆæœŦ", @@ -2309,7 +2317,7 @@ "unstack_action_prompt": "{count} 個取æļˆå †į–Š", "unstacked_assets_count": "åˇ˛č§Ŗé™¤å †į–Š {count, plural, other {# 個æĒ”æĄˆ}}", "unsupported_field_type": "ä¸æ”¯æ´įš„æŦ„äŊéĄžåž‹", - "unsupported_file_type": "不支持 {type} éĄžåž‹įš„æĒ”æĄˆīŧŒį„Ąæŗ•ä¸Šå‚ŗ {file} 文äģļ。", + "unsupported_file_type": "不支援 {type} éĄžåž‹įš„æĒ”æĄˆīŧŒį„Ąæŗ•ä¸Šå‚ŗ {file} æĒ”æĄˆã€‚", "untagged": "į„Ąæ¨™įą¤", "untitled_workflow": "æœĒå‘Ŋ名åˇĨäŊœæĩį¨‹", "up_next": "下一個", @@ -2337,6 +2345,7 @@ "usage": "į”¨é‡", "use_biometric": "äŊŋį”¨į”Ÿį‰Ščž¨č­˜", "use_browser_locale": "äŊŋį”¨į€čĻŊ器čĒžč¨€", + "use_browser_locale_description": "栚據äŊ į€čĻŊå™¨įš„čĒžč¨€å’Œåœ°å€č¨­åŽšäž†æ›´æ”šæ—Ĩ期īŧŒæ™‚é–“å’Œæ•¸å­—įš„æ ŧåŧ", "use_current_connection": "äŊŋį”¨į›Žå‰įš„é€Ŗįˇš", "use_custom_date_range": "æ”šį”¨č‡Ē訂æ—ĨæœŸį¯„åœ", "user": "äŊŋᔍ者", @@ -2366,7 +2375,7 @@ "version_history": "į‰ˆæœŦį´€éŒ„", "version_history_item": "{date} åŽ‰čŖäē† {version}", "video": "åŊąį‰‡", - "video_hover_setting": "éŠæ¨™åœį•™æ™‚æ’­æ”žåŊąį‰‡į¸Žåœ–", + "video_hover_setting": "æ¸¸æ¨™åœį•™æ™‚æ’­æ”žåŊąį‰‡į¸Žåœ–", "video_hover_setting_description": "į•ļæģ‘éŧ åœåœ¨é …į›Žä¸Šæ™‚æ’­æ”žåŊąį‰‡į¸Žåœ–ã€‚åŗäŊŋåœį”¨æ­¤åŠŸčƒŊīŧŒäģå¯é€éŽå°‡æģ‘éŧ åœåœ¨æ’­æ”žåœ–į¤ē上䞆開始播攞。", "videos": "åŊąį‰‡", "videos_count": "{count, plural, other {# 部åŊąį‰‡}}", @@ -2390,6 +2399,7 @@ "viewer_remove_from_stack": "åžžå †į–Šä¸­į§ģ除", "viewer_stack_use_as_main_asset": "äŊœį‚ēä¸ģé …į›ŽäŊŋᔍ", "viewer_unstack": "取æļˆå †į–Š", + "visibility": "可čĻ–æ€§", "visibility_changed": "åˇ˛čŽŠæ›´ {count, plural, other {# äŊäēēį‰Š}}įš„å¯čĻ‹æ€§", "visual": "čĻ–čĻēįš„", "visual_builder": "čĻ–čĻēæ§‹åģē器", diff --git a/machine-learning/pyproject.toml b/machine-learning/pyproject.toml index 9afaf2ecc8..ee5eab7c89 100644 --- a/machine-learning/pyproject.toml +++ b/machine-learning/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "immich-ml" -version = "2.6.2" +version = "2.7.5" description = "" authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }] requires-python = ">=3.11,<4.0" @@ -11,7 +11,7 @@ dependencies = [ "gunicorn>=21.1.0", "huggingface-hub>=0.20.1,<1.0", "insightface>=0.7.3,<1.0", - "numpy>=2.3.4", + "numpy<2.4.0", "opencv-python-headless>=4.7.0.72,<5.0", "orjson>=3.9.5", "pillow>=12.1.1,<12.2", diff --git a/machine-learning/uv.lock b/machine-learning/uv.lock index 0c1ecf1846..099a22b118 100644 --- a/machine-learning/uv.lock +++ b/machine-learning/uv.lock @@ -898,7 +898,7 @@ wheels = [ [[package]] name = "immich-ml" -version = "2.6.2" +version = "2.7.5" source = { editable = "." } dependencies = [ { name = "aiocache" }, @@ -987,7 +987,7 @@ requires-dist = [ { name = "gunicorn", specifier = ">=21.1.0" }, { name = "huggingface-hub", specifier = ">=0.20.1,<1.0" }, { name = "insightface", specifier = ">=0.7.3,<1.0" }, - { name = "numpy", specifier = ">=2.3.4" }, + { name = "numpy", specifier = "<2.4.0" }, { name = "onnxruntime", marker = "extra == 'armnn'", specifier = ">=1.23.2,<2" }, { name = "onnxruntime", marker = "extra == 'cpu'", specifier = ">=1.23.2,<2" }, { name = "onnxruntime", marker = "extra == 'rknn'", specifier = ">=1.23.2,<2" }, @@ -1519,81 +1519,83 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.2" +version = "2.3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, - { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, - { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, - { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, - { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, - { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, - { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, - { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, - { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, - { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, - { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, - { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, - { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, - { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, - { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, - { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, - { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, - { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, - { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, - { url = "https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c", size = 16663696, upload-time = "2026-01-31T23:11:17.516Z" }, - { url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979", size = 14688322, upload-time = "2026-01-31T23:11:19.883Z" }, - { url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98", size = 5198157, upload-time = "2026-01-31T23:11:22.375Z" }, - { url = "https://files.pythonhosted.org/packages/74/09/826e4289844eccdcd64aac27d13b0fd3f32039915dd5b9ba01baae1f436c/numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef", size = 6546330, upload-time = "2026-01-31T23:11:23.958Z" }, - { url = "https://files.pythonhosted.org/packages/19/fb/cbfdbfa3057a10aea5422c558ac57538e6acc87ec1669e666d32ac198da7/numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7", size = 15660968, upload-time = "2026-01-31T23:11:25.713Z" }, - { url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499", size = 16607311, upload-time = "2026-01-31T23:11:28.117Z" }, - { url = "https://files.pythonhosted.org/packages/14/d9/4b5adfc39a43fa6bf918c6d544bc60c05236cc2f6339847fc5b35e6cb5b0/numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb", size = 17012850, upload-time = "2026-01-31T23:11:30.888Z" }, - { url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7", size = 18334210, upload-time = "2026-01-31T23:11:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/78/0e/0a73b3dff26803a8c02baa76398015ea2a5434d9b8265a7898a6028c1591/numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110", size = 5958199, upload-time = "2026-01-31T23:11:35.385Z" }, - { url = "https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622", size = 12310848, upload-time = "2026-01-31T23:11:38.001Z" }, - { url = "https://files.pythonhosted.org/packages/6e/8d/6da186483e308da5da1cc6918ce913dcfe14ffde98e710bfeff2a6158d4e/numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71", size = 10221082, upload-time = "2026-01-31T23:11:40.392Z" }, - { url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262", size = 14815866, upload-time = "2026-01-31T23:11:42.495Z" }, - { url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913", size = 5325631, upload-time = "2026-01-31T23:11:44.7Z" }, - { url = "https://files.pythonhosted.org/packages/46/00/3a490938800c1923b567b3a15cd17896e68052e2145d8662aaf3e1ffc58f/numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab", size = 6646254, upload-time = "2026-01-31T23:11:46.341Z" }, - { url = "https://files.pythonhosted.org/packages/d3/e9/fac0890149898a9b609caa5af7455a948b544746e4b8fe7c212c8edd71f8/numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82", size = 15720138, upload-time = "2026-01-31T23:11:48.082Z" }, - { url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f", size = 16655398, upload-time = "2026-01-31T23:11:50.293Z" }, - { url = "https://files.pythonhosted.org/packages/4d/89/253db0fa0e66e9129c745e4ef25631dc37d5f1314dad2b53e907b8538e6d/numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554", size = 17079064, upload-time = "2026-01-31T23:11:52.927Z" }, - { url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257", size = 18379680, upload-time = "2026-01-31T23:11:55.22Z" }, - { url = "https://files.pythonhosted.org/packages/40/62/48f99ae172a4b63d981babe683685030e8a3df4f246c893ea5c6ef99f018/numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657", size = 6082433, upload-time = "2026-01-31T23:11:58.096Z" }, - { url = "https://files.pythonhosted.org/packages/07/38/e054a61cfe48ad9f1ed0d188e78b7e26859d0b60ef21cd9de4897cdb5326/numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b", size = 12451181, upload-time = "2026-01-31T23:11:59.782Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a4/a05c3a6418575e185dd84d0b9680b6bb2e2dc3e4202f036b7b4e22d6e9dc/numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1", size = 10290756, upload-time = "2026-01-31T23:12:02.438Z" }, - { url = "https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b", size = 16663092, upload-time = "2026-01-31T23:12:04.521Z" }, - { url = "https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000", size = 14698770, upload-time = "2026-01-31T23:12:06.96Z" }, - { url = "https://files.pythonhosted.org/packages/fb/0b/f9e49ba6c923678ad5bc38181c08ac5e53b7a5754dbca8e581aa1a56b1ff/numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1", size = 5208562, upload-time = "2026-01-31T23:12:09.632Z" }, - { url = "https://files.pythonhosted.org/packages/7d/12/d7de8f6f53f9bb76997e5e4c069eda2051e3fe134e9181671c4391677bb2/numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74", size = 6543710, upload-time = "2026-01-31T23:12:11.969Z" }, - { url = "https://files.pythonhosted.org/packages/09/63/c66418c2e0268a31a4cf8a8b512685748200f8e8e8ec6c507ce14e773529/numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a", size = 15677205, upload-time = "2026-01-31T23:12:14.33Z" }, - { url = "https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325", size = 16611738, upload-time = "2026-01-31T23:12:16.525Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a7/39c4cdda9f019b609b5c473899d87abff092fc908cfe4d1ecb2fcff453b0/numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909", size = 17028888, upload-time = "2026-01-31T23:12:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/da/b3/e84bb64bdfea967cc10950d71090ec2d84b49bc691df0025dddb7c26e8e3/numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a", size = 18339556, upload-time = "2026-01-31T23:12:21.816Z" }, - { url = "https://files.pythonhosted.org/packages/88/f5/954a291bc1192a27081706862ac62bb5920fbecfbaa302f64682aa90beed/numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a", size = 6006899, upload-time = "2026-01-31T23:12:24.14Z" }, - { url = "https://files.pythonhosted.org/packages/05/cb/eff72a91b2efdd1bc98b3b8759f6a1654aa87612fc86e3d87d6fe4f948c4/numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75", size = 12443072, upload-time = "2026-01-31T23:12:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/37/75/62726948db36a56428fce4ba80a115716dc4fad6a3a4352487f8bb950966/numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05", size = 10494886, upload-time = "2026-01-31T23:12:28.488Z" }, - { url = "https://files.pythonhosted.org/packages/36/2f/ee93744f1e0661dc267e4b21940870cabfae187c092e1433b77b09b50ac4/numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308", size = 14818567, upload-time = "2026-01-31T23:12:30.709Z" }, - { url = "https://files.pythonhosted.org/packages/a7/24/6535212add7d76ff938d8bdc654f53f88d35cddedf807a599e180dcb8e66/numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef", size = 5328372, upload-time = "2026-01-31T23:12:32.962Z" }, - { url = "https://files.pythonhosted.org/packages/5e/9d/c48f0a035725f925634bf6b8994253b43f2047f6778a54147d7e213bc5a7/numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d", size = 6649306, upload-time = "2026-01-31T23:12:34.797Z" }, - { url = "https://files.pythonhosted.org/packages/81/05/7c73a9574cd4a53a25907bad38b59ac83919c0ddc8234ec157f344d57d9a/numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8", size = 15722394, upload-time = "2026-01-31T23:12:36.565Z" }, - { url = "https://files.pythonhosted.org/packages/35/fa/4de10089f21fc7d18442c4a767ab156b25c2a6eaf187c0db6d9ecdaeb43f/numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5", size = 16653343, upload-time = "2026-01-31T23:12:39.188Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f9/d33e4ffc857f3763a57aa85650f2e82486832d7492280ac21ba9efda80da/numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e", size = 17078045, upload-time = "2026-01-31T23:12:42.041Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b8/54bdb43b6225badbea6389fa038c4ef868c44f5890f95dd530a218706da3/numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a", size = 18380024, upload-time = "2026-01-31T23:12:44.331Z" }, - { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, - { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, - { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, - { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, - { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, - { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, - { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, - { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, + { url = "https://files.pythonhosted.org/packages/43/77/84dd1d2e34d7e2792a236ba180b5e8fcc1e3e414e761ce0253f63d7f572e/numpy-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de5672f4a7b200c15a4127042170a694d4df43c992948f5e1af57f0174beed10", size = 17034641, upload-time = "2025-11-16T22:49:19.336Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ea/25e26fa5837106cde46ae7d0b667e20f69cbbc0efd64cba8221411ab26ae/numpy-2.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:acfd89508504a19ed06ef963ad544ec6664518c863436306153e13e94605c218", size = 12528324, upload-time = "2025-11-16T22:49:22.582Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1a/e85f0eea4cf03d6a0228f5c0256b53f2df4bc794706e7df019fc622e47f1/numpy-2.3.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ffe22d2b05504f786c867c8395de703937f934272eb67586817b46188b4ded6d", size = 5356872, upload-time = "2025-11-16T22:49:25.408Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bb/35ef04afd567f4c989c2060cde39211e4ac5357155c1833bcd1166055c61/numpy-2.3.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:872a5cf366aec6bb1147336480fef14c9164b154aeb6542327de4970282cd2f5", size = 6893148, upload-time = "2025-11-16T22:49:27.549Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2b/05bbeb06e2dff5eab512dfc678b1cc5ee94d8ac5956a0885c64b6b26252b/numpy-2.3.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3095bdb8dd297e5920b010e96134ed91d852d81d490e787beca7e35ae1d89cf7", size = 14557282, upload-time = "2025-11-16T22:49:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/65/fb/2b23769462b34398d9326081fad5655198fcf18966fcb1f1e49db44fbf31/numpy-2.3.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cba086a43d54ca804ce711b2a940b16e452807acebe7852ff327f1ecd49b0d4", size = 16897903, upload-time = "2025-11-16T22:49:34.191Z" }, + { url = "https://files.pythonhosted.org/packages/ac/14/085f4cf05fc3f1e8aa95e85404e984ffca9b2275a5dc2b1aae18a67538b8/numpy-2.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6cf9b429b21df6b99f4dee7a1218b8b7ffbbe7df8764dc0bd60ce8a0708fed1e", size = 16341672, upload-time = "2025-11-16T22:49:37.2Z" }, + { url = "https://files.pythonhosted.org/packages/6f/3b/1f73994904142b2aa290449b3bb99772477b5fd94d787093e4f24f5af763/numpy-2.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:396084a36abdb603546b119d96528c2f6263921c50df3c8fd7cb28873a237748", size = 18838896, upload-time = "2025-11-16T22:49:39.727Z" }, + { url = "https://files.pythonhosted.org/packages/cd/b9/cf6649b2124f288309ffc353070792caf42ad69047dcc60da85ee85fea58/numpy-2.3.5-cp311-cp311-win32.whl", hash = "sha256:b0c7088a73aef3d687c4deef8452a3ac7c1be4e29ed8bf3b366c8111128ac60c", size = 6563608, upload-time = "2025-11-16T22:49:42.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/44/9fe81ae1dcc29c531843852e2874080dc441338574ccc4306b39e2ff6e59/numpy-2.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:a414504bef8945eae5f2d7cb7be2d4af77c5d1cb5e20b296c2c25b61dff2900c", size = 13078442, upload-time = "2025-11-16T22:49:43.99Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a7/f99a41553d2da82a20a2f22e93c94f928e4490bb447c9ff3c4ff230581d3/numpy-2.3.5-cp311-cp311-win_arm64.whl", hash = "sha256:0cd00b7b36e35398fa2d16af7b907b65304ef8bb4817a550e06e5012929830fa", size = 10458555, upload-time = "2025-11-16T22:49:47.092Z" }, + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/c6/65/f9dea8e109371ade9c782b4e4756a82edf9d3366bca495d84d79859a0b79/numpy-2.3.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0963b55cdd70fad460fa4c1341f12f976bb26cb66021a5580329bd498988310", size = 16910689, upload-time = "2025-11-16T22:52:23.247Z" }, + { url = "https://files.pythonhosted.org/packages/00/4f/edb00032a8fb92ec0a679d3830368355da91a69cab6f3e9c21b64d0bb986/numpy-2.3.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f4255143f5160d0de972d28c8f9665d882b5f61309d8362fdd3e103cf7bf010c", size = 12457053, upload-time = "2025-11-16T22:52:26.367Z" }, + { url = "https://files.pythonhosted.org/packages/16/a4/e8a53b5abd500a63836a29ebe145fc1ab1f2eefe1cfe59276020373ae0aa/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:a4b9159734b326535f4dd01d947f919c6eefd2d9827466a696c44ced82dfbc18", size = 5285635, upload-time = "2025-11-16T22:52:29.266Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2f/37eeb9014d9c8b3e9c55bc599c68263ca44fdbc12a93e45a21d1d56df737/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2feae0d2c91d46e59fcd62784a3a83b3fb677fead592ce51b5a6fbb4f95965ff", size = 6801770, upload-time = "2025-11-16T22:52:31.421Z" }, + { url = "https://files.pythonhosted.org/packages/7d/e4/68d2f474df2cb671b2b6c2986a02e520671295647dad82484cde80ca427b/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffac52f28a7849ad7576293c0cb7b9f08304e8f7d738a8cb8a90ec4c55a998eb", size = 14391768, upload-time = "2025-11-16T22:52:33.593Z" }, + { url = "https://files.pythonhosted.org/packages/b8/50/94ccd8a2b141cb50651fddd4f6a48874acb3c91c8f0842b08a6afc4b0b21/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63c0e9e7eea69588479ebf4a8a270d5ac22763cc5854e9a7eae952a3908103f7", size = 16729263, upload-time = "2025-11-16T22:52:36.369Z" }, + { url = "https://files.pythonhosted.org/packages/2d/ee/346fa473e666fe14c52fcdd19ec2424157290a032d4c41f98127bfb31ac7/numpy-2.3.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f16417ec91f12f814b10bafe79ef77e70113a2f5f7018640e7425ff979253425", size = 12967213, upload-time = "2025-11-16T22:52:39.38Z" }, ] [[package]] diff --git a/mise.toml b/mise.toml index 0ec32de20c..ab44ea8652 100644 --- a/mise.toml +++ b/mise.toml @@ -14,10 +14,10 @@ config_roots = [ ] [tools] -node = "24.13.1" +node = "24.14.1" flutter = "3.35.7" -pnpm = "10.30.3" -terragrunt = "0.99.4" +pnpm = "10.32.1" +terragrunt = "0.99.5" opentofu = "1.11.5" java = "21.0.2" diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index 103cf79e4e..ecc0f8420f 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -113,8 +113,8 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "com.squareup.okhttp3:okhttp:$okhttp_version" implementation 'org.chromium.net:cronet-embedded:143.7445.0' - implementation("androidx.media3:media3-datasource-okhttp:1.9.2") - implementation("androidx.media3:media3-datasource-cronet:1.9.2") + implementation("androidx.media3:media3-datasource-okhttp:1.10.0") + implementation("androidx.media3:media3-datasource-cronet:1.10.0") implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation "androidx.work:work-runtime-ktx:$work_version" implementation "androidx.concurrent:concurrent-futures:$concurrent_version" diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt index cefdf4fbd2..73f7a09183 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt @@ -53,7 +53,7 @@ import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509KeyManager import javax.net.ssl.X509TrustManager -const val USER_AGENT = "Immich_Android_${BuildConfig.VERSION_NAME}" +const val USER_AGENT = "immich-android/${BuildConfig.VERSION_NAME}" private const val CERT_ALIAS = "client_cert" private const val PREFS_NAME = "immich.ssl" private const val PREFS_CERT_ALIAS = "immich.client_cert" diff --git a/mobile/android/fastlane/Fastfile b/mobile/android/fastlane/Fastfile index b40f394d01..7312a8ca68 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" => 3040, - "android.injected.version.name" => "2.6.2", + "android.injected.version.code" => 3046, + "android.injected.version.name" => "2.7.5", } ) 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/ios/Runner.xcodeproj/project.pbxproj b/mobile/ios/Runner.xcodeproj/project.pbxproj index 22a7abcbac..178454f381 100644 --- a/mobile/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 77; objects = { /* Begin PBXBuildFile section */ @@ -16,6 +16,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + A01DD69B2F7F43B40049AB63 /* ImageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01DD6982F7F43B40049AB63 /* ImageRequest.swift */; }; B21E34AA2E5AFD2B0031FDB9 /* BackgroundWorkerApiImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21E34A92E5AFD210031FDB9 /* BackgroundWorkerApiImpl.swift */; }; B21E34AC2E5B09190031FDB9 /* BackgroundWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21E34AB2E5B09100031FDB9 /* BackgroundWorker.swift */; }; B25D377A2E72CA15008B6CA7 /* Connectivity.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B25D37782E72CA15008B6CA7 /* Connectivity.g.swift */; }; @@ -102,6 +103,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A01DD6982F7F43B40049AB63 /* ImageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRequest.swift; sourceTree = ""; }; B1FBA9EE014DE20271B0FE77 /* Pods-ShareExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.profile.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.profile.xcconfig"; sourceTree = ""; }; B21E34A92E5AFD210031FDB9 /* BackgroundWorkerApiImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundWorkerApiImpl.swift; sourceTree = ""; }; B21E34AB2E5B09100031FDB9 /* BackgroundWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundWorker.swift; sourceTree = ""; }; @@ -137,20 +139,23 @@ ); target = F0B57D372DF764BD00DC5BCC /* WidgetExtension */; }; + FE1BB4572F83196E0087DBF9 /* Exceptions for "Utility" folder in "Runner" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Mutex.swift, + ); + target = 97C146ED1CF9000F007C117D /* Runner */; + }; /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ B231F52D2E93A44A00BC45D1 /* Core */ = { isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); path = Core; sourceTree = ""; }; B2CF7F8C2DDE4EBB00744BF6 /* Sync */ = { isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); path = Sync; sourceTree = ""; }; @@ -162,10 +167,16 @@ path = WidgetExtension; sourceTree = ""; }; - FEE084F22EC172080045228E /* Schemas */ = { + FE1BB4562F8319560087DBF9 /* Utility */ = { isa = PBXFileSystemSynchronizedRootGroup; exceptions = ( + FE1BB4572F83196E0087DBF9 /* Exceptions for "Utility" folder in "Runner" target */, ); + path = Utility; + sourceTree = ""; + }; + FEE084F22EC172080045228E /* Schemas */ = { + isa = PBXFileSystemSynchronizedRootGroup; path = Schemas; sourceTree = ""; }; @@ -273,6 +284,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + FE1BB4562F8319560087DBF9 /* Utility */, FEE084F22EC172080045228E /* Schemas */, B231F52D2E93A44A00BC45D1 /* Core */, B25D37792E72CA15008B6CA7 /* Connectivity */, @@ -327,6 +339,7 @@ FED3B1952E253E9B0030FD97 /* Images */ = { isa = PBXGroup; children = ( + A01DD6982F7F43B40049AB63 /* ImageRequest.swift */, FE5FE4AD2F30FBC000A71243 /* ImageProcessing.swift */, FE5499F72F1198DE006016CB /* RemoteImagesImpl.swift */, FE5499F52F11980E006016CB /* LocalImagesImpl.swift */, @@ -558,10 +571,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -590,10 +607,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -608,6 +629,7 @@ files = ( 65F32F31299BD2F800CE9261 /* BackgroundServicePlugin.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + A01DD69B2F7F43B40049AB63 /* ImageRequest.swift in Sources */, B21E34AC2E5B09190031FDB9 /* BackgroundWorker.swift in Sources */, FE5499F32F1197D8006016CB /* LocalImages.g.swift in Sources */, FE5499F62F11980E006016CB /* LocalImagesImpl.swift in Sources */, diff --git a/mobile/ios/Runner/Core/URLSessionManager.swift b/mobile/ios/Runner/Core/URLSessionManager.swift index 0b73ed71a6..e9d65d3113 100644 --- a/mobile/ios/Runner/Core/URLSessionManager.swift +++ b/mobile/ios/Runner/Core/URLSessionManager.swift @@ -36,7 +36,7 @@ extension UserDefaults { /// Old sessions are kept alive by Dart's FFI retain until all isolates release them. class URLSessionManager: NSObject { static let shared = URLSessionManager() - + private(set) var session: URLSession let delegate: URLSessionManagerDelegate private static let cacheDir: URL = { @@ -53,7 +53,7 @@ class URLSessionManager: NSObject { ) static let userAgent: String = { let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "unknown" - return "Immich_iOS_\(version)" + return "immich-ios/\(version)" }() static let cookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: APP_GROUP) private static var serverUrls: [String] = [] @@ -150,7 +150,6 @@ class URLSessionManager: NSObject { config.httpCookieStorage = cookieStorage config.httpMaximumConnectionsPerHost = 64 config.timeoutIntervalForRequest = 60 - config.timeoutIntervalForResource = 300 var headers = UserDefaults.group.dictionary(forKey: HEADERS_KEY) as? [String: String] ?? [:] headers["User-Agent"] = headers["User-Agent"] ?? userAgent diff --git a/mobile/ios/Runner/Images/ImageProcessing.swift b/mobile/ios/Runner/Images/ImageProcessing.swift index 2270bbffac..686a3464a7 100644 --- a/mobile/ios/Runner/Images/ImageProcessing.swift +++ b/mobile/ios/Runner/Images/ImageProcessing.swift @@ -1,7 +1,12 @@ import Foundation enum ImageProcessing { - static let queue = DispatchQueue(label: "thumbnail.processing", qos: .userInitiated, attributes: .concurrent) - static let semaphore = DispatchSemaphore(value: ProcessInfo.processInfo.activeProcessorCount * 2) + static let queue = { + let q = OperationQueue() + q.name = "thumbnail.processing" + q.qualityOfService = .userInitiated + q.maxConcurrentOperationCount = ProcessInfo.processInfo.activeProcessorCount * 2 + return q + }() static let cancelledResult = Result<[String: Int64]?, any Error>.success(nil) } diff --git a/mobile/ios/Runner/Images/ImageRequest.swift b/mobile/ios/Runner/Images/ImageRequest.swift new file mode 100644 index 0000000000..6c8bb04c70 --- /dev/null +++ b/mobile/ios/Runner/Images/ImageRequest.swift @@ -0,0 +1,41 @@ +import Foundation + +class ImageRequest: @unchecked Sendable { + private struct State: Sendable { + var isCancelled = false + } + + let completion: @Sendable (Result<[String: Int64]?, any Error>) -> Void + private let state: Mutex + + var isCancelled: Bool { + get { + state.withLock { $0.isCancelled } + } + set { + state.withLock { $0.isCancelled = newValue } + } + } + + init(completion: @escaping @Sendable (Result<[String: Int64]?, any Error>) -> Void) { + self.state = Mutex(State()) + self.completion = completion + } + + func cancel() { + isCancelled = true + } +} + +struct RequestRegistry: ~Copyable, Sendable { + private let requests = Mutex<[Int64: T]>([:]) + + func add(requestId: Int64, request: T) { + requests.withLock { $0[requestId] = request } + } + + @discardableResult + func remove(requestId: Int64) -> T? { + requests.withLock { $0.removeValue(forKey: requestId) } + } +} diff --git a/mobile/ios/Runner/Images/LocalImagesImpl.swift b/mobile/ios/Runner/Images/LocalImagesImpl.swift index 303ff5bc33..9c142da054 100644 --- a/mobile/ios/Runner/Images/LocalImagesImpl.swift +++ b/mobile/ios/Runner/Images/LocalImagesImpl.swift @@ -3,16 +3,6 @@ import Flutter import MobileCoreServices import Photos -class LocalImageRequest { - weak var workItem: DispatchWorkItem? - var isCancelled = false - let callback: (Result<[String: Int64]?, any Error>) -> Void - - init(callback: @escaping (Result<[String: Int64]?, any Error>) -> Void) { - self.callback = callback - } -} - class LocalImageApiImpl: LocalImageApi { private static let imageManager = PHImageManager.default() private static let fetchOptions = { @@ -31,18 +21,15 @@ class LocalImageApiImpl: LocalImageApi { return requestOptions }() - private static let assetQueue = DispatchQueue(label: "thumbnail.assets", qos: .userInitiated) - private static let requestQueue = DispatchQueue(label: "thumbnail.requests", qos: .userInitiated) - private static let cancelQueue = DispatchQueue(label: "thumbnail.cancellation", qos: .default) + private static let registry = RequestRegistry() - private static var rgbaFormat = vImage_CGImageFormat( + private static let rgbaFormat = vImage_CGImageFormat( bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue), renderingIntent: .defaultIntent )! - private static var requests = [Int64: LocalImageRequest]() private static let assetCache = { let assetCache = NSCache() assetCache.countLimit = 10000 @@ -50,7 +37,7 @@ class LocalImageApiImpl: LocalImageApi { }() func getThumbhash(thumbhash: String, completion: @escaping (Result<[String : Int64], any Error>) -> Void) { - ImageProcessing.queue.async { + ImageProcessing.queue.addOperation { guard let data = Data(base64Encoded: thumbhash) else { return completion(.failure(PigeonError(code: "", message: "Invalid base64 string: \(thumbhash)", details: nil)))} @@ -65,30 +52,20 @@ class LocalImageApiImpl: LocalImageApi { } func requestImage(assetId: String, requestId: Int64, width: Int64, height: Int64, isVideo: Bool, preferEncoded: Bool, completion: @escaping (Result<[String: Int64]?, any Error>) -> Void) { - let request = LocalImageRequest(callback: completion) - let item = DispatchWorkItem { + let request = ImageRequest(completion: completion) + let operation = BlockOperation { if request.isCancelled { - return completion(ImageProcessing.cancelledResult) - } - - ImageProcessing.semaphore.wait() - defer { - ImageProcessing.semaphore.signal() - } - - if request.isCancelled { - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } guard let asset = Self.requestAsset(assetId: assetId) else { - Self.remove(requestId: requestId) - completion(.failure(PigeonError(code: "", message: "Could not get asset data for \(assetId)", details: nil))) - return + Self.registry.remove(requestId: requestId) + return request.completion(.failure(PigeonError(code: "", message: "Could not get asset data for \(assetId)", details: nil))) } if request.isCancelled { - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } if preferEncoded { @@ -107,13 +84,12 @@ class LocalImageApiImpl: LocalImageApi { ) if request.isCancelled { - Self.remove(requestId: requestId) - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } guard let data = imageData else { - Self.remove(requestId: requestId) - return completion(.failure(PigeonError(code: "", message: "Could not get image data for \(assetId)", details: nil))) + Self.registry.remove(requestId: requestId) + return request.completion(.failure(PigeonError(code: "", message: "Could not get image data for \(assetId)", details: nil))) } let length = data.count @@ -122,16 +98,14 @@ class LocalImageApiImpl: LocalImageApi { if request.isCancelled { free(pointer) - Self.remove(requestId: requestId) - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } - request.callback(.success([ + Self.registry.remove(requestId: requestId) + return request.completion(.success([ "pointer": Int64(Int(bitPattern: pointer)), "length": Int64(length), ])) - Self.remove(requestId: requestId) - return } var image: UIImage? @@ -146,17 +120,17 @@ class LocalImageApiImpl: LocalImageApi { ) if request.isCancelled { - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } guard let image = image, let cgImage = image.cgImage else { - Self.remove(requestId: requestId) - return completion(.failure(PigeonError(code: "", message: "Could not get pixel data for \(assetId)", details: nil))) + Self.registry.remove(requestId: requestId) + return request.completion(.failure(PigeonError(code: "", message: "Could not get pixel data for \(assetId)", details: nil))) } if request.isCancelled { - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } do { @@ -164,58 +138,38 @@ class LocalImageApiImpl: LocalImageApi { if request.isCancelled { buffer.free() - return completion(ImageProcessing.cancelledResult) + return request.completion(ImageProcessing.cancelledResult) } - request.callback(.success([ + Self.registry.remove(requestId: requestId) + return request.completion(.success([ "pointer": Int64(Int(bitPattern: buffer.data)), "width": Int64(buffer.width), "height": Int64(buffer.height), - "rowBytes": Int64(buffer.rowBytes) + "rowBytes": Int64(buffer.rowBytes), ])) - Self.remove(requestId: requestId) } catch { - Self.remove(requestId: requestId) - return completion(.failure(PigeonError(code: "", message: "Failed to convert image for \(assetId): \(error)", details: nil))) + Self.registry.remove(requestId: requestId) + return request.completion(.failure(PigeonError(code: "", message: "Failed to convert image for \(assetId): \(error)", details: nil))) } } - request.workItem = item - Self.add(requestId: requestId, request: request) - ImageProcessing.queue.async(execute: item) + Self.registry.add(requestId: requestId, request: request) + ImageProcessing.queue.addOperation(operation) } func cancelRequest(requestId: Int64) { - Self.cancel(requestId: requestId) - } - - private static func add(requestId: Int64, request: LocalImageRequest) -> Void { - requestQueue.sync { requests[requestId] = request } - } - - private static func remove(requestId: Int64) -> Void { - requestQueue.sync { requests[requestId] = nil } - } - - private static func cancel(requestId: Int64) -> Void { - requestQueue.async { - guard let request = requests.removeValue(forKey: requestId) else { return } - request.isCancelled = true - guard let item = request.workItem else { return } - if item.isCancelled { - cancelQueue.async { request.callback(ImageProcessing.cancelledResult) } - } - } + Self.registry.remove(requestId: requestId)?.cancel() } private static func requestAsset(assetId: String) -> PHAsset? { - var asset: PHAsset? - assetQueue.sync { asset = assetCache.object(forKey: assetId as NSString) } - if asset != nil { return asset } + if let cached = assetCache.object(forKey: assetId as NSString) { + return cached + } guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: Self.fetchOptions).firstObject else { return nil } - assetQueue.async { assetCache.setObject(asset, forKey: assetId as NSString) } + assetCache.setObject(asset, forKey: assetId as NSString) return asset } } diff --git a/mobile/ios/Runner/Images/RemoteImagesImpl.swift b/mobile/ios/Runner/Images/RemoteImagesImpl.swift index f2a0c37254..de1f6dec89 100644 --- a/mobile/ios/Runner/Images/RemoteImagesImpl.swift +++ b/mobile/ios/Runner/Images/RemoteImagesImpl.swift @@ -3,23 +3,24 @@ import Flutter import MobileCoreServices import Photos -class RemoteImageRequest { - weak var task: URLSessionDataTask? +final class RemoteImageRequest: ImageRequest { + var task: URLSessionDataTask? let id: Int64 - var isCancelled = false - let completion: (Result<[String: Int64]?, any Error>) -> Void - init(id: Int64, task: URLSessionDataTask, completion: @escaping (Result<[String: Int64]?, any Error>) -> Void) { + init(id: Int64, completion: @escaping @Sendable (Result<[String: Int64]?, any Error>) -> Void) { self.id = id - self.task = task - self.completion = completion + super.init(completion: completion) + } + + override func cancel() { + super.cancel() + task?.cancel() } } class RemoteImageApiImpl: NSObject, RemoteImageApi { - private static var lock = os_unfair_lock() - private static var requests = [Int64: RemoteImageRequest]() - private static var rgbaFormat = vImage_CGImageFormat( + private static let registry = RequestRegistry() + private static let rgbaFormat = vImage_CGImageFormat( bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: CGColorSpaceCreateDeviceRGB(), @@ -37,70 +38,58 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi { var urlRequest = URLRequest(url: URL(string: url)!) urlRequest.cachePolicy = .returnCacheDataElseLoad + let request = RemoteImageRequest(id: requestId, completion: completion) + let task = URLSessionManager.shared.session.dataTask(with: urlRequest) { data, response, error in - Self.handleCompletion(requestId: requestId, encoded: preferEncoded, data: data, response: response, error: error) + Self.handleCompletion(request: request, encoded: preferEncoded, data: data, response: response, error: error) } - let request = RemoteImageRequest(id: requestId, task: task, completion: completion) - - os_unfair_lock_lock(&Self.lock) - Self.requests[requestId] = request - os_unfair_lock_unlock(&Self.lock) - + request.task = task + Self.registry.add(requestId: requestId, request: request) task.resume() } - private static func handleCompletion(requestId: Int64, encoded: Bool, data: Data?, response: URLResponse?, error: Error?) { - os_unfair_lock_lock(&Self.lock) - guard let request = requests[requestId] else { - return os_unfair_lock_unlock(&Self.lock) - } - requests[requestId] = nil - os_unfair_lock_unlock(&Self.lock) - - if let error = error { - if request.isCancelled || (error as NSError).code == NSURLErrorCancelled { - return request.completion(ImageProcessing.cancelledResult) - } - return request.completion(.failure(error)) - } - + private static func handleCompletion(request: RemoteImageRequest, encoded: Bool, data: Data?, response: URLResponse?, error: Error?) { if request.isCancelled { return request.completion(ImageProcessing.cancelledResult) } + if let error = error { + registry.remove(requestId: request.id) + return request.completion(.failure(error)) + } + guard let data = data else { + registry.remove(requestId: request.id) return request.completion(.failure(PigeonError(code: "", message: "No data received", details: nil))) } - ImageProcessing.queue.async { - ImageProcessing.semaphore.wait() - defer { ImageProcessing.semaphore.signal() } + if encoded { + let length = data.count + let pointer = malloc(length)! + data.copyBytes(to: pointer.assumingMemoryBound(to: UInt8.self), count: length) + if request.isCancelled { + free(pointer) + return request.completion(ImageProcessing.cancelledResult) + } + + registry.remove(requestId: request.id) + return request.completion( + .success([ + "pointer": Int64(Int(bitPattern: pointer)), + "length": Int64(length), + ])) + } + + ImageProcessing.queue.addOperation { if request.isCancelled { return request.completion(ImageProcessing.cancelledResult) } - // Return raw encoded bytes when requested (for animated images) - if encoded { - let length = data.count - let pointer = malloc(length)! - data.copyBytes(to: pointer.assumingMemoryBound(to: UInt8.self), count: length) - - if request.isCancelled { - free(pointer) - return request.completion(ImageProcessing.cancelledResult) - } - - return request.completion( - .success([ - "pointer": Int64(Int(bitPattern: pointer)), - "length": Int64(length), - ])) - } - guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil), let cgImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, decodeOptions) else { + registry.remove(requestId: request.id) return request.completion(.failure(PigeonError(code: "", message: "Failed to decode image for request", details: nil))) } @@ -116,27 +105,23 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi { return request.completion(ImageProcessing.cancelledResult) } - request.completion( - .success([ - "pointer": Int64(Int(bitPattern: buffer.data)), - "width": Int64(buffer.width), - "height": Int64(buffer.height), - "rowBytes": Int64(buffer.rowBytes), - ])) + registry.remove(requestId: request.id) + return request.completion( + .success([ + "pointer": Int64(Int(bitPattern: buffer.data)), + "width": Int64(buffer.width), + "height": Int64(buffer.height), + "rowBytes": Int64(buffer.rowBytes), + ])) } catch { + registry.remove(requestId: request.id) return request.completion(.failure(PigeonError(code: "", message: "Failed to convert image for request: \(error)", details: nil))) } } } func cancelRequest(requestId: Int64) { - os_unfair_lock_lock(&Self.lock) - let request = Self.requests[requestId] - os_unfair_lock_unlock(&Self.lock) - - guard let request = request else { return } - request.isCancelled = true - request.task?.cancel() + Self.registry.remove(requestId: requestId)?.cancel() } func clearCache(completion: @escaping (Result) -> Void) { diff --git a/mobile/ios/Runner/Info.plist b/mobile/ios/Runner/Info.plist index 71be571216..b5d7d780a6 100644 --- a/mobile/ios/Runner/Info.plist +++ b/mobile/ios/Runner/Info.plist @@ -80,7 +80,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.6.2 + 2.7.5 CFBundleSignature ???? CFBundleURLTypes diff --git a/mobile/ios/Runner/Utility/Mutex.swift b/mobile/ios/Runner/Utility/Mutex.swift new file mode 100644 index 0000000000..fbfe168ff4 --- /dev/null +++ b/mobile/ios/Runner/Utility/Mutex.swift @@ -0,0 +1,54 @@ +import Darwin + +// Can be replaced with std Mutex when the deployment target is iOS 18+ +struct Mutex: ~Copyable, @unchecked Sendable { + struct _Buffer: ~Copyable { + var lock: os_unfair_lock = .init() + var value: Value + + init(value: consuming Value) { + self.value = value + } + + deinit {} + } + + let _buffer: UnsafeMutablePointer<_Buffer> + + init(_ initialValue: consuming sending Value) { + _buffer = .allocate(capacity: 1) + _buffer.initialize(to: _Buffer(value: initialValue)) + } + + deinit { + _buffer.deinitialize(count: 1) + _buffer.deallocate() + } + + @discardableResult + borrowing func withLock( + _ body: (inout sending Value) throws(E) -> sending Result + ) throws(E) -> sending Result { + os_unfair_lock_lock(&_buffer.pointee.lock) + defer { os_unfair_lock_unlock(&_buffer.pointee.lock) } + return try body(&_buffer.pointee.value) + } +} + +// Can be replaced with OSAllocatedUnfairLock when the deployment target is iOS 16+ +typealias UnfairLock = Mutex + +extension Mutex where Value == Void { + init() { + self.init(()) + } + + @discardableResult + borrowing func withLock( + _ body: () throws(E) -> sending Result + ) throws(E) -> sending Result { + os_unfair_lock_lock(&_buffer.pointee.lock) + defer { os_unfair_lock_unlock(&_buffer.pointee.lock) } + return try body() + } +} diff --git a/mobile/lib/infrastructure/repositories/network.repository.dart b/mobile/lib/infrastructure/repositories/network.repository.dart index bb5796e220..75f7850168 100644 --- a/mobile/lib/infrastructure/repositories/network.repository.dart +++ b/mobile/lib/infrastructure/repositories/network.repository.dart @@ -22,7 +22,14 @@ class NetworkRepository { final session = URLSession.fromRawPointer(clientPointer.cast()); _client = CupertinoClient.fromSharedSession(session); } else { - _client = OkHttpClient.fromJniGlobalRef(clientPointer); + _client = OkHttpClient.fromJniGlobalRef( + clientPointer, + configuration: const OkHttpClientConfiguration( + connectTimeout: Duration(seconds: 30), + readTimeout: Duration(seconds: 60), + writeTimeout: Duration(seconds: 60), + ), + ); } } diff --git a/mobile/lib/pages/backup/drift_backup.page.dart b/mobile/lib/pages/backup/drift_backup.page.dart index 3ba3389eea..6bdb8dd552 100644 --- a/mobile/lib/pages/backup/drift_backup.page.dart +++ b/mobile/lib/pages/backup/drift_backup.page.dart @@ -45,14 +45,17 @@ class _DriftBackupPageState extends ConsumerState { } WidgetsBinding.instance.addPostFrameCallback((_) async { - await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); + final backupNotifier = ref.read(driftBackupProvider.notifier); + final syncManager = ref.read(backgroundSyncProvider); - ref.read(driftBackupProvider.notifier).updateSyncing(true); - syncSuccess = await ref.read(backgroundSyncProvider).syncRemote(); - ref.read(driftBackupProvider.notifier).updateSyncing(false); + await backupNotifier.getBackupStatus(currentUser.id); + + backupNotifier.updateSyncing(true); + syncSuccess = await syncManager.syncRemote(); + backupNotifier.updateSyncing(false); if (mounted) { - await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); + await backupNotifier.getBackupStatus(currentUser.id); } }); } @@ -82,9 +85,9 @@ class _DriftBackupPageState extends ConsumerState { } if (syncSuccess == null) { - ref.read(driftBackupProvider.notifier).updateSyncing(true); + backupNotifier.updateSyncing(true); syncSuccess = await backupSyncManager.syncRemote(); - ref.read(driftBackupProvider.notifier).updateSyncing(false); + backupNotifier.updateSyncing(false); } await backupNotifier.getBackupStatus(currentUser.id); diff --git a/mobile/lib/presentation/pages/drift_memory.page.dart b/mobile/lib/presentation/pages/drift_memory.page.dart index 3f8879c91d..846f062501 100644 --- a/mobile/lib/presentation/pages/drift_memory.page.dart +++ b/mobile/lib/presentation/pages/drift_memory.page.dart @@ -207,6 +207,11 @@ class DriftMemoryPage extends HookConsumerWidget { WidgetsBinding.instance.addPostFrameCallback((_) { DriftMemoryPage.setMemory(ref, memories[pageNumber]); }); + + // Update currentAsset to the first asset of the new memory + if (memories[pageNumber].assets.isNotEmpty) { + currentAsset.value = memories[pageNumber].assets.first; + } } currentAssetPage.value = 0; diff --git a/mobile/lib/presentation/pages/search/drift_search.page.dart b/mobile/lib/presentation/pages/search/drift_search.page.dart index 452f6cc1d5..7e47a742ae 100644 --- a/mobile/lib/presentation/pages/search/drift_search.page.dart +++ b/mobile/lib/presentation/pages/search/drift_search.page.dart @@ -52,24 +52,20 @@ class DriftSearchPage extends HookConsumerWidget { : 'file_name_or_extension'.t(context: context), ); final textSearchController = useTextEditingController(); - final preFilter = ref.watch(searchPreFilterProvider); final filter = useState( SearchFilter( - people: preFilter?.people ?? {}, - location: preFilter?.location ?? SearchLocationFilter(), - camera: preFilter?.camera ?? SearchCameraFilter(), - date: preFilter?.date ?? SearchDateFilter(), - display: preFilter?.display ?? SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false), - rating: preFilter?.rating ?? SearchRatingFilter(), - mediaType: preFilter?.mediaType ?? AssetType.other, + people: {}, + location: SearchLocationFilter(), + camera: SearchCameraFilter(), + date: SearchDateFilter(), + display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false), + rating: SearchRatingFilter(), + mediaType: AssetType.other, language: "${context.locale.languageCode}-${context.locale.countryCode}", - assetId: preFilter?.assetId, - tagIds: preFilter?.tagIds ?? [], + tagIds: [], ), ); - final previousFilter = useState(null); - final hasRequestedSearch = useState(false); final dateInputFilter = useState(null); final peopleCurrentFilterWidget = useState(null); @@ -83,68 +79,58 @@ class DriftSearchPage extends HookConsumerWidget { final userPreferences = ref.watch(userMetadataPreferencesProvider); - searchFilter(SearchFilter filter) { - if (preFilter == null && filter == previousFilter.value) { + search(SearchFilter f) { + if (f == filter.value) { return; } + filter.value = f; + ref.read(paginatedSearchProvider.notifier).clear(); - if (filter.isEmpty) { - previousFilter.value = null; - hasRequestedSearch.value = false; - return; + if (!f.isEmpty) { + unawaited(ref.read(paginatedSearchProvider.notifier).search(f)); } - - hasRequestedSearch.value = true; - unawaited(ref.read(paginatedSearchProvider.notifier).search(filter)); - previousFilter.value = filter; } - search() => searchFilter(filter.value); - loadMoreSearchResults() { unawaited(ref.read(paginatedSearchProvider.notifier).search(filter.value)); } - searchPreFilter() { - if (preFilter != null) { - Future.delayed(Duration.zero, () { - filter.value = preFilter; - textSearchController.clear(); - searchFilter(preFilter); - - if (preFilter.location.city != null) { - locationCurrentFilterWidget.value = Text(preFilter.location.city!, style: context.textTheme.labelLarge); - } - }); - } - } - + // TODO: Use ref.listen with `fireImmediately` in the new riverpod version. + final preFilter = ref.watch(searchPreFilterProvider); useEffect(() { - Future.microtask(() => ref.invalidate(paginatedSearchProvider)); - searchPreFilter(); + if (preFilter == null) { + return null; + } + + Future.microtask(() { + textSearchController.clear(); + search(preFilter); + if (preFilter.location.city != null) { + locationCurrentFilterWidget.value = Text(preFilter.location.city!, style: context.textTheme.labelLarge); + } + }); return null; }, [preFilter]); showPeoplePicker() { - handleOnSelect(Set value) { - filter.value = filter.value.copyWith(people: value); + var people = filter.value.people; - final label = value.map((e) => e.name != '' ? e.name : 'no_name'.t(context: context)).join(', '); - if (label.isNotEmpty) { - peopleCurrentFilterWidget.value = Text(label, style: context.textTheme.labelLarge); - } else { - peopleCurrentFilterWidget.value = null; - } + handleOnSelect(Set value) { + people = value; } handleClear() { - filter.value = filter.value.copyWith(people: {}); - peopleCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(people: {})); + } + + handleApply() { + final label = people.map((e) => e.name != '' ? e.name : 'no_name'.t(context: context)).join(', '); + peopleCurrentFilterWidget.value = label.isNotEmpty ? Text(label, style: context.textTheme.labelLarge) : null; + search(filter.value.copyWith(people: people)); } showFilterBottomSheet( @@ -155,7 +141,7 @@ class DriftSearchPage extends HookConsumerWidget { child: FilterBottomSheetScaffold( title: 'search_filter_people_title'.t(context: context), expanded: true, - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: PeoplePicker(onSelect: handleOnSelect, filter: filter.value.people), ), @@ -164,23 +150,22 @@ class DriftSearchPage extends HookConsumerWidget { } showTagPicker() { + var tagIds = filter.value.tagIds ?? []; + String tagLabel = ''; + handleOnSelect(Iterable tags) { - filter.value = filter.value.copyWith(tagIds: tags.map((t) => t.id).toList()); - final label = tags.map((t) => t.value).join(', '); - if (label.isEmpty) { - tagCurrentFilterWidget.value = null; - } else { - tagCurrentFilterWidget.value = Text( - label.isEmpty ? 'tags'.t(context: context) : label, - style: context.textTheme.labelLarge, - ); - } + tagIds = tags.map((t) => t.id).toList(); + tagLabel = tags.map((t) => t.value).join(', '); } handleClear() { - filter.value = filter.value.copyWith(tagIds: []); tagCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(tagIds: [])); + } + + handleApply() { + tagCurrentFilterWidget.value = tagLabel.isNotEmpty ? Text(tagLabel, style: context.textTheme.labelLarge) : null; + search(filter.value.copyWith(tagIds: tagIds)); } showFilterBottomSheet( @@ -191,7 +176,7 @@ class DriftSearchPage extends HookConsumerWidget { child: FilterBottomSheetScaffold( title: 'search_filter_tags_title'.t(context: context), expanded: true, - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: TagPicker(onSelect: handleOnSelect, filter: (filter.value.tagIds ?? []).toSet()), ), @@ -200,32 +185,27 @@ class DriftSearchPage extends HookConsumerWidget { } showLocationPicker() { + var location = filter.value.location; + handleOnSelect(Map value) { - filter.value = filter.value.copyWith( - location: SearchLocationFilter(country: value['country'], city: value['city'], state: value['state']), - ); - - final locationText = []; - if (value['country'] != null) { - locationText.add(value['country']!); - } - - if (value['state'] != null) { - locationText.add(value['state']!); - } - - if (value['city'] != null) { - locationText.add(value['city']!); - } - - locationCurrentFilterWidget.value = Text(locationText.join(', '), style: context.textTheme.labelLarge); + location = SearchLocationFilter(country: value['country'], city: value['city'], state: value['state']); } handleClear() { - filter.value = filter.value.copyWith(location: SearchLocationFilter()); - locationCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(location: SearchLocationFilter())); + } + + handleApply() { + final locationText = [ + if (location.country != null) location.country!, + if (location.state != null) location.state!, + if (location.city != null) location.city!, + ]; + locationCurrentFilterWidget.value = locationText.isNotEmpty + ? Text(locationText.join(', '), style: context.textTheme.labelLarge) + : null; + search(filter.value.copyWith(location: location)); } showFilterBottomSheet( @@ -234,7 +214,7 @@ class DriftSearchPage extends HookConsumerWidget { isDismissible: true, child: FilterBottomSheetScaffold( title: 'search_filter_location_title'.t(context: context), - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), @@ -251,22 +231,24 @@ class DriftSearchPage extends HookConsumerWidget { } showCameraPicker() { - handleOnSelect(Map value) { - filter.value = filter.value.copyWith( - camera: SearchCameraFilter(make: value['make'], model: value['model']), - ); + var camera = filter.value.camera; - cameraCurrentFilterWidget.value = Text( - '${value['make'] ?? ''} ${value['model'] ?? ''}', - style: context.textTheme.labelLarge, - ); + handleOnSelect(Map value) { + camera = SearchCameraFilter(make: value['make'], model: value['model']); } handleClear() { - filter.value = filter.value.copyWith(camera: SearchCameraFilter()); - cameraCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(camera: SearchCameraFilter())); + } + + handleApply() { + final make = camera.make ?? ''; + final model = camera.model ?? ''; + cameraCurrentFilterWidget.value = (make.isNotEmpty || model.isNotEmpty) + ? Text('$make $model', style: context.textTheme.labelLarge) + : null; + search(filter.value.copyWith(camera: camera)); } showFilterBottomSheet( @@ -275,7 +257,7 @@ class DriftSearchPage extends HookConsumerWidget { isDismissible: true, child: FilterBottomSheetScaffold( title: 'search_filter_camera_title'.t(context: context), - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: Padding( padding: const EdgeInsets.all(16.0), @@ -288,28 +270,24 @@ class DriftSearchPage extends HookConsumerWidget { datePicked(DateFilterInputModel? selectedDate) { dateInputFilter.value = selectedDate; if (selectedDate == null) { - filter.value = filter.value.copyWith(date: SearchDateFilter()); - dateRangeCurrentFilterWidget.value = null; - unawaited(search()); + search(filter.value.copyWith(date: SearchDateFilter())); return; } final date = selectedDate.asDateTimeRange(); - - filter.value = filter.value.copyWith( - date: SearchDateFilter( - takenAfter: date.start, - takenBefore: date.end.add(const Duration(hours: 23, minutes: 59, seconds: 59)), - ), - ); - dateRangeCurrentFilterWidget.value = Text( selectedDate.asHumanReadable(context), style: context.textTheme.labelLarge, ); - - unawaited(search()); + search( + filter.value.copyWith( + date: SearchDateFilter( + takenAfter: date.start, + takenBefore: date.end.add(const Duration(hours: 23, minutes: 59, seconds: 59)), + ), + ), + ); } showDatePicker() async { @@ -376,31 +354,32 @@ class DriftSearchPage extends HookConsumerWidget { // MEDIA PICKER showMediaTypePicker() { - handleOnSelected(AssetType assetType) { - filter.value = filter.value.copyWith(mediaType: assetType); + var mediaType = filter.value.mediaType; - mediaTypeCurrentFilterWidget.value = Text( - assetType == AssetType.image - ? 'image'.t(context: context) - : assetType == AssetType.video - ? 'video'.t(context: context) - : 'all'.t(context: context), - style: context.textTheme.labelLarge, - ); + handleOnSelected(AssetType assetType) { + mediaType = assetType; } handleClear() { - filter.value = filter.value.copyWith(mediaType: AssetType.other); - mediaTypeCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(mediaType: AssetType.other)); + } + + handleApply() { + mediaTypeCurrentFilterWidget.value = mediaType != AssetType.other + ? Text( + mediaType == AssetType.image ? 'image'.t(context: context) : 'video'.t(context: context), + style: context.textTheme.labelLarge, + ) + : null; + search(filter.value.copyWith(mediaType: mediaType)); } showFilterBottomSheet( context: context, child: FilterBottomSheetScaffold( title: 'search_filter_media_type_title'.t(context: context), - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: MediaTypePicker(onSelect: handleOnSelected, filter: filter.value.mediaType), ), @@ -409,19 +388,22 @@ class DriftSearchPage extends HookConsumerWidget { // STAR RATING PICKER showStarRatingPicker() { - handleOnSelected(SearchRatingFilter rating) { - filter.value = filter.value.copyWith(rating: rating); + var rating = filter.value.rating; - ratingCurrentFilterWidget.value = Text( - 'rating_count'.t(args: {'count': rating.rating!}), - style: context.textTheme.labelLarge, - ); + handleOnSelected(SearchRatingFilter value) { + rating = value; } handleClear() { - filter.value = filter.value.copyWith(rating: SearchRatingFilter(rating: null)); ratingCurrentFilterWidget.value = null; - search(); + search(filter.value.copyWith(rating: SearchRatingFilter(rating: null))); + } + + handleApply() { + ratingCurrentFilterWidget.value = rating.rating != null + ? Text('rating_count'.t(args: {'count': rating.rating!}), style: context.textTheme.labelLarge) + : null; + search(filter.value.copyWith(rating: rating)); } showFilterBottomSheet( @@ -429,7 +411,7 @@ class DriftSearchPage extends HookConsumerWidget { isScrollControlled: true, child: FilterBottomSheetScaffold( title: 'rating'.t(context: context), - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: StarRatingPicker(onSelect: handleOnSelected, filter: filter.value.rating), ), @@ -438,79 +420,54 @@ class DriftSearchPage extends HookConsumerWidget { // DISPLAY OPTION showDisplayOptionPicker() { + var display = filter.value.display; + handleOnSelect(Map value) { - final filterText = []; - value.forEach((key, value) { - switch (key) { - case DisplayOption.notInAlbum: - filter.value = filter.value.copyWith(display: filter.value.display.copyWith(isNotInAlbum: value)); - if (value) { - filterText.add('search_filter_display_option_not_in_album'.t(context: context)); - } - break; - case DisplayOption.archive: - filter.value = filter.value.copyWith(display: filter.value.display.copyWith(isArchive: value)); - if (value) { - filterText.add('archive'.t(context: context)); - } - break; - case DisplayOption.favorite: - filter.value = filter.value.copyWith(display: filter.value.display.copyWith(isFavorite: value)); - if (value) { - filterText.add('favorite'.t(context: context)); - } - break; - } - }); - - if (filterText.isEmpty) { - displayOptionCurrentFilterWidget.value = null; - return; - } - - displayOptionCurrentFilterWidget.value = Text(filterText.join(', '), style: context.textTheme.labelLarge); + display = display.copyWith( + isNotInAlbum: value[DisplayOption.notInAlbum], + isArchive: value[DisplayOption.archive], + isFavorite: value[DisplayOption.favorite], + ); } handleClear() { - filter.value = filter.value.copyWith( - display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false), - ); - displayOptionCurrentFilterWidget.value = null; - search(); + search( + filter.value.copyWith( + display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false), + ), + ); + } + + handleApply() { + final filterText = [ + if (display.isNotInAlbum) 'search_filter_display_option_not_in_album'.t(context: context), + if (display.isArchive) 'archive'.t(context: context), + if (display.isFavorite) 'favorite'.t(context: context), + ]; + displayOptionCurrentFilterWidget.value = filterText.isNotEmpty + ? Text(filterText.join(', '), style: context.textTheme.labelLarge) + : null; + search(filter.value.copyWith(display: display)); } showFilterBottomSheet( context: context, child: FilterBottomSheetScaffold( title: 'display_options'.t(context: context), - onSearch: search, + onSearch: handleApply, onClear: handleClear, child: DisplayOptionPicker(onSelect: handleOnSelect, filter: filter.value.display), ), ); } - handleTextSubmitted(String value) { - switch (textSearchType.value) { - case TextSearchType.context: - filter.value = filter.value.copyWith(filename: '', context: value, description: '', ocr: ''); - - break; - case TextSearchType.filename: - filter.value = filter.value.copyWith(filename: value, context: '', description: '', ocr: ''); - - break; - case TextSearchType.description: - filter.value = filter.value.copyWith(filename: '', context: '', description: value, ocr: ''); - break; - case TextSearchType.ocr: - filter.value = filter.value.copyWith(filename: '', context: '', description: '', ocr: value); - break; - } - - search(); - } + handleTextSubmitted(String value) => search(switch (textSearchType.value) { + TextSearchType.context => filter.value.copyWith(filename: '', context: value, description: '', ocr: ''), + TextSearchType.filename => filter.value.copyWith(filename: value, context: '', description: '', ocr: ''), + TextSearchType.description => filter.value.copyWith(filename: '', context: '', description: value, ocr: ''), + TextSearchType.ocr => filter.value.copyWith(filename: '', context: '', description: '', ocr: value), + }); IconData getSearchPrefixIcon() => switch (textSearchType.value) { TextSearchType.context => Icons.image_search_rounded, @@ -648,8 +605,10 @@ class DriftSearchPage extends HookConsumerWidget { hintText: searchHintText.value, key: const Key('search_text_field'), controller: textSearchController, - contentPadding: preFilter != null ? const EdgeInsets.only(left: 24) : const EdgeInsets.all(8), - prefixIcon: preFilter != null ? null : Icon(getSearchPrefixIcon(), color: context.colorScheme.primary), + contentPadding: filter.value.assetId != null ? const EdgeInsets.only(left: 24) : const EdgeInsets.all(8), + prefixIcon: filter.value.assetId != null + ? null + : Icon(getSearchPrefixIcon(), color: context.colorScheme.primary), onSubmitted: handleTextSubmitted, focusNode: ref.watch(searchInputFocusProvider), ), @@ -724,7 +683,7 @@ class DriftSearchPage extends HookConsumerWidget { ), ), ), - if (!hasRequestedSearch.value) + if (filter.value.isEmpty) const _SearchSuggestions() else _SearchResultGrid(onScrollEnd: loadMoreSearchResults), diff --git a/mobile/lib/presentation/widgets/action_buttons/favorite_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/favorite_action_button.widget.dart index ba2491365d..07ace7e631 100644 --- a/mobile/lib/presentation/widgets/action_buttons/favorite_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/favorite_action_button.widget.dart @@ -2,8 +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/asset/base_asset.model.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/providers/asset_viewer/asset_viewer.provider.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'; @@ -23,6 +25,12 @@ class FavoriteActionButton extends ConsumerWidget { final result = await ref.read(actionProvider.notifier).favorite(source); if (source == ActionSource.viewer) { + if (result.success) { + final currentAsset = ref.read(assetViewerProvider).currentAsset; + if (currentAsset is RemoteAsset && !currentAsset.isFavorite) { + ref.read(assetViewerProvider.notifier).setAsset(currentAsset.copyWith(isFavorite: true)); + } + } return; } diff --git a/mobile/lib/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart index ec5513e0a8..5e88735d9c 100644 --- a/mobile/lib/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart @@ -2,8 +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/asset/base_asset.model.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/providers/asset_viewer/asset_viewer.provider.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'; @@ -23,6 +25,12 @@ class UnFavoriteActionButton extends ConsumerWidget { final result = await ref.read(actionProvider.notifier).unFavorite(source); if (source == ActionSource.viewer) { + if (result.success) { + final currentAsset = ref.read(assetViewerProvider).currentAsset; + if (currentAsset is RemoteAsset && currentAsset.isFavorite) { + ref.read(assetViewerProvider.notifier).setAsset(currentAsset.copyWith(isFavorite: false)); + } + } return; } 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 4d8954d4ef..3308ae8295 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart @@ -65,13 +65,15 @@ class AssetViewer extends ConsumerStatefulWidget { static void setAsset(WidgetRef ref, BaseAsset asset) { ref.read(assetViewerProvider.notifier).reset(); + + // Hide controls by default for videos + if (asset.isVideo) ref.read(assetViewerProvider.notifier).setControls(false); + _setAsset(ref, asset); } static void _setAsset(WidgetRef ref, BaseAsset asset) { ref.read(assetViewerProvider.notifier).setAsset(asset); - // Hide controls by default for videos - if (asset.isVideo) ref.read(assetViewerProvider.notifier).setControls(false); } } diff --git a/mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart index cc171f4490..b51960bb05 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart @@ -71,16 +71,13 @@ class ViewerBottomBar extends ConsumerWidget { ), child: SafeArea( top: false, - child: Padding( - padding: const EdgeInsets.only(top: 16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (asset.isVideo) VideoControls(videoPlayerName: asset.heroTag), - if (!isReadonlyModeEnabled) - Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: actions), - ], - ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (asset.isVideo) VideoControls(videoPlayerName: asset.heroTag), + if (!isReadonlyModeEnabled) + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: actions), + ], ), ), ), diff --git a/mobile/lib/presentation/widgets/bottom_sheet/trash_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/trash_bottom_sheet.widget.dart index 9f8216c4ed..c96e680966 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/trash_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/trash_bottom_sheet.widget.dart @@ -10,20 +10,19 @@ class TrashBottomBar extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - return SafeArea( - child: Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - height: 64, - child: Container( - color: context.themeData.canvasColor, - child: const Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - DeleteTrashActionButton(source: ActionSource.timeline), - RestoreTrashActionButton(source: ActionSource.timeline), - ], - ), + return Align( + alignment: Alignment.bottomCenter, + child: Container( + color: context.themeData.canvasColor, + padding: const EdgeInsets.symmetric(vertical: 8), + child: const SafeArea( + top: false, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + DeleteTrashActionButton(source: ActionSource.timeline), + RestoreTrashActionButton(source: ActionSource.timeline), + ], ), ), ), diff --git a/mobile/lib/presentation/widgets/images/animated_image_stream_completer.dart b/mobile/lib/presentation/widgets/images/animated_image_stream_completer.dart index be4fbff8cf..796d30e992 100644 --- a/mobile/lib/presentation/widgets/images/animated_image_stream_completer.dart +++ b/mobile/lib/presentation/widgets/images/animated_image_stream_completer.dart @@ -3,24 +3,21 @@ import 'dart:ui' as ui; import 'package:flutter/foundation.dart' show InformationCollector; import 'package:flutter/painting.dart'; +import 'package:immich_mobile/presentation/widgets/images/cache_aware_listener_tracker.mixin.dart'; /// A [MultiFrameImageStreamCompleter] with support for listener tracking /// which makes resource cleanup possible when no longer needed. /// Codec is disposed through the MultiFrameImageStreamCompleter's internals onDispose method -class AnimatedImageStreamCompleter extends MultiFrameImageStreamCompleter { - void Function()? _onLastListenerRemoved; - int _listenerCount = 0; - // True once any image or the codec has been provided. - // Until then the image cache holds one listener, so "last real listener gone" - // is _listenerCount == 1, not 0. - bool didProvideImage = false; - +class AnimatedImageStreamCompleter extends MultiFrameImageStreamCompleter with CacheAwareListenerTrackerMixin { AnimatedImageStreamCompleter._({ required super.codec, required super.scale, + required bool hadInitialImage, super.informationCollector, void Function()? onLastListenerRemoved, - }) : _onLastListenerRemoved = onLastListenerRemoved; + }) { + setupListenerTracking(hadInitialImage: hadInitialImage, onLastListenerRemoved: onLastListenerRemoved); + } factory AnimatedImageStreamCompleter({ required Stream stream, @@ -33,23 +30,21 @@ class AnimatedImageStreamCompleter extends MultiFrameImageStreamCompleter { final self = AnimatedImageStreamCompleter._( codec: codecCompleter.future, scale: scale, + hadInitialImage: initialImage != null, informationCollector: informationCollector, onLastListenerRemoved: onLastListenerRemoved, ); if (initialImage != null) { - self.didProvideImage = true; self.setImage(initialImage); } stream.listen( (item) { if (item is ImageInfo) { - self.didProvideImage = true; self.setImage(item); } else if (item is ui.Codec) { if (!codecCompleter.isCompleted) { - self.didProvideImage = true; codecCompleter.complete(item); } } @@ -70,27 +65,4 @@ class AnimatedImageStreamCompleter extends MultiFrameImageStreamCompleter { return self; } - - @override - void addListener(ImageStreamListener listener) { - super.addListener(listener); - _listenerCount++; - } - - @override - void removeListener(ImageStreamListener listener) { - super.removeListener(listener); - _listenerCount--; - - final bool onlyCacheListenerLeft = _listenerCount == 1 && !didProvideImage; - final bool noListenersAfterCodec = _listenerCount == 0 && didProvideImage; - - if (onlyCacheListenerLeft || noListenersAfterCodec) { - final onLastListenerRemoved = _onLastListenerRemoved; - if (onLastListenerRemoved != null) { - _onLastListenerRemoved = null; - onLastListenerRemoved(); - } - } - } } diff --git a/mobile/lib/presentation/widgets/images/cache_aware_listener_tracker.mixin.dart b/mobile/lib/presentation/widgets/images/cache_aware_listener_tracker.mixin.dart new file mode 100644 index 0000000000..e63d5c4cfc --- /dev/null +++ b/mobile/lib/presentation/widgets/images/cache_aware_listener_tracker.mixin.dart @@ -0,0 +1,84 @@ +import 'package:flutter/painting.dart'; + +/// Tracks listeners on an [ImageStreamCompleter] to safely cancel in-flight +/// network requests without interfering with [ImageCache] internals. +/// +/// ### Problem +/// Cancelling fetches when the listener count drops to 1 (cache only) or 0 +/// is unsafe due to three framework behaviours: +/// +/// 1. **Memory-pressure eviction** — `ImageCache.clear()` removes the cache +/// listener while UI widgets still need the image. A count-based check +/// would cancel the active fetch, leaving the UI with no image. +/// 2. **Synchronous detach during `putIfAbsent`** — When an `initialImage` +/// is provided, the cache attaches, receives the frame, and detaches +/// synchronously *before* the UI widget can attach. Count reaches 0 and +/// would trigger a false cancel. +/// 3. **Listener misidentification** — After the cache detaches (via 1 or 2), +/// the next UI listener could be mistaken for the cache listener, causing +/// incorrect cancellations when that widget is disposed. +/// +/// ### Solution: First-Listener Heuristic +/// The cache is always the first listener attached (via `putIfAbsent`). This +/// mixin records that identity once and uses it for all subsequent decisions: +/// +/// * **Identity locking** — The first listener is assumed to be the cache. +/// Once identified, `_hasIdentifiedCacheListener` prevents reassignment. +/// * **Targeted cancellation** — Cancel only when the identified cache +/// listener is the sole remaining listener and no image has been delivered. +/// * **Sync-removal bypass** — When `hadInitialImage` is set, the first +/// synchronous removal of the cache listener is ignored so the fetch +/// survives until the UI attaches. +mixin CacheAwareListenerTrackerMixin on ImageStreamCompleter { + void Function()? _onLastListenerRemoved; + int _listenerCount = 0; + bool _hadInitialImage = false; + bool _hasIgnoredFirstSyncRemoval = false; + ImageStreamListener? _cacheListener; + bool _hasIdentifiedCacheListener = false; + + /// Initializes the tracking state. Must be called in the subclass constructor. + void setupListenerTracking({required bool hadInitialImage, void Function()? onLastListenerRemoved}) { + _hadInitialImage = hadInitialImage; + _onLastListenerRemoved = onLastListenerRemoved; + } + + @override + void addListener(ImageStreamListener listener) { + if (!_hasIdentifiedCacheListener) { + _hasIdentifiedCacheListener = true; + _cacheListener = listener; + } + + _listenerCount++; + super.addListener(listener); + } + + @override + void removeListener(ImageStreamListener listener) { + super.removeListener(listener); + _listenerCount--; + + final bool isCacheListener = listener == _cacheListener; + if (isCacheListener) { + _cacheListener = null; + } + + if (_hadInitialImage && !_hasIgnoredFirstSyncRemoval && isCacheListener) { + _hasIgnoredFirstSyncRemoval = true; + return; + } + + final bool onlyCacheListenerLeft = _listenerCount == 1 && _cacheListener != null; + + final bool completelyAbandoned = _listenerCount == 0; + + if (onlyCacheListenerLeft || completelyAbandoned) { + final onLastListenerRemoved = _onLastListenerRemoved; + if (onLastListenerRemoved != null) { + _onLastListenerRemoved = null; + onLastListenerRemoved(); + } + } + } +} diff --git a/mobile/lib/presentation/widgets/images/image_provider.dart b/mobile/lib/presentation/widgets/images/image_provider.dart index bf29f9482f..47ebd37014 100644 --- a/mobile/lib/presentation/widgets/images/image_provider.dart +++ b/mobile/lib/presentation/widgets/images/image_provider.dart @@ -19,6 +19,7 @@ mixin CancellableImageProviderMixin on CancellableImageProvide static final _log = Logger('CancellableImageProviderMixin'); bool isCancelled = false; + bool isFinished = false; ImageRequest? request; CancelableOperation? cachedOperation; @@ -50,24 +51,26 @@ mixin CancellableImageProviderMixin on CancellableImageProvide return null; } - Stream loadRequest(ImageRequest request, ImageDecoderCallback decode, {bool evictOnError = true}) async* { + Stream loadRequest(ImageRequest request, ImageDecoderCallback decode, {required bool isFinal}) async* { if (isCancelled) { this.request = null; - PaintingBinding.instance.imageCache.evict(this); return; } try { final image = await request.load(decode); - if ((image == null && evictOnError) || isCancelled) { - PaintingBinding.instance.imageCache.evict(this); - return; - } else if (image == null) { + if (isCancelled || image == null) { + image?.dispose(); return; } + isFinished = isFinal; yield image; } catch (e, stack) { - if (evictOnError) { + if (isCancelled) { + return; + } + if (isFinal) { + isFinished = true; PaintingBinding.instance.imageCache.evict(this); rethrow; } @@ -77,24 +80,27 @@ mixin CancellableImageProviderMixin on CancellableImageProvide } } - Future loadCodecRequest(ImageRequest request) async { + Future loadCodecRequest(ImageRequest request, {required bool isFinal}) async { if (isCancelled) { this.request = null; - PaintingBinding.instance.imageCache.evict(this); return null; } try { final codec = await request.loadCodec(); - if (codec == null || isCancelled) { + if (isCancelled || codec == null) { codec?.dispose(); - PaintingBinding.instance.imageCache.evict(this); return null; } + isFinished = isFinal; return codec; } catch (e) { - PaintingBinding.instance.imageCache.evict(this); - rethrow; + if (isFinal) { + isFinished = true; + PaintingBinding.instance.imageCache.evict(this); + rethrow; + } + return null; } finally { this.request = null; } @@ -121,6 +127,8 @@ mixin CancellableImageProviderMixin on CancellableImageProvide @override void cancel() { isCancelled = true; + final hasActiveWork = !isFinished; + final request = this.request; if (request != null) { this.request = null; @@ -132,6 +140,10 @@ mixin CancellableImageProviderMixin on CancellableImageProvide cachedOperation = null; operation.cancel(); } + + if (hasActiveWork) { + PaintingBinding.instance.imageCache.evict(this); + } } } diff --git a/mobile/lib/presentation/widgets/images/local_image_provider.dart b/mobile/lib/presentation/widgets/images/local_image_provider.dart index 1ed2c361ff..d29a1cd56d 100644 --- a/mobile/lib/presentation/widgets/images/local_image_provider.dart +++ b/mobile/lib/presentation/widgets/images/local_image_provider.dart @@ -36,7 +36,7 @@ class LocalThumbProvider extends CancellableImageProvider Stream _codec(LocalThumbProvider key, ImageDecoderCallback decode) { final request = this.request = LocalImageRequest(localId: key.id, size: key.size, assetType: key.assetType); - return loadRequest(request, decode); + return loadRequest(request, decode, isFinal: true); } @override @@ -100,37 +100,35 @@ class LocalFullImageProvider extends CancellableImageProvider _animatedCodec(LocalFullImageProvider key, ImageDecoderCallback decode) async* { yield* initialImageStream(); if (isCancelled) { - PaintingBinding.instance.imageCache.evict(this); return; } @@ -140,17 +138,17 @@ class LocalFullImageProvider extends CancellableImageProvider Stream _codec(RemoteImageProvider key, ImageDecoderCallback decode) { final request = this.request = RemoteImageRequest(uri: key.url); - return loadRequest(request, decode); + return loadRequest(request, decode, isFinal: true); } @override @@ -105,7 +105,6 @@ class RemoteFullImageProvider extends CancellableImageProvider _animatedCodec(RemoteFullImageProvider key, ImageDecoderCallback decode) async* { yield* initialImageStream(); if (isCancelled) { - PaintingBinding.instance.imageCache.evict(this); return; } final previewRequest = request = RemoteImageRequest( uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview, thumbhash: key.thumbhash), ); - yield* loadRequest(previewRequest, decode, evictOnError: false); + yield* loadRequest(previewRequest, decode, isFinal: false); if (isCancelled) { - PaintingBinding.instance.imageCache.evict(this); return; } // always try original for animated, since previews don't support animation final originalRequest = request = RemoteImageRequest(uri: getOriginalUrlForRemoteId(key.assetId)); - final codec = await loadCodecRequest(originalRequest); + final codec = await loadCodecRequest(originalRequest, isFinal: true); if (codec == null) { + if (isCancelled) { + return; + } throw StateError('Failed to load animated codec for asset ${key.assetId}'); } yield codec; diff --git a/mobile/lib/presentation/widgets/images/thumb_hash_provider.dart b/mobile/lib/presentation/widgets/images/thumb_hash_provider.dart index 7076febe3b..02f957a5d9 100644 --- a/mobile/lib/presentation/widgets/images/thumb_hash_provider.dart +++ b/mobile/lib/presentation/widgets/images/thumb_hash_provider.dart @@ -22,7 +22,7 @@ class ThumbHashProvider extends CancellableImageProvider Stream _loadCodec(ThumbHashProvider key, ImageDecoderCallback decode) { final request = this.request = ThumbhashImageRequest(thumbhash: key.thumbHash); - return loadRequest(request, decode); + return loadRequest(request, decode, isFinal: true); } @override diff --git a/mobile/lib/providers/asset_viewer/video_player_provider.dart b/mobile/lib/providers/asset_viewer/video_player_provider.dart index a4a8bd1762..8093926873 100644 --- a/mobile/lib/providers/asset_viewer/video_player_provider.dart +++ b/mobile/lib/providers/asset_viewer/video_player_provider.dart @@ -226,7 +226,7 @@ class VideoPlayerNotifier extends StateNotifier { void _startBufferingTimer() { _bufferingTimer?.cancel(); - _bufferingTimer = Timer(const Duration(seconds: 3), () { + _bufferingTimer = Timer(const Duration(seconds: 1), () { if (mounted && state.status != VideoPlaybackStatus.completed) { state = state.copyWith(status: VideoPlaybackStatus.buffering); } diff --git a/mobile/lib/services/download.service.dart b/mobile/lib/services/download.service.dart index 7d2cf01b7c..8e810ced2a 100644 --- a/mobile/lib/services/download.service.dart +++ b/mobile/lib/services/download.service.dart @@ -109,7 +109,7 @@ class DownloadService { return result != null; } on PlatformException catch (error, stack) { // Handle saving MotionPhotos on iOS - if (error.code == 'PHPhotosErrorDomain (-1)') { + if (error.code.startsWith('PHPhotosErrorDomain')) { final result = await _fileMediaRepository.saveImageWithFile(imageFilePath, title: task.filename); return result != null; } diff --git a/mobile/lib/theme/dynamic_theme.dart b/mobile/lib/theme/dynamic_theme.dart index d0cb8e646f..7f7c4d05d7 100644 --- a/mobile/lib/theme/dynamic_theme.dart +++ b/mobile/lib/theme/dynamic_theme.dart @@ -19,8 +19,16 @@ abstract final class DynamicTheme { // Some palettes do not generate surface container colors accurately, // so we regenerate all colors using the primary color _theme = ImmichTheme( - light: ColorScheme.fromSeed(seedColor: primaryColor, brightness: Brightness.light), - dark: ColorScheme.fromSeed(seedColor: primaryColor, brightness: Brightness.dark), + light: ColorScheme.fromSeed( + seedColor: primaryColor, + brightness: Brightness.light, + dynamicSchemeVariant: DynamicSchemeVariant.fidelity, + ), + dark: ColorScheme.fromSeed( + seedColor: primaryColor, + brightness: Brightness.dark, + dynamicSchemeVariant: DynamicSchemeVariant.fidelity, + ), ); } } catch (error) { diff --git a/mobile/lib/theme/theme_data.dart b/mobile/lib/theme/theme_data.dart index 69b8596490..7200d58dca 100644 --- a/mobile/lib/theme/theme_data.dart +++ b/mobile/lib/theme/theme_data.dart @@ -62,6 +62,7 @@ ThemeData getThemeData({required ColorScheme colorScheme, required Locale locale ), chipTheme: const ChipThemeData(side: BorderSide.none), sliderTheme: const SliderThemeData( + trackHeight: 12, // ignore: deprecated_member_use year2023: false, ), diff --git a/mobile/lib/utils/user_agent.dart b/mobile/lib/utils/user_agent.dart index 232bcaec38..f08793e3a1 100644 --- a/mobile/lib/utils/user_agent.dart +++ b/mobile/lib/utils/user_agent.dart @@ -1,15 +1,16 @@ import 'dart:io' show Platform; + import 'package:package_info_plus/package_info_plus.dart'; Future getUserAgentString() async { final packageInfo = await PackageInfo.fromPlatform(); String platform; if (Platform.isAndroid) { - platform = 'Android'; + platform = 'android'; } else if (Platform.isIOS) { - platform = 'iOS'; + platform = 'ios'; } else { - platform = 'Unknown'; + platform = 'unknown'; } - return 'Immich_${platform}_${packageInfo.version}'; + return 'immich-$platform/${packageInfo.version}'; } diff --git a/mobile/lib/widgets/asset_viewer/video_controls.dart b/mobile/lib/widgets/asset_viewer/video_controls.dart index 85707c82ea..89b0f0ec30 100644 --- a/mobile/lib/widgets/asset_viewer/video_controls.dart +++ b/mobile/lib/widgets/asset_viewer/video_controls.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:async/async.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/colors.dart'; @@ -7,26 +8,63 @@ import 'package:immich_mobile/models/cast/cast_manager_state.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; -import 'package:immich_mobile/utils/hooks/timer_hook.dart'; import 'package:immich_mobile/extensions/duration_extensions.dart'; import 'package:immich_mobile/widgets/asset_viewer/animated_play_pause.dart'; -class VideoControls extends HookConsumerWidget { +class VideoControls extends ConsumerStatefulWidget { final String videoPlayerName; static const List _controlShadows = [Shadow(color: Colors.black87, blurRadius: 6, offset: Offset(0, 1))]; const VideoControls({super.key, required this.videoPlayerName}); - void _toggle(WidgetRef ref, bool isCasting) { - if (isCasting) { - ref.read(castProvider.notifier).toggle(); - } else { - ref.read(videoPlayerProvider(videoPlayerName).notifier).toggle(); + @override + ConsumerState createState() => _VideoControlsState(); +} + +class _VideoControlsState extends ConsumerState { + late final RestartableTimer _hideTimer; + + AutoDisposeStateNotifierProvider get _provider => + videoPlayerProvider(widget.videoPlayerName); + + @override + void initState() { + super.initState(); + _hideTimer = RestartableTimer(const Duration(seconds: 5), _onHideTimer); + } + + @override + void didUpdateWidget(covariant VideoControls oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.videoPlayerName != widget.videoPlayerName) { + _hideTimer.reset(); } } - void _onSeek(WidgetRef ref, bool isCasting, double value) { + @override + void dispose() { + _hideTimer.cancel(); + super.dispose(); + } + + void _onHideTimer() { + if (!mounted) return; + if (ref.read(_provider).status == VideoPlaybackStatus.playing) { + ref.read(assetViewerProvider.notifier).setControls(false); + } + } + + void _toggle(bool isCasting) { + if (isCasting) { + ref.read(castProvider.notifier).toggle(); + return; + } + + ref.read(_provider.notifier).toggle(); + } + + void _onSeek(bool isCasting, double value) { final seekTo = Duration(microseconds: value.toInt()); if (isCasting) { @@ -34,41 +72,36 @@ class VideoControls extends HookConsumerWidget { return; } - ref.read(videoPlayerProvider(videoPlayerName).notifier).seekTo(seekTo); + ref.read(_provider.notifier).seekTo(seekTo); } @override - Widget build(BuildContext context, WidgetRef ref) { - final provider = videoPlayerProvider(videoPlayerName); + Widget build(BuildContext context) { final cast = ref.watch(castProvider); final isCasting = cast.isCasting; final (position, duration) = isCasting ? ref.watch(castProvider.select((c) => (c.currentTime, c.duration))) - : ref.watch(provider.select((v) => (v.position, v.duration))); + : ref.watch(_provider.select((v) => (v.position, v.duration))); - final videoStatus = ref.watch(provider.select((v) => v.status)); + final videoStatus = ref.watch(_provider.select((v) => v.status)); final isPlaying = isCasting ? cast.castState == CastState.playing : videoStatus == VideoPlaybackStatus.playing || videoStatus == VideoPlaybackStatus.buffering; final isFinished = !isCasting && videoStatus == VideoPlaybackStatus.completed; - final hideTimer = useTimer(const Duration(seconds: 5), () { - if (!context.mounted) return; - if (ref.read(provider).status == VideoPlaybackStatus.playing) { - ref.read(assetViewerProvider.notifier).setControls(false); - } + ref.listen(assetViewerProvider.select((v) => v.showingControls), (prev, showing) { + if (showing && prev != showing) _hideTimer.reset(); }); + ref.listen(_provider.select((v) => v.status), (_, __) => _hideTimer.reset()); - ref.listen(provider.select((v) => v.status), (_, __) => hideTimer.reset()); - - final notifier = ref.read(provider.notifier); + final notifier = ref.read(_provider.notifier); final isLoaded = duration != Duration.zero; return Padding( - padding: const EdgeInsets.all(24), + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 12), child: Column( - spacing: 16, + spacing: 4, children: [ Row( children: [ @@ -77,9 +110,13 @@ class VideoControls extends HookConsumerWidget { padding: const EdgeInsets.all(12), constraints: const BoxConstraints(), icon: isFinished - ? const Icon(Icons.replay, color: Colors.white, size: 32, shadows: _controlShadows) - : AnimatedPlayPause(color: Colors.white, size: 32, playing: isPlaying, shadows: _controlShadows), - onPressed: () => _toggle(ref, isCasting), + ? const Icon(Icons.replay, color: Colors.white, shadows: VideoControls._controlShadows) + : AnimatedPlayPause( + color: Colors.white, + playing: isPlaying, + shadows: VideoControls._controlShadows, + ), + onPressed: () => _toggle(isCasting), ), const Spacer(), Text( @@ -88,10 +125,10 @@ class VideoControls extends HookConsumerWidget { color: Colors.white, fontWeight: FontWeight.w500, fontFeatures: [FontFeature.tabularFigures()], - shadows: _controlShadows, + shadows: VideoControls._controlShadows, ), ), - const SizedBox(width: 16), + const SizedBox(width: 12), ], ), Slider( @@ -104,7 +141,7 @@ class VideoControls extends HookConsumerWidget { padding: EdgeInsets.zero, onChangeStart: (_) => notifier.hold(), onChangeEnd: (_) => notifier.release(), - onChanged: isLoaded ? (value) => _onSeek(ref, isCasting, value) : null, + onChanged: isLoaded ? (value) => _onSeek(isCasting, value) : null, ), ], ), diff --git a/mobile/lib/widgets/common/immich_toast.dart b/mobile/lib/widgets/common/immich_toast.dart index dad8b33283..3e7ab273d8 100644 --- a/mobile/lib/widgets/common/immich_toast.dart +++ b/mobile/lib/widgets/common/immich_toast.dart @@ -55,7 +55,7 @@ class ImmichToast { bottom: gravity == ToastGravity.BOTTOM ? 150 : null, left: MediaQuery.of(context).size.width / 2 - 150, right: MediaQuery.of(context).size.width / 2 - 150, - child: child, + child: IgnorePointer(child: child), ); }, gravity: gravity, diff --git a/mobile/lib/widgets/search/search_filter/search_filter_chip.dart b/mobile/lib/widgets/search/search_filter/search_filter_chip.dart index a72b4668dd..d539ee38f3 100644 --- a/mobile/lib/widgets/search/search_filter/search_filter_chip.dart +++ b/mobile/lib/widgets/search/search_filter/search_filter_chip.dart @@ -16,7 +16,7 @@ class SearchFilterChip extends StatelessWidget { onTap: onTap, child: Card( elevation: 0, - color: context.primaryColor.withValues(alpha: .5), + color: context.colorScheme.secondaryContainer, shape: StadiumBorder(side: BorderSide(color: context.colorScheme.secondaryContainer)), child: Padding( padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 14.0), @@ -32,7 +32,13 @@ class SearchFilterChip extends StatelessWidget { shape: StadiumBorder(side: BorderSide(color: context.colorScheme.outline.withAlpha(15))), child: Padding( padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 14.0), - child: Row(children: [Icon(icon, size: 18), const SizedBox(width: 4.0), Text(label)]), + child: Row( + children: [ + Icon(icon, size: 18), + const SizedBox(width: 4.0), + Text(label, style: TextStyle(color: context.colorScheme.onSecondaryContainer)), + ], + ), ), ), ); diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index d8b70b7b4e..000f7a8144 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.6.2 +- API version: 2.7.5 - Generator version: 7.8.0 - Build package: org.openapitools.codegen.languages.DartClientCodegen @@ -156,6 +156,7 @@ Class | Method | HTTP request | Description *DuplicatesApi* | [**deleteDuplicate**](doc//DuplicatesApi.md#deleteduplicate) | **DELETE** /duplicates/{id} | Delete a duplicate *DuplicatesApi* | [**deleteDuplicates**](doc//DuplicatesApi.md#deleteduplicates) | **DELETE** /duplicates | Delete duplicates *DuplicatesApi* | [**getAssetDuplicates**](doc//DuplicatesApi.md#getassetduplicates) | **GET** /duplicates | Retrieve duplicates +*DuplicatesApi* | [**resolveDuplicates**](doc//DuplicatesApi.md#resolveduplicates) | **POST** /duplicates/resolve | Resolve duplicate groups *FacesApi* | [**createFace**](doc//FacesApi.md#createface) | **POST** /faces | Create a face *FacesApi* | [**deleteFace**](doc//FacesApi.md#deleteface) | **DELETE** /faces/{id} | Delete a face *FacesApi* | [**getFaces**](doc//FacesApi.md#getfaces) | **GET** /faces | Retrieve faces for asset @@ -422,6 +423,8 @@ Class | Method | HTTP request | Description - [DownloadResponseDto](doc//DownloadResponseDto.md) - [DownloadUpdate](doc//DownloadUpdate.md) - [DuplicateDetectionConfig](doc//DuplicateDetectionConfig.md) + - [DuplicateResolveDto](doc//DuplicateResolveDto.md) + - [DuplicateResolveGroupDto](doc//DuplicateResolveGroupDto.md) - [DuplicateResponseDto](doc//DuplicateResponseDto.md) - [EmailNotificationsResponse](doc//EmailNotificationsResponse.md) - [EmailNotificationsUpdate](doc//EmailNotificationsUpdate.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index 9a276f832f..819c49da89 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -161,6 +161,8 @@ part 'model/download_response.dart'; part 'model/download_response_dto.dart'; part 'model/download_update.dart'; part 'model/duplicate_detection_config.dart'; +part 'model/duplicate_resolve_dto.dart'; +part 'model/duplicate_resolve_group_dto.dart'; part 'model/duplicate_response_dto.dart'; part 'model/email_notifications_response.dart'; part 'model/email_notifications_update.dart'; diff --git a/mobile/openapi/lib/api/duplicates_api.dart b/mobile/openapi/lib/api/duplicates_api.dart index 7fa7b368b5..e873537592 100644 --- a/mobile/openapi/lib/api/duplicates_api.dart +++ b/mobile/openapi/lib/api/duplicates_api.dart @@ -163,4 +163,63 @@ class DuplicatesApi { } return null; } + + /// Resolve duplicate groups + /// + /// Resolve duplicate groups by synchronizing metadata across assets and deleting/trashing duplicates. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [DuplicateResolveDto] duplicateResolveDto (required): + Future resolveDuplicatesWithHttpInfo(DuplicateResolveDto duplicateResolveDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/duplicates/resolve'; + + // ignore: prefer_final_locals + Object? postBody = duplicateResolveDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Resolve duplicate groups + /// + /// Resolve duplicate groups by synchronizing metadata across assets and deleting/trashing duplicates. + /// + /// Parameters: + /// + /// * [DuplicateResolveDto] duplicateResolveDto (required): + Future?> resolveDuplicates(DuplicateResolveDto duplicateResolveDto,) async { + final response = await resolveDuplicatesWithHttpInfo(duplicateResolveDto,); + 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; + } } diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 6defd952dd..b9ecf21c95 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -368,6 +368,10 @@ class ApiClient { return DownloadUpdate.fromJson(value); case 'DuplicateDetectionConfig': return DuplicateDetectionConfig.fromJson(value); + case 'DuplicateResolveDto': + return DuplicateResolveDto.fromJson(value); + case 'DuplicateResolveGroupDto': + return DuplicateResolveGroupDto.fromJson(value); case 'DuplicateResponseDto': return DuplicateResponseDto.fromJson(value); case 'EmailNotificationsResponse': diff --git a/mobile/openapi/lib/model/bulk_id_error_reason.dart b/mobile/openapi/lib/model/bulk_id_error_reason.dart index ea56e9dbba..fd6c61d6fd 100644 --- a/mobile/openapi/lib/model/bulk_id_error_reason.dart +++ b/mobile/openapi/lib/model/bulk_id_error_reason.dart @@ -27,6 +27,7 @@ class BulkIdErrorReason { static const noPermission = BulkIdErrorReason._(r'no_permission'); static const notFound = BulkIdErrorReason._(r'not_found'); static const unknown = BulkIdErrorReason._(r'unknown'); + static const validation = BulkIdErrorReason._(r'validation'); /// List of all possible values in this [enum][BulkIdErrorReason]. static const values = [ @@ -34,6 +35,7 @@ class BulkIdErrorReason { noPermission, notFound, unknown, + validation, ]; static BulkIdErrorReason? fromJson(dynamic value) => BulkIdErrorReasonTypeTransformer().decode(value); @@ -76,6 +78,7 @@ class BulkIdErrorReasonTypeTransformer { case r'no_permission': return BulkIdErrorReason.noPermission; case r'not_found': return BulkIdErrorReason.notFound; case r'unknown': return BulkIdErrorReason.unknown; + case r'validation': return BulkIdErrorReason.validation; default: if (!allowNull) { throw ArgumentError('Unknown enum value to decode: $data'); diff --git a/mobile/openapi/lib/model/bulk_id_response_dto.dart b/mobile/openapi/lib/model/bulk_id_response_dto.dart index cd122785dd..1fa8536964 100644 --- a/mobile/openapi/lib/model/bulk_id_response_dto.dart +++ b/mobile/openapi/lib/model/bulk_id_response_dto.dart @@ -14,6 +14,7 @@ class BulkIdResponseDto { /// Returns a new [BulkIdResponseDto] instance. BulkIdResponseDto({ this.error, + this.errorMessage, required this.id, required this.success, }); @@ -21,6 +22,14 @@ class BulkIdResponseDto { /// Error reason if failed BulkIdResponseDtoErrorEnum? error; + /// + /// 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? errorMessage; + /// ID String id; @@ -30,6 +39,7 @@ class BulkIdResponseDto { @override bool operator ==(Object other) => identical(this, other) || other is BulkIdResponseDto && other.error == error && + other.errorMessage == errorMessage && other.id == id && other.success == success; @@ -37,11 +47,12 @@ class BulkIdResponseDto { int get hashCode => // ignore: unnecessary_parenthesis (error == null ? 0 : error!.hashCode) + + (errorMessage == null ? 0 : errorMessage!.hashCode) + (id.hashCode) + (success.hashCode); @override - String toString() => 'BulkIdResponseDto[error=$error, id=$id, success=$success]'; + String toString() => 'BulkIdResponseDto[error=$error, errorMessage=$errorMessage, id=$id, success=$success]'; Map toJson() { final json = {}; @@ -49,6 +60,11 @@ class BulkIdResponseDto { json[r'error'] = this.error; } else { // json[r'error'] = null; + } + if (this.errorMessage != null) { + json[r'errorMessage'] = this.errorMessage; + } else { + // json[r'errorMessage'] = null; } json[r'id'] = this.id; json[r'success'] = this.success; @@ -65,6 +81,7 @@ class BulkIdResponseDto { return BulkIdResponseDto( error: BulkIdResponseDtoErrorEnum.fromJson(json[r'error']), + errorMessage: mapValueOfType(json, r'errorMessage'), id: mapValueOfType(json, r'id')!, success: mapValueOfType(json, r'success')!, ); @@ -136,6 +153,7 @@ class BulkIdResponseDtoErrorEnum { static const noPermission = BulkIdResponseDtoErrorEnum._(r'no_permission'); static const notFound = BulkIdResponseDtoErrorEnum._(r'not_found'); static const unknown = BulkIdResponseDtoErrorEnum._(r'unknown'); + static const validation = BulkIdResponseDtoErrorEnum._(r'validation'); /// List of all possible values in this [enum][BulkIdResponseDtoErrorEnum]. static const values = [ @@ -143,6 +161,7 @@ class BulkIdResponseDtoErrorEnum { noPermission, notFound, unknown, + validation, ]; static BulkIdResponseDtoErrorEnum? fromJson(dynamic value) => BulkIdResponseDtoErrorEnumTypeTransformer().decode(value); @@ -185,6 +204,7 @@ class BulkIdResponseDtoErrorEnumTypeTransformer { case r'no_permission': return BulkIdResponseDtoErrorEnum.noPermission; case r'not_found': return BulkIdResponseDtoErrorEnum.notFound; case r'unknown': return BulkIdResponseDtoErrorEnum.unknown; + case r'validation': return BulkIdResponseDtoErrorEnum.validation; default: if (!allowNull) { throw ArgumentError('Unknown enum value to decode: $data'); diff --git a/mobile/openapi/lib/model/database_backup_dto.dart b/mobile/openapi/lib/model/database_backup_dto.dart index 4bf231587b..34912a55e0 100644 --- a/mobile/openapi/lib/model/database_backup_dto.dart +++ b/mobile/openapi/lib/model/database_backup_dto.dart @@ -15,30 +15,36 @@ class DatabaseBackupDto { DatabaseBackupDto({ required this.filename, required this.filesize, + required this.timezone, }); String filename; num filesize; + String timezone; + @override bool operator ==(Object other) => identical(this, other) || other is DatabaseBackupDto && other.filename == filename && - other.filesize == filesize; + other.filesize == filesize && + other.timezone == timezone; @override int get hashCode => // ignore: unnecessary_parenthesis (filename.hashCode) + - (filesize.hashCode); + (filesize.hashCode) + + (timezone.hashCode); @override - String toString() => 'DatabaseBackupDto[filename=$filename, filesize=$filesize]'; + String toString() => 'DatabaseBackupDto[filename=$filename, filesize=$filesize, timezone=$timezone]'; Map toJson() { final json = {}; json[r'filename'] = this.filename; json[r'filesize'] = this.filesize; + json[r'timezone'] = this.timezone; return json; } @@ -53,6 +59,7 @@ class DatabaseBackupDto { return DatabaseBackupDto( filename: mapValueOfType(json, r'filename')!, filesize: num.parse('${json[r'filesize']}'), + timezone: mapValueOfType(json, r'timezone')!, ); } return null; @@ -102,6 +109,7 @@ class DatabaseBackupDto { static const requiredKeys = { 'filename', 'filesize', + 'timezone', }; } diff --git a/mobile/openapi/lib/model/duplicate_resolve_dto.dart b/mobile/openapi/lib/model/duplicate_resolve_dto.dart new file mode 100644 index 0000000000..3466d3a620 --- /dev/null +++ b/mobile/openapi/lib/model/duplicate_resolve_dto.dart @@ -0,0 +1,100 @@ +// +// 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 DuplicateResolveDto { + /// Returns a new [DuplicateResolveDto] instance. + DuplicateResolveDto({ + this.groups = const [], + }); + + /// List of duplicate groups to resolve + List groups; + + @override + bool operator ==(Object other) => identical(this, other) || other is DuplicateResolveDto && + _deepEquality.equals(other.groups, groups); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (groups.hashCode); + + @override + String toString() => 'DuplicateResolveDto[groups=$groups]'; + + Map toJson() { + final json = {}; + json[r'groups'] = this.groups; + return json; + } + + /// Returns a new [DuplicateResolveDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DuplicateResolveDto? fromJson(dynamic value) { + upgradeDto(value, "DuplicateResolveDto"); + if (value is Map) { + final json = value.cast(); + + return DuplicateResolveDto( + groups: DuplicateResolveGroupDto.listFromJson(json[r'groups']), + ); + } + 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 = DuplicateResolveDto.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 = DuplicateResolveDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DuplicateResolveDto-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] = DuplicateResolveDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'groups', + }; +} + diff --git a/mobile/openapi/lib/model/duplicate_resolve_group_dto.dart b/mobile/openapi/lib/model/duplicate_resolve_group_dto.dart new file mode 100644 index 0000000000..94ca53eb7d --- /dev/null +++ b/mobile/openapi/lib/model/duplicate_resolve_group_dto.dart @@ -0,0 +1,121 @@ +// +// 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 DuplicateResolveGroupDto { + /// Returns a new [DuplicateResolveGroupDto] instance. + DuplicateResolveGroupDto({ + required this.duplicateId, + this.keepAssetIds = const [], + this.trashAssetIds = const [], + }); + + String duplicateId; + + /// Asset IDs to keep + List keepAssetIds; + + /// Asset IDs to trash or delete + List trashAssetIds; + + @override + bool operator ==(Object other) => identical(this, other) || other is DuplicateResolveGroupDto && + other.duplicateId == duplicateId && + _deepEquality.equals(other.keepAssetIds, keepAssetIds) && + _deepEquality.equals(other.trashAssetIds, trashAssetIds); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (duplicateId.hashCode) + + (keepAssetIds.hashCode) + + (trashAssetIds.hashCode); + + @override + String toString() => 'DuplicateResolveGroupDto[duplicateId=$duplicateId, keepAssetIds=$keepAssetIds, trashAssetIds=$trashAssetIds]'; + + Map toJson() { + final json = {}; + json[r'duplicateId'] = this.duplicateId; + json[r'keepAssetIds'] = this.keepAssetIds; + json[r'trashAssetIds'] = this.trashAssetIds; + return json; + } + + /// Returns a new [DuplicateResolveGroupDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DuplicateResolveGroupDto? fromJson(dynamic value) { + upgradeDto(value, "DuplicateResolveGroupDto"); + if (value is Map) { + final json = value.cast(); + + return DuplicateResolveGroupDto( + duplicateId: mapValueOfType(json, r'duplicateId')!, + keepAssetIds: json[r'keepAssetIds'] is Iterable + ? (json[r'keepAssetIds'] as Iterable).cast().toList(growable: false) + : const [], + trashAssetIds: json[r'trashAssetIds'] is Iterable + ? (json[r'trashAssetIds'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = DuplicateResolveGroupDto.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 = DuplicateResolveGroupDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DuplicateResolveGroupDto-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] = DuplicateResolveGroupDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'duplicateId', + 'keepAssetIds', + 'trashAssetIds', + }; +} + diff --git a/mobile/openapi/lib/model/duplicate_response_dto.dart b/mobile/openapi/lib/model/duplicate_response_dto.dart index 6c85dc8013..f0ddbb4fdd 100644 --- a/mobile/openapi/lib/model/duplicate_response_dto.dart +++ b/mobile/openapi/lib/model/duplicate_response_dto.dart @@ -15,6 +15,7 @@ class DuplicateResponseDto { DuplicateResponseDto({ this.assets = const [], required this.duplicateId, + this.suggestedKeepAssetIds = const [], }); /// Duplicate assets @@ -23,24 +24,30 @@ class DuplicateResponseDto { /// Duplicate group ID String duplicateId; + /// Suggested asset IDs to keep based on file size and EXIF data + List suggestedKeepAssetIds; + @override bool operator ==(Object other) => identical(this, other) || other is DuplicateResponseDto && _deepEquality.equals(other.assets, assets) && - other.duplicateId == duplicateId; + other.duplicateId == duplicateId && + _deepEquality.equals(other.suggestedKeepAssetIds, suggestedKeepAssetIds); @override int get hashCode => // ignore: unnecessary_parenthesis (assets.hashCode) + - (duplicateId.hashCode); + (duplicateId.hashCode) + + (suggestedKeepAssetIds.hashCode); @override - String toString() => 'DuplicateResponseDto[assets=$assets, duplicateId=$duplicateId]'; + String toString() => 'DuplicateResponseDto[assets=$assets, duplicateId=$duplicateId, suggestedKeepAssetIds=$suggestedKeepAssetIds]'; Map toJson() { final json = {}; json[r'assets'] = this.assets; json[r'duplicateId'] = this.duplicateId; + json[r'suggestedKeepAssetIds'] = this.suggestedKeepAssetIds; return json; } @@ -55,6 +62,9 @@ class DuplicateResponseDto { return DuplicateResponseDto( assets: AssetResponseDto.listFromJson(json[r'assets']), duplicateId: mapValueOfType(json, r'duplicateId')!, + suggestedKeepAssetIds: json[r'suggestedKeepAssetIds'] is Iterable + ? (json[r'suggestedKeepAssetIds'] as Iterable).cast().toList(growable: false) + : const [], ); } return null; @@ -104,6 +114,7 @@ class DuplicateResponseDto { static const requiredKeys = { 'assets', 'duplicateId', + 'suggestedKeepAssetIds', }; } diff --git a/mobile/openapi/lib/model/metadata_search_dto.dart b/mobile/openapi/lib/model/metadata_search_dto.dart index 81f8d41527..4dbc90d407 100644 --- a/mobile/openapi/lib/model/metadata_search_dto.dart +++ b/mobile/openapi/lib/model/metadata_search_dto.dart @@ -379,7 +379,7 @@ class MetadataSearchDto { /// bool? withExif; - /// Include assets with people + /// Include people data in response /// /// 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 diff --git a/mobile/openapi/lib/model/random_search_dto.dart b/mobile/openapi/lib/model/random_search_dto.dart index 4166fc9f3c..d5803c9cc7 100644 --- a/mobile/openapi/lib/model/random_search_dto.dart +++ b/mobile/openapi/lib/model/random_search_dto.dart @@ -273,7 +273,7 @@ class RandomSearchDto { /// bool? withExif; - /// Include assets with people + /// Include people data in response /// /// 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 diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index b0046ec449..1e03bd6e7f 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.6.2+3040 +version: 2.7.5+3046 environment: sdk: '>=3.8.0 <4.0.0' diff --git a/mobile/test/presentation/widgets/images/cache_aware_listener_tracker_mixin_test.dart b/mobile/test/presentation/widgets/images/cache_aware_listener_tracker_mixin_test.dart new file mode 100644 index 0000000000..02bb0c1053 --- /dev/null +++ b/mobile/test/presentation/widgets/images/cache_aware_listener_tracker_mixin_test.dart @@ -0,0 +1,183 @@ +import 'dart:ui' as ui; + +import 'package:flutter/painting.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/presentation/widgets/images/cache_aware_listener_tracker.mixin.dart'; + +class TestImageCompleter extends ImageStreamCompleter with CacheAwareListenerTrackerMixin { + bool wasCancelled = false; + + TestImageCompleter({required bool hadInitialImage}) { + setupListenerTracking( + hadInitialImage: hadInitialImage, + onLastListenerRemoved: () { + wasCancelled = true; + }, + ); + } + + @override + void setImage(ImageInfo image) { + super.setImage(image); + } +} + +void main() { + late ImageCache cache; + late ImageStreamListener uiListener; + + setUp(() { + // Create a fresh, real Flutter ImageCache for every test + cache = ImageCache(); + uiListener = ImageStreamListener((_, __) {}); + }); + + group('CacheAwareListenerTrackerMixin with Real ImageCache', () { + + testWidgets('cancels fetch when UI detaches before completion', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + // 1. Request image from the real cache (simulating the provider) + final stream = cache.putIfAbsent(key, () => completer)!; + + // 2. UI attaches + stream.addListener(uiListener); + expect(completer.wasCancelled, isFalse); + + // 3. Simulate asynchronous network delay... + await tester.pump(const Duration(milliseconds: 150)); + + // 4. User scrolls away before network finishes. UI detaches. + stream.removeListener(uiListener); + + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('survives cache eviction while UI listener is still attached', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + // 1. Request image and attach UI + final stream = cache.putIfAbsent(key, () => completer)!; + stream.addListener(uiListener); + + // 2. Simulate app going to background -> OS Memory Warning -> Cache clears + cache.clear(); + + // Even though the real cache just aggressively detached its listener, + // the stream MUST survive because the UI widget is still on screen! + expect(completer.wasCancelled, isFalse); + + // 3. UI widget finally detaches + stream.removeListener(uiListener); + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('survives synchronous cache detach during putIfAbsent with initialImage', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: true); + final key = Object(); + + // Run image creation outside FakeAsync zone to avoid hang + late ui.Image dummyImage; + await tester.runAsync(() async { + dummyImage = await createTestImage(width: 1, height: 1); + }); + + final initialImageInfo = ImageInfo(image: dummyImage); + + final stream = cache.putIfAbsent(key, () { + completer.setImage(initialImageInfo); + return completer; + })!; + + expect(completer.wasCancelled, isFalse); + + stream.addListener(uiListener); + expect(completer.wasCancelled, isFalse); + + stream.removeListener(uiListener); + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('fires cleanup on full abandonment even after successful fetch', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + final stream = cache.putIfAbsent(key, () => completer)!; + stream.addListener(uiListener); + + await tester.pump(const Duration(milliseconds: 100)); + + // Run image creation outside FakeAsync zone to avoid hang + late ui.Image dummyImage; + await tester.runAsync(() async { + dummyImage = await createTestImage(width: 1, height: 1); + }); + + completer.setImage(ImageInfo(image: dummyImage)); + + stream.removeListener(uiListener); + + // The stream is completely abandoned (0 listeners), so it fires the cleanup hook. + // Since the image is already downloaded, canceling the network token is a safe no-op. + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('Multiple UI listeners — only all detached, should cancel', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + final stream = cache.putIfAbsent(key, () => completer)!; + + final uiListener2 = ImageStreamListener((_, __) {}); + stream.addListener(uiListener); + stream.addListener(uiListener2); + + // First UI detach leaves cache + one UI → no cancel + stream.removeListener(uiListener); + expect(completer.wasCancelled, isFalse); + + // Second UI detach leaves only cache → cancel + stream.removeListener(uiListener2); + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('Listener misidentification: new listener after cache eviction is not treated as cache', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + final stream = cache.putIfAbsent(key, () => completer)!; + + // UI attaches + stream.addListener(uiListener); + + // Cache eviction removes the cache listener + cache.clear(); + expect(completer.wasCancelled, isFalse); + + // A second UI listener attaches — must NOT be treated as cache + final uiListener2 = ImageStreamListener((_, __) {}); + stream.addListener(uiListener2); + + // Remove first UI listener; second UI still active → no cancel + stream.removeListener(uiListener); + expect(completer.wasCancelled, isFalse); + + // Remove second UI listener; completely abandoned → cancel + stream.removeListener(uiListener2); + expect(completer.wasCancelled, isTrue); + }); + + testWidgets('No UI listener ever attaches (cache-only) — cache detaches should cancel', (WidgetTester tester) async { + final completer = TestImageCompleter(hadInitialImage: false); + final key = Object(); + + cache.putIfAbsent(key, () => completer); + + // Cache eviction removes the only listener + cache.clear(); + expect(completer.wasCancelled, isTrue); + }); + }); +} diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 5a52ffee6f..664ae10add 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -5285,6 +5285,65 @@ "x-immich-state": "Stable" } }, + "/duplicates/resolve": { + "post": { + "description": "Resolve duplicate groups by synchronizing metadata across assets and deleting/trashing duplicates.", + "operationId": "resolveDuplicates", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DuplicateResolveDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/BulkIdResponseDto" + }, + "type": "array" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Resolve duplicate groups", + "tags": [ + "Duplicates" + ], + "x-immich-history": [ + { + "version": "v3.0.0", + "state": "Added" + }, + { + "version": "v3.0.0", + "state": "Alpha" + } + ], + "x-immich-permission": "duplicate.delete", + "x-immich-state": "Alpha" + } + }, "/duplicates/{id}": { "delete": { "description": "Delete a single duplicate asset specified by its ID.", @@ -15166,7 +15225,7 @@ "info": { "title": "Immich", "description": "Immich API", - "version": "2.6.2", + "version": "2.7.5", "contact": {} }, "tags": [ @@ -17299,7 +17358,8 @@ "duplicate", "no_permission", "not_found", - "unknown" + "unknown", + "validation" ], "type": "string" }, @@ -17311,10 +17371,14 @@ "duplicate", "no_permission", "not_found", - "unknown" + "unknown", + "validation" ], "type": "string" }, + "errorMessage": { + "type": "string" + }, "id": { "description": "ID", "type": "string" @@ -17657,11 +17721,15 @@ }, "filesize": { "type": "number" + }, + "timezone": { + "type": "string" } }, "required": [ "filename", - "filesize" + "filesize", + "timezone" ], "type": "object" }, @@ -17828,6 +17896,52 @@ ], "type": "object" }, + "DuplicateResolveDto": { + "properties": { + "groups": { + "description": "List of duplicate groups to resolve", + "items": { + "$ref": "#/components/schemas/DuplicateResolveGroupDto" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "groups" + ], + "type": "object" + }, + "DuplicateResolveGroupDto": { + "properties": { + "duplicateId": { + "format": "uuid", + "type": "string" + }, + "keepAssetIds": { + "description": "Asset IDs to keep", + "items": { + "format": "uuid", + "type": "string" + }, + "type": "array" + }, + "trashAssetIds": { + "description": "Asset IDs to trash or delete", + "items": { + "format": "uuid", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "duplicateId", + "keepAssetIds", + "trashAssetIds" + ], + "type": "object" + }, "DuplicateResponseDto": { "properties": { "assets": { @@ -17840,11 +17954,20 @@ "duplicateId": { "description": "Duplicate group ID", "type": "string" + }, + "suggestedKeepAssetIds": { + "description": "Suggested asset IDs to keep based on file size and EXIF data", + "items": { + "format": "uuid", + "type": "string" + }, + "type": "array" } }, "required": [ "assets", - "duplicateId" + "duplicateId", + "suggestedKeepAssetIds" ], "type": "object" }, @@ -19129,7 +19252,7 @@ "type": "boolean" }, "withPeople": { - "description": "Include assets with people", + "description": "Include people data in response", "type": "boolean" }, "withStacked": { @@ -20868,7 +20991,7 @@ "type": "boolean" }, "withPeople": { - "description": "Include assets with people", + "description": "Include people data in response", "type": "boolean" }, "withStacked": { diff --git a/open-api/typescript-sdk/.nvmrc b/open-api/typescript-sdk/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/open-api/typescript-sdk/.nvmrc +++ b/open-api/typescript-sdk/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/open-api/typescript-sdk/package.json b/open-api/typescript-sdk/package.json index 9f6846d072..bb4f3cfe05 100644 --- a/open-api/typescript-sdk/package.json +++ b/open-api/typescript-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@immich/sdk", - "version": "2.6.2", + "version": "2.7.5", "description": "Auto-generated TypeScript SDK for the Immich API", "type": "module", "main": "./build/index.js", @@ -19,8 +19,8 @@ "@oazapfts/runtime": "^1.0.2" }, "devDependencies": { - "@types/node": "^24.11.0", - "typescript": "^5.3.3" + "@types/node": "^24.12.0", + "typescript": "^6.0.0" }, "repository": { "type": "git", @@ -28,6 +28,6 @@ "directory": "open-api/typescript-sdk" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" } } diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index 653ad1703d..d42a5a6b04 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.6.2 + * 2.7.5 * DO NOT MODIFY - This file has been generated using oazapfts. * See https://www.npmjs.com/package/oazapfts */ @@ -63,6 +63,7 @@ export type DatabaseBackupDeleteDto = { export type DatabaseBackupDto = { filename: string; filesize: number; + timezone: string; }; export type DatabaseBackupListResponseDto = { backups: DatabaseBackupDto[]; @@ -725,6 +726,7 @@ export type BulkIdsDto = { export type BulkIdResponseDto = { /** Error reason if failed */ error?: Error; + errorMessage?: string; /** ID */ id: string; /** Whether operation succeeded */ @@ -1163,6 +1165,19 @@ export type DuplicateResponseDto = { assets: AssetResponseDto[]; /** Duplicate group ID */ duplicateId: string; + /** Suggested asset IDs to keep based on file size and EXIF data */ + suggestedKeepAssetIds: string[]; +}; +export type DuplicateResolveGroupDto = { + duplicateId: string; + /** Asset IDs to keep */ + keepAssetIds: string[]; + /** Asset IDs to trash or delete */ + trashAssetIds: string[]; +}; +export type DuplicateResolveDto = { + /** List of duplicate groups to resolve */ + groups: DuplicateResolveGroupDto[]; }; export type PersonResponseDto = { /** Person date of birth */ @@ -1741,7 +1756,7 @@ export type MetadataSearchDto = { withDeleted?: boolean; /** Include EXIF data in response */ withExif?: boolean; - /** Include assets with people */ + /** Include people data in response */ withPeople?: boolean; /** Include stacked assets */ withStacked?: boolean; @@ -1855,7 +1870,7 @@ export type RandomSearchDto = { withDeleted?: boolean; /** Include EXIF data in response */ withExif?: boolean; - /** Include assets with people */ + /** Include people data in response */ withPeople?: boolean; /** Include stacked assets */ withStacked?: boolean; @@ -4569,6 +4584,21 @@ export function getAssetDuplicates(opts?: Oazapfts.RequestOpts) { ...opts })); } +/** + * Resolve duplicate groups + */ +export function resolveDuplicates({ duplicateResolveDto }: { + duplicateResolveDto: DuplicateResolveDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: BulkIdResponseDto[]; + }>("/duplicates/resolve", oazapfts.json({ + ...opts, + method: "POST", + body: duplicateResolveDto + }))); +} /** * Delete a duplicate */ @@ -6931,13 +6961,15 @@ export enum BulkIdErrorReason { Duplicate = "duplicate", NoPermission = "no_permission", NotFound = "not_found", - Unknown = "unknown" + Unknown = "unknown", + Validation = "validation" } export enum Error { Duplicate = "duplicate", NoPermission = "no_permission", NotFound = "not_found", - Unknown = "unknown" + Unknown = "unknown", + Validation = "validation" } export enum Permission { All = "all", diff --git a/open-api/typescript-sdk/tsconfig.json b/open-api/typescript-sdk/tsconfig.json index 30d58d5177..a4255c3f6c 100644 --- a/open-api/typescript-sdk/tsconfig.json +++ b/open-api/typescript-sdk/tsconfig.json @@ -7,6 +7,7 @@ "outDir": "build", "module": "Node16", "moduleResolution": "Node16", + "rootDir": "./src", "lib": ["esnext", "dom"] }, "include": ["src/**/*.ts"] diff --git a/package.json b/package.json index a02b7efc8b..3b223811d2 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "immich-monorepo", - "version": "2.6.2", + "version": "2.7.5", "description": "Monorepo for Immich", "private": true, - "packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017", + "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be", "engines": { "pnpm": ">=10.0.0" } diff --git a/plugins/package-lock.json b/plugins/package-lock.json index 9ebaa59a02..efff7ef4fe 100644 --- a/plugins/package-lock.json +++ b/plugins/package-lock.json @@ -11,13 +11,13 @@ "devDependencies": { "@extism/js-pdk": "^1.0.1", "esbuild": "^0.27.0", - "typescript": "^5.3.2" + "typescript": "^6.0.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", "cpu": [ "ppc64" ], @@ -32,9 +32,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", "cpu": [ "arm" ], @@ -49,9 +49,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", "cpu": [ "arm64" ], @@ -66,9 +66,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", "cpu": [ "x64" ], @@ -83,9 +83,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", "cpu": [ "arm64" ], @@ -100,9 +100,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", "cpu": [ "x64" ], @@ -117,9 +117,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", "cpu": [ "arm64" ], @@ -134,9 +134,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", "cpu": [ "x64" ], @@ -151,9 +151,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", "cpu": [ "arm" ], @@ -168,9 +168,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", "cpu": [ "arm64" ], @@ -185,9 +185,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", "cpu": [ "ia32" ], @@ -202,9 +202,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", "cpu": [ "loong64" ], @@ -219,9 +219,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", "cpu": [ "mips64el" ], @@ -236,9 +236,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", "cpu": [ "ppc64" ], @@ -253,9 +253,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", "cpu": [ "riscv64" ], @@ -270,9 +270,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", "cpu": [ "s390x" ], @@ -287,9 +287,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", "cpu": [ "x64" ], @@ -304,9 +304,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", "cpu": [ "arm64" ], @@ -321,9 +321,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", "cpu": [ "x64" ], @@ -338,9 +338,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", "cpu": [ "arm64" ], @@ -355,9 +355,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", "cpu": [ "x64" ], @@ -372,9 +372,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", "cpu": [ "arm64" ], @@ -389,9 +389,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", "cpu": [ "x64" ], @@ -406,9 +406,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", "cpu": [ "arm64" ], @@ -423,9 +423,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", "cpu": [ "ia32" ], @@ -440,9 +440,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", "cpu": [ "x64" ], @@ -467,9 +467,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -480,38 +480,38 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/plugins/package.json b/plugins/package.json index abeabe7161..04d6600480 100644 --- a/plugins/package.json +++ b/plugins/package.json @@ -14,6 +14,6 @@ "devDependencies": { "@extism/js-pdk": "^1.0.1", "esbuild": "^0.27.0", - "typescript": "^5.3.2" + "typescript": "^6.0.0" } } diff --git a/plugins/src/index.ts b/plugins/src/index.ts index 9566c02cd8..5cf666fc87 100644 --- a/plugins/src/index.ts +++ b/plugins/src/index.ts @@ -44,7 +44,7 @@ export function actionAddToAlbum() { authToken, assetId: data.asset.id, albumId: albumId, - }) + }), ); addAssetToAlbum(ptr.offset); @@ -61,7 +61,7 @@ export function actionArchive() { authToken, id: data.asset.id, visibility: 'archive', - }) + }), ); updateAsset(ptr.offset); diff --git a/plugins/tsconfig.json b/plugins/tsconfig.json index 86c9e766bf..a0bc730661 100644 --- a/plugins/tsconfig.json +++ b/plugins/tsconfig.json @@ -2,17 +2,13 @@ "compilerOptions": { "target": "es2020", // Specify ECMAScript target version "module": "commonjs", // Specify module code generation - "lib": [ - "es2020" - ], // Specify a list of library files to be included in the compilation - "types": [ - "@extism/js-pdk", - "./src/index.d.ts" - ], // Specify a list of type definition files to be included in the compilation + "lib": ["es2020"], // Specify a list of library files to be included in the compilation + "types": ["./src/index.d.ts", "./node_modules/@extism/js-pdk"], // Specify a list of type definition files to be included in the compilation "strict": true, // Enable all strict type-checking options "esModuleInterop": true, // Enables compatibility with Babel-style module imports "skipLibCheck": true, // Skip type checking of declaration files "allowJs": true, // Allow JavaScript files to be compiled + "rootDir": "./src", "noEmit": true // Do not emit outputs (no .js or .d.ts files) }, "include": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 320815b631..524c9cca26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,14 +36,14 @@ importers: version: 1.20.1 lodash-es: specifier: ^4.17.21 - version: 4.17.23 + version: 4.18.1 micromatch: specifier: ^4.0.8 version: 4.0.8 devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.0.2(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) '@immich/sdk': specifier: workspace:* version: link:../open-api/typescript-sdk @@ -63,11 +63,11 @@ importers: specifier: ^4.13.1 version: 4.13.4 '@types/node': - specifier: ^24.11.0 - version: 24.12.0 + specifier: ^24.12.0 + version: 24.12.2 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.0(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))) byte-size: specifier: ^9.0.0 version: 9.0.1 @@ -79,16 +79,16 @@ importers: version: 12.1.0 eslint: specifier: ^10.0.0 - version: 10.0.2(jiti@2.6.1) + version: 10.1.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.0.2(jiti@2.6.1)) + version: 10.1.8(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@3.8.1) eslint-plugin-unicorn: - specifier: ^63.0.0 - version: 63.0.0(eslint@10.0.2(jiti@2.6.1)) + specifier: ^64.0.0 + version: 64.0.0(eslint@10.1.0(jiti@2.6.1)) globals: specifier: ^17.0.0 version: 17.4.0 @@ -100,40 +100,40 @@ importers: version: 3.8.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.8.1)(typescript@5.9.3) + version: 4.3.0(prettier@3.8.1)(typescript@6.0.2) typescript: - specifier: ^5.3.3 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 typescript-eslint: - specifier: ^8.28.0 - version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.58.0 + version: 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) vite: specifier: ^8.0.0 - version: 8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) vitest: specifier: ^4.0.0 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) vitest-fetch-mock: specifier: ^0.4.0 - version: 0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.4.5(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))) yaml: specifier: ^2.3.1 - version: 2.8.2 + version: 2.8.3 docs: dependencies: '@docusaurus/core': specifier: ~3.9.0 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@docusaurus/preset-classic': specifier: ~3.9.0 - version: 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(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.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3)(typescript@6.0.2) '@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.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@docusaurus/theme-mermaid': 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.14)(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.14)(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(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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.14)(react@18.3.1) + version: 3.1.1(@types/react@19.2.14)(react@19.2.4) autoprefixer: specifier: ^10.4.17 version: 10.4.27(postcss@8.5.8) 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.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) lunr: specifier: ^2.3.9 version: 2.3.9 @@ -157,44 +157,44 @@ importers: version: 8.5.8 prism-react-renderer: specifier: ^2.3.1 - version: 2.4.1(react@18.3.1) + version: 2.4.1(react@19.2.4) raw-loader: specifier: ^4.0.2 version: 4.0.2(webpack@5.104.1) react: - specifier: ^18.0.0 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.2.4 react-dom: - specifier: ^18.0.0 - version: 18.3.1(react@18.3.1) + specifier: ^19.0.0 + version: 19.2.4(react@19.2.4) tailwindcss: specifier: ^3.2.4 - version: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + version: 3.4.19(tsx@4.21.0)(yaml@2.8.3) url: specifier: ^0.11.0 version: 0.11.4 devDependencies: '@docusaurus/module-type-aliases': specifier: ~3.9.0 - version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@docusaurus/tsconfig': - specifier: ^3.7.0 - version: 3.9.2 + specifier: ^3.10.0 + version: 3.10.0 '@docusaurus/types': specifier: ^3.7.0 - version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) prettier: specifier: ^3.7.4 version: 3.8.1 typescript: - specifier: ^5.1.6 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 e2e: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.0.2(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) '@faker-js/faker': specifier: ^10.1.0 version: 10.3.0 @@ -217,35 +217,35 @@ importers: specifier: ^3.4.2 version: 3.7.1 '@types/node': - specifier: ^24.11.0 - version: 24.12.0 + specifier: ^24.12.0 + version: 24.12.2 '@types/pg': specifier: ^8.15.1 - version: 8.18.0 + version: 8.20.0 '@types/pngjs': specifier: ^6.0.4 version: 6.0.5 '@types/supertest': - specifier: ^6.0.2 - version: 6.0.3 + specifier: ^7.0.0 + version: 7.2.0 dotenv: specifier: ^17.2.3 version: 17.3.1 eslint: specifier: ^10.0.0 - version: 10.0.2(jiti@2.6.1) + version: 10.1.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.0.2(jiti@2.6.1)) + version: 10.1.8(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@3.8.1) eslint-plugin-unicorn: - specifier: ^63.0.0 - version: 63.0.0(eslint@10.0.2(jiti@2.6.1)) + specifier: ^64.0.0 + version: 64.0.0(eslint@10.1.0(jiti@2.6.1)) exiftool-vendored: specifier: ^35.0.0 - version: 35.13.1 + version: 35.15.1 globals: specifier: ^17.0.0 version: 17.4.0 @@ -263,7 +263,7 @@ importers: version: 3.8.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.8.1)(typescript@5.9.3) + version: 4.3.0(prettier@3.8.1)(typescript@6.0.2) sharp: specifier: ^0.34.5 version: 0.34.5 @@ -274,20 +274,20 @@ importers: specifier: ^7.0.0 version: 7.2.2 typescript: - specifier: ^5.3.3 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 typescript-eslint: specifier: ^8.28.0 - version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) utimes: specifier: ^5.2.1 version: 5.2.1(encoding@0.1.13) vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(typescript@5.9.3)(vite@8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.1.1(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) vitest: specifier: ^4.0.0 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) e2e-auth-server: devDependencies: @@ -299,7 +299,7 @@ importers: version: 5.10.0 oidc-provider: specifier: ^9.0.0 - version: 9.6.1 + version: 9.7.1 tsx: specifier: ^4.20.6 version: 4.21.0 @@ -320,11 +320,11 @@ importers: version: 1.2.0 devDependencies: '@types/node': - specifier: ^24.11.0 - version: 24.12.0 + specifier: ^24.12.0 + version: 24.12.2 typescript: - specifier: ^5.3.3 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 plugins: devDependencies: @@ -333,10 +333,10 @@ importers: version: 1.1.1 esbuild: specifier: ^0.27.0 - version: 0.27.3 + version: 0.27.4 typescript: - specifier: ^5.3.2 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 server: dependencies: @@ -348,28 +348,28 @@ importers: version: 0.3.2 '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.4(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(bullmq@5.70.4) + version: 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(bullmq@5.71.0) '@nestjs/common': specifier: ^11.0.4 - version: 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': specifier: ^11.0.4 - version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.4 - version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) '@nestjs/platform-socket.io': specifier: ^11.0.4 - version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.16)(rxjs@7.8.2) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) '@nestjs/schedule': specifier: ^6.0.0 - version: 6.1.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) '@nestjs/swagger': specifier: ^11.0.2 - version: 11.2.6(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + version: 11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) '@nestjs/websockets': specifier: ^11.0.4 - version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-socket.io@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -429,7 +429,7 @@ importers: version: 2.2.2 bullmq: specifier: ^5.51.0 - version: 5.70.4 + version: 5.71.0 chokidar: specifier: ^4.0.3 version: 4.0.3 @@ -453,7 +453,7 @@ importers: version: 4.4.0 exiftool-vendored: specifier: ^35.0.0 - version: 35.13.1 + version: 35.15.1 express: specifier: ^5.1.0 version: 5.2.1 @@ -465,16 +465,19 @@ importers: version: 2.1.3 geo-tz: specifier: ^8.0.0 - version: 8.1.5 + version: 8.1.6 handlebars: specifier: ^4.7.8 - version: 4.7.8 + version: 4.7.9 + helmet: + specifier: ^8.1.0 + version: 8.1.0 i18n-iso-countries: specifier: ^7.6.0 version: 7.14.0 ioredis: specifier: ^5.8.2 - version: 5.10.0 + version: 5.10.1 jose: specifier: ^5.10.0 version: 5.10.0 @@ -485,14 +488,14 @@ importers: specifier: ^9.0.2 version: 9.0.3 kysely: - specifier: 0.28.11 - version: 0.28.11 + specifier: 0.28.14 + version: 0.28.14 kysely-postgres-js: specifier: ^3.0.0 - version: 3.0.0(kysely@0.28.11)(postgres@3.4.8) + version: 3.0.0(kysely@0.28.14)(postgres@3.4.8) lodash: specifier: ^4.17.21 - version: 4.17.23 + version: 4.18.1 luxon: specifier: ^3.4.2 version: 3.7.2 @@ -504,19 +507,19 @@ importers: version: 2.1.1 nest-commander: specifier: ^3.16.0 - version: 3.20.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@types/inquirer@8.2.12)(@types/node@24.12.0)(typescript@5.9.3) + version: 3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2) nestjs-cls: specifier: ^5.0.0 - version: 5.4.3(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: 3.1.2 - version: 3.1.2(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(kysely@0.28.11)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(kysely@0.28.14)(reflect-metadata@0.2.2) nestjs-otel: specifier: ^7.0.0 - version: 7.0.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) nodemailer: - specifier: ^7.0.0 - version: 7.0.13 + specifier: ^8.0.0 + version: 8.0.4 openid-client: specifier: ^6.3.3 version: 6.8.2 @@ -528,7 +531,7 @@ importers: version: 2.12.0 picomatch: specifier: ^4.0.2 - version: 4.0.3 + version: 4.0.4 postgres: specifier: 3.4.8 version: 3.4.8 @@ -549,10 +552,7 @@ importers: version: 7.8.2 sanitize-filename: specifier: ^1.6.3 - version: 1.6.3 - sanitize-html: - specifier: ^2.14.0 - version: 2.17.1 + version: 1.6.4 semver: specifier: ^7.6.2 version: 7.7.4 @@ -567,7 +567,7 @@ importers: version: 4.8.3 tailwindcss-preset-email: specifier: ^1.4.0 - version: 1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + version: 1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) thumbhash: specifier: ^0.1.1 version: 0.1.1 @@ -586,16 +586,16 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.0.2(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) '@nestjs/cli': specifier: ^11.0.2 - version: 11.0.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(@types/node@24.12.0)(esbuild@0.27.3) + version: 11.0.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(@types/node@24.12.2)(esbuild@0.27.4) '@nestjs/schematics': specifier: ^11.0.0 - version: 11.0.9(chokidar@4.0.3)(typescript@5.9.3) + version: 11.0.9(chokidar@4.0.3)(typescript@6.0.2) '@nestjs/testing': specifier: ^11.0.4 - version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-express@11.1.17) '@swc/core': specifier: ^1.4.14 version: 1.15.18(@swc/helpers@0.5.17) @@ -642,8 +642,8 @@ importers: specifier: ^2.0.0 version: 2.1.0 '@types/node': - specifier: ^24.11.0 - version: 24.12.0 + specifier: ^24.12.0 + version: 24.12.2 '@types/nodemailer': specifier: ^7.0.0 version: 7.0.11 @@ -656,15 +656,12 @@ importers: '@types/react': specifier: ^19.0.0 version: 19.2.14 - '@types/sanitize-html': - specifier: ^2.13.0 - version: 2.16.1 '@types/semver': specifier: ^7.5.8 version: 7.7.1 '@types/supertest': - specifier: ^6.0.0 - version: 6.0.3 + specifier: ^7.0.0 + version: 7.2.0 '@types/ua-parser-js': specifier: ^0.7.36 version: 0.7.39 @@ -673,19 +670,19 @@ importers: 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@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) eslint: specifier: ^10.0.0 - version: 10.0.2(jiti@2.6.1) + version: 10.1.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.0.2(jiti@2.6.1)) + version: 10.1.8(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@3.8.1) eslint-plugin-unicorn: - specifier: ^63.0.0 - version: 63.0.0(eslint@10.0.2(jiti@2.6.1)) + specifier: ^64.0.0 + version: 64.0.0(eslint@10.1.0(jiti@2.6.1)) globals: specifier: ^17.0.0 version: 17.4.0 @@ -703,7 +700,7 @@ importers: version: 3.8.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.8.1)(typescript@5.9.3) + version: 4.3.0(prettier@3.8.1)(typescript@6.0.2) sql-formatter: specifier: ^15.0.0 version: 15.7.2 @@ -712,31 +709,31 @@ importers: version: 7.2.2 tailwindcss: specifier: ^3.4.0 - version: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + version: 3.4.19(tsx@4.21.0)(yaml@2.8.3) testcontainers: specifier: ^11.0.0 - version: 11.12.0 + version: 11.13.0 typescript: - specifier: ^5.9.2 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 typescript-eslint: specifier: ^8.28.0 - version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) unplugin-swc: specifier: ^1.4.5 version: 1.5.9(@swc/core@1.15.18(@swc/helpers@0.5.17))(rollup@4.55.1) vite-tsconfig-paths: specifier: ^6.0.0 - version: 6.1.1(typescript@5.9.3)(vite@8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.1.1(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) web: dependencies: '@formatjs/icu-messageformat-parser': specifier: ^3.0.0 - version: 3.5.1 + version: 3.5.3 '@immich/justified-layout-wasm': specifier: ^0.4.3 version: 0.4.3 @@ -744,8 +741,8 @@ importers: specifier: workspace:* version: link:../open-api/typescript-sdk '@immich/ui': - specifier: ^0.65.3 - version: 0.65.3(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13) + specifier: ^0.69.0 + version: 0.69.0(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1) '@mapbox/mapbox-gl-rtl-text': specifier: 0.3.0 version: 0.3.0 @@ -778,7 +775,7 @@ importers: version: 0.42.0 '@zoom-image/svelte': specifier: ^0.3.0 - version: 0.3.9(svelte@5.53.13) + version: 0.3.9(svelte@5.54.1) dom-to-image: specifier: ^2.6.0 version: 2.6.0 @@ -793,25 +790,25 @@ importers: version: 0.5.0 handlebars: specifier: ^4.7.8 - version: 4.7.8 + version: 4.7.9 happy-dom: specifier: ^20.0.0 - version: 20.8.3 + version: 20.8.9 intl-messageformat: specifier: ^11.0.0 - version: 11.1.2 + version: 11.2.0 justified-layout: specifier: ^4.1.0 version: 4.1.0 lodash-es: specifier: ^4.17.21 - version: 4.17.23 + version: 4.18.1 luxon: specifier: ^3.4.4 version: 3.7.2 maplibre-gl: specifier: ^5.6.2 - version: 5.19.0 + version: 5.21.0 pmtiles: specifier: ^4.3.0 version: 4.4.0 @@ -829,16 +826,16 @@ importers: version: 5.2.2 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.53.13) + version: 4.0.1(svelte@5.54.1) svelte-jsoneditor: specifier: ^3.10.0 - version: 3.11.0(svelte@5.53.13) + version: 3.11.0(svelte@5.54.1) svelte-maplibre: specifier: ^1.2.5 - version: 1.2.6(svelte@5.53.13) + version: 1.2.6(svelte@5.54.1) svelte-persisted-store: specifier: ^0.12.0 - version: 0.12.0(svelte@5.53.13) + version: 0.12.0(svelte@5.54.1) tabbable: specifier: ^6.2.0 version: 6.4.0 @@ -860,37 +857,37 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.0.2(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) '@faker-js/faker': specifier: ^10.0.0 version: 10.3.0 '@koddsson/eslint-plugin-tscompat': specifier: ^0.2.0 - version: 0.2.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + version: 0.2.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) '@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.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))) + version: 3.0.10(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))) '@sveltejs/enhanced-img': specifier: ^0.10.4 - version: 0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(rollup@4.55.1)(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(rollup@4.55.1)(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@sveltejs/kit': specifier: ^2.27.1 - version: 2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@sveltejs/vite-plugin-svelte': specifier: 7.0.0 - version: 7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@tailwindcss/vite': specifier: ^4.2.2 - version: 4.2.2(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.2(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@testing-library/jest-dom': specifier: ^6.4.2 version: 6.9.1 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.3.1(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.3.1(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))) '@testing-library/user-event': specifier: ^14.5.2 version: 14.6.1(@testing-library/dom@10.4.1) @@ -914,25 +911,25 @@ importers: version: 1.5.6 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.0(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))) dotenv: specifier: ^17.0.0 version: 17.3.1 eslint: specifier: ^10.0.0 - version: 10.0.2(jiti@2.6.1) + version: 10.1.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.0.2(jiti@2.6.1)) + version: 10.1.8(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-compat: - specifier: ^6.0.2 - version: 6.2.1(eslint@10.0.2(jiti@2.6.1)) + specifier: ^7.0.0 + version: 7.0.1(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-svelte: specifier: ^3.12.4 - version: 3.15.0(eslint@10.0.2(jiti@2.6.1))(svelte@5.53.13) + version: 3.16.0(eslint@10.1.0(jiti@2.6.1))(svelte@5.54.1) eslint-plugin-unicorn: - specifier: ^63.0.0 - version: 63.0.0(eslint@10.0.2(jiti@2.6.1)) + specifier: ^64.0.0 + version: 64.0.0(eslint@10.1.0(jiti@2.6.1)) factory.ts: specifier: ^1.4.1 version: 1.4.2 @@ -944,40 +941,40 @@ importers: version: 3.8.1 prettier-plugin-organize-imports: specifier: ^4.0.0 - version: 4.3.0(prettier@3.8.1)(typescript@5.9.3) + version: 4.3.0(prettier@3.8.1)(typescript@6.0.2) prettier-plugin-sort-json: specifier: ^4.1.1 version: 4.2.0(prettier@3.8.1) prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.5.1(prettier@3.8.1)(svelte@5.53.13) + version: 3.5.1(prettier@3.8.1)(svelte@5.54.1) rollup-plugin-visualizer: - specifier: ^6.0.0 - version: 6.0.11(rolldown@1.0.0-rc.9)(rollup@4.55.1) + specifier: ^7.0.0 + version: 7.0.1(rolldown@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1))(rollup@4.55.1) svelte: - specifier: 5.53.13 - version: 5.53.13 + specifier: 5.54.1 + version: 5.54.1 svelte-check: specifier: ^4.1.5 - version: 4.4.4(picomatch@4.0.3)(svelte@5.53.13)(typescript@5.9.3) + version: 4.4.5(picomatch@4.0.4)(svelte@5.54.1)(typescript@6.0.2) svelte-eslint-parser: specifier: ^1.3.3 - version: 1.6.0(svelte@5.53.13) + version: 1.6.0(svelte@5.54.1) tailwindcss: specifier: ^4.2.2 version: 4.2.2 typescript: - specifier: ^5.8.3 - version: 5.9.3 + specifier: ^6.0.0 + version: 6.0.2 typescript-eslint: specifier: ^8.45.0 - version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) vite: specifier: ^8.0.0 - version: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) vitest: specifier: ^4.0.0 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) packages: @@ -1231,8 +1228,8 @@ packages: resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true @@ -1682,8 +1679,8 @@ packages: resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': @@ -1705,8 +1702,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@borewit/text-codec@0.2.1': - resolution: {integrity: sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==} + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} @@ -2240,8 +2237,8 @@ packages: resolution: {integrity: sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==} engines: {node: '>=20.0'} - '@docusaurus/tsconfig@3.9.2': - resolution: {integrity: sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==} + '@docusaurus/tsconfig@3.10.0': + resolution: {integrity: sha512-TXdC3WXuPrdQAexLvjUJfnYf3YKEgEqAs5nK0Q88pRBCW7t7oN4ILvWYb3A5Z1wlSXyXGWW/mCUmLEhdWsjnDQ==} '@docusaurus/types@3.9.2': resolution: {integrity: sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==} @@ -2261,11 +2258,11 @@ packages: resolution: {integrity: sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==} engines: {node: '>=20.0'} - '@emnapi/core@1.9.0': - resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} '@emnapi/wasi-threads@1.2.0': resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} @@ -2282,8 +2279,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.3': - resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -2300,8 +2297,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.3': - resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -2318,8 +2315,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.3': - resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -2336,8 +2333,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.3': - resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -2354,8 +2351,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.3': - resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -2372,8 +2369,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.3': - resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -2390,8 +2387,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.3': - resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -2408,8 +2405,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.3': - resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -2426,8 +2423,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.3': - resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -2444,8 +2441,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.3': - resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -2462,8 +2459,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.3': - resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -2480,8 +2477,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.3': - resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -2498,8 +2495,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.3': - resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -2516,8 +2513,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.3': - resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -2534,8 +2531,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.3': - resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -2552,8 +2549,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.3': - resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -2570,8 +2567,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.3': - resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -2582,8 +2579,8 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.3': - resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -2600,8 +2597,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.3': - resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -2612,8 +2609,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.3': - resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -2630,8 +2627,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.3': - resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -2642,8 +2639,8 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.3': - resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -2660,8 +2657,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.3': - resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -2678,8 +2675,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.3': - resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -2696,8 +2693,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.3': - resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -2714,8 +2711,8 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.3': - resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -2730,16 +2727,16 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.23.2': - resolution: {integrity: sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==} + '@eslint/config-array@0.23.3': + resolution: {integrity: sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.5.2': - resolution: {integrity: sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==} + '@eslint/config-helpers@0.5.3': + resolution: {integrity: sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/core@1.1.0': - resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==} + '@eslint/core@1.1.1': + resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/js@10.0.1': @@ -2751,12 +2748,12 @@ packages: eslint: optional: true - '@eslint/object-schema@3.0.2': - resolution: {integrity: sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==} + '@eslint/object-schema@3.0.3': + resolution: {integrity: sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.6.0': - resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==} + '@eslint/plugin-kit@0.6.1': + resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@extism/extism@2.0.0-rc13': @@ -2783,35 +2780,38 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@formatjs/bigdecimal@0.2.0': + resolution: {integrity: sha512-GeaxHZbUoYvHL9tC5eltHLs+1zU70aPw0s7LwqgktIzF5oMhNY4o4deEtusJMsq7WFJF3Ye2zQEzdG8beVk73w==} + '@formatjs/ecma402-abstract@2.3.6': resolution: {integrity: sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==} - '@formatjs/ecma402-abstract@3.1.1': - resolution: {integrity: sha512-jhZbTwda+2tcNrs4kKvxrPLPjx8QsBCLCUgrrJ/S+G9YrGHWLhAyFMMBHJBnBoOwuLHd7L14FgYudviKaxkO2Q==} + '@formatjs/ecma402-abstract@3.2.0': + resolution: {integrity: sha512-dHnqHgBo6GXYGRsepaE1wmsC2etaivOWd5VaJstZd+HI2zR3DCUjbDVZRtoPGkkXZmyHvBwrdEUuqfvzhF/DtQ==} '@formatjs/fast-memoize@2.2.7': resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==} - '@formatjs/fast-memoize@3.1.0': - resolution: {integrity: sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg==} + '@formatjs/fast-memoize@3.1.1': + resolution: {integrity: sha512-CbNbf+tlJn1baRnPkNePnBqTLxGliG6DDgNa/UtV66abwIjwsliPMOt0172tzxABYzSuxZBZfcp//qI8AvBWPg==} '@formatjs/icu-messageformat-parser@2.11.4': resolution: {integrity: sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==} - '@formatjs/icu-messageformat-parser@3.5.1': - resolution: {integrity: sha512-sSDmSvmmoVQ92XqWb499KrIhv/vLisJU8ITFrx7T7NZHUmMY7EL9xgRowAosaljhqnj/5iufG24QrdzB6X3ItA==} + '@formatjs/icu-messageformat-parser@3.5.3': + resolution: {integrity: sha512-HJWZ9S6JWey6iY5+YXE3Kd0ofWU1sC2KTTp56e1168g/xxWvVvr8k9G4fexIgwYV9wbtjY7kGYK5FjoWB3B2OQ==} '@formatjs/icu-skeleton-parser@1.8.16': resolution: {integrity: sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==} - '@formatjs/icu-skeleton-parser@2.1.1': - resolution: {integrity: sha512-PSFABlcNefjI6yyk8f7nyX1DC7NHmq6WaCHZLySEXBrXuLOB2f935YsnzuPjlz+ibhb9yWTdPeVX1OVcj24w2Q==} + '@formatjs/icu-skeleton-parser@2.1.3': + resolution: {integrity: sha512-9mFp8TJ166ZM2pcjKwsBWXrDnOJGT7vMEScVgLygUODPOsE8S6f/FHoacvrlHK1B4dYZk8vSCNruyPU64AfgJQ==} '@formatjs/intl-localematcher@0.6.2': resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} - '@formatjs/intl-localematcher@0.8.1': - resolution: {integrity: sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==} + '@formatjs/intl-localematcher@0.8.2': + resolution: {integrity: sha512-q05KMYGJLyqFNFtIb8NhWLF5X3aK/k0wYt7dnRFuy6aLQL+vUwQ1cg5cO4qawEiINybeCPXAWlprY2mSBjSXAQ==} '@fortawesome/fontawesome-common-types@7.1.0': resolution: {integrity: sha512-l/BQM7fYntsCI//du+6sEnHOP6a74UixFyOYUyz2DLMXKx+6DEhfR3F2NYGE45XH1JJuIamacb4IZs9S0ZOWLA==} @@ -3038,8 +3038,8 @@ packages: peerDependencies: svelte: ^5.0.0 - '@immich/ui@0.65.3': - resolution: {integrity: sha512-jMXzCzMNTcCdWXt9IUP7GkALE5oEvPQk/jCOuI2bfxsxCZFzMkUfUS+AV83Vg1vQ6l+g39PbKSPKBEzv125ATQ==} + '@immich/ui@0.69.0': + resolution: {integrity: sha512-YQ+27pGQhzdRBOo/7cHcbXnax5BUrrJeYjUc+VdRYp6KMS8SlGWAKQhvZPdcqiPB332fxJMmpHjV+VqXJJjrqg==} peerDependencies: svelte: ^5.0.0 @@ -3186,8 +3186,8 @@ packages: '@types/node': optional: true - '@internationalized/date@3.10.0': - resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} + '@internationalized/date@3.12.0': + resolution: {integrity: sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==} '@ioredis/commands@1.5.0': resolution: {integrity: sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==} @@ -3293,8 +3293,8 @@ packages: resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} engines: {node: '>= 14.0.0'} - '@koa/router@15.3.0': - resolution: {integrity: sha512-s87hWJjFYky2Z97u8jzah73sSHp4IZivD/2PZCuspHRvcKU69OPLoBIbKigVlBmS50yFTh9GHFfr1hDag4+wXw==} + '@koa/router@15.4.0': + resolution: {integrity: sha512-vKYlXtoCfcAN8z4dHiveYX55rTYOgHEYJNumK1WM9ZAwaArhreGVkyC1LTMGfUQUJyIO/SbwRFBOHeOCY8/MaQ==} engines: {node: '>= 20'} peerDependencies: koa: ^2.0.0 || ^3.0.0 @@ -3324,10 +3324,6 @@ packages: resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} - '@mapbox/geojson-rewind@0.5.2': - resolution: {integrity: sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==} - hasBin: true - '@mapbox/jsonlint-lines-primitives@2.0.2': resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} engines: {node: '>= 0.6'} @@ -3358,12 +3354,15 @@ packages: '@maplibre/geojson-vt@5.0.4': resolution: {integrity: sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==} - '@maplibre/maplibre-gl-style-spec@24.6.0': - resolution: {integrity: sha512-+lxMYE+DvInshwVrqSQ3CkW9YRwVlRXeDzfthVOa1c9pwK5d7YgCwhgFwlSmjJLvTXn4gL8EvPUGT620sk2Pzg==} + '@maplibre/geojson-vt@6.0.4': + resolution: {integrity: sha512-HYv3POhMRCdhP3UPPATM/hfcy6/WuVIf5FKboH8u/ZuFMTnAIcSVlq5nfOqroLokd925w2QtE7YwquFOIacwVQ==} + + '@maplibre/maplibre-gl-style-spec@24.7.0': + resolution: {integrity: sha512-Ed7rcKYU5iELfablg9Mj+TVCsXsPBgdMyXPRAxb2v7oWg9YJnpQdZ5msDs1LESu/mtXy3Z48Vdppv2t/x5kAhw==} hasBin: true - '@maplibre/mlt@1.1.6': - resolution: {integrity: sha512-rgtY3x65lrrfXycLf6/T22ZnjTg5WgIOsptOIoCaMZy4O4UAKTyZlYY0h6v8le721pTptF94U65yMDQkug+URw==} + '@maplibre/mlt@1.1.8': + resolution: {integrity: sha512-8vtfYGidr1rNkv5IwIoU2lfe3Oy+Wa8HluzQYcQi9cveU9K3pweAal/poQj4GJ0K/EW4bTQp2wVAs09g2yDRZg==} '@maplibre/vt-pbf@4.3.0': resolution: {integrity: sha512-jIvp8F5hQCcreqOOpEt42TJMUlsrEcpf/kI1T2v85YrQRV6PPXUcEXUg5karKtH6oh47XJZ4kHu56pUkOuqA7w==} @@ -3431,8 +3430,11 @@ packages: '@namnode/store@0.1.0': resolution: {integrity: sha512-4NGTldxKcmY0UuZ7OEkvCjs8ZEoeYB6M2UwMu74pdLiFMKxXbj9HdNk1Qn213bxX1O7bY5h+PLh5DZsTURZkYA==} - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@napi-rs/wasm-runtime@1.1.2': + resolution: {integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 '@nestjs/bull-shared@11.0.4': resolution: {integrity: sha512-VBJcDHSAzxQnpcDfA0kt9MTGUD1XZzfByV70su0W0eDCQ9aqIEBlzWRW21tv9FG9dIut22ysgDidshdjlnczLw==} @@ -3460,8 +3462,8 @@ packages: '@swc/core': optional: true - '@nestjs/common@11.1.16': - resolution: {integrity: sha512-JSIeW+USuMJkkcNbiOdcPkVCeI3TSnXstIVEPpp3HiaKnPRuSbUUKm9TY9o/XpIcPHWUOQItAtC5BiAwFdVITQ==} + '@nestjs/common@11.1.17': + resolution: {integrity: sha512-hLODw5Abp8OQgA+mUO4tHou4krKgDtUcM9j5Ihxncst9XeyxYBTt2bwZm4e4EQr5E352S4Fyy6V3iFx9ggxKAg==} peerDependencies: class-transformer: '>=0.4.1' class-validator: '>=0.13.2' @@ -3473,8 +3475,8 @@ packages: class-validator: optional: true - '@nestjs/core@11.1.16': - resolution: {integrity: sha512-tXWXyCiqWthelJjrE0KLFjf0O98VEt+WPVx5CrqCf+059kIxJ8y1Vw7Cy7N4fwQafWNrmFL2AfN87DDMbVAY0w==} + '@nestjs/core@11.1.17': + resolution: {integrity: sha512-lD5mAYekTTurF3vDaa8C2OKPnjiz4tsfxIc5XlcSUzOhkwWf6Ay3HKvt6FmvuWQam6uIIHX52Clg+e6tAvf/cg==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -3504,14 +3506,14 @@ packages: class-validator: optional: true - '@nestjs/platform-express@11.1.16': - resolution: {integrity: sha512-IOegr5+ZfUiMKgk+garsSU4MOkPRhm46e6w8Bp1GcO4vCdl9Piz6FlWAzKVfa/U3Hn/DdzSVJOW3TWcQQFdBDw==} + '@nestjs/platform-express@11.1.17': + resolution: {integrity: sha512-mAf4eOsSBsTOn/VbrUO1gsjW6dVh91qqXPMXun4dN8SnNjf7PTQagM9o8d6ab8ZBpNe6UdZftdrZoDetU+n4Qg==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 - '@nestjs/platform-socket.io@11.1.16': - resolution: {integrity: sha512-3fYQTi8F2hb7HDkes/ArGhY8lkjB/Df29F5CN4cjbk4cmfpRVy89p6N1BC7PjVOHMAzdwqeX8FabqspdSAnywA==} + '@nestjs/platform-socket.io@11.1.17': + resolution: {integrity: sha512-BSOAsENdmTtsnDL0hb4takbWzPy9WoPybjlM57ab3/rQgm0biMFYUupH2uzmCjmmIXJL/EFbAWznVl8xw2Sa6Q==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/websockets': ^11.0.0 @@ -3545,8 +3547,8 @@ packages: class-validator: optional: true - '@nestjs/testing@11.1.16': - resolution: {integrity: sha512-E7/aUCxzeMSJV80L5GWGIuiMyR/1ncS7uOIetAImfbS4ATE1/h2GBafk0qpk+vjFtPIbtoh9BWDGICzUEU5jDA==} + '@nestjs/testing@11.1.17': + resolution: {integrity: sha512-lNffw+z+2USewmw4W0tsK+Rq94A2N4PiHbcqoRUu5y8fnqxQeIWGHhjo5BFCqj7eivqJBhT7WdRydxVq4rAHzg==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3558,8 +3560,8 @@ packages: '@nestjs/platform-express': optional: true - '@nestjs/websockets@11.1.16': - resolution: {integrity: sha512-kfLhCFsq6139JVFCQpbFB6LOEjZzdpE7JzXsZtRbVjqmsgTKVSIh8gKRgzpcq27rbLNqHhhZavboOltOfSxZow==} + '@nestjs/websockets@11.1.17': + resolution: {integrity: sha512-YbwQ0QfVj0lxkKQhdIIgk14ZSVWDqGk1J8nNSN6SLjf36sVv58Ma5ro+dtQua8wj3l2Ub7JJCVFixEhKtYc/rQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3810,12 +3812,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 - '@oxc-project/runtime@0.115.0': - resolution: {integrity: sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==} - engines: {node: ^20.19.0 || >=22.12.0} - - '@oxc-project/types@0.115.0': - resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} + '@oxc-project/types@0.122.0': + resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} '@paralleldrive/cuid2@2.3.1': resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} @@ -4131,103 +4129,103 @@ packages: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 - '@rolldown/binding-android-arm64@1.0.0-rc.9': - resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==} + '@rolldown/binding-android-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.9': - resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.9': - resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==} + '@rolldown/binding-darwin-x64@1.0.0-rc.12': + resolution: {integrity: sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.9': - resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': + resolution: {integrity: sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': - resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': + resolution: {integrity: sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': - resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': - resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': - resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': - resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': - resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': - resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': - resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': - resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': + resolution: {integrity: sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': - resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': - resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.9': - resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} + '@rolldown/pluginutils@1.0.0-rc.12': + resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==} '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} @@ -4443,8 +4441,8 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || >=7.0.0 - '@sveltejs/kit@2.53.4': - resolution: {integrity: sha512-iAIPEahFgDJJyvz8g0jP08KvqnM6JvdW8YfsygZ+pMeMvyM2zssWMltcsotETvjSZ82G3VlitgDtBIvpQSZrTA==} + '@sveltejs/kit@2.55.0': + resolution: {integrity: sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -4768,14 +4766,14 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@turf/boolean-point-in-polygon@7.3.2': - resolution: {integrity: sha512-PAfPDQ0TW1+VLgZ7tReTSyZ/X41AW7/nMRQxVpY+h/aG7JomZJ779lojnODT4dWCn3IMTA3xD2dDDfVYBAQMYg==} + '@turf/boolean-point-in-polygon@7.3.4': + resolution: {integrity: sha512-v/4hfyY90Vz9cDgs2GwjQf+Lft8o7mNCLJOTz/iv8SHAIgMMX0czEoIaNVOJr7tBqPqwin1CGwsncrkf5C9n8Q==} - '@turf/helpers@7.3.2': - resolution: {integrity: sha512-5HFN42rgWjSobdTMxbuq+ZdXPcqp1IbMgFYULTLCplEQM3dXhsyRFe7DCss4Eiw12iW3q6Z5UeTNVfITsE5lgA==} + '@turf/helpers@7.3.4': + resolution: {integrity: sha512-U/S5qyqgx3WTvg4twaH0WxF3EixoTCfDsmk98g1E3/5e2YKp7JKYZdz0vivsS5/UZLJeZDEElOSFH4pUgp+l7g==} - '@turf/invariant@7.3.2': - resolution: {integrity: sha512-brGmL1EFhZH/YNXhq6S+8sPWBEnmvEyxMWJO8bUNOFZyWHYiRTwxQHZM+An1blkbQ77PiEzsdNAspZqE1j7YKA==} + '@turf/invariant@7.3.4': + resolution: {integrity: sha512-88Eo4va4rce9sNZs6XiMJowWkikM3cS2TBhaCKlU+GFHdNf8PFEpiU42VDU8q5tOF6/fu21Rvlke5odgOGW4AQ==} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -5103,11 +5101,11 @@ packages: '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@24.12.0': - resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} - '@types/node@25.4.0': - resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} + '@types/node@25.5.0': + resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} '@types/nodemailer@7.0.11': resolution: {integrity: sha512-E+U4RzR2dKrx+u3N4DlsmLaDC6mMZOM/TPROxA0UAPiTgI0y4CEFBmZE+coGWTjakDriRsXG368lNk1u9Q0a2g==} @@ -5124,8 +5122,8 @@ packages: '@types/pg@8.15.6': resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} - '@types/pg@8.18.0': - resolution: {integrity: sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==} + '@types/pg@8.20.0': + resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==} '@types/picomatch@4.0.2': resolution: {integrity: sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA==} @@ -5163,9 +5161,6 @@ packages: '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - '@types/sanitize-html@2.16.1': - resolution: {integrity: sha512-n9wjs8bCOTyN/ynwD8s/nTcTreIHB1vf31vhLMGqUPNHaweKC4/fAl4Dj+hUlCTKYgm4P3k83fmiFfzkZ6sgMA==} - '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} @@ -5205,8 +5200,8 @@ packages: '@types/supercluster@7.1.3': resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} - '@types/supertest@6.0.3': - resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} + '@types/supertest@7.2.0': + resolution: {integrity: sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==} '@types/through@0.0.33': resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} @@ -5238,63 +5233,63 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.56.1': - resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} + '@typescript-eslint/eslint-plugin@8.58.0': + resolution: {integrity: sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.56.1 + '@typescript-eslint/parser': ^8.58.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.56.1': - resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} + '@typescript-eslint/parser@8.58.0': + resolution: {integrity: sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.56.1': - resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} + '@typescript-eslint/project-service@8.58.0': + resolution: {integrity: sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.56.1': - resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} + '@typescript-eslint/scope-manager@8.58.0': + resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.56.1': - resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} + '@typescript-eslint/tsconfig-utils@8.58.0': + resolution: {integrity: sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.56.1': - resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} + '@typescript-eslint/type-utils@8.58.0': + resolution: {integrity: sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.56.1': - resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} + '@typescript-eslint/types@8.58.0': + resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.56.1': - resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} + '@typescript-eslint/typescript-estree@8.58.0': + resolution: {integrity: sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.56.1': - resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} + '@typescript-eslint/utils@8.58.0': + resolution: {integrity: sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.56.1': - resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} + '@typescript-eslint/visitor-keys@8.58.0': + resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -5313,11 +5308,11 @@ packages: '@vitest/browser': optional: true - '@vitest/coverage-v8@4.0.18': - resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} + '@vitest/coverage-v8@4.1.0': + resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==} peerDependencies: - '@vitest/browser': 4.0.18 - vitest: 4.0.18 + '@vitest/browser': 4.1.0 + vitest: 4.1.0 peerDependenciesMeta: '@vitest/browser': optional: true @@ -5325,8 +5320,8 @@ packages: '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/expect@4.0.18': - resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + '@vitest/expect@4.1.0': + resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} '@vitest/mocker@3.2.4': resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} @@ -5339,11 +5334,11 @@ packages: vite: optional: true - '@vitest/mocker@4.0.18': - resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + '@vitest/mocker@4.1.0': + resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} peerDependencies: msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 peerDependenciesMeta: msw: optional: true @@ -5353,32 +5348,32 @@ packages: '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/pretty-format@4.0.18': - resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + '@vitest/pretty-format@4.1.0': + resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} '@vitest/runner@3.2.4': resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/runner@4.0.18': - resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + '@vitest/runner@4.1.0': + resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} '@vitest/snapshot@3.2.4': resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/snapshot@4.0.18': - resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + '@vitest/snapshot@4.1.0': + resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/spy@4.0.18': - resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + '@vitest/spy@4.1.0': + resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@vitest/utils@4.0.18': - resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + '@vitest/utils@4.1.0': + resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -5664,6 +5659,9 @@ packages: ast-v8-to-istanbul@0.3.12: resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} + ast-v8-to-istanbul@1.0.0: + resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} + astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true @@ -5694,8 +5692,8 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.7.3: - resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -5748,8 +5746,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.5.4: - resolution: {integrity: sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==} + bare-fs@4.5.6: + resolution: {integrity: sha512-1QovqDrR80Pmt5HPAsMsXTCFcDYr+NSUKW6nd6WO5v0JBmnItc/irNRzm2KOQ5oZ69P37y+AMujNyNtG+1Rggw==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -5757,26 +5755,29 @@ packages: bare-buffer: optional: true - bare-os@3.6.2: - resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} + bare-os@3.8.0: + resolution: {integrity: sha512-Dc9/SlwfxkXIGYhvMQNUtKaXCaGkZYGcd1vuNUUADVqzu4/vQfvnMkYYOUnt2VwQ2AqKr/8qAVFRtwETljgeFg==} engines: {bare: '>=1.14.0'} bare-path@3.0.0: resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - bare-stream@2.8.0: - resolution: {integrity: sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==} + bare-stream@2.11.0: + resolution: {integrity: sha512-Y/+iQ49fL3rIn6w/AVxI/2+BRrpmzJvdWt5Jv8Za6Ngqc6V227c+pYjYYgLdpR3MwQ9ObVXD0ZrqoBztakM0rw==} peerDependencies: + bare-abort-controller: '*' bare-buffer: '*' bare-events: '*' peerDependenciesMeta: + bare-abort-controller: + optional: true bare-buffer: optional: true bare-events: optional: true - bare-url@2.3.2: - resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} + bare-url@2.4.0: + resolution: {integrity: sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5814,8 +5815,8 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bits-ui@2.16.0: - resolution: {integrity: sha512-utsUZE7W7MxOQF1jmSYfzUrt2nZxgkq0yPqQcBQ0WQDMq8ETd1yEiHlPpqhMrpKU7IivjSf4XVysDDy+UVkMUw==} + bits-ui@2.16.3: + resolution: {integrity: sha512-5hJ5dEhf5yPzkRFcxzgQHScGodeo0gK0MUUXrdLlRHWaBOBGZiacWLG96j/wwFatKwZvouw7q+sn14i0fx3RIg==} engines: {node: '>=20'} peerDependencies: '@internationalized/date': ^3.8.1 @@ -5852,8 +5853,8 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@5.0.4: - resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -5889,8 +5890,8 @@ packages: resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} engines: {node: '>=18.20'} - bullmq@5.70.4: - resolution: {integrity: sha512-S58YT/tGdhc4pEPcIahtZRBR1TcTLpss1UKiXimF+Vy4yZwF38pW2IvhHqs4j4dEbZqDt8oi0jGGN/WYQHbPDg==} + bullmq@5.71.0: + resolution: {integrity: sha512-aeNWh4drsafSKnAJeiNH/nZP/5O8ZdtdMbnOPZmpjXj7NZUP5YC901U3bIH41iZValm7d1i3c34ojv7q31m30w==} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -6069,8 +6070,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-info@4.3.1: - resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} citty@0.1.6: @@ -6140,6 +6141,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -6347,8 +6352,8 @@ packages: peerDependencies: webpack: ^5.1.0 - core-js-compat@3.47.0: - resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} core-js-pure@3.47.0: resolution: {integrity: sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==} @@ -6855,9 +6860,6 @@ packages: engines: {node: '>= 4.0.0'} hasBin: true - devalue@5.6.3: - resolution: {integrity: sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==} - devalue@5.6.4: resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==} @@ -6898,16 +6900,16 @@ packages: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} - docker-compose@1.3.1: - resolution: {integrity: sha512-rF0wH69G3CCcmkN9J1RVMQBaKe8o77LT/3XmqcLIltWWVxcWAzp2TnO7wS3n/umZHN3/EVrlT3exSBMal+Ou1w==} + docker-compose@1.3.3: + resolution: {integrity: sha512-LzcZ6Dk+Ps5SbLZ4iqAcagzYFZ+bBWQ52uzUNfORNkXyash2EjHZI4REf1ccG19emroS0iWElfQN8RQJ8HOIIg==} engines: {node: '>= 6.0.0'} - docker-modem@5.0.6: - resolution: {integrity: sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ==} + docker-modem@5.0.7: + resolution: {integrity: sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==} engines: {node: '>= 8.0'} - dockerode@4.0.9: - resolution: {integrity: sha512-iND4mcOWhPaCNh54WmK/KoSb35AFqPAUWFMffTQcp52uQt36b5uNwEJTSXntJZBbeGad72Crbi/hvDIv6us/6Q==} + dockerode@4.0.10: + resolution: {integrity: sha512-8L/P9JynLBiG7/coiA4FlQXegHltRqS0a+KqI44P1zgQh8QLHTg7FKOwhkBgSJwZTeHsq30WRoVFLuwkfK0YFg==} engines: {node: '>= 8.0'} docusaurus-lunr-search@3.6.0: @@ -7110,8 +7112,8 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.27.3: - resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} engines: {node: '>=18'} hasBin: true @@ -7144,11 +7146,11 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-compat@6.2.1: - resolution: {integrity: sha512-gLKqUH+lQcCL+HzsROUjBDvakc5Zaga51Y4ZAkPCXc41pzKBfyluqTr2j8zOx8QQQb7zyglu1LVoL5aSNWf2SQ==} + eslint-plugin-compat@7.0.1: + resolution: {integrity: sha512-wDID2fVIAfxV9R1uSkCn5HscnNu8yMxDF1IaQGyD1C6XuWwJbuaDgMOSkVgOom0LzY8z0fXXXCy7AQQTERQUvQ==} engines: {node: '>=18.x'} peerDependencies: - eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + eslint: ^9.0.0 || ^10.0.0 eslint-plugin-prettier@5.5.5: resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==} @@ -7164,8 +7166,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-svelte@3.15.0: - resolution: {integrity: sha512-QKB7zqfuB8aChOfBTComgDptMf2yxiJx7FE04nneCmtQzgTHvY8UJkuh8J2Rz7KB9FFV9aTHX6r7rdYGvG8T9Q==} + eslint-plugin-svelte@3.16.0: + resolution: {integrity: sha512-DJXxqpYZUxcE0SfYo8EJzV2ZC+zAD7fJp1n1HwcEMRR1cOEUYvjT9GuzJeNghMjgb7uxuK3IJAzI+x6zzUxO5A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -7174,8 +7176,8 @@ packages: svelte: optional: true - eslint-plugin-unicorn@63.0.0: - resolution: {integrity: sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA==} + eslint-plugin-unicorn@64.0.0: + resolution: {integrity: sha512-rNZwalHh8i0UfPlhNwg5BTUO1CMdKNmjqe+TgzOTZnpKoi8VBgsW7u9qCHIdpxEzZ1uwrJrPF0uRb7l//K38gA==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: eslint: '>=9.38.0' @@ -7188,8 +7190,8 @@ packages: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint-scope@9.1.1: - resolution: {integrity: sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==} + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} eslint-visitor-keys@3.4.3: @@ -7204,8 +7206,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.0.2: - resolution: {integrity: sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==} + eslint@10.1.0: + resolution: {integrity: sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -7225,8 +7227,8 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - espree@11.1.1: - resolution: {integrity: sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==} + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} esprima@4.0.1: @@ -7325,17 +7327,17 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - exiftool-vendored.exe@13.52.0: - resolution: {integrity: sha512-8KSHKluRebjm2FL4S8rtwMLMELn/64CTI5BV3zmIdLnpS5N+aJEh6t9Y7aB7YBn5CwUao0T9/rxv4BMQqusukg==} + exiftool-vendored.exe@13.53.0: + resolution: {integrity: sha512-CX8w1iVDOdt6iitqoOmUCWLYVmfBVmd59htXGpns/+CItu8LBAT9qVHdBP+Jl0abZyCcDrZf0eaLsfXb9mZOcQ==} os: [win32] - exiftool-vendored.pl@13.52.0: - resolution: {integrity: sha512-DXsMRRNdjordn1Ckcp1h9OQJRQy9VDDOcs60H+3IP+W9zRnpSU3HqQMhAVKyHR4FzioiGDbREN9BI/M1oDNoEw==} + exiftool-vendored.pl@13.53.0: + resolution: {integrity: sha512-D/3yJymCPeMQPtQA9Q8ou/+vvEeQcTjrNt2jT7GS2A9tE0s0NiMNVc62HaKdwm5reQXQRbPrnp56sNxWpNCHKA==} os: ['!win32'] hasBin: true - exiftool-vendored@35.13.1: - resolution: {integrity: sha512-RiXz8RrJSBQ5jiZA1yMicmE/FgEFK/4QkU2KsqmlvTvouOOgANsNWv0f0uZbf098Ee933BE4bec5YAOBT0DuIQ==} + exiftool-vendored@35.15.1: + resolution: {integrity: sha512-ox+pcW9m52MGeXMMuZjbdaKgeha9WmWPE7HhVw6GNZ607a9Hx2HyiAUDQm+XdAzv6Y34sahLReCeJRmS9F70Ww==} engines: {node: '>=20.0.0'} expect-type@1.3.0: @@ -7445,8 +7447,8 @@ packages: file-source@0.6.1: resolution: {integrity: sha512-1R1KneL7eTXmXfKxC10V/9NeGOdbsAXJ+lQ//fvvcHUgtaZcZDWNJNblxAoVOyV1cj45pOtUrR3vZTBwqcW8XA==} - file-type@21.3.0: - resolution: {integrity: sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==} + file-type@21.3.2: + resolution: {integrity: sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==} engines: {node: '>=20'} fill-range@7.1.1: @@ -7489,8 +7491,8 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} fluent-ffmpeg@2.1.3: resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==} @@ -7604,8 +7606,8 @@ packages: geo-coordinates-parser@1.7.4: resolution: {integrity: sha512-gVGxBW+s1csexXVMf5bIwz3TH9n4sCEglOOOqmrPk8YazUI5f79jCowKjTw05m/0h1//3+Z2m/nv8IIozgZyUw==} - geo-tz@8.1.5: - resolution: {integrity: sha512-C0g6Zyo/4/wtaONcprVq6gHq4LnbheC7HXXi0nZMG8lbxqvOj8IZcTolCd0MeOmBekXnyXKKeDlh6g2o4Yy3qw==} + geo-tz@8.1.6: + resolution: {integrity: sha512-6YEper1rtHi1l3ZS99oy9ZBvrBO4qsLzvQwZoxYtV3fyxPuxh7yqiOUWRVs1bzSj693EXEO4k60jKXQmkY/JnQ==} engines: {node: '>=16'} geobuf@3.0.2: @@ -7631,8 +7633,8 @@ packages: get-own-enumerable-property-symbols@3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - get-port@7.1.0: - resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + get-port@7.2.0: + resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} engines: {node: '>=16'} get-proto@1.0.1: @@ -7750,13 +7752,13 @@ packages: handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true - happy-dom@20.8.3: - resolution: {integrity: sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ==} + happy-dom@20.8.9: + resolution: {integrity: sha512-Tz23LR9T9jOGVZm2x1EPdXqwA37G/owYMxRwU0E4miurAtFsPMQ1d2Jc2okUaSjZqAFz2oEn3FLXC5a0a+siyA==} engines: {node: '>=20.0.0'} has-flag@4.0.0: @@ -7840,6 +7842,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + helmet@8.1.0: + resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} + engines: {node: '>=18.0.0'} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -7897,9 +7903,6 @@ packages: webpack: optional: true - htmlparser2@10.1.0: - resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} - htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} @@ -8081,14 +8084,14 @@ packages: intl-messageformat@10.7.18: resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==} - intl-messageformat@11.1.2: - resolution: {integrity: sha512-ucSrQmZGAxfiBHfBRXW/k7UC8MaGFlEj4Ry1tKiDcmgwQm1y3EDl40u+4VNHYomxJQMJi9NEI3riDRlth96jKg==} + intl-messageformat@11.2.0: + resolution: {integrity: sha512-IhghAA8n4KSlXuWKzYsWyWb82JoYTzShfyvdSF85oJPnNOjvv4kAo7S7Jtkm3/vJ53C7dQNRO+Gpnj3iWgTjBQ==} invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - ioredis@5.10.0: - resolution: {integrity: sha512-HVBe9OFuqs+Z6n64q09PQvP1/R4Bm+30PAyyD4wIEqssh3v9L21QjCVk4kRLucMBcDokJTcLjsGeVRlq/nH6DA==} + ioredis@5.10.1: + resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} ioredis@5.9.3: @@ -8168,6 +8171,10 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -8225,10 +8232,6 @@ packages: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -8357,8 +8360,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -8490,8 +8493,8 @@ packages: koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} - koa@3.1.1: - resolution: {integrity: sha512-KDDuvpfqSK0ZKEO2gCPedNjl5wYpfj+HNiuVRlbhd1A88S3M0ySkdf2V/EJ4NWt5dwh5PXCdcenrKK2IQJAxsg==} + koa@3.1.2: + resolution: {integrity: sha512-2LOQnFKu3m0VxpE+5sb5+BRTSKrXmNxGgxVRiKwD9s5KQB1zID/FRXhtzeV7RT1L2GVpdEEAfVuclFOMGl1ikA==} engines: {node: '>= 18'} kysely-postgres-js@3.0.0: @@ -8504,8 +8507,8 @@ packages: postgres: optional: true - kysely@0.28.11: - resolution: {integrity: sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg==} + kysely@0.28.14: + resolution: {integrity: sha512-SU3lgh0rPvq7upc6vvdVrCsSMUG1h3ChvHVOY7wJ2fw4C9QEB7X3d5eyYEyULUX7UQtxZJtZXGuT6U2US72UYA==} engines: {node: '>=20.0.0'} langium@3.3.1: @@ -8662,8 +8665,8 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash-es@4.17.23: - resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -8707,6 +8710,9 @@ packages: lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -8790,8 +8796,8 @@ packages: resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} engines: {node: ^20.17.0 || >=22.9.0} - maplibre-gl@5.19.0: - resolution: {integrity: sha512-REhYUN8gNP3HlcIZS6QU2uy8iovl31cXsrNDkCcqWSQbCkcpdYLczqDz5PVIwNH42UQNyvukjes/RoHPDrOUmQ==} + maplibre-gl@5.21.0: + resolution: {integrity: sha512-n0v4J/Ge0EG8ix/z3TY3ragtJYMqzbtSnj1riOC0OwQbzwp0lUF2maS1ve1z8HhitQCKtZZiZJhb8to36aMMfQ==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} mark.js@8.11.1: @@ -8817,8 +8823,8 @@ packages: engines: {node: '>= 20'} hasBin: true - marked@17.0.3: - resolution: {integrity: sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==} + marked@17.0.5: + resolution: {integrity: sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==} engines: {node: '>= 20'} hasBin: true @@ -9130,12 +9136,15 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} - minimatch@9.0.6: - resolution: {integrity: sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -9256,16 +9265,16 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.25.0: - resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==} + nan@2.26.2: + resolution: {integrity: sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.6: - resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} + nanoid@5.1.7: + resolution: {integrity: sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==} engines: {node: ^18 || >=20} hasBin: true @@ -9380,8 +9389,8 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - nodemailer@7.0.13: - resolution: {integrity: sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==} + nodemailer@8.0.4: + resolution: {integrity: sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==} engines: {node: '>=6.0.0'} nopt@1.0.10: @@ -9472,8 +9481,8 @@ packages: obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - oidc-provider@9.6.1: - resolution: {integrity: sha512-8AtFXE4gEV6MLd8Re78VhqGNjBm/SUw0fUxrP2XwQc+5DZKw6GyuTuy2M4jkidpH3jRrhtkkqQpXlxD1Awi6tg==} + oidc-provider@9.7.1: + resolution: {integrity: sha512-yzOdAYxQEisPspCy6xVPrK++bYz71011uylwhR3XLDfb3r0NfVuJStApQvXoeMXj928nkZoxRTBC4ECYM94KOw==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -9498,6 +9507,10 @@ packages: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -9604,9 +9617,6 @@ packages: parse-numeric-range@1.3.0: resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} - parse-srcset@1.0.2: - resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} - parse5-htmlparser2-tree-adapter@7.1.0: resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} @@ -9662,8 +9672,8 @@ packages: path-source@0.1.3: resolution: {integrity: sha512-dWRHm5mIw5kw0cs3QZLNmpUWty48f5+5v9nWD2dw3Y0Hf+s01Ag8iJEWV0Sm0kocE8kK27DrIowha03e1YR+Qw==} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} path-to-regexp@1.9.0: resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} @@ -9733,16 +9743,16 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} picomatch@4.0.2: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} pify@2.3.0: @@ -10274,6 +10284,10 @@ packages: potpack@2.1.0: resolution: {integrity: sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==} + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -10378,8 +10392,8 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -10451,11 +10465,6 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 - react-dom@19.2.4: resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: @@ -10507,10 +10516,6 @@ packages: peerDependencies: react: '>=15' - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} - react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -10723,20 +10728,20 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - robust-predicates@3.0.2: - resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} - rolldown@1.0.0-rc.9: - resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==} + rolldown@1.0.0-rc.12: + resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup-plugin-visualizer@6.0.11: - resolution: {integrity: sha512-TBwVHVY7buHjIKVLqr9scTVFwqZqMXINcCphPwIWKPDCOBIa+jCQfafvbjRJDZgXdq/A996Dy6yGJ/+/NtAXDQ==} - engines: {node: '>=18'} + rollup-plugin-visualizer@7.0.1: + resolution: {integrity: sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==} + engines: {node: '>=22'} hasBin: true peerDependencies: - rolldown: 1.x || ^1.0.0-beta + rolldown: 1.x || ^1.0.0-beta || ^1.0.0-rc rollup: 2.x || 3.x || 4.x peerDependenciesMeta: rolldown: @@ -10806,11 +10811,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-filename@1.6.3: - resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - - sanitize-html@2.17.1: - resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==} + sanitize-filename@1.6.4: + resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} sass@1.97.1: resolution: {integrity: sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==} @@ -10824,9 +10826,6 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -10900,8 +10899,8 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-cookie-parser@3.0.1: - resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + set-cookie-parser@3.1.0: + resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -10976,8 +10975,8 @@ packages: resolution: {integrity: sha512-i/w5Ie4tENfGYbdCo2iJ+oies0vOFd8QXWHopKOUzudfLCvnmeheF2PpHp89Z2azpc+c2su3lMiWO/SpP+429A==} engines: {node: '>=0.12.18'} - simple-icons@16.9.0: - resolution: {integrity: sha512-aKst2C7cLkFyaiQ/Crlwxt9xYOpGPk05XuJZ0ZTJNNCzHCKYrGWz2ebJSi5dG8CmTCxUF/BGs6A8uyJn/EQxqw==} + simple-icons@16.13.0: + resolution: {integrity: sha512-N4AMZvFERU5YLEtUudtUesiM2H4O5xQ9qfS3K0oOV5II5KVtxOUAlmZ7KqBgiTSGBgCVkuLD/Z9dJKBtnI3kKQ==} engines: {node: '>=0.12.18'} sirv@2.0.4: @@ -11126,6 +11125,9 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@4.0.0: + resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -11137,8 +11139,8 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - streamx@2.23.0: - resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + streamx@2.25.0: + resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -11204,8 +11206,8 @@ packages: strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} - strtok3@10.3.4: - resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + strtok3@10.3.5: + resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} engines: {node: '>=18'} style-mod@4.1.3: @@ -11259,8 +11261,8 @@ packages: peerDependencies: svelte: '>= 3.43.1 < 6' - svelte-check@4.4.4: - resolution: {integrity: sha512-F1pGqXc710Oi/wTI4d/x7d6lgPwwfx1U6w3Q35n4xsC2e8C/yN2sM1+mWxjlMcpAfWucjlq4vPi+P4FZ8a14sQ==} + svelte-check@4.4.5: + resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -11332,8 +11334,8 @@ packages: peerDependencies: svelte: ^5.30.2 - svelte@5.53.13: - resolution: {integrity: sha512-9P6I/jGcQMzAMb76Uyd6L6RELAC7qt53GOSBLCke9lubh9iJjmjCo+EffRH4gOPnTB/x4RR2Tmt6s3o9ywQO3g==} + svelte@5.54.1: + resolution: {integrity: sha512-ow8tncN097Ty8U1H+C3bM1xNlsCbnO2UZeN0lWBnv8f3jKho7QTTQ2LWbMXrPQDodLjH91n4kpNnLolyRhVE6A==} engines: {node: '>=18'} svg-parser@2.0.4: @@ -11417,15 +11419,15 @@ packages: tar-fs@2.1.4: resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} - tar-fs@3.1.1: - resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} + tar-fs@3.1.2: + resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==} tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar-stream@3.1.8: + resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} @@ -11465,11 +11467,11 @@ packages: resolution: {integrity: sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==} engines: {node: '>=18'} - testcontainers@11.12.0: - resolution: {integrity: sha512-VWtH+UQejVYYvb53ohEZRbx2naxyDvwO9lQ6A0VgmVE2Oh8r9EF09I+BfmrXpd9N9ntpzhao9di2yNwibSz5KA==} + testcontainers@11.13.0: + resolution: {integrity: sha512-fzTvgOtd6U/esOzgmDatJh79OSK0tU6vjDOJ3B6ICrrJf0dqCWtFdpOr6f/g/KixMxKDTDbszmZYjSORJXsVCQ==} - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} text-encoding@0.6.4: resolution: {integrity: sha512-hJnc6Qg3dWoOMkqP53F0dzRIgtmsAge09kxUIqGrEUS4qr5rWLckGYaQAVr+opBrIMRErGgy6f5aPnyPpyGRfg==} @@ -11526,8 +11528,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} tinyglobby@0.2.15: @@ -11545,8 +11547,8 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tinyspy@4.0.4: @@ -11615,8 +11617,8 @@ packages: truncate-utf8-bytes@1.0.2: resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -11694,18 +11696,23 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.56.1: - resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} + typescript-eslint@8.58.0: + resolution: {integrity: sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} + engines: {node: '>=14.17'} + hasBin: true + ua-is-frozen@0.1.2: resolution: {integrity: sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==} @@ -11742,8 +11749,8 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - undici@7.22.0: - resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + undici@7.24.6: + resolution: {integrity: sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==} engines: {node: '>=20.18.1'} unicode-canonical-property-names-ecmascript@2.0.1: @@ -11951,8 +11958,8 @@ packages: peerDependencies: vite: '*' - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -11991,14 +11998,14 @@ packages: yaml: optional: true - vite@8.0.0: - resolution: {integrity: sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==} + vite@8.0.5: + resolution: {integrity: sha512-nmu43Qvq9UopTRfMx2jOYW5l16pb3iDC1JH6yMuPkpVbzK0k+L7dfsEDH4jRgYFmsg0sTAqkojoZgzLMlwHsCQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.0.0-alpha.31 - esbuild: ^0.27.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -12076,20 +12083,21 @@ packages: jsdom: optional: true - vitest@4.0.18: - resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + vitest@4.1.0: + resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.18 - '@vitest/browser-preview': 4.0.18 - '@vitest/browser-webdriverio': 4.0.18 - '@vitest/ui': 4.0.18 + '@vitest/browser-playwright': 4.1.0 + '@vitest/browser-preview': 4.1.0 + '@vitest/browser-webdriverio': 4.1.0 + '@vitest/ui': 4.1.0 happy-dom: '*' jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -12301,6 +12309,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -12331,8 +12343,8 @@ packages: utf-8-validate: optional: true - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -12347,6 +12359,10 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + xdg-basedir@5.1.0: resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} @@ -12387,12 +12403,12 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} engines: {node: '>= 14.6'} hasBin: true @@ -12404,6 +12420,10 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} @@ -12412,6 +12432,10 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -12466,12 +12490,12 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@2.0.115(react@18.3.1)(zod@4.2.1)': + '@ai-sdk/react@2.0.115(react@19.2.4)(zod@4.2.1)': dependencies: '@ai-sdk/provider-utils': 3.0.19(zod@4.2.1) ai: 5.0.113(zod@4.2.1) - react: 18.3.1 - swr: 2.3.8(react@18.3.1) + react: 19.2.4 + swr: 2.3.8(react@19.2.4) throttleit: 2.1.0 optionalDependencies: zod: 4.2.1 @@ -12613,11 +12637,11 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.19(@types/node@24.12.0)(chokidar@4.0.3)': + '@angular-devkit/schematics-cli@19.2.19(@types/node@24.12.2)(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.12.0) + '@inquirer/prompts': 7.3.2(@types/node@24.12.2) ansi-colors: 4.1.3 symbol-observable: 4.0.0 yargs-parser: 21.1.1 @@ -12648,7 +12672,7 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 - tinyexec: 1.0.2 + tinyexec: 1.0.4 '@asamuzakjp/css-color@3.2.0': dependencies: @@ -12674,7 +12698,7 @@ snapshots: '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) '@babel/helpers': 7.28.4 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 '@babel/types': 7.29.0 @@ -12689,7 +12713,7 @@ snapshots: '@babel/generator@7.28.5': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -12813,7 +12837,7 @@ snapshots: '@babel/template': 7.27.2 '@babel/types': 7.29.0 - '@babel/parser@7.29.0': + '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -13348,7 +13372,7 @@ snapshots: babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) - core-js-compat: 3.47.0 + core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -13387,12 +13411,12 @@ snapshots: dependencies: core-js-pure: 3.47.0 - '@babel/runtime@7.28.6': {} + '@babel/runtime@7.29.2': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@babel/traverse@7.28.5': @@ -13400,7 +13424,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/template': 7.27.2 '@babel/types': 7.29.0 debug: 4.4.3 @@ -13416,7 +13440,7 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@borewit/text-codec@0.2.1': {} + '@borewit/text-codec@0.2.2': {} '@braintree/sanitize-url@7.1.1': {} @@ -13791,19 +13815,19 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/core@4.3.1(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docsearch/core@4.3.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': optionalDependencies: '@types/react': 19.2.14 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@docsearch/css@4.3.2': {} - '@docsearch/react@4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/react@4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3)': dependencies: - '@ai-sdk/react': 2.0.115(react@18.3.1)(zod@4.2.1) + '@ai-sdk/react': 2.0.115(react@19.2.4)(zod@4.2.1) '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) - '@docsearch/core': 4.3.1(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docsearch/core': 4.3.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@docsearch/css': 4.3.2 ai: 5.0.113(zod@4.2.1) algoliasearch: 5.46.0 @@ -13811,13 +13835,13 @@ snapshots: zod: 4.2.1 optionalDependencies: '@types/react': 19.2.14 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/babel@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/babel@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/core': 7.28.5 '@babel/generator': 7.28.5 @@ -13826,11 +13850,11 @@ snapshots: '@babel/preset-env': 7.28.5(@babel/core@7.28.5) '@babel/preset-react': 7.28.5(@babel/core@7.28.5) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@babel/runtime-corejs3': 7.28.4 '@babel/traverse': 7.28.5 '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) babel-plugin-dynamic-import-node: 2.3.3 fs-extra: 11.3.2 tslib: 2.8.1 @@ -13843,14 +13867,14 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/bundler@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/bundler@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: '@babel/core': 7.28.5 - '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/babel': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@docusaurus/cssnano-preset': 3.9.2 '@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) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.104.1) clean-css: 5.3.3 copy-webpack-plugin: 11.0.0(webpack@5.104.1) @@ -13862,7 +13886,7 @@ snapshots: mini-css-extract-plugin: 2.9.4(webpack@5.104.1) null-loader: 4.0.1(webpack@5.104.1) postcss: 8.5.8 - postcss-loader: 7.3.4(postcss@8.5.8)(typescript@5.9.3)(webpack@5.104.1) + postcss-loader: 7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.104.1) postcss-preset-env: 10.5.0(postcss@8.5.8) terser-webpack-plugin: 5.3.16(webpack@5.104.1) tslib: 2.8.1 @@ -13884,16 +13908,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': 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) + '@docusaurus/babel': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/bundler': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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/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.14)(react@18.3.1) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -13910,18 +13934,18 @@ snapshots: html-tags: 3.3.1 html-webpack-plugin: 5.6.5(webpack@5.104.1) leven: 3.1.0 - lodash: 4.17.23 + lodash: 4.18.1 open: 8.4.2 p-map: 4.0.0 prompts: 2.4.2 - 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)' - 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.104.1) - 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) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.4)' + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.4))(webpack@5.104.1) + react-router: 5.3.4(react@19.2.4) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.4))(react@19.2.4) + react-router-dom: 5.3.4(react@19.2.4) semver: 7.7.4 serve-handler: 6.1.6 tinypool: 1.1.1 @@ -13960,11 +13984,11 @@ snapshots: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@docusaurus/logger': 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) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mdx-js/mdx': 3.1.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 @@ -13974,8 +13998,8 @@ snapshots: image-size: 2.0.2 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) rehype-raw: 7.0.0 remark-directive: 3.0.1 remark-emoji: 4.0.1 @@ -13995,17 +14019,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@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@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/history': 4.7.11 '@types/react': 19.2.14 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.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)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.4)' transitivePeerDependencies: - '@swc/core' - esbuild @@ -14013,23 +14037,23 @@ 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.14)(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.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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.14)(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.14)(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) - '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.3.2 - lodash: 4.17.23 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + lodash: 4.18.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) schema-dts: 1.1.5 srcset: 4.0.0 tslib: 2.8.1 @@ -14054,24 +14078,24 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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.14)(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) - '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.2 js-yaml: 4.1.1 - lodash: 4.17.23 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + lodash: 4.18.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 @@ -14094,16 +14118,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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) - '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) fs-extra: 11.3.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 webpack: 5.104.1 transitivePeerDependencies: @@ -14124,12 +14148,12 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14151,15 +14175,15 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) fs-extra: 11.3.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-json-view-lite: 2.5.0(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-json-view-lite: 2.5.0(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14179,13 +14203,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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 - react-dom: 18.3.1(react@18.3.1) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14205,14 +14229,14 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/gtag.js': 0.0.12 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14232,13 +14256,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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 - react-dom: 18.3.1(react@18.3.1) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14258,17 +14282,17 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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) - '@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) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) fs-extra: 11.3.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) sitemap: 7.1.2 tslib: 2.8.1 transitivePeerDependencies: @@ -14289,16 +14313,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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) - '@svgr/core': 8.1.0(typescript@5.9.3) - '@svgr/webpack': 8.1.0(typescript@5.9.3) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@svgr/core': 8.1.0(typescript@6.0.2) + '@svgr/webpack': 8.1.0(typescript@6.0.2) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 webpack: 5.104.1 transitivePeerDependencies: @@ -14319,25 +14343,25 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(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.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.14)(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.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(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) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3)(typescript@6.0.2) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' @@ -14359,37 +14383,37 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/react-loadable@6.0.0(react@18.3.1)': + '@docusaurus/react-loadable@6.0.0(react@19.2.4)': dependencies: '@types/react': 19.2.14 - react: 18.3.1 + react: 19.2.4 - '@docusaurus/theme-classic@3.9.2(@types/react@19.2.14)(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.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@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.14)(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.14)(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.14)(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.14)(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.14)(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/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@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.14)(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) clsx: 2.1.1 infima: 0.2.0-alpha.45 - lodash: 4.17.23 + lodash: 4.18.1 nprogress: 0.2.0 postcss: 8.5.8 - prism-react-renderer: 2.4.1(react@18.3.1) + prism-react-renderer: 2.4.1(react@19.2.4) prismjs: 1.30.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router-dom: 5.3.4(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-router-dom: 5.3.4(react@19.2.4) rtlcss: 4.3.0 tslib: 2.8.1 utility-types: 3.11.0 @@ -14411,21 +14435,21 @@ 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.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': 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.14)(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) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/history': 4.7.11 '@types/react': 19.2.14 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + prism-react-renderer: 2.4.1(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -14435,16 +14459,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-mermaid@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + '@docusaurus/theme-mermaid@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - '@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.14)(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-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) mermaid: 11.12.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -14465,24 +14489,24 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(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.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3)(typescript@6.0.2)': dependencies: - '@docsearch/react': 4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(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.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docsearch/react': 4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) '@docusaurus/logger': 3.9.2 - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@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) + '@docusaurus/utils': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) algoliasearch: 5.46.0 algoliasearch-helper: 3.26.1(algoliasearch@5.46.0) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.2 - lodash: 4.17.23 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + lodash: 4.18.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -14511,9 +14535,9 @@ snapshots: fs-extra: 11.3.2 tslib: 2.8.1 - '@docusaurus/tsconfig@3.9.2': {} + '@docusaurus/tsconfig@3.10.0': {} - '@docusaurus/types@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 @@ -14521,9 +14545,9 @@ snapshots: '@types/react': 19.2.14 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)' + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)' utility-types: 3.11.0 webpack: 5.104.1 webpack-merge: 5.10.0 @@ -14534,9 +14558,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils-common@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -14547,15 +14571,15 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils-validation@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@docusaurus/logger': 3.9.2 - '@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': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) fs-extra: 11.3.2 joi: 17.13.3 js-yaml: 4.1.1 - lodash: 4.17.23 + lodash: 4.18.1 tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -14566,11 +14590,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/utils@3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@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-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) escape-string-regexp: 4.0.0 execa: 5.1.1 file-loader: 6.2.0(webpack@5.104.1) @@ -14580,7 +14604,7 @@ snapshots: gray-matter: 4.0.3 jiti: 1.21.7 js-yaml: 4.1.1 - lodash: 4.17.23 + lodash: 4.18.1 micromatch: 4.0.8 p-queue: 6.6.2 prompts: 2.4.2 @@ -14598,13 +14622,13 @@ snapshots: - uglify-js - webpack-cli - '@emnapi/core@1.9.0': + '@emnapi/core@1.9.1': dependencies: '@emnapi/wasi-threads': 1.2.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.9.1': dependencies: tslib: 2.8.1 optional: true @@ -14620,7 +14644,7 @@ snapshots: '@esbuild/aix-ppc64@0.25.12': optional: true - '@esbuild/aix-ppc64@0.27.3': + '@esbuild/aix-ppc64@0.27.4': optional: true '@esbuild/android-arm64@0.19.12': @@ -14629,7 +14653,7 @@ snapshots: '@esbuild/android-arm64@0.25.12': optional: true - '@esbuild/android-arm64@0.27.3': + '@esbuild/android-arm64@0.27.4': optional: true '@esbuild/android-arm@0.19.12': @@ -14638,7 +14662,7 @@ snapshots: '@esbuild/android-arm@0.25.12': optional: true - '@esbuild/android-arm@0.27.3': + '@esbuild/android-arm@0.27.4': optional: true '@esbuild/android-x64@0.19.12': @@ -14647,7 +14671,7 @@ snapshots: '@esbuild/android-x64@0.25.12': optional: true - '@esbuild/android-x64@0.27.3': + '@esbuild/android-x64@0.27.4': optional: true '@esbuild/darwin-arm64@0.19.12': @@ -14656,7 +14680,7 @@ snapshots: '@esbuild/darwin-arm64@0.25.12': optional: true - '@esbuild/darwin-arm64@0.27.3': + '@esbuild/darwin-arm64@0.27.4': optional: true '@esbuild/darwin-x64@0.19.12': @@ -14665,7 +14689,7 @@ snapshots: '@esbuild/darwin-x64@0.25.12': optional: true - '@esbuild/darwin-x64@0.27.3': + '@esbuild/darwin-x64@0.27.4': optional: true '@esbuild/freebsd-arm64@0.19.12': @@ -14674,7 +14698,7 @@ snapshots: '@esbuild/freebsd-arm64@0.25.12': optional: true - '@esbuild/freebsd-arm64@0.27.3': + '@esbuild/freebsd-arm64@0.27.4': optional: true '@esbuild/freebsd-x64@0.19.12': @@ -14683,7 +14707,7 @@ snapshots: '@esbuild/freebsd-x64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.27.3': + '@esbuild/freebsd-x64@0.27.4': optional: true '@esbuild/linux-arm64@0.19.12': @@ -14692,7 +14716,7 @@ snapshots: '@esbuild/linux-arm64@0.25.12': optional: true - '@esbuild/linux-arm64@0.27.3': + '@esbuild/linux-arm64@0.27.4': optional: true '@esbuild/linux-arm@0.19.12': @@ -14701,7 +14725,7 @@ snapshots: '@esbuild/linux-arm@0.25.12': optional: true - '@esbuild/linux-arm@0.27.3': + '@esbuild/linux-arm@0.27.4': optional: true '@esbuild/linux-ia32@0.19.12': @@ -14710,7 +14734,7 @@ snapshots: '@esbuild/linux-ia32@0.25.12': optional: true - '@esbuild/linux-ia32@0.27.3': + '@esbuild/linux-ia32@0.27.4': optional: true '@esbuild/linux-loong64@0.19.12': @@ -14719,7 +14743,7 @@ snapshots: '@esbuild/linux-loong64@0.25.12': optional: true - '@esbuild/linux-loong64@0.27.3': + '@esbuild/linux-loong64@0.27.4': optional: true '@esbuild/linux-mips64el@0.19.12': @@ -14728,7 +14752,7 @@ snapshots: '@esbuild/linux-mips64el@0.25.12': optional: true - '@esbuild/linux-mips64el@0.27.3': + '@esbuild/linux-mips64el@0.27.4': optional: true '@esbuild/linux-ppc64@0.19.12': @@ -14737,7 +14761,7 @@ snapshots: '@esbuild/linux-ppc64@0.25.12': optional: true - '@esbuild/linux-ppc64@0.27.3': + '@esbuild/linux-ppc64@0.27.4': optional: true '@esbuild/linux-riscv64@0.19.12': @@ -14746,7 +14770,7 @@ snapshots: '@esbuild/linux-riscv64@0.25.12': optional: true - '@esbuild/linux-riscv64@0.27.3': + '@esbuild/linux-riscv64@0.27.4': optional: true '@esbuild/linux-s390x@0.19.12': @@ -14755,7 +14779,7 @@ snapshots: '@esbuild/linux-s390x@0.25.12': optional: true - '@esbuild/linux-s390x@0.27.3': + '@esbuild/linux-s390x@0.27.4': optional: true '@esbuild/linux-x64@0.19.12': @@ -14764,13 +14788,13 @@ snapshots: '@esbuild/linux-x64@0.25.12': optional: true - '@esbuild/linux-x64@0.27.3': + '@esbuild/linux-x64@0.27.4': optional: true '@esbuild/netbsd-arm64@0.25.12': optional: true - '@esbuild/netbsd-arm64@0.27.3': + '@esbuild/netbsd-arm64@0.27.4': optional: true '@esbuild/netbsd-x64@0.19.12': @@ -14779,13 +14803,13 @@ snapshots: '@esbuild/netbsd-x64@0.25.12': optional: true - '@esbuild/netbsd-x64@0.27.3': + '@esbuild/netbsd-x64@0.27.4': optional: true '@esbuild/openbsd-arm64@0.25.12': optional: true - '@esbuild/openbsd-arm64@0.27.3': + '@esbuild/openbsd-arm64@0.27.4': optional: true '@esbuild/openbsd-x64@0.19.12': @@ -14794,13 +14818,13 @@ snapshots: '@esbuild/openbsd-x64@0.25.12': optional: true - '@esbuild/openbsd-x64@0.27.3': + '@esbuild/openbsd-x64@0.27.4': optional: true '@esbuild/openharmony-arm64@0.25.12': optional: true - '@esbuild/openharmony-arm64@0.27.3': + '@esbuild/openharmony-arm64@0.27.4': optional: true '@esbuild/sunos-x64@0.19.12': @@ -14809,7 +14833,7 @@ snapshots: '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/sunos-x64@0.27.3': + '@esbuild/sunos-x64@0.27.4': optional: true '@esbuild/win32-arm64@0.19.12': @@ -14818,7 +14842,7 @@ snapshots: '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/win32-arm64@0.27.3': + '@esbuild/win32-arm64@0.27.4': optional: true '@esbuild/win32-ia32@0.19.12': @@ -14827,7 +14851,7 @@ snapshots: '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/win32-ia32@0.27.3': + '@esbuild/win32-ia32@0.27.4': optional: true '@esbuild/win32-x64@0.19.12': @@ -14836,41 +14860,41 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.27.3': + '@esbuild/win32-x64@0.27.4': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.0.2(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@2.6.1))': dependencies: - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.23.2': + '@eslint/config-array@0.23.3': dependencies: - '@eslint/object-schema': 3.0.2 + '@eslint/object-schema': 3.0.3 debug: 4.4.3 minimatch: 10.2.4 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.5.2': + '@eslint/config-helpers@0.5.3': dependencies: - '@eslint/core': 1.1.0 + '@eslint/core': 1.1.1 - '@eslint/core@1.1.0': + '@eslint/core@1.1.1': dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.0.2(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@10.1.0(jiti@2.6.1))': optionalDependencies: - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) - '@eslint/object-schema@3.0.2': {} + '@eslint/object-schema@3.0.3': {} - '@eslint/plugin-kit@0.6.0': + '@eslint/plugin-kit@0.6.1': dependencies: - '@eslint/core': 1.1.0 + '@eslint/core': 1.1.1 levn: 0.4.1 '@extism/extism@2.0.0-rc13': {} @@ -14897,6 +14921,8 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@formatjs/bigdecimal@0.2.0': {} + '@formatjs/ecma402-abstract@2.3.6': dependencies: '@formatjs/fast-memoize': 2.2.7 @@ -14904,20 +14930,17 @@ snapshots: decimal.js: 10.6.0 tslib: 2.8.1 - '@formatjs/ecma402-abstract@3.1.1': + '@formatjs/ecma402-abstract@3.2.0': dependencies: - '@formatjs/fast-memoize': 3.1.0 - '@formatjs/intl-localematcher': 0.8.1 - decimal.js: 10.6.0 - tslib: 2.8.1 + '@formatjs/bigdecimal': 0.2.0 + '@formatjs/fast-memoize': 3.1.1 + '@formatjs/intl-localematcher': 0.8.2 '@formatjs/fast-memoize@2.2.7': dependencies: tslib: 2.8.1 - '@formatjs/fast-memoize@3.1.0': - dependencies: - tslib: 2.8.1 + '@formatjs/fast-memoize@3.1.1': {} '@formatjs/icu-messageformat-parser@2.11.4': dependencies: @@ -14925,30 +14948,27 @@ snapshots: '@formatjs/icu-skeleton-parser': 1.8.16 tslib: 2.8.1 - '@formatjs/icu-messageformat-parser@3.5.1': + '@formatjs/icu-messageformat-parser@3.5.3': dependencies: - '@formatjs/ecma402-abstract': 3.1.1 - '@formatjs/icu-skeleton-parser': 2.1.1 - tslib: 2.8.1 + '@formatjs/ecma402-abstract': 3.2.0 + '@formatjs/icu-skeleton-parser': 2.1.3 '@formatjs/icu-skeleton-parser@1.8.16': dependencies: '@formatjs/ecma402-abstract': 2.3.6 tslib: 2.8.1 - '@formatjs/icu-skeleton-parser@2.1.1': + '@formatjs/icu-skeleton-parser@2.1.3': dependencies: - '@formatjs/ecma402-abstract': 3.1.1 - tslib: 2.8.1 + '@formatjs/ecma402-abstract': 3.2.0 '@formatjs/intl-localematcher@0.6.2': dependencies: tslib: 2.8.1 - '@formatjs/intl-localematcher@0.8.1': + '@formatjs/intl-localematcher@0.8.2': dependencies: - '@formatjs/fast-memoize': 3.1.0 - tslib: 2.8.1 + '@formatjs/fast-memoize': 3.1.1 '@fortawesome/fontawesome-common-types@7.1.0': {} @@ -14960,11 +14980,11 @@ snapshots: dependencies: '@fortawesome/fontawesome-common-types': 7.1.0 - '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) - lodash: 4.17.23 + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + lodash: 4.18.1 '@grpc/grpc-js@1.14.3': dependencies: @@ -15094,7 +15114,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.9.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -15111,27 +15131,27 @@ snapshots: '@immich/sql-tools@0.3.2': dependencies: commander: 14.0.3 - kysely: 0.28.11 - kysely-postgres-js: 3.0.0(kysely@0.28.11)(postgres@3.4.8) + kysely: 0.28.14 + kysely-postgres-js: 3.0.0(kysely@0.28.14)(postgres@3.4.8) pg-connection-string: 2.12.0 postgres: 3.4.8 - '@immich/svelte-markdown-preprocess@0.2.1(svelte@5.53.13)': + '@immich/svelte-markdown-preprocess@0.2.1(svelte@5.54.1)': dependencies: front-matter: 4.0.2 - marked: 17.0.3 + marked: 17.0.5 node-emoji: 2.2.0 - svelte: 5.53.13 + svelte: 5.54.1 - '@immich/ui@0.65.3(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)': + '@immich/ui@0.69.0(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)': dependencies: - '@immich/svelte-markdown-preprocess': 0.2.1(svelte@5.53.13) - '@internationalized/date': 3.10.0 + '@immich/svelte-markdown-preprocess': 0.2.1(svelte@5.54.1) + '@internationalized/date': 3.12.0 '@mdi/js': 7.4.47 - bits-ui: 2.16.0(@internationalized/date@3.10.0)(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13) + bits-ui: 2.16.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1) luxon: 3.7.2 - simple-icons: 16.9.0 - svelte: 5.53.13 + simple-icons: 16.13.0 + svelte: 5.54.1 svelte-highlight: 7.9.0 tailwind-merge: 3.5.0 tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2) @@ -15141,145 +15161,145 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.2(@types/node@24.12.0)': + '@inquirer/checkbox@4.3.2(@types/node@24.12.2)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/confirm@5.1.21(@types/node@24.12.0)': + '@inquirer/confirm@5.1.21(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/core@10.3.2(@types/node@24.12.0)': + '@inquirer/core@10.3.2(@types/node@24.12.2)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.2) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/editor@4.2.23(@types/node@24.12.0)': + '@inquirer/editor@4.2.23(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/external-editor': 1.0.3(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/external-editor': 1.0.3(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/expand@4.0.23(@types/node@24.12.0)': + '@inquirer/expand@4.0.23(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/external-editor@1.0.3(@types/node@24.12.0)': + '@inquirer/external-editor@1.0.3(@types/node@24.12.2)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.1(@types/node@24.12.0)': + '@inquirer/input@4.3.1(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/number@3.0.23(@types/node@24.12.0)': + '@inquirer/number@3.0.23(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/password@4.0.23(@types/node@24.12.0)': + '@inquirer/password@4.0.23(@types/node@24.12.2)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/prompts@7.10.1(@types/node@24.12.0)': + '@inquirer/prompts@7.10.1(@types/node@24.12.2)': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.12.0) - '@inquirer/confirm': 5.1.21(@types/node@24.12.0) - '@inquirer/editor': 4.2.23(@types/node@24.12.0) - '@inquirer/expand': 4.0.23(@types/node@24.12.0) - '@inquirer/input': 4.3.1(@types/node@24.12.0) - '@inquirer/number': 3.0.23(@types/node@24.12.0) - '@inquirer/password': 4.0.23(@types/node@24.12.0) - '@inquirer/rawlist': 4.1.11(@types/node@24.12.0) - '@inquirer/search': 3.2.2(@types/node@24.12.0) - '@inquirer/select': 4.4.2(@types/node@24.12.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.12.2) + '@inquirer/confirm': 5.1.21(@types/node@24.12.2) + '@inquirer/editor': 4.2.23(@types/node@24.12.2) + '@inquirer/expand': 4.0.23(@types/node@24.12.2) + '@inquirer/input': 4.3.1(@types/node@24.12.2) + '@inquirer/number': 3.0.23(@types/node@24.12.2) + '@inquirer/password': 4.0.23(@types/node@24.12.2) + '@inquirer/rawlist': 4.1.11(@types/node@24.12.2) + '@inquirer/search': 3.2.2(@types/node@24.12.2) + '@inquirer/select': 4.4.2(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/prompts@7.3.2(@types/node@24.12.0)': + '@inquirer/prompts@7.3.2(@types/node@24.12.2)': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.12.0) - '@inquirer/confirm': 5.1.21(@types/node@24.12.0) - '@inquirer/editor': 4.2.23(@types/node@24.12.0) - '@inquirer/expand': 4.0.23(@types/node@24.12.0) - '@inquirer/input': 4.3.1(@types/node@24.12.0) - '@inquirer/number': 3.0.23(@types/node@24.12.0) - '@inquirer/password': 4.0.23(@types/node@24.12.0) - '@inquirer/rawlist': 4.1.11(@types/node@24.12.0) - '@inquirer/search': 3.2.2(@types/node@24.12.0) - '@inquirer/select': 4.4.2(@types/node@24.12.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.12.2) + '@inquirer/confirm': 5.1.21(@types/node@24.12.2) + '@inquirer/editor': 4.2.23(@types/node@24.12.2) + '@inquirer/expand': 4.0.23(@types/node@24.12.2) + '@inquirer/input': 4.3.1(@types/node@24.12.2) + '@inquirer/number': 3.0.23(@types/node@24.12.2) + '@inquirer/password': 4.0.23(@types/node@24.12.2) + '@inquirer/rawlist': 4.1.11(@types/node@24.12.2) + '@inquirer/search': 3.2.2(@types/node@24.12.2) + '@inquirer/select': 4.4.2(@types/node@24.12.2) optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/rawlist@4.1.11(@types/node@24.12.0)': + '@inquirer/rawlist@4.1.11(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/search@3.2.2(@types/node@24.12.0)': + '@inquirer/search@3.2.2(@types/node@24.12.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/select@4.4.2(@types/node@24.12.0)': + '@inquirer/select@4.4.2(@types/node@24.12.2)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/core': 10.3.2(@types/node@24.12.2) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@inquirer/type@3.0.10(@types/node@24.12.0)': + '@inquirer/type@3.0.10(@types/node@24.12.2)': optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 - '@internationalized/date@3.10.0': + '@internationalized/date@3.12.0': dependencies: '@swc/helpers': 0.5.17 @@ -15311,7 +15331,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -15391,21 +15411,21 @@ snapshots: dependencies: vary: 1.1.2 - '@koa/router@15.3.0(koa@3.1.1)': + '@koa/router@15.4.0(koa@3.1.2)': dependencies: debug: 4.4.3 http-errors: 2.0.1 - koa: 3.1.1 + koa: 3.1.2 koa-compose: 4.1.0 path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color - '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': + '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2)': dependencies: '@mdn/browser-compat-data': 6.1.5 - '@typescript-eslint/type-utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) browserslist: 4.28.1 transitivePeerDependencies: - eslint @@ -15438,11 +15458,6 @@ snapshots: '@lukeed/csprng@1.1.0': {} - '@mapbox/geojson-rewind@0.5.2': - dependencies: - get-stream: 6.0.1 - minimist: 1.2.8 - '@mapbox/jsonlint-lines-primitives@2.0.2': {} '@mapbox/mapbox-gl-rtl-text@0.3.0': {} @@ -15494,7 +15509,11 @@ snapshots: '@maplibre/geojson-vt@5.0.4': {} - '@maplibre/maplibre-gl-style-spec@24.6.0': + '@maplibre/geojson-vt@6.0.4': + dependencies: + kdbush: 4.0.2 + + '@maplibre/maplibre-gl-style-spec@24.7.0': dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/unitbezier': 0.0.1 @@ -15504,7 +15523,7 @@ snapshots: rw: 1.3.3 tinyqueue: 3.0.0 - '@maplibre/mlt@1.1.6': + '@maplibre/mlt@1.1.8': dependencies: '@mapbox/point-geometry': 1.1.0 @@ -15560,11 +15579,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1)': + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)': dependencies: '@types/mdx': 2.0.13 '@types/react': 19.2.14 - react: 18.3.1 + react: 19.2.4 '@mermaid-js/parser@0.6.3': dependencies: @@ -15592,46 +15611,46 @@ snapshots: '@namnode/store@0.1.0': {} - '@napi-rs/wasm-runtime@1.1.1': + '@napi-rs/wasm-runtime@1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': dependencies: - '@emnapi/core': 1.9.0 - '@emnapi/runtime': 1.7.1 + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 '@tybys/wasm-util': 0.10.1 optional: true - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(bullmq@5.70.4)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(bullmq@5.71.0)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) - bullmq: 5.70.4 + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + bullmq: 5.71.0 tslib: 2.8.1 - '@nestjs/cli@11.0.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(@types/node@24.12.0)(esbuild@0.27.3)': + '@nestjs/cli@11.0.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(@types/node@24.12.2)(esbuild@0.27.4)': dependencies: '@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.12.0)(chokidar@4.0.3) - '@inquirer/prompts': 7.10.1(@types/node@24.12.0) + '@angular-devkit/schematics-cli': 19.2.19(@types/node@24.12.2)(chokidar@4.0.3) + '@inquirer/prompts': 7.10.1(@types/node@24.12.2) '@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.9.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)) glob: 13.0.0 node-emoji: 1.11.0 ora: 5.4.1 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3) + webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/core': 1.15.18(@swc/helpers@0.5.17) @@ -15641,9 +15660,9 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - file-type: 21.3.0 + file-type: 21.3.2 iterare: 1.2.1 load-esm: 1.0.3 reflect-metadata: 0.2.2 @@ -15656,9 +15675,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -15668,21 +15687,21 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) - '@nestjs/websockets': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-socket.io@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) + '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.15.1 - '@nestjs/platform-express@11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/platform-express@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.6 express: 5.2.1 multer: 2.1.1 @@ -15691,10 +15710,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/platform-socket.io@11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.16)(rxjs@7.8.2)': + '@nestjs/platform-socket.io@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/websockets': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-socket.io@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) rxjs: 7.8.2 socket.io: 4.8.3 tslib: 2.8.1 @@ -15703,10 +15722,10 @@ snapshots: - supports-color - utf-8-validate - '@nestjs/schedule@6.1.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/schedule@6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': @@ -15720,12 +15739,23 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.2.6(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': + '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@6.0.2)': + 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: 6.0.2 + transitivePeerDependencies: + - chokidar + + '@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) js-yaml: 4.1.1 lodash: 4.17.23 path-to-regexp: 8.3.0 @@ -15735,25 +15765,25 @@ snapshots: class-transformer: 0.5.1 class-validator: 0.15.1 - '@nestjs/testing@11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16)': + '@nestjs/testing@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-express@11.1.17)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) - '@nestjs/websockets@11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-socket.io@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/websockets@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(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.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.16)(rxjs@7.8.2) + '@nestjs/platform-socket.io': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) '@noble/hashes@1.8.0': {} @@ -15799,7 +15829,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) - yaml: 2.8.2 + yaml: 2.8.3 '@opentelemetry/context-async-hooks@2.6.0(@opentelemetry/api@1.9.0)': dependencies: @@ -16077,9 +16107,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) - '@oxc-project/runtime@0.115.0': {} - - '@oxc-project/types@0.115.0': {} + '@oxc-project/types@0.122.0': {} '@paralleldrive/cuid2@2.3.1': dependencies: @@ -16340,60 +16368,63 @@ snapshots: '@codemirror/state': 6.5.3 '@codemirror/view': 6.39.8 - '@rolldown/binding-android-arm64@1.0.0-rc.9': + '@rolldown/binding-android-arm64@1.0.0-rc.12': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.9': + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.9': + '@rolldown/binding-darwin-x64@1.0.0-rc.12': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.9': + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': dependencies: - '@napi-rs/wasm-runtime': 1.1.1 + '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': optional: true - '@rolldown/pluginutils@1.0.0-rc.9': {} + '@rolldown/pluginutils@1.0.0-rc.12': {} '@rollup/pluginutils@5.3.0(rollup@4.55.1)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.55.1 @@ -16493,13 +16524,13 @@ snapshots: '@sindresorhus/is@5.6.0': {} - '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 invariant: 2.2.4 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) react-fast-compare: 3.2.2 shallowequal: 1.1.0 @@ -16528,53 +16559,53 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))': + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: - '@sveltejs/kit': 2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/kit': 2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) - '@sveltejs/enhanced-img@0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(rollup@4.55.1)(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/enhanced-img@0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(rollup@4.55.1)(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) magic-string: 0.30.21 sharp: 0.34.5 - svelte: 5.53.13 - svelte-parse-markup: 0.1.5(svelte@5.53.13) - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + svelte: 5.54.1 + svelte-parse-markup: 0.1.5(svelte@5.54.1) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) vite-imagetools: 9.0.3(rollup@4.55.1) zimmerframe: 1.1.4 transitivePeerDependencies: - rollup - supports-color - '@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@standard-schema/spec': 1.1.0 '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@types/cookie': 0.6.0 acorn: 8.16.0 cookie: 0.6.0 - devalue: 5.6.3 + devalue: 5.6.4 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 mrmime: 2.0.1 - set-cookie-parser: 3.0.1 + set-cookie-parser: 3.1.0 sirv: 3.0.2 - svelte: 5.53.13 - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + svelte: 5.54.1 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) optionalDependencies: '@opentelemetry/api': 1.9.0 - typescript: 5.9.3 + typescript: 6.0.2 - '@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.53.13 - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.2(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + svelte: 5.54.1 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) + vitefu: 1.1.2(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)': dependencies: @@ -16620,12 +16651,12 @@ snapshots: '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.5) '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.5) - '@svgr/core@8.1.0(typescript@5.9.3)': + '@svgr/core@8.1.0(typescript@6.0.2)': dependencies: '@babel/core': 7.28.5 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@6.0.2) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -16636,35 +16667,35 @@ snapshots: '@babel/types': 7.29.0 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@6.0.2))': dependencies: '@babel/core': 7.28.5 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) - '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/core': 8.1.0(typescript@6.0.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.2))(typescript@6.0.2)': dependencies: - '@svgr/core': 8.1.0(typescript@5.9.3) - cosmiconfig: 8.3.6(typescript@5.9.3) + '@svgr/core': 8.1.0(typescript@6.0.2) + cosmiconfig: 8.3.6(typescript@6.0.2) deepmerge: 4.3.1 svgo: 3.3.2 transitivePeerDependencies: - typescript - '@svgr/webpack@8.1.0(typescript@5.9.3)': + '@svgr/webpack@8.1.0(typescript@6.0.2)': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.5) '@babel/preset-env': 7.28.5(@babel/core@7.28.5) '@babel/preset-react': 7.28.5(@babel/core@7.28.5) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@svgr/core': 8.1.0(typescript@5.9.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) + '@svgr/core': 8.1.0(typescript@6.0.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.2)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.2))(typescript@6.0.2) transitivePeerDependencies: - supports-color - typescript @@ -16791,17 +16822,17 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 - '@tailwindcss/vite@4.2.2(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.2.2(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.2.2 '@tailwindcss/oxide': 4.2.2 tailwindcss: 4.2.2 - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -16818,18 +16849,18 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/svelte-core@1.0.0(svelte@5.53.13)': + '@testing-library/svelte-core@1.0.0(svelte@5.54.1)': dependencies: - svelte: 5.53.13 + svelte: 5.54.1 - '@testing-library/svelte@5.3.1(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@testing-library/svelte@5.3.1(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@testing-library/dom': 10.4.1 - '@testing-library/svelte-core': 1.0.0(svelte@5.53.13) - svelte: 5.53.13 + '@testing-library/svelte-core': 1.0.0(svelte@5.54.1) + svelte: 5.54.1 optionalDependencies: - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) + vitest: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: @@ -16846,22 +16877,22 @@ snapshots: '@trysound/sax@0.2.0': {} - '@turf/boolean-point-in-polygon@7.3.2': + '@turf/boolean-point-in-polygon@7.3.4': dependencies: - '@turf/helpers': 7.3.2 - '@turf/invariant': 7.3.2 + '@turf/helpers': 7.3.4 + '@turf/invariant': 7.3.4 '@types/geojson': 7946.0.16 point-in-polygon-hao: 1.2.4 tslib: 2.8.1 - '@turf/helpers@7.3.2': + '@turf/helpers@7.3.4': dependencies: '@types/geojson': 7946.0.16 tslib: 2.8.1 - '@turf/invariant@7.3.2': + '@turf/invariant@7.3.4': dependencies: - '@turf/helpers': 7.3.2 + '@turf/helpers': 7.3.4 '@types/geojson': 7946.0.16 tslib: 2.8.1 @@ -16872,7 +16903,7 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/archiver@7.0.0': dependencies: @@ -16884,16 +16915,16 @@ snapshots: '@types/bcrypt@6.0.0': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/bonjour@3.5.13': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/braces@3.0.5': {} @@ -16915,21 +16946,21 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/compression@1.8.1': dependencies: '@types/express': 5.0.6 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.1.0 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/connect@3.4.38': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/content-disposition@0.5.9': {} @@ -16946,11 +16977,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.6 '@types/keygrip': 1.0.6 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/cors@2.8.19': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/d3-array@3.2.2': {} @@ -17077,13 +17108,13 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ssh2': 1.15.5 '@types/dockerode@4.0.1': dependencies: '@types/docker-modem': 3.0.6 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ssh2': 1.15.5 '@types/dom-to-image@2.6.7': {} @@ -17108,14 +17139,14 @@ snapshots: '@types/express-serve-static-core@4.19.7': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@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': 24.12.0 + '@types/node': 24.12.2 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -17141,7 +17172,7 @@ snapshots: '@types/fluent-ffmpeg@2.1.28': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/geojson@7946.0.16': {} @@ -17169,7 +17200,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/inquirer@8.2.12': dependencies: @@ -17193,7 +17224,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/justified-layout@4.1.4': {} @@ -17212,7 +17243,7 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.9 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/leaflet@1.9.21': dependencies: @@ -17242,7 +17273,7 @@ snapshots: '@types/mock-fs@4.13.4': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ms@2.1.0': {} @@ -17252,7 +17283,7 @@ snapshots: '@types/node-forge@1.3.14': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/node@17.0.45': {} @@ -17260,40 +17291,40 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@24.12.0': + '@types/node@24.12.2': dependencies: undici-types: 7.16.0 - '@types/node@25.4.0': + '@types/node@25.5.0': dependencies: undici-types: 7.18.2 optional: true '@types/nodemailer@7.0.11': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/oidc-provider@9.5.0': dependencies: '@types/keygrip': 1.0.6 '@types/koa': 3.0.1 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/parse5@5.0.3': {} '@types/pg-pool@2.0.7': dependencies: - '@types/pg': 8.18.0 + '@types/pg': 8.20.0 '@types/pg@8.15.6': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 pg-protocol: 1.13.0 pg-types: 2.2.0 - '@types/pg@8.18.0': + '@types/pg@8.20.0': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 pg-protocol: 1.13.0 pg-types: 2.2.0 @@ -17301,13 +17332,13 @@ snapshots: '@types/pngjs@6.0.5': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/prismjs@1.26.5': {} '@types/qrcode@1.5.6': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/qs@6.14.0': {} @@ -17336,28 +17367,24 @@ snapshots: '@types/readdir-glob@1.1.5': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/retry@0.12.2': {} - '@types/sanitize-html@2.16.1': - dependencies: - htmlparser2: 10.1.0 - '@types/sax@1.2.7': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/semver@7.7.1': {} '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/send@1.2.1': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/serve-index@1.9.4': dependencies: @@ -17366,25 +17393,25 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/sockjs@0.3.36': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ssh2-streams@0.1.13': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ssh2@0.5.52': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/ssh2-streams': 0.1.13 '@types/ssh2@1.15.5': @@ -17395,21 +17422,21 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 24.12.0 + '@types/node': 24.12.2 form-data: 4.0.5 '@types/supercluster@7.1.3': dependencies: '@types/geojson': 7946.0.16 - '@types/supertest@6.0.3': + '@types/supertest@7.2.0': dependencies: '@types/methods': 1.1.4 '@types/superagent': 8.1.9 '@types/through@0.0.33': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/trusted-types@2.0.7': {} @@ -17425,7 +17452,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/yargs-parser@21.0.3': {} @@ -17433,102 +17460,102 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.58.0(@typescript-eslint/parser@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 - eslint: 10.0.2(jiti@2.6.1) + '@typescript-eslint/parser': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/type-utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.0 + eslint: 10.1.0(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2)': dependencies: - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.0 debug: 4.4.3 - eslint: 10.0.2(jiti@2.6.1) - typescript: 5.9.3 + eslint: 10.1.0(jiti@2.6.1) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.58.0(typescript@6.0.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.58.0(typescript@6.0.2) + '@typescript-eslint/types': 8.58.0 debug: 4.4.3 - typescript: 5.9.3 + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.56.1': + '@typescript-eslint/scope-manager@8.58.0': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.58.0(typescript@6.0.2)': dependencies: - typescript: 5.9.3 + typescript: 6.0.2 - '@typescript-eslint/type-utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2)': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) debug: 4.4.3 - eslint: 10.0.2(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + eslint: 10.1.0(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.56.1': {} + '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.58.0(typescript@6.0.2)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/project-service': 8.58.0(typescript@6.0.2) + '@typescript-eslint/tsconfig-utils': 8.58.0(typescript@6.0.2) + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - eslint: 10.0.2(jiti@2.6.1) - typescript: 5.9.3 + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + eslint: 10.1.0(jiti@2.6.1) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.56.1': + '@typescript-eslint/visitor-keys@8.58.0': dependencies: - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.1 '@ungap/structured-clone@1.3.0': {} '@vercel/oidc@3.0.5': {} - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -17543,37 +17570,37 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.2 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.12 + '@vitest/utils': 4.1.0 + ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.2 obug: 2.1.1 - std-env: 3.10.0 - tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + std-env: 4.0.0 + tinyrainbow: 3.1.0 + vitest: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.12 + '@vitest/utils': 4.1.0 + ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.2 obug: 2.1.1 - std-env: 3.10.0 - tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + std-env: 4.0.0 + tinyrainbow: 3.1.0 + vitest: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/expect@3.2.4': dependencies: @@ -17583,46 +17610,46 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/expect@4.0.18': + '@vitest/expect@4.1.0': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 chai: 6.2.2 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@vitest/spy': 4.0.18 + '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@vitest/spy': 4.0.18 + '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@4.0.18': + '@vitest/pretty-format@4.1.0': dependencies: - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 '@vitest/runner@3.2.4': dependencies: @@ -17630,9 +17657,9 @@ snapshots: pathe: 2.0.3 strip-literal: 3.1.0 - '@vitest/runner@4.0.18': + '@vitest/runner@4.1.0': dependencies: - '@vitest/utils': 4.0.18 + '@vitest/utils': 4.1.0 pathe: 2.0.3 '@vitest/snapshot@3.2.4': @@ -17641,9 +17668,10 @@ snapshots: magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/snapshot@4.0.18': + '@vitest/snapshot@4.1.0': dependencies: - '@vitest/pretty-format': 4.0.18 + '@vitest/pretty-format': 4.1.0 + '@vitest/utils': 4.1.0 magic-string: 0.30.21 pathe: 2.0.3 @@ -17651,7 +17679,7 @@ snapshots: dependencies: tinyspy: 4.0.4 - '@vitest/spy@4.0.18': {} + '@vitest/spy@4.1.0': {} '@vitest/utils@3.2.4': dependencies: @@ -17659,10 +17687,11 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@vitest/utils@4.0.18': + '@vitest/utils@4.1.0': dependencies: - '@vitest/pretty-format': 4.0.18 - tinyrainbow: 3.0.3 + '@vitest/pretty-format': 4.1.0 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 '@webassemblyjs/ast@1.14.1': dependencies: @@ -17748,10 +17777,10 @@ snapshots: dependencies: '@namnode/store': 0.1.0 - '@zoom-image/svelte@0.3.9(svelte@5.53.13)': + '@zoom-image/svelte@0.3.9(svelte@5.54.1)': dependencies: '@zoom-image/core': 0.42.0 - svelte: 5.53.13 + svelte: 5.54.1 abbrev@1.1.1: {} @@ -17903,7 +17932,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 append-field@1.0.0: {} @@ -17915,7 +17944,7 @@ snapshots: graceful-fs: 4.2.11 is-stream: 2.0.1 lazystream: 1.0.1 - lodash: 4.17.23 + lodash: 4.18.1 normalize-path: 3.0.0 readable-stream: 4.7.0 @@ -17926,10 +17955,11 @@ snapshots: buffer-crc32: 1.0.0 readable-stream: 4.7.0 readdir-glob: 1.1.3 - tar-stream: 3.1.7 + tar-stream: 3.1.8 zip-stream: 6.0.1 transitivePeerDependencies: - bare-abort-controller + - bare-buffer - react-native-b4a are-we-there-yet@2.0.0: @@ -17979,6 +18009,12 @@ snapshots: estree-walker: 3.0.3 js-tokens: 10.0.0 + ast-v8-to-istanbul@1.0.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + astring@1.9.0: {} async-lock@1.4.1: {} @@ -18004,7 +18040,7 @@ snapshots: axobject-query@4.1.0: {} - b4a@1.7.3: {} + b4a@1.8.0: {} babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.104.1): dependencies: @@ -18030,7 +18066,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) - core-js-compat: 3.47.0 + core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color @@ -18051,41 +18087,35 @@ snapshots: bare-events@2.8.2: {} - bare-fs@4.5.4: + bare-fs@4.5.6: dependencies: bare-events: 2.8.2 bare-path: 3.0.0 - bare-stream: 2.8.0(bare-events@2.8.2) - bare-url: 2.3.2 + bare-stream: 2.11.0(bare-events@2.8.2) + bare-url: 2.4.0 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - optional: true - bare-os@3.6.2: - optional: true + bare-os@3.8.0: {} bare-path@3.0.0: dependencies: - bare-os: 3.6.2 - optional: true + bare-os: 3.8.0 - bare-stream@2.8.0(bare-events@2.8.2): + bare-stream@2.11.0(bare-events@2.8.2): dependencies: - streamx: 2.23.0 + streamx: 2.25.0 teex: 1.0.1 optionalDependencies: bare-events: 2.8.2 transitivePeerDependencies: - - bare-abort-controller - react-native-b4a - optional: true - bare-url@2.3.2: + bare-url@2.4.0: dependencies: bare-path: 3.0.0 - optional: true base64-js@1.5.1: {} @@ -18115,15 +18145,15 @@ snapshots: binary-extensions@2.3.0: {} - bits-ui@2.16.0(@internationalized/date@3.10.0)(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13): + bits-ui@2.16.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 - '@internationalized/date': 3.10.0 + '@internationalized/date': 3.12.0 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13) - svelte: 5.53.13 - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13) + runed: 0.35.1(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1) + svelte: 5.54.1 + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1) tabbable: 6.4.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -18203,7 +18233,7 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.4: + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -18240,7 +18270,7 @@ snapshots: builtin-modules@5.0.0: {} - bullmq@5.70.4: + bullmq@5.71.0: dependencies: cron-parser: 4.9.0 ioredis: 5.9.3 @@ -18340,7 +18370,7 @@ snapshots: canvas@2.11.2: dependencies: '@mapbox/node-pre-gyp': 1.0.11 - nan: 2.25.0 + nan: 2.26.2 simple-get: 3.1.1 transitivePeerDependencies: - encoding @@ -18350,7 +18380,7 @@ snapshots: canvas@2.11.2(encoding@0.1.13): dependencies: '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) - nan: 2.25.0 + nan: 2.26.2 simple-get: 3.1.1 transitivePeerDependencies: - encoding @@ -18414,7 +18444,7 @@ snapshots: chevrotain-allstar@0.3.1(chevrotain@11.0.3): dependencies: chevrotain: 11.0.3 - lodash-es: 4.17.23 + lodash-es: 4.18.1 chevrotain@11.0.3: dependencies: @@ -18451,7 +18481,7 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.1: {} + ci-info@4.4.0: {} citty@0.1.6: dependencies: @@ -18523,6 +18553,12 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 @@ -18697,7 +18733,7 @@ snapshots: serialize-javascript: 6.0.2 webpack: 5.104.1 - core-js-compat@3.47.0: + core-js-compat@3.49.0: dependencies: browserslist: 4.28.1 @@ -18729,10 +18765,19 @@ snapshots: optionalDependencies: typescript: 5.9.3 + cosmiconfig@8.3.6(typescript@6.0.2): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 6.0.2 + cpu-features@0.0.10: dependencies: buildcheck: 0.0.7 - nan: 2.25.0 + nan: 2.26.2 optional: true crc-32@1.2.2: {} @@ -19098,7 +19143,7 @@ snapshots: dagre-d3-es@7.0.13: dependencies: d3: 7.9.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 data-urls@5.0.0: dependencies: @@ -19182,7 +19227,7 @@ snapshots: delaunator@5.0.1: dependencies: - robust-predicates: 3.0.2 + robust-predicates: 3.0.3 delayed-stream@1.0.0: {} @@ -19214,8 +19259,6 @@ snapshots: transitivePeerDependencies: - supports-color - devalue@5.6.3: {} - devalue@5.6.4: {} devlop@1.1.0: @@ -19249,11 +19292,11 @@ snapshots: dependencies: '@leichtgewicht/ip-codec': 2.0.5 - docker-compose@1.3.1: + docker-compose@1.3.3: dependencies: - yaml: 2.8.2 + yaml: 2.8.3 - docker-modem@5.0.6: + docker-modem@5.0.7: dependencies: debug: 4.4.3 readable-stream: 3.6.2 @@ -19262,21 +19305,21 @@ snapshots: transitivePeerDependencies: - supports-color - dockerode@4.0.9: + dockerode@4.0.10: dependencies: '@balena/dockerignore': 1.0.2 '@grpc/grpc-js': 1.14.3 '@grpc/proto-loader': 0.7.15 - docker-modem: 5.0.6 + docker-modem: 5.0.7 protobufjs: 7.5.4 tar-fs: 2.1.4 uuid: 10.0.0 transitivePeerDependencies: - supports-color - docusaurus-lunr-search@3.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(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.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) autocomplete.js: 0.37.1 clsx: 2.1.1 gauge: 3.0.2 @@ -19286,9 +19329,9 @@ snapshots: lunr: 2.3.9 lunr-languages: 1.14.0 mark.js: 8.11.1 - minimatch: 3.1.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + minimatch: 3.1.5 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) rehype-parse: 7.0.1 to-vfile: 6.1.0 unified: 9.2.2 @@ -19413,7 +19456,7 @@ snapshots: engine.io@6.6.5: dependencies: '@types/cors': 2.8.19 - '@types/node': 24.12.0 + '@types/node': 24.12.2 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -19560,34 +19603,34 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 - esbuild@0.27.3: + esbuild@0.27.4: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.3 - '@esbuild/android-arm': 0.27.3 - '@esbuild/android-arm64': 0.27.3 - '@esbuild/android-x64': 0.27.3 - '@esbuild/darwin-arm64': 0.27.3 - '@esbuild/darwin-x64': 0.27.3 - '@esbuild/freebsd-arm64': 0.27.3 - '@esbuild/freebsd-x64': 0.27.3 - '@esbuild/linux-arm': 0.27.3 - '@esbuild/linux-arm64': 0.27.3 - '@esbuild/linux-ia32': 0.27.3 - '@esbuild/linux-loong64': 0.27.3 - '@esbuild/linux-mips64el': 0.27.3 - '@esbuild/linux-ppc64': 0.27.3 - '@esbuild/linux-riscv64': 0.27.3 - '@esbuild/linux-s390x': 0.27.3 - '@esbuild/linux-x64': 0.27.3 - '@esbuild/netbsd-arm64': 0.27.3 - '@esbuild/netbsd-x64': 0.27.3 - '@esbuild/openbsd-arm64': 0.27.3 - '@esbuild/openbsd-x64': 0.27.3 - '@esbuild/openharmony-arm64': 0.27.3 - '@esbuild/sunos-x64': 0.27.3 - '@esbuild/win32-arm64': 0.27.3 - '@esbuild/win32-ia32': 0.27.3 - '@esbuild/win32-x64': 0.27.3 + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 escalade@3.2.0: {} @@ -19601,36 +19644,36 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)): dependencies: - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) - eslint-plugin-compat@6.2.1(eslint@10.0.2(jiti@2.6.1)): + eslint-plugin-compat@7.0.1(eslint@10.1.0(jiti@2.6.1)): dependencies: '@mdn/browser-compat-data': 6.1.5 ast-metadata-inferer: 0.8.1 browserslist: 4.28.1 - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) find-up: 5.0.0 globals: 15.15.0 lodash.memoize: 4.1.2 semver: 7.7.4 - eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1): + eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@3.8.1): dependencies: - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) prettier: 3.8.1 prettier-linter-helpers: 1.0.1 synckit: 0.11.12 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@10.0.2(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@10.1.0(jiti@2.6.1)) - eslint-plugin-svelte@3.15.0(eslint@10.0.2(jiti@2.6.1))(svelte@5.53.13): + eslint-plugin-svelte@3.16.0(eslint@10.1.0(jiti@2.6.1))(svelte@5.54.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 10.0.2(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 @@ -19638,23 +19681,23 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.8) postcss-safe-parser: 7.0.1(postcss@8.5.8) semver: 7.7.4 - svelte-eslint-parser: 1.6.0(svelte@5.53.13) + svelte-eslint-parser: 1.6.0(svelte@5.54.1) optionalDependencies: - svelte: 5.53.13 + svelte: 5.54.1 transitivePeerDependencies: - ts-node - eslint-plugin-unicorn@63.0.0(eslint@10.0.2(jiti@2.6.1)): + eslint-plugin-unicorn@64.0.0(eslint@10.1.0(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) change-case: 5.4.4 - ci-info: 4.3.1 + ci-info: 4.4.0 clean-regexp: 1.0.0 - core-js-compat: 3.47.0 - eslint: 10.0.2(jiti@2.6.1) + core-js-compat: 3.49.0 + eslint: 10.1.0(jiti@2.6.1) find-up-simple: 1.0.1 - globals: 16.5.0 + globals: 17.4.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 @@ -19674,7 +19717,7 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-scope@9.1.1: + eslint-scope@9.1.2: dependencies: '@types/esrecurse': 4.3.1 '@types/estree': 1.0.8 @@ -19687,14 +19730,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.0.2(jiti@2.6.1): + eslint@10.1.0(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.2 - '@eslint/config-helpers': 0.5.2 - '@eslint/core': 1.1.0 - '@eslint/plugin-kit': 0.6.0 + '@eslint/config-array': 0.23.3 + '@eslint/config-helpers': 0.5.3 + '@eslint/core': 1.1.1 + '@eslint/plugin-kit': 0.6.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -19703,9 +19746,9 @@ snapshots: cross-spawn: 7.0.6 debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint-scope: 9.1.1 + eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 - espree: 11.1.1 + espree: 11.2.0 esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -19739,7 +19782,7 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 - espree@11.1.1: + espree@11.2.0: dependencies: acorn: 8.16.0 acorn-jsx: 5.3.2(acorn@8.16.0) @@ -19812,7 +19855,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 require-like: 0.1.2 event-emitter@0.3.5: @@ -19846,21 +19889,21 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exiftool-vendored.exe@13.52.0: + exiftool-vendored.exe@13.53.0: optional: true - exiftool-vendored.pl@13.52.0: {} + exiftool-vendored.pl@13.53.0: {} - exiftool-vendored@35.13.1: + exiftool-vendored@35.15.1: dependencies: '@photostructure/tz-lookup': 11.5.0 '@types/luxon': 3.7.1 batch-cluster: 17.3.1 - exiftool-vendored.pl: 13.52.0 + exiftool-vendored.pl: 13.53.0 he: 1.2.0 luxon: 3.7.2 optionalDependencies: - exiftool-vendored.exe: 13.52.0 + exiftool-vendored.exe: 13.53.0 expect-type@1.3.0: {} @@ -19887,7 +19930,7 @@ snapshots: methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.12 + path-to-regexp: 0.1.13 proxy-addr: 2.0.7 qs: 6.14.1 range-parser: 1.2.1 @@ -19998,9 +20041,9 @@ snapshots: dependencies: websocket-driver: 0.7.4 - fdir@6.5.0(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 feed@4.2.2: dependencies: @@ -20026,10 +20069,10 @@ snapshots: dependencies: stream-source: 0.3.5 - file-type@21.3.0: + file-type@21.3.2: dependencies: '@tokenizer/inflate': 0.4.1 - strtok3: 10.3.4 + strtok3: 10.3.5 token-types: 6.1.2 uint8array-extras: 1.5.0 transitivePeerDependencies: @@ -20086,12 +20129,12 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 flat@5.0.2: {} - flatted@3.3.3: {} + flatted@3.4.2: {} fluent-ffmpeg@2.1.3: dependencies: @@ -20105,7 +20148,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)): dependencies: '@babel/code-frame': 7.29.0 chalk: 4.1.2 @@ -20114,13 +20157,13 @@ snapshots: deepmerge: 4.3.1 fs-extra: 10.1.0 memfs: 3.5.3 - minimatch: 3.1.2 + minimatch: 3.1.5 node-abort-controller: 3.1.1 schema-utils: 3.3.0 semver: 7.7.4 tapable: 2.3.0 typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3) + webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4) form-data-encoder@2.1.4: {} @@ -20204,10 +20247,10 @@ snapshots: geo-coordinates-parser@1.7.4: {} - geo-tz@8.1.5: + geo-tz@8.1.6: dependencies: - '@turf/boolean-point-in-polygon': 7.3.2 - '@turf/helpers': 7.3.2 + '@turf/boolean-point-in-polygon': 7.3.4 + '@turf/helpers': 7.3.4 geobuf: 3.0.2 pbf: 3.3.0 @@ -20238,7 +20281,7 @@ snapshots: get-own-enumerable-property-symbols@3.0.2: {} - get-port@7.1.0: {} + get-port@7.2.0: {} get-proto@1.0.1: dependencies: @@ -20273,7 +20316,7 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.6 + minimatch: 9.0.9 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 @@ -20304,7 +20347,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -20374,7 +20417,7 @@ snapshots: handle-thing@2.0.1: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -20383,14 +20426,14 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - happy-dom@20.8.3: + happy-dom@20.8.9: dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.19.0 + ws: 8.20.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -20561,11 +20604,13 @@ snapshots: he@1.2.0: {} + helmet@8.1.0: {} + highlight.js@11.11.1: {} history@4.10.1: dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.3.3 @@ -20631,19 +20676,12 @@ snapshots: dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 - lodash: 4.17.23 + lodash: 4.18.1 pretty-error: 4.0.0 tapable: 2.3.0 optionalDependencies: webpack: 5.104.1 - htmlparser2@10.1.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 7.0.1 - htmlparser2@6.1.0: dependencies: domelementtype: 2.3.0 @@ -20815,15 +20853,15 @@ snapshots: inline-style-parser@0.2.7: {} - inquirer@8.2.7(@types/node@24.12.0): + inquirer@8.2.7(@types/node@24.12.2): dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@24.12.0) + '@inquirer/external-editor': 1.0.3(@types/node@24.12.2) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 cli-width: 3.0.0 figures: 3.2.0 - lodash: 4.17.23 + lodash: 4.18.1 mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 @@ -20846,18 +20884,17 @@ snapshots: '@formatjs/icu-messageformat-parser': 2.11.4 tslib: 2.8.1 - intl-messageformat@11.1.2: + intl-messageformat@11.2.0: dependencies: - '@formatjs/ecma402-abstract': 3.1.1 - '@formatjs/fast-memoize': 3.1.0 - '@formatjs/icu-messageformat-parser': 3.5.1 - tslib: 2.8.1 + '@formatjs/ecma402-abstract': 3.2.0 + '@formatjs/fast-memoize': 3.1.1 + '@formatjs/icu-messageformat-parser': 3.5.3 invariant@2.2.4: dependencies: loose-envify: 1.4.0 - ioredis@5.10.0: + ioredis@5.10.1: dependencies: '@ioredis/commands': 1.5.1 cluster-key-slot: 1.1.2 @@ -20936,6 +20973,8 @@ snapshots: is-hexadecimal@2.0.1: {} + is-in-ssh@1.0.0: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -20971,8 +21010,6 @@ snapshots: dependencies: isobject: 3.0.1 - is-plain-object@5.0.0: {} - is-potential-custom-element-name@1.0.1: optional: true @@ -21054,21 +21091,21 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 24.12.0 + '@types/node': 24.12.2 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 2.3.2 jest-worker@27.5.1: dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -21091,7 +21128,7 @@ snapshots: jose@5.10.0: {} - jose@6.1.3: {} + jose@6.2.2: {} js-tokens@10.0.0: {} @@ -21128,7 +21165,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.19.0 + ws: 8.20.0 xml-name-validator: 5.0.0 optionalDependencies: canvas: 2.11.2(encoding@0.1.13) @@ -21158,7 +21195,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.19.0 + ws: 8.20.0 xml-name-validator: 5.0.0 optionalDependencies: canvas: 2.11.2 @@ -21260,10 +21297,10 @@ snapshots: koa-compose@4.1.0: {} - koa@3.1.1: + koa@3.1.2: dependencies: accepts: 1.3.8 - content-disposition: 0.5.4 + content-disposition: 1.0.1 content-type: 1.0.5 cookies: 0.9.1 delegates: 1.0.0 @@ -21281,13 +21318,13 @@ snapshots: type-is: 2.0.1 vary: 1.1.2 - kysely-postgres-js@3.0.0(kysely@0.28.11)(postgres@3.4.8): + kysely-postgres-js@3.0.0(kysely@0.28.14)(postgres@3.4.8): dependencies: - kysely: 0.28.11 + kysely: 0.28.14 optionalDependencies: postgres: 3.4.8 - kysely@0.28.11: {} + kysely@0.28.14: {} langium@3.3.1: dependencies: @@ -21408,7 +21445,7 @@ snapshots: lodash-es@4.17.21: {} - lodash-es@4.17.23: {} + lodash-es@4.18.1: {} lodash.camelcase@4.3.0: {} @@ -21438,6 +21475,8 @@ snapshots: lodash@4.17.23: {} + lodash@4.18.1: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -21499,13 +21538,13 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 source-map-js: 1.2.1 magicast@0.5.2: dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 source-map-js: 1.2.1 @@ -21533,21 +21572,19 @@ snapshots: transitivePeerDependencies: - supports-color - maplibre-gl@5.19.0: + maplibre-gl@5.21.0: dependencies: - '@mapbox/geojson-rewind': 0.5.2 '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/point-geometry': 1.1.0 '@mapbox/tiny-sdf': 2.0.7 '@mapbox/unitbezier': 0.0.1 '@mapbox/vector-tile': 2.0.4 '@mapbox/whoots-js': 3.1.0 - '@maplibre/geojson-vt': 5.0.4 - '@maplibre/maplibre-gl-style-spec': 24.6.0 - '@maplibre/mlt': 1.1.6 + '@maplibre/geojson-vt': 6.0.4 + '@maplibre/maplibre-gl-style-spec': 24.7.0 + '@maplibre/mlt': 1.1.8 '@maplibre/vt-pbf': 4.3.0 '@types/geojson': 7946.0.16 - '@types/supercluster': 7.1.3 earcut: 3.0.2 gl-matrix: 3.4.4 kdbush: 4.0.2 @@ -21555,7 +21592,6 @@ snapshots: pbf: 4.0.1 potpack: 2.1.0 quickselect: 3.0.0 - supercluster: 8.0.1 tinyqueue: 3.0.0 mark.js@8.11.1: {} @@ -21572,7 +21608,7 @@ snapshots: marked@16.4.2: {} - marked@17.0.3: {} + marked@17.0.5: {} math-intrinsics@1.1.0: {} @@ -21822,7 +21858,7 @@ snapshots: dompurify: 3.3.1 katex: 0.16.27 khroma: 2.1.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 marked: 16.4.2 roughjs: 4.6.6 stylis: 4.3.6 @@ -22129,7 +22165,7 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 mime-db@1.33.0: {} @@ -22176,19 +22212,23 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.4 + brace-expansion: 5.0.5 minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 - minimatch@5.1.6: + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@5.1.9: dependencies: brace-expansion: 2.0.2 - minimatch@9.0.6: + minimatch@9.0.9: dependencies: - brace-expansion: 5.0.4 + brace-expansion: 2.0.2 minimist@1.2.8: {} @@ -22306,12 +22346,12 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.25.0: + nan@2.26.2: optional: true nanoid@3.3.11: {} - nanoid@5.1.6: {} + nanoid@5.1.7: {} natural-compare-lite@1.4.0: {} @@ -22332,39 +22372,39 @@ snapshots: neo-async@2.6.2: {} - nest-commander@3.20.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@types/inquirer@8.2.12)(@types/node@24.12.0)(typescript@5.9.3): + nest-commander@3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@types/inquirer': 8.2.12 commander: 11.1.0 - cosmiconfig: 8.3.6(typescript@5.9.3) - inquirer: 8.2.7(@types/node@24.12.0) + cosmiconfig: 8.3.6(typescript@6.0.2) + inquirer: 8.2.7(@types/node@24.12.2) transitivePeerDependencies: - '@types/node' - typescript - nestjs-cls@5.4.3(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(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.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(kysely@0.28.11)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17)(kysely@0.28.14)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) - kysely: 0.28.11 + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + kysely: 0.28.14 reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-otel@7.0.1(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16): + nestjs-otel@7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.17): dependencies: - '@nestjs/common': 11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(@nestjs/websockets@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': 1.9.0 '@opentelemetry/host-metrics': 0.36.2(@opentelemetry/api@1.9.0) response-time: 2.3.4 @@ -22388,7 +22428,7 @@ snapshots: node-emoji@1.11.0: dependencies: - lodash: 4.17.23 + lodash: 4.18.1 node-emoji@2.2.0: dependencies: @@ -22434,7 +22474,7 @@ snapshots: node-releases@2.0.27: {} - nodemailer@7.0.13: {} + nodemailer@8.0.4: {} nopt@1.0.10: dependencies: @@ -22515,18 +22555,19 @@ snapshots: obug@2.1.1: {} - oidc-provider@9.6.1: + oidc-provider@9.7.1: dependencies: '@koa/cors': 5.0.0 - '@koa/router': 15.3.0(koa@3.1.1) + '@koa/router': 15.4.0(koa@3.1.2) debug: 4.4.3 eta: 4.5.1 - jose: 6.1.3 + jose: 6.2.2 jsesc: 3.1.0 - koa: 3.1.1 - nanoid: 5.1.6 + koa: 3.1.2 + nanoid: 5.1.7 quick-lru: 7.3.0 raw-body: 3.0.2 + undici: 7.24.6 transitivePeerDependencies: - supports-color @@ -22555,6 +22596,15 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + open@11.0.0: + dependencies: + default-browser: 5.4.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -22565,7 +22615,7 @@ snapshots: openid-client@6.8.2: dependencies: - jose: 6.1.3 + jose: 6.2.2 oauth4webapi: 3.8.5 optionator@0.9.4: @@ -22691,8 +22741,6 @@ snapshots: parse-numeric-range@1.3.0: {} - parse-srcset@1.0.2: {} - parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 @@ -22745,7 +22793,7 @@ snapshots: array-source: 0.0.4 file-source: 0.6.1 - path-to-regexp@0.1.12: {} + path-to-regexp@0.1.13: {} path-to-regexp@1.9.0: dependencies: @@ -22809,11 +22857,11 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} picomatch@4.0.2: {} - picomatch@4.0.3: {} + picomatch@4.0.4: {} pify@2.3.0: {} @@ -22860,7 +22908,7 @@ snapshots: point-in-polygon-hao@1.2.4: dependencies: - robust-predicates: 3.0.2 + robust-predicates: 3.0.3 points-on-curve@0.2.0: {} @@ -23026,22 +23074,22 @@ snapshots: postcss-load-config@3.1.4(postcss@8.5.8): dependencies: lilconfig: 2.1.0 - yaml: 1.10.2 + yaml: 1.10.3 optionalDependencies: postcss: 8.5.8 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.3): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.8 tsx: 4.21.0 - yaml: 2.8.2 + yaml: 2.8.3 - postcss-loader@7.3.4(postcss@8.5.8)(typescript@5.9.3)(webpack@5.104.1): + postcss-loader@7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.104.1): dependencies: - cosmiconfig: 8.3.6(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@6.0.2) jiti: 1.21.7 postcss: 8.5.8 semver: 7.7.4 @@ -23363,31 +23411,33 @@ snapshots: potpack@2.1.0: {} + powershell-utils@0.1.0: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.1: dependencies: fast-diff: 1.3.0 - prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.9.3): + prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@6.0.2): dependencies: prettier: 3.8.1 - typescript: 5.9.3 + typescript: 6.0.2 prettier-plugin-sort-json@4.2.0(prettier@3.8.1): dependencies: prettier: 3.8.1 - prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.53.13): + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.54.1): dependencies: prettier: 3.8.1 - svelte: 5.53.13 + svelte: 5.54.1 prettier@3.8.1: {} pretty-error@4.0.0: dependencies: - lodash: 4.17.23 + lodash: 4.18.1 renderkid: 3.0.0 pretty-format@27.5.1: @@ -23398,11 +23448,11 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.4.1(react@18.3.1): + prism-react-renderer@2.4.1(react@19.2.4): dependencies: '@types/prismjs': 1.26.5 clsx: 2.1.1 - react: 18.3.1 + react: 19.2.4 prismjs@1.30.0: {} @@ -23461,7 +23511,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 24.12.0 + '@types/node': 24.12.2 long: 5.3.2 protocol-buffers-schema@3.6.0: {} @@ -23471,7 +23521,7 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 @@ -23544,12 +23594,6 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@18.3.1(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 - react-dom@19.2.4(react@19.2.4): dependencies: react: 19.2.4 @@ -23557,7 +23601,7 @@ snapshots: react-email@4.3.2: dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/traverse': 7.28.5 chokidar: 4.0.3 commander: 13.1.0 @@ -23584,54 +23628,50 @@ snapshots: react-is@17.0.2: {} - react-json-view-lite@2.5.0(react@18.3.1): + react-json-view-lite@2.5.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.104.1): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.4))(webpack@5.104.1): dependencies: - '@babel/runtime': 7.28.6 - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + '@babel/runtime': 7.29.2 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.4)' webpack: 5.104.1 react-promise-suspense@0.3.4: dependencies: fast-deep-equal: 2.0.1 - react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1): + react-router-config@5.1.1(react-router@5.3.4(react@19.2.4))(react@19.2.4): dependencies: - '@babel/runtime': 7.28.6 - react: 18.3.1 - react-router: 5.3.4(react@18.3.1) + '@babel/runtime': 7.29.2 + react: 19.2.4 + react-router: 5.3.4(react@19.2.4) - react-router-dom@5.3.4(react@18.3.1): + react-router-dom@5.3.4(react@19.2.4): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.3.1 - react-router: 5.3.4(react@18.3.1) + react: 19.2.4 + react-router: 5.3.4(react@19.2.4) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-router@5.3.4(react@18.3.1): + react-router@5.3.4(react@19.2.4): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 path-to-regexp: 1.9.0 prop-types: 15.8.1 - react: 18.3.1 + react: 19.2.4 react-is: 16.13.1 tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react@18.3.1: - dependencies: - loose-envify: 1.4.0 - react@19.2.4: {} read-cache@1.0.0: @@ -23664,11 +23704,11 @@ snapshots: readdir-glob@1.1.3: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.9 readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 readdirp@4.1.2: {} @@ -23838,7 +23878,7 @@ snapshots: css-select: 4.3.0 dom-converter: 0.2.0 htmlparser2: 6.1.0 - lodash: 4.17.23 + lodash: 4.18.1 strip-ansi: 6.0.1 repeat-string@1.6.1: {} @@ -23909,37 +23949,40 @@ snapshots: dependencies: glob: 7.2.3 - robust-predicates@3.0.2: {} + robust-predicates@3.0.3: {} - rolldown@1.0.0-rc.9: + rolldown@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1): dependencies: - '@oxc-project/types': 0.115.0 - '@rolldown/pluginutils': 1.0.0-rc.9 + '@oxc-project/types': 0.122.0 + '@rolldown/pluginutils': 1.0.0-rc.12 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.9 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.9 - '@rolldown/binding-darwin-x64': 1.0.0-rc.9 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.9 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9 + '@rolldown/binding-android-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-x64': 1.0.0-rc.12 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.12 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.12 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.12 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.12 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.12 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.12 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - rollup-plugin-visualizer@6.0.11(rolldown@1.0.0-rc.9)(rollup@4.55.1): + rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1))(rollup@4.55.1): dependencies: - open: 8.4.2 - picomatch: 4.0.3 + open: 11.0.0 + picomatch: 4.0.4 source-map: 0.7.6 - yargs: 17.7.2 + yargs: 18.0.0 optionalDependencies: - rolldown: 1.0.0-rc.9 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) rollup: 4.55.1 rollup@4.55.1: @@ -24008,14 +24051,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 - runed@0.35.1(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13): + runed@0.35.1(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 - svelte: 5.53.13 + svelte: 5.54.1 optionalDependencies: - '@sveltejs/kit': 2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/kit': 2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) rw@1.3.3: {} @@ -24037,19 +24080,10 @@ snapshots: safer-buffer@2.1.2: {} - sanitize-filename@1.6.3: + sanitize-filename@1.6.4: dependencies: truncate-utf8-bytes: 1.0.2 - sanitize-html@2.17.1: - dependencies: - deepmerge: 4.3.1 - escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 - is-plain-object: 5.0.0 - parse-srcset: 1.0.2 - postcss: 8.5.8 - sass@1.97.1: dependencies: chokidar: 4.0.3 @@ -24065,10 +24099,6 @@ snapshots: xmlchars: 2.2.0 optional: true - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 - scheduler@0.27.0: {} schema-dts@1.1.5: {} @@ -24192,7 +24222,7 @@ snapshots: set-blocking@2.0.0: {} - set-cookie-parser@3.0.1: {} + set-cookie-parser@3.1.0: {} set-function-length@1.2.2: dependencies: @@ -24311,7 +24341,7 @@ snapshots: simple-icons@15.22.0: {} - simple-icons@16.9.0: {} + simple-icons@16.13.0: {} sirv@2.0.4: dependencies: @@ -24475,7 +24505,7 @@ snapshots: bcrypt-pbkdf: 1.0.2 optionalDependencies: cpu-features: 0.0.10 - nan: 2.25.0 + nan: 2.26.2 ssri@13.0.1: dependencies: @@ -24491,17 +24521,19 @@ snapshots: std-env@3.10.0: {} + std-env@4.0.0: {} + stdin-discarder@0.2.2: {} stream-source@0.3.5: {} streamsearch@1.1.0: {} - streamx@2.23.0: + streamx@2.25.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 - text-decoder: 1.2.3 + text-decoder: 1.2.7 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -24571,7 +24603,7 @@ snapshots: dependencies: js-tokens: 9.0.1 - strtok3@10.3.4: + strtok3@10.3.5: dependencies: '@tokenizer/token': 0.3.0 @@ -24639,23 +24671,23 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-awesome@3.3.5(svelte@5.53.13): + svelte-awesome@3.3.5(svelte@5.54.1): dependencies: - svelte: 5.53.13 + svelte: 5.54.1 - svelte-check@4.4.4(picomatch@4.0.3)(svelte@5.53.13)(typescript@5.9.3): + svelte-check@4.4.5(picomatch@4.0.4)(svelte@5.54.1)(typescript@6.0.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.53.13 - typescript: 5.9.3 + svelte: 5.54.1 + typescript: 6.0.2 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.0(svelte@5.53.13): + svelte-eslint-parser@1.6.0(svelte@5.54.1): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -24665,7 +24697,7 @@ snapshots: postcss-selector-parser: 7.1.1 semver: 7.7.4 optionalDependencies: - svelte: 5.53.13 + svelte: 5.54.1 svelte-floating-ui@1.5.8: dependencies: @@ -24678,7 +24710,7 @@ snapshots: dependencies: highlight.js: 11.11.1 - svelte-i18n@4.0.1(svelte@5.53.13): + svelte-i18n@4.0.1(svelte@5.54.1): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -24686,10 +24718,10 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.18 sade: 1.8.1 - svelte: 5.53.13 + svelte: 5.54.1 tiny-glob: 0.2.9 - svelte-jsoneditor@3.11.0(svelte@5.53.13): + svelte-jsoneditor@3.11.0(svelte@5.54.1): dependencies: '@codemirror/autocomplete': 6.20.0 '@codemirror/commands': 6.10.1 @@ -24712,46 +24744,46 @@ snapshots: json-source-map: 0.6.1 jsonpath-plus: 10.3.0 jsonrepair: 3.13.1 - lodash-es: 4.17.23 + lodash-es: 4.18.1 memoize-one: 6.0.0 natural-compare-lite: 1.4.0 sass: 1.97.1 - svelte: 5.53.13 - svelte-awesome: 3.3.5(svelte@5.53.13) + svelte: 5.54.1 + svelte-awesome: 3.3.5(svelte@5.54.1) svelte-select: 5.8.3 vanilla-picker: 2.12.3 - svelte-maplibre@1.2.6(svelte@5.53.13): + svelte-maplibre@1.2.6(svelte@5.54.1): dependencies: d3-geo: 3.1.1 dequal: 2.0.3 just-compare: 2.3.0 - maplibre-gl: 5.19.0 + maplibre-gl: 5.21.0 pmtiles: 3.2.1 - svelte: 5.53.13 + svelte: 5.54.1 - svelte-parse-markup@0.1.5(svelte@5.53.13): + svelte-parse-markup@0.1.5(svelte@5.54.1): dependencies: - svelte: 5.53.13 + svelte: 5.54.1 - svelte-persisted-store@0.12.0(svelte@5.53.13): + svelte-persisted-store@0.12.0(svelte@5.54.1): dependencies: - svelte: 5.53.13 + svelte: 5.54.1 svelte-select@5.8.3: dependencies: svelte-floating-ui: 1.5.8 - svelte-toolbelt@0.10.6(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.53.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.53.13)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13)(typescript@5.9.3)(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.13) + runed: 0.35.1(@sveltejs/kit@2.55.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.54.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.54.1) style-to-object: 1.0.14 - svelte: 5.53.13 + svelte: 5.54.1 transitivePeerDependencies: - '@sveltejs/kit' - svelte@5.53.13: + svelte@5.54.1: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -24786,11 +24818,11 @@ snapshots: dependencies: '@scarf/scarf': 1.4.0 - swr@2.3.8(react@18.3.1): + swr@2.3.8(react@19.2.4): dependencies: dequal: 2.0.3 - react: 18.3.1 - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) symbol-observable@4.0.0: {} @@ -24813,21 +24845,21 @@ snapshots: optionalDependencies: tailwind-merge: 3.5.0 - tailwindcss-email-variants@3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): + tailwindcss-email-variants@3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) - tailwindcss-mso@2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): + tailwindcss-mso@2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) - tailwindcss-preset-email@1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): + tailwindcss-preset-email@1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) - tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) - tailwindcss-mso: 2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) + tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) + tailwindcss-mso: 2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) - tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2): + tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -24846,7 +24878,7 @@ snapshots: postcss: 8.5.8 postcss-import: 15.1.0(postcss@8.5.8) postcss-js: 4.1.0(postcss@8.5.8) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.3) postcss-nested: 6.2.0(postcss@8.5.8) postcss-selector-parser: 6.1.2 resolve: 1.22.11 @@ -24863,15 +24895,15 @@ snapshots: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.3 + pump: 3.0.4 tar-stream: 2.2.0 - tar-fs@3.1.1: + tar-fs@3.1.2: dependencies: - pump: 3.0.3 - tar-stream: 3.1.7 + pump: 3.0.4 + tar-stream: 3.1.8 optionalDependencies: - bare-fs: 4.5.4 + bare-fs: 4.5.6 bare-path: 3.0.0 transitivePeerDependencies: - bare-abort-controller @@ -24886,13 +24918,15 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - tar-stream@3.1.7: + tar-stream@3.1.8: dependencies: - b4a: 1.7.3 + b4a: 1.8.0 + bare-fs: 4.5.6 fast-fifo: 1.3.2 - streamx: 2.23.0 + streamx: 2.25.0 transitivePeerDependencies: - bare-abort-controller + - bare-buffer - react-native-b4a tar@6.2.1: @@ -24914,23 +24948,22 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.23.0 + streamx: 2.25.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - optional: true - terser-webpack-plugin@5.3.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)): + terser-webpack-plugin@5.3.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)): 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.1 - webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3) + webpack: 5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4) optionalDependencies: '@swc/core': 1.15.18(@swc/helpers@0.5.17) - esbuild: 0.27.3 + esbuild: 0.27.4 terser-webpack-plugin@5.3.16(webpack@5.104.1): dependencies: @@ -24954,7 +24987,7 @@ snapshots: glob: 10.5.0 minimatch: 10.2.4 - testcontainers@11.12.0: + testcontainers@11.13.0: dependencies: '@balena/dockerignore': 1.0.2 '@types/dockerode': 4.0.1 @@ -24962,24 +24995,24 @@ snapshots: async-lock: 1.4.1 byline: 5.0.0 debug: 4.4.3 - docker-compose: 1.3.1 - dockerode: 4.0.9 - get-port: 7.1.0 + docker-compose: 1.3.3 + dockerode: 4.0.10 + get-port: 7.2.0 proper-lockfile: 4.1.2 properties-reader: 3.0.1 ssh-remote-port-forward: 1.0.4 - tar-fs: 3.1.1 + tar-fs: 3.1.2 tmp: 0.2.5 - undici: 7.22.0 + undici: 7.24.6 transitivePeerDependencies: - bare-abort-controller - bare-buffer - react-native-b4a - supports-color - text-decoder@1.2.3: + text-decoder@1.2.7: dependencies: - b4a: 1.7.3 + b4a: 1.8.0 transitivePeerDependencies: - react-native-b4a @@ -25027,12 +25060,12 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.0.2: {} + tinyexec@1.0.4: {} tinyglobby@0.2.15: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 tinypool@1.1.1: {} @@ -25040,7 +25073,7 @@ snapshots: tinyrainbow@2.0.0: {} - tinyrainbow@3.0.3: {} + tinyrainbow@3.1.0: {} tinyspy@4.0.4: {} @@ -25067,7 +25100,7 @@ snapshots: token-types@6.1.2: dependencies: - '@borewit/text-codec': 0.2.1 + '@borewit/text-codec': 0.2.2 '@tokenizer/token': 0.3.0 ieee754: 1.2.1 @@ -25101,17 +25134,17 @@ snapshots: dependencies: utf8-byte-length: 1.0.5 - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@6.0.2): dependencies: - typescript: 5.9.3 + typescript: 6.0.2 ts-dedent@2.2.0: {} ts-interface-checker@0.1.13: {} - tsconfck@3.1.6(typescript@5.9.3): + tsconfck@3.1.6(typescript@6.0.2): optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.2 tsconfig-paths-webpack-plugin@4.2.0: dependencies: @@ -25132,7 +25165,7 @@ snapshots: tsx@4.21.0: dependencies: - esbuild: 0.27.3 + esbuild: 0.27.4 get-tsconfig: 4.13.0 optionalDependencies: fsevents: 2.3.3 @@ -25168,19 +25201,21 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) - eslint: 10.0.2(jiti@2.6.1) - typescript: 5.9.3 + '@typescript-eslint/eslint-plugin': 8.58.0(@typescript-eslint/parser@8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/parser': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@10.1.0(jiti@2.6.1))(typescript@6.0.2) + eslint: 10.1.0(jiti@2.6.1) + typescript: 6.0.2 transitivePeerDependencies: - supports-color typescript@5.9.3: {} + typescript@6.0.2: {} + ua-is-frozen@0.1.2: {} ua-parser-js@2.0.9: @@ -25209,7 +25244,7 @@ snapshots: undici-types@7.18.2: optional: true - undici@7.22.0: {} + undici@7.24.6: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -25321,7 +25356,7 @@ snapshots: dependencies: '@jridgewell/remapping': 2.3.5 acorn: 8.16.0 - picomatch: 4.0.3 + picomatch: 4.0.4 webpack-virtual-modules: 0.6.2 update-browserslist-db@1.2.3(browserslist@4.28.1): @@ -25369,9 +25404,9 @@ snapshots: urlpattern-polyfill@8.0.2: {} - use-sync-external-store@1.6.0(react@18.3.1): + use-sync-external-store@1.6.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 utf8-byte-length@1.0.5: {} @@ -25445,13 +25480,13 @@ snapshots: - rollup - supports-color - vite-node@3.2.4(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite-node@3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -25466,101 +25501,87 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + vite-tsconfig-paths@6.1.1(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: debug: 4.4.3 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.9.3) - vite: 8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + tsconfck: 3.1.6(typescript@6.0.2) + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: - esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + esbuild: 0.27.4 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.8 rollup: 4.55.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 sass: 1.97.1 terser: 5.44.1 tsx: 4.21.0 - yaml: 2.8.2 + yaml: 2.8.3 - vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: - esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + lightningcss: 1.32.0 + picomatch: 4.0.4 postcss: 8.5.8 - rollup: 4.55.1 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.4.0 + '@types/node': 24.12.2 + esbuild: 0.27.4 fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.32.0 sass: 1.97.1 terser: 5.44.1 tsx: 4.21.0 - yaml: 2.8.2 + yaml: 2.8.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - vite@8.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: - '@oxc-project/runtime': 0.115.0 lightningcss: 1.32.0 - picomatch: 4.0.3 + picomatch: 4.0.4 postcss: 8.5.8 - rolldown: 1.0.0-rc.9 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.12.0 - esbuild: 0.27.3 + '@types/node': 25.5.0 + esbuild: 0.27.4 fsevents: 2.3.3 jiti: 2.6.1 sass: 1.97.1 terser: 5.44.1 tsx: 4.21.0 - yaml: 2.8.2 + yaml: 2.8.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): - dependencies: - '@oxc-project/runtime': 0.115.0 - lightningcss: 1.32.0 - picomatch: 4.0.3 - postcss: 8.5.8 - rolldown: 1.0.0-rc.9 - tinyglobby: 0.2.15 + vitefu@1.1.2(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)): optionalDependencies: - '@types/node': 25.4.0 - esbuild: 0.27.3 - fsevents: 2.3.3 - jiti: 2.6.1 - sass: 1.97.1 - terser: 5.44.1 - tsx: 4.21.0 - yaml: 2.8.2 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) - vitefu@1.1.2(vite@8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): - optionalDependencies: - vite: 8.0.0(@types/node@25.4.0)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - - vitest-fetch-mock@0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + vitest-fetch-mock@0.4.5(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3))): dependencies: - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -25571,20 +25592,20 @@ snapshots: expect-type: 1.3.0 magic-string: 0.30.21 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.4 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.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) + vite-node: 3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 24.12.0 - happy-dom: 20.8.3 + '@types/node': 24.12.2 + happy-dom: 20.8.9 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - jiti @@ -25600,125 +25621,95 @@ snapshots: - tsx - yaml - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 + picomatch: 4.0.4 + std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.0.2 + tinyexec: 1.0.4 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + tinyrainbow: 3.1.0 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@types/node': 24.12.0 - happy-dom: 20.8.3 + '@types/node': 24.12.2 + happy-dom: 20.8.9 jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 + picomatch: 4.0.4 + std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.0.2 + tinyexec: 1.0.4 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + tinyrainbow: 3.1.0 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@24.12.2)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@types/node': 24.12.0 - happy-dom: 20.8.3 + '@types/node': 24.12.2 + happy-dom: 20.8.9 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.8.9)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 + picomatch: 4.0.4 + std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.0.2 + tinyexec: 1.0.4 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + tinyrainbow: 3.1.0 + vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@types/node': 25.4.0 - happy-dom: 20.8.3 + '@types/node': 25.5.0 + happy-dom: 20.8.9 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml vscode-jsonrpc@8.2.0: {} @@ -25824,7 +25815,7 @@ snapshots: sockjs: 0.3.24 spdy: 4.0.2 webpack-dev-middleware: 7.4.5(webpack@5.104.1) - ws: 8.19.0 + ws: 8.20.0 optionalDependencies: webpack: 5.104.1 transitivePeerDependencies: @@ -25883,7 +25874,7 @@ snapshots: - esbuild - uglify-js - webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3): + webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -25907,7 +25898,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.3)) + terser-webpack-plugin: 5.3.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)(webpack@5.104.1(@swc/core@1.15.18(@swc/helpers@0.5.17))(esbuild@0.27.4)) watchpack: 2.5.1 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -26007,6 +25998,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.2.0 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} write-file-atomic@3.0.3: @@ -26020,12 +26017,17 @@ snapshots: ws@8.18.3: {} - ws@8.19.0: {} + ws@8.20.0: {} wsl-utils@0.1.0: dependencies: is-wsl: 3.1.1 + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + xdg-basedir@5.1.0: {} xml-js@1.6.11: @@ -26052,9 +26054,9 @@ snapshots: yallist@5.0.0: {} - yaml@1.10.2: {} + yaml@1.10.3: {} - yaml@2.8.2: {} + yaml@2.8.3: {} yargs-parser@18.1.3: dependencies: @@ -26063,6 +26065,8 @@ snapshots: yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@15.4.1: dependencies: cliui: 6.0.0 @@ -26087,6 +26091,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yocto-queue@0.1.0: {} yocto-queue@1.2.2: {} diff --git a/renovate.json b/renovate.json index fbbc8976bd..0fdf5a7f69 100644 --- a/renovate.json +++ b/renovate.json @@ -27,6 +27,10 @@ "matchUpdateTypes": ["major"], "enabled": false }, + { + "matchPackageNames": ["ghcr.io/immich-app/base-server-*"], + "maxMajorIncrement": 0 + }, { "matchPackageNames": ["ruby"], "groupName": "ruby", diff --git a/server/.nvmrc b/server/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/server/.nvmrc +++ b/server/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/server/Dockerfile b/server/Dockerfile index a26dfdd354..476d58b983 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/immich-app/base-server-dev:202603031112@sha256:837536db5fd9e432f0f474ef9b61712fe3b3815821c3e4edf5e5b0b1f1ed30ad AS builder +FROM ghcr.io/immich-app/base-server-dev:202603251709@sha256:2bf3053c732fcb87ec90c3c614632ac44847423468ccc57fd935bff771828d9d AS builder ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ COREPACK_HOME=/tmp \ @@ -71,7 +71,7 @@ RUN --mount=type=cache,id=pnpm-plugins,target=/buildcache/pnpm-store \ --mount=type=cache,id=mise-tools-${TARGETPLATFORM},target=/buildcache/mise \ cd plugins && mise run build -FROM ghcr.io/immich-app/base-server-prod:202603031112@sha256:bb8c8645ee61977140121e56ba09db7ae656a7506f9a6af1be8461b4d81fdf03 +FROM ghcr.io/immich-app/base-server-prod:202603251709@sha256:17de30977ff87aa06758a56ad7f10d6b5c97bf9dab76e4ec4177a2a8d1b2b5f3 WORKDIR /usr/src/app ENV NODE_ENV=production \ diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev index f64a1a904b..096ffdf0bf 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -1,5 +1,5 @@ # dev build -FROM ghcr.io/immich-app/base-server-dev:202603031112@sha256:837536db5fd9e432f0f474ef9b61712fe3b3815821c3e4edf5e5b0b1f1ed30ad AS dev +FROM ghcr.io/immich-app/base-server-dev:202603251709@sha256:2bf3053c732fcb87ec90c3c614632ac44847423468ccc57fd935bff771828d9d AS dev ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ diff --git a/server/bin/start.sh b/server/bin/start.sh index 0a26be8e0b..15f4411959 100755 --- a/server/bin/start.sh +++ b/server/bin/start.sh @@ -15,13 +15,12 @@ log_message() { log_message "Initializing Immich $IMMICH_SOURCE_REF" -# TODO: Update to mimalloc v3 when verified memory isn't released issue is fixed -# lib_path="/usr/lib/$(arch)-linux-gnu/libmimalloc.so.3" -# if [ -f "$lib_path" ]; then -# export LD_PRELOAD="$lib_path" -# else -# echo "skipping libmimalloc - path not found $lib_path" -# fi +lib_path="/usr/lib/$(arch)-linux-gnu/libmimalloc.so.3" +if [ -f "$lib_path" ]; then + export LD_PRELOAD="$lib_path" +else + echo "skipping libmimalloc - path not found $lib_path" +fi export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib/jellyfin-ffmpeg/lib" SERVER_HOME="$(readlink -f "$(dirname "$0")/..")" diff --git a/server/helmet.json b/server/helmet.json new file mode 100644 index 0000000000..1cd301d813 --- /dev/null +++ b/server/helmet.json @@ -0,0 +1,21 @@ +{ + "contentSecurityPolicy": { + "directives": { + "default-src": ["'self'"], + "script-src": ["'self'", "'wasm-unsafe-eval'", "'unsafe-inline'", "https://www.gstatic.com"], + "style-src": ["'self'", "'unsafe-inline'"], + "img-src": ["'self'", "data:", "blob:"], + "connect-src": [ + "'self'", + "blob:", + "https://pay.futo.org", + "https://static.immich.cloud", + "https://tiles.immich.cloud" + ], + "worker-src": ["'self'", "blob:"], + "frame-src": ["'none'"], + "object-src": ["'none'"], + "base-uri": ["'self'"] + } + } +} diff --git a/server/package.json b/server/package.json index 554f2540d5..4cad008b9e 100644 --- a/server/package.json +++ b/server/package.json @@ -1,10 +1,15 @@ { "name": "immich", - "version": "2.6.2", + "version": "2.7.5", "description": "", "author": "", "private": true, "license": "GNU Affero General Public License version 3", + "files": [ + "bin", + "dist", + "helmet.json" + ], "scripts": { "build": "nest build", "format": "prettier --cache --check .", @@ -77,12 +82,13 @@ "fluent-ffmpeg": "^2.1.2", "geo-tz": "^8.0.0", "handlebars": "^4.7.8", + "helmet": "^8.1.0", "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.11", + "kysely": "0.28.14", "kysely-postgres-js": "^3.0.0", "lodash": "^4.17.21", "luxon": "^3.4.2", @@ -92,7 +98,7 @@ "nestjs-cls": "^5.0.0", "nestjs-kysely": "3.1.2", "nestjs-otel": "^7.0.0", - "nodemailer": "^7.0.0", + "nodemailer": "^8.0.0", "openid-client": "^6.3.3", "pg": "^8.11.3", "pg-connection-string": "^2.9.1", @@ -104,7 +110,6 @@ "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "sanitize-filename": "^1.6.3", - "sanitize-html": "^2.14.0", "semver": "^7.6.2", "sharp": "^0.34.5", "sirv": "^3.0.0", @@ -136,21 +141,20 @@ "@types/luxon": "^3.6.2", "@types/mock-fs": "^4.13.1", "@types/multer": "^2.0.0", - "@types/node": "^24.11.0", + "@types/node": "^24.12.0", "@types/nodemailer": "^7.0.0", "@types/picomatch": "^4.0.0", "@types/pngjs": "^6.0.5", "@types/react": "^19.0.0", - "@types/sanitize-html": "^2.13.0", "@types/semver": "^7.5.8", - "@types/supertest": "^6.0.0", + "@types/supertest": "^7.0.0", "@types/ua-parser-js": "^0.7.36", "@types/validator": "^13.15.2", "@vitest/coverage-v8": "^3.0.0", "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^63.0.0", + "eslint-plugin-unicorn": "^64.0.0", "globals": "^17.0.0", "mock-fs": "^5.2.0", "node-gyp": "^12.0.0", @@ -161,14 +165,14 @@ "supertest": "^7.1.0", "tailwindcss": "^3.4.0", "testcontainers": "^11.0.0", - "typescript": "^5.9.2", + "typescript": "^6.0.0", "typescript-eslint": "^8.28.0", "unplugin-swc": "^1.4.5", "vite-tsconfig-paths": "^6.0.0", "vitest": "^3.0.0" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" }, "overrides": { "sharp": "^0.34.5" diff --git a/server/resources/style-dark.json b/server/resources/style-dark.json deleted file mode 100644 index 91148e7814..0000000000 --- a/server/resources/style-dark.json +++ /dev/null @@ -1,3180 +0,0 @@ -{ - "version": 8, - "name": "Immich Map", - "id": "immich-map-dark", - "sources": { - "protomaps": { - "type": "vector", - "url": "https://tiles.immich.cloud/v1.json" - } - }, - "layers": [ - { - "id": "background", - "type": "background", - "paint": { - "background-color": "#2b2b2b" - } - }, - { - "id": "earth", - "type": "fill", - "source": "protomaps", - "source-layer": "earth", - "paint": { - "fill-color": "#141414" - } - }, - { - "id": "landuse_park", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "national_park", - "park", - "cemetery", - "protected_area", - "nature_reserve", - "forest", - "golf_course" - ] - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#181818", - 12, - "#181818" - ] - } - }, - { - "id": "landuse_urban_green", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "allotments", - "village_green", - "playground" - ] - ], - "paint": { - "fill-color": "#181818", - "fill-opacity": 0.7 - } - }, - { - "id": "landuse_hospital", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "hospital" - ] - ], - "paint": { - "fill-color": "#1d1d1d" - } - }, - { - "id": "landuse_industrial", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "industrial" - ] - ], - "paint": { - "fill-color": "#101010" - } - }, - { - "id": "landuse_school", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "school", - "university", - "college" - ] - ], - "paint": { - "fill-color": "#111111" - } - }, - { - "id": "landuse_beach", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "beach" - ] - ], - "paint": { - "fill-color": "#1f1f1f" - } - }, - { - "id": "landuse_zoo", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "zoo" - ] - ], - "paint": { - "fill-color": "#191919" - } - }, - { - "id": "landuse_military", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "military", - "naval_base", - "airfield" - ] - ], - "paint": { - "fill-color": "#191919" - } - }, - { - "id": "natural_wood", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "wood", - "nature_reserve", - "forest" - ] - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#1a1a1a", - 12, - "#1a1a1a" - ] - } - }, - { - "id": "natural_scrub", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "in", - "pmap:kind", - "scrub", - "grassland", - "grass" - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#1c1c1c", - 12, - "#1c1c1c" - ] - } - }, - { - "id": "natural_glacier", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "==", - "pmap:kind", - "glacier" - ], - "paint": { - "fill-color": "#191919" - } - }, - { - "id": "natural_sand", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "==", - "pmap:kind", - "sand" - ], - "paint": { - "fill-color": "#161616" - } - }, - { - "id": "landuse_aerodrome", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "aerodrome" - ] - ], - "paint": { - "fill-color": "#191919" - } - }, - { - "id": "transit_runway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "any", - [ - "in", - "pmap:kind_detail", - "runway" - ] - ], - "paint": { - "line-color": "#323232", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 12, - 4, - 18, - 30 - ] - } - }, - { - "id": "transit_taxiway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "minzoom": 13, - "filter": [ - "any", - [ - "in", - "pmap:kind_detail", - "taxiway" - ] - ], - "paint": { - "line-color": "#323232", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 15, - 6 - ] - } - }, - { - "id": "water", - "type": "fill", - "source": "protomaps", - "source-layer": "water", - "paint": { - "fill-color": "#333333" - } - }, - { - "id": "physical_line_stream", - "type": "line", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 14, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "stream" - ] - ], - "paint": { - "line-color": "#333333", - "line-width": 0.5 - } - }, - { - "id": "physical_line_river", - "type": "line", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 9, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "river" - ] - ], - "paint": { - "line-color": "#333333", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1, - 18, - 12 - ] - } - }, - { - "id": "landuse_pedestrian", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pedestrian" - ] - ], - "paint": { - "fill-color": "#191919" - } - }, - { - "id": "landuse_pier", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pier" - ] - ], - "paint": { - "fill-color": "#0a0a0a" - } - }, - { - "id": "roads_tunnels_other_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#101010", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_tunnels_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#101010", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#101010", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#101010", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_major_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#101010", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_highway_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#101010", - "line-dasharray": [ - 6, - 0.5 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_tunnels_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#292929", - "line-dasharray": [ - 4.5, - 0.5 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_tunnels_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_tunnels_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_tunnels_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_tunnels_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_tunnels_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "buildings", - "type": "fill", - "source": "protomaps", - "source-layer": "buildings", - "paint": { - "fill-color": "#0a0a0a", - "fill-opacity": 0.5 - } - }, - { - "id": "transit_pier", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pier" - ] - ], - "paint": { - "line-color": "#0a0a0a", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 0.5, - 20, - 16 - ] - } - }, - { - "id": "roads_minor_service_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "==", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 18, - 8 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 0.8 - ] - } - }, - { - "id": "roads_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "!=", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1.5 - ] - } - }, - { - "id": "roads_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1.5 - ] - } - }, - { - "id": "roads_major_casing_late", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_highway_casing_late", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-dasharray": [ - 3, - 1 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_minor_service", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "==", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 18, - 8 - ] - } - }, - { - "id": "roads_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "!=", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - "#292929", - 16, - "#1f1f1f" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_major_casing_early", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "maxzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_highway_casing_early", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "maxzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1 - ] - } - }, - { - "id": "roads_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "transit_railway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "all", - [ - "==", - "pmap:kind", - "rail" - ] - ], - "paint": { - "line-dasharray": [ - 0.3, - 0.75 - ], - "line-opacity": 0.5, - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 0.15, - 18, - 9 - ] - } - }, - { - "id": "boundaries_country", - "type": "line", - "source": "protomaps", - "source-layer": "boundaries", - "filter": [ - "<=", - "pmap:min_admin_level", - 2 - ], - "paint": { - "line-color": "#707070", - "line-width": 1, - "line-dasharray": [ - 3, - 2 - ] - } - }, - { - "id": "boundaries", - "type": "line", - "source": "protomaps", - "source-layer": "boundaries", - "filter": [ - ">", - "pmap:min_admin_level", - 2 - ], - "paint": { - "line-color": "#707070", - "line-width": 0.5, - "line-dasharray": [ - 3, - 2 - ] - } - }, - { - "id": "roads_bridges_other_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_bridges_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 0.8 - ] - } - }, - { - "id": "roads_bridges_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_major_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 10 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-dasharray": [ - 2, - 1 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_bridges_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_bridges_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#1f1f1f", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_bridges_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_bridges_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_bridges_highway_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#141414", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_bridges_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#292929", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "physical_line_waterway_label", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 13, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "river", - "stream" - ] - ], - "layout": { - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12, - "text-letter-spacing": 0.3 - }, - "paint": { - "text-color": "#707070" - } - }, - { - "id": "physical_point_peak", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "peak" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Italic" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 8, - 16, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9 - }, - "paint": { - "text-color": "#707070", - "text-halo-width": 1.5 - } - }, - { - "id": "roads_labels_minor", - "type": "symbol", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 15, - "filter": [ - "any", - [ - "in", - "pmap:kind", - "minor_road", - "other", - "path" - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12 - }, - "paint": { - "text-color": "#525252", - "text-halo-color": "#141414", - "text-halo-width": 2 - } - }, - { - "id": "physical_point_ocean", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "sea", - "ocean", - "lake", - "water", - "bay", - "strait", - "fjord" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Medium" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 10, - 10, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9, - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#707070" - } - }, - { - "id": "physical_point_lakes", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "lake", - "water" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Medium" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 6, - 12, - 10, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9 - }, - "paint": { - "text-color": "#707070" - } - }, - { - "id": "roads_labels_major", - "type": "symbol", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 11, - "filter": [ - "any", - [ - "in", - "pmap:kind", - "highway", - "major_road", - "medium_road" - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12 - }, - "paint": { - "text-color": "#5c5c5c", - "text-halo-color": "#141414", - "text-halo-width": 2 - } - }, - { - "id": "places_subplace", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "neighbourhood" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": "{name}", - "text-font": [ - "Noto Sans Regular" - ], - "text-max-width": 7, - "text-letter-spacing": 0.1, - "text-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 5, - 2, - 8, - 4, - 12, - 18, - 15, - 20 - ], - "text-size": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 11, - 8, - 14, - 14, - 18, - 24 - ], - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#5c5c5c", - "text-halo-color": "#141414", - "text-halo-width": 1.5 - } - }, - { - "id": "places_locality", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "locality" - ], - "layout": { - "icon-image": [ - "step", - [ - "zoom" - ], - "townspot", - 8, - "" - ], - "icon-size": 0.7, - "text-field": "{name}", - "text-font": [ - "case", - [ - "<=", - [ - "get", - "pmap:min_zoom" - ], - 5 - ], - [ - "literal", - [ - "Noto Sans Medium" - ] - ], - [ - "literal", - [ - "Noto Sans Regular" - ] - ] - ], - "text-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 5, - 3, - 8, - 7, - 12, - 11 - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 8, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 13, - 0 - ], - 4, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 10, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 15, - 0 - ], - 6, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 12 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 12 - ], - 17, - 0 - ], - 8, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 11 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 11 - ], - 18, - 0 - ], - 10, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 9 - ], - 12, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 9 - ], - 20, - 0 - ], - 15, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 12, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 22, - 0 - ] - ], - "icon-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - 0, - 8, - 4, - 10, - 8, - 12, - 6, - 22, - 2 - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - "left", - 8, - "center" - ], - "text-radial-offset": 0.4 - }, - "paint": { - "text-color": "#999999", - "text-halo-color": "#141414", - "text-halo-width": 1 - } - }, - { - "id": "places_region", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "region" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": [ - "step", - [ - "zoom" - ], - [ - "get", - "name:short" - ], - 6, - [ - "get", - "name" - ] - ], - "text-font": [ - "Noto Sans Regular" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 11, - 7, - 16 - ], - "text-radial-offset": 0.2, - "text-anchor": "center", - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#3d3d3d", - "text-halo-color": "#141414", - "text-halo-width": 2 - } - }, - { - "id": "places_country", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "country" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": "{name}", - "text-font": [ - "Noto Sans Medium" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 10 - ], - 8, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 10 - ], - 12, - 0 - ], - 6, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 10, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 18, - 0 - ], - 8, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 7 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 7 - ], - 20, - 0 - ] - ], - "icon-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - 2, - 14, - 2, - 16, - 20, - 17, - 2, - 22, - 2 - ], - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#707070" - } - } - ], - "sprite": "https://static.immich.cloud/tiles/sprites/v1/dark", - "glyphs": "https://static.immich.cloud/tiles/fonts/{fontstack}/{range}.pbf" -} diff --git a/server/resources/style-light.json b/server/resources/style-light.json deleted file mode 100644 index 612622ef85..0000000000 --- a/server/resources/style-light.json +++ /dev/null @@ -1,3180 +0,0 @@ -{ - "version": 8, - "name": "Immich Map", - "id": "immich-map-light", - "sources": { - "protomaps": { - "type": "vector", - "url": "https://tiles.immich.cloud/v1.json" - } - }, - "layers": [ - { - "id": "background", - "type": "background", - "paint": { - "background-color": "#cccccc" - } - }, - { - "id": "earth", - "type": "fill", - "source": "protomaps", - "source-layer": "earth", - "paint": { - "fill-color": "#e0e0e0" - } - }, - { - "id": "landuse_park", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "national_park", - "park", - "cemetery", - "protected_area", - "nature_reserve", - "forest", - "golf_course" - ] - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#cfddd5", - 12, - "#9cd3b4" - ] - } - }, - { - "id": "landuse_urban_green", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "allotments", - "village_green", - "playground" - ] - ], - "paint": { - "fill-color": "#9cd3b4", - "fill-opacity": 0.7 - } - }, - { - "id": "landuse_hospital", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "hospital" - ] - ], - "paint": { - "fill-color": "#e4dad9" - } - }, - { - "id": "landuse_industrial", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "industrial" - ] - ], - "paint": { - "fill-color": "#d1dde1" - } - }, - { - "id": "landuse_school", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "school", - "university", - "college" - ] - ], - "paint": { - "fill-color": "#e4ded7" - } - }, - { - "id": "landuse_beach", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "beach" - ] - ], - "paint": { - "fill-color": "#e8e4d0" - } - }, - { - "id": "landuse_zoo", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "zoo" - ] - ], - "paint": { - "fill-color": "#c6dcdc" - } - }, - { - "id": "landuse_military", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "military", - "naval_base", - "airfield" - ] - ], - "paint": { - "fill-color": "#c6dcdc" - } - }, - { - "id": "natural_wood", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "wood", - "nature_reserve", - "forest" - ] - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#d0ded0", - 12, - "#a0d9a0" - ] - } - }, - { - "id": "natural_scrub", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "in", - "pmap:kind", - "scrub", - "grassland", - "grass" - ], - "paint": { - "fill-color": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - "#cedcd7", - 12, - "#99d2bb" - ] - } - }, - { - "id": "natural_glacier", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "==", - "pmap:kind", - "glacier" - ], - "paint": { - "fill-color": "#e7e7e7" - } - }, - { - "id": "natural_sand", - "type": "fill", - "source": "protomaps", - "source-layer": "natural", - "filter": [ - "==", - "pmap:kind", - "sand" - ], - "paint": { - "fill-color": "#e2e0d7" - } - }, - { - "id": "landuse_aerodrome", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "aerodrome" - ] - ], - "paint": { - "fill-color": "#dadbdf" - } - }, - { - "id": "transit_runway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "any", - [ - "in", - "pmap:kind_detail", - "runway" - ] - ], - "paint": { - "line-color": "#e9e9ed", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 12, - 4, - 18, - 30 - ] - } - }, - { - "id": "transit_taxiway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "minzoom": 13, - "filter": [ - "any", - [ - "in", - "pmap:kind_detail", - "taxiway" - ] - ], - "paint": { - "line-color": "#e9e9ed", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 15, - 6 - ] - } - }, - { - "id": "water", - "type": "fill", - "source": "protomaps", - "source-layer": "water", - "paint": { - "fill-color": "rgba(148, 209, 236, 0.66)" - } - }, - { - "id": "physical_line_stream", - "type": "line", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 14, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "stream" - ] - ], - "paint": { - "line-color": "rgba(148, 209, 236, 0.66)", - "line-width": 0.5 - } - }, - { - "id": "physical_line_river", - "type": "line", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 9, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "river" - ] - ], - "paint": { - "line-color": "rgba(148, 209, 236, 0.66)", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1, - 18, - 12 - ] - } - }, - { - "id": "landuse_pedestrian", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pedestrian" - ] - ], - "paint": { - "fill-color": "#e3e0d4" - } - }, - { - "id": "landuse_pier", - "type": "fill", - "source": "protomaps", - "source-layer": "landuse", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pier" - ] - ], - "paint": { - "fill-color": "#e0e0e0" - } - }, - { - "id": "roads_tunnels_other_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_tunnels_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_major_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-dasharray": [ - 3, - 2 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_tunnels_highway_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-dasharray": [ - 6, - 0.5 - ], - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_tunnels_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-dasharray": [ - 4.5, - 0.5 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_tunnels_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_tunnels_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_tunnels_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_tunnels_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_tunnels_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "<", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#d5d5d5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "buildings", - "type": "fill", - "source": "protomaps", - "source-layer": "buildings", - "paint": { - "fill-color": "#cccccc", - "fill-opacity": 0.5 - } - }, - { - "id": "transit_pier", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "pier" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 0.5, - 20, - 16 - ] - } - }, - { - "id": "roads_minor_service_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "==", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 18, - 8 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 0.8 - ] - } - }, - { - "id": "roads_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "!=", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1 - ] - } - }, - { - "id": "roads_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 13, - "filter": [ - "all", - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1.5 - ] - } - }, - { - "id": "roads_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1.5 - ] - } - }, - { - "id": "roads_major_casing_late", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_highway_casing_late", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#ebebeb", - "line-dasharray": [ - 3, - 1 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_minor_service", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "==", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": "#ebebeb", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 18, - 8 - ] - } - }, - { - "id": "roads_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ], - [ - "!=", - "pmap:kind_detail", - "service" - ] - ], - "paint": { - "line-color": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - "#ebebeb", - 16, - "#ffffff" - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#f5f5f5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_major_casing_early", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "maxzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1 - ] - } - }, - { - "id": "roads_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_highway_casing_early", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "maxzoom": 12, - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1 - ] - } - }, - { - "id": "roads_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - "==", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "transit_railway", - "type": "line", - "source": "protomaps", - "source-layer": "transit", - "filter": [ - "all", - [ - "==", - "pmap:kind", - "rail" - ] - ], - "paint": { - "line-dasharray": [ - 0.3, - 0.75 - ], - "line-opacity": 0.5, - "line-color": "#a7b1b3", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 0.15, - 18, - 9 - ] - } - }, - { - "id": "boundaries_country", - "type": "line", - "source": "protomaps", - "source-layer": "boundaries", - "filter": [ - "<=", - "pmap:min_admin_level", - 2 - ], - "paint": { - "line-color": "#adadad", - "line-width": 1, - "line-dasharray": [ - 3, - 2 - ] - } - }, - { - "id": "boundaries", - "type": "line", - "source": "protomaps", - "source-layer": "boundaries", - "filter": [ - ">", - "pmap:min_admin_level", - 2 - ], - "paint": { - "line-color": "#adadad", - "line-width": 0.5, - "line-dasharray": [ - 3, - 2 - ] - } - }, - { - "id": "roads_bridges_other_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_bridges_link_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 12, - 0, - 12.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_minor_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 0.8 - ] - } - }, - { - "id": "roads_bridges_medium_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 10, - 0, - 10.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_major_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 0.5, - 18, - 10 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 9, - 0, - 9.5, - 1.5 - ] - } - }, - { - "id": "roads_bridges_other", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "in", - "pmap:kind", - "other", - "path" - ] - ], - "paint": { - "line-color": "#ebebeb", - "line-dasharray": [ - 2, - 1 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 14, - 0, - 20, - 7 - ] - } - }, - { - "id": "roads_bridges_minor", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "minor_road" - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 11, - 0, - 12.5, - 0.5, - 15, - 2, - 18, - 11 - ] - } - }, - { - "id": "roads_bridges_link", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 13, - 0, - 13.5, - 1, - 18, - 11 - ] - } - }, - { - "id": "roads_bridges_medium", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "medium_road" - ] - ], - "paint": { - "line-color": "#f0eded", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 12, - 1.2, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_bridges_major", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "major_road" - ] - ], - "paint": { - "line-color": "#f5f5f5", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 6, - 0, - 12, - 1.6, - 15, - 3, - 18, - 13 - ] - } - }, - { - "id": "roads_bridges_highway_casing", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 12, - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#e0e0e0", - "line-gap-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 3.5, - 0.5, - 18, - 15 - ], - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 7, - 0, - 7.5, - 1, - 20, - 15 - ] - } - }, - { - "id": "roads_bridges_highway", - "type": "line", - "source": "protomaps", - "source-layer": "roads", - "filter": [ - "all", - [ - ">", - "pmap:level", - 0 - ], - [ - "==", - "pmap:kind", - "highway" - ], - [ - "!=", - "pmap:link", - 1 - ] - ], - "paint": { - "line-color": "#ffffff", - "line-width": [ - "interpolate", - [ - "exponential", - 1.6 - ], - [ - "zoom" - ], - 3, - 0, - 6, - 1.1, - 12, - 1.6, - 15, - 5, - 18, - 15 - ] - } - }, - { - "id": "physical_line_waterway_label", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_line", - "minzoom": 13, - "filter": [ - "all", - [ - "in", - "pmap:kind", - "river", - "stream" - ] - ], - "layout": { - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12, - "text-letter-spacing": 0.3 - }, - "paint": { - "text-color": "#ffffff" - } - }, - { - "id": "physical_point_peak", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "==", - "pmap:kind", - "peak" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Italic" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 10, - 8, - 16, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9 - }, - "paint": { - "text-color": "#7e9aa0", - "text-halo-width": 1.5 - } - }, - { - "id": "roads_labels_minor", - "type": "symbol", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 15, - "filter": [ - "any", - [ - "in", - "pmap:kind", - "minor_road", - "other", - "path" - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12 - }, - "paint": { - "text-color": "#91888b", - "text-halo-color": "#ffffff", - "text-halo-width": 2 - } - }, - { - "id": "physical_point_ocean", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "sea", - "ocean", - "lake", - "water", - "bay", - "strait", - "fjord" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Medium" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 10, - 10, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9, - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#ffffff" - } - }, - { - "id": "physical_point_lakes", - "type": "symbol", - "source": "protomaps", - "source-layer": "physical_point", - "filter": [ - "any", - [ - "in", - "pmap:kind", - "lake", - "water" - ] - ], - "layout": { - "text-font": [ - "Noto Sans Medium" - ], - "text-field": [ - "get", - "name" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 0, - 6, - 12, - 10, - 12 - ], - "text-letter-spacing": 0.1, - "text-max-width": 9 - }, - "paint": { - "text-color": "#ffffff" - } - }, - { - "id": "roads_labels_major", - "type": "symbol", - "source": "protomaps", - "source-layer": "roads", - "minzoom": 11, - "filter": [ - "any", - [ - "in", - "pmap:kind", - "highway", - "major_road", - "medium_road" - ] - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "symbol-placement": "line", - "text-font": [ - "Noto Sans Regular" - ], - "text-field": [ - "get", - "name" - ], - "text-size": 12 - }, - "paint": { - "text-color": "#938a8d", - "text-halo-color": "#ffffff", - "text-halo-width": 2 - } - }, - { - "id": "places_subplace", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "neighbourhood" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": "{name}", - "text-font": [ - "Noto Sans Regular" - ], - "text-max-width": 7, - "text-letter-spacing": 0.1, - "text-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 5, - 2, - 8, - 4, - 12, - 18, - 15, - 20 - ], - "text-size": [ - "interpolate", - [ - "exponential", - 1.2 - ], - [ - "zoom" - ], - 11, - 8, - 14, - 14, - 18, - 24 - ], - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#8f8f8f", - "text-halo-color": "#e0e0e0", - "text-halo-width": 1.5 - } - }, - { - "id": "places_locality", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "locality" - ], - "layout": { - "icon-image": [ - "step", - [ - "zoom" - ], - "townspot", - 8, - "" - ], - "icon-size": 0.7, - "text-field": "{name}", - "text-font": [ - "case", - [ - "<=", - [ - "get", - "pmap:min_zoom" - ], - 5 - ], - [ - "literal", - [ - "Noto Sans Medium" - ] - ], - [ - "literal", - [ - "Noto Sans Regular" - ] - ] - ], - "text-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 5, - 3, - 8, - 7, - 12, - 11 - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 8, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 13, - 0 - ], - 4, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 10, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 13 - ], - 15, - 0 - ], - 6, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 12 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 12 - ], - 17, - 0 - ], - 8, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 11 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 11 - ], - 18, - 0 - ], - 10, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 9 - ], - 12, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 9 - ], - 20, - 0 - ], - 15, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 12, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 22, - 0 - ] - ], - "icon-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - 0, - 8, - 4, - 10, - 8, - 12, - 6, - 22, - 2 - ], - "text-anchor": [ - "step", - [ - "zoom" - ], - "left", - 8, - "center" - ], - "text-radial-offset": 0.4 - }, - "paint": { - "text-color": "#5c5c5c", - "text-halo-color": "#e0e0e0", - "text-halo-width": 1 - } - }, - { - "id": "places_region", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "region" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": [ - "step", - [ - "zoom" - ], - [ - "get", - "name:short" - ], - 6, - [ - "get", - "name" - ] - ], - "text-font": [ - "Noto Sans Regular" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 3, - 11, - 7, - 16 - ], - "text-radial-offset": 0.2, - "text-anchor": "center", - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#b3b3b3", - "text-halo-color": "#e0e0e0", - "text-halo-width": 2 - } - }, - { - "id": "places_country", - "type": "symbol", - "source": "protomaps", - "source-layer": "places", - "filter": [ - "==", - "pmap:kind", - "country" - ], - "layout": { - "symbol-sort-key": [ - "get", - "pmap:min_zoom" - ], - "text-field": "{name}", - "text-font": [ - "Noto Sans Medium" - ], - "text-size": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 2, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 10 - ], - 8, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 10 - ], - 12, - 0 - ], - 6, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 10, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 8 - ], - 18, - 0 - ], - 8, - [ - "case", - [ - "<", - [ - "get", - "pmap:population_rank" - ], - 7 - ], - 11, - [ - ">=", - [ - "get", - "pmap:population_rank" - ], - 7 - ], - 20, - 0 - ] - ], - "icon-padding": [ - "interpolate", - [ - "linear" - ], - [ - "zoom" - ], - 0, - 2, - 14, - 2, - 16, - 20, - 17, - 2, - 22, - 2 - ], - "text-transform": "uppercase" - }, - "paint": { - "text-color": "#a3a3a3" - } - } - ], - "sprite": "https://static.immich.cloud/tiles/sprites/v1/light", - "glyphs": "https://static.immich.cloud/tiles/fonts/{fontstack}/{range}.pbf" -} diff --git a/server/src/app.common.ts b/server/src/app.common.ts index 934c13343f..2159721932 100644 --- a/server/src/app.common.ts +++ b/server/src/app.common.ts @@ -2,9 +2,10 @@ import { NestExpressApplication } from '@nestjs/platform-express'; import { json } from 'body-parser'; import compression from 'compression'; import cookieParser from 'cookie-parser'; +import helmetMiddleware from 'helmet'; import { existsSync } from 'node:fs'; import sirv from 'sirv'; -import { excludePaths, serverVersion } from 'src/constants'; +import { IMMICH_SERVER_START, 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'; @@ -39,7 +40,7 @@ export async function configureExpress( }, ) { const configRepository = app.get(ConfigRepository); - const { environment, host, port, resourcePaths, network } = configRepository.getEnv(); + const { environment, host, port, helmet, resourcePaths, network } = configRepository.getEnv(); const logger = await app.resolve(LoggingRepository); logger.setContext('Bootstrap'); @@ -47,6 +48,12 @@ export async function configureExpress( app.set('trust proxy', ['loopback', ...network.trustedProxies]); app.set('etag', 'strong'); + + if (helmet.config) { + app.use(helmetMiddleware(helmet.config)); + logger.log('Initialized helmet middleware'); + } + app.use(cookieParser()); app.use(json({ limit: '10mb' })); @@ -83,5 +90,5 @@ export async function configureExpress( 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}] `); + logger.log(`${IMMICH_SERVER_START} on ${await app.getUrl()} [v${serverVersion}] [${environment}] `); } diff --git a/server/src/app.module.ts b/server/src/app.module.ts index 49b779ca18..f2b6a7e805 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -29,6 +29,7 @@ import { ProcessRepository } from 'src/repositories/process.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository'; +import { UserRepository } from 'src/repositories/user.repository'; import { WebsocketRepository } from 'src/repositories/websocket.repository'; import { services } from 'src/services'; import { AuthService } from 'src/services/auth.service'; @@ -36,6 +37,7 @@ import { CliService } from 'src/services/cli.service'; import { DatabaseBackupService } from 'src/services/database-backup.service'; import { QueueService } from 'src/services/queue.service'; import { getKyselyConfig } from 'src/utils/database'; +import { configureUserAgent } from 'src/utils/fetch'; const common = [...repositories, ...services, GlobalExceptionFilter]; @@ -59,6 +61,8 @@ const commonImports = [ const bullImports = [BullModule.forRoot(bull.config), BullModule.registerQueue(...bull.queues)]; +configureUserAgent(); + export class BaseModule implements OnModuleInit, OnModuleDestroy { constructor( @Inject(IWorker) private worker: ImmichWorker, @@ -111,6 +115,7 @@ export class ApiModule extends BaseModule {} StorageRepository, ProcessRepository, DatabaseRepository, + UserRepository, SystemMetadataRepository, AppRepository, MaintenanceHealthRepository, diff --git a/server/src/constants.ts b/server/src/constants.ts index e24057beba..4f8d9342c7 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -4,6 +4,8 @@ import { dirname, join } from 'node:path'; import { SemVer } from 'semver'; import { ApiTag, AudioCodec, DatabaseExtension, ExifOrientation, VectorIndex } from 'src/enum'; +export const IMMICH_SERVER_START = 'Immich Server is listening'; + export const ErrorMessages = { InconsistentMediaLocation: 'Detected an inconsistent media location. For more information, see https://docs.immich.app/errors#inconsistent-media-location', diff --git a/server/src/controllers/duplicate.controller.spec.ts b/server/src/controllers/duplicate.controller.spec.ts new file mode 100644 index 0000000000..66598b9920 --- /dev/null +++ b/server/src/controllers/duplicate.controller.spec.ts @@ -0,0 +1,47 @@ +import { DuplicateController } from 'src/controllers/duplicate.controller'; +import { DuplicateService } from 'src/services/duplicate.service'; +import request from 'supertest'; +import { factory } from 'test/small.factory'; +import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils'; + +describe(DuplicateController.name, () => { + let ctx: ControllerContext; + const service = mockBaseService(DuplicateService); + + beforeAll(async () => { + ctx = await controllerSetup(DuplicateController, [{ provide: DuplicateService, useValue: service }]); + return () => ctx.close(); + }); + + beforeEach(() => { + service.resetAllMocks(); + ctx.reset(); + }); + + describe('GET /duplicates', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).get('/duplicates'); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + }); + + describe('DELETE /duplicates', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).delete('/duplicates'); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + }); + + describe('DELETE /duplicates/:id', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).delete(`/duplicates/${factory.uuid()}`); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it('should require a valid uuid', async () => { + const { status, body } = await request(ctx.getHttpServer()).delete(`/duplicates/123`); + expect(status).toBe(400); + expect(body).toEqual(factory.responses.badRequest(['id must be a UUID'])); + }); + }); +}); diff --git a/server/src/controllers/duplicate.controller.ts b/server/src/controllers/duplicate.controller.ts index e8c8e5ef80..0a8c451ed4 100644 --- a/server/src/controllers/duplicate.controller.ts +++ b/server/src/controllers/duplicate.controller.ts @@ -1,9 +1,9 @@ -import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param } from '@nestjs/common'; +import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Endpoint, HistoryBuilder } from 'src/decorators'; -import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; +import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { DuplicateResponseDto } from 'src/dtos/duplicate.dto'; +import { DuplicateResolveDto, DuplicateResponseDto } from 'src/dtos/duplicate.dto'; import { ApiTag, Permission } from 'src/enum'; import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { DuplicateService } from 'src/services/duplicate.service'; @@ -48,4 +48,16 @@ export class DuplicateController { deleteDuplicate(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise { return this.service.delete(auth, id); } + + @Post('resolve') + @HttpCode(HttpStatus.OK) + @Authenticated({ permission: Permission.DuplicateDelete }) + @Endpoint({ + summary: 'Resolve duplicate groups', + description: 'Resolve duplicate groups by synchronizing metadata across assets and deleting/trashing duplicates.', + history: new HistoryBuilder().added('v3.0.0').alpha('v3.0.0'), + }) + resolveDuplicates(@Auth() auth: AuthDto, @Body() dto: DuplicateResolveDto): Promise { + return this.service.resolve(auth, dto); + } } diff --git a/server/src/database.ts b/server/src/database.ts index 2c08101fa6..ad03b118f5 100644 --- a/server/src/database.ts +++ b/server/src/database.ts @@ -5,6 +5,7 @@ import { AssetFileType, AssetType, AssetVisibility, + ChecksumAlgorithm, MemoryType, Permission, PluginContext, @@ -112,6 +113,7 @@ export type Memory = { export type Asset = { id: string; checksum: Buffer; + checksumAlgorithm: ChecksumAlgorithm; deviceAssetId: string; deviceId: string; fileCreatedAt: Date; @@ -330,6 +332,7 @@ export const columns = { asset: [ 'asset.id', 'asset.checksum', + 'asset.checksumAlgorithm', 'asset.deviceAssetId', 'asset.deviceId', 'asset.fileCreatedAt', @@ -345,6 +348,7 @@ export const columns = { 'asset.type', 'asset.width', 'asset.height', + 'asset.isEdited', ], assetFiles: ['asset_file.id', 'asset_file.path', 'asset_file.type', 'asset_file.isEdited'], assetFilesForThumbnail: [ diff --git a/server/src/decorators.ts b/server/src/decorators.ts index 695adb4a36..a5c5bf38db 100644 --- a/server/src/decorators.ts +++ b/server/src/decorators.ts @@ -73,7 +73,8 @@ export function Chunked( const originalMethod = descriptor.value; const parameterIndex = options.paramIndex ?? 0; const chunkSize = options.chunkSize || DATABASE_PARAMETER_CHUNK_SIZE; - descriptor.value = async function (...arguments_: any[]) { + const mergeFn = options.mergeFn; + descriptor.value = function (...arguments_: any[]) { const argument = arguments_[parameterIndex]; // Early return if argument length is less than or equal to the chunk size. @@ -81,27 +82,27 @@ export function Chunked( (Array.isArray(argument) && argument.length <= chunkSize) || (argument instanceof Set && argument.size <= chunkSize) ) { - return await originalMethod.apply(this, arguments_); + return originalMethod.apply(this, arguments_); } return Promise.all( - chunks(argument, chunkSize).map(async (chunk) => { - return await Reflect.apply(originalMethod, this, [ + chunks(argument, chunkSize).map((chunk) => { + return Reflect.apply(originalMethod, this, [ ...arguments_.slice(0, parameterIndex), chunk, ...arguments_.slice(parameterIndex + 1), ]); }), - ).then((results) => (options.mergeFn ? options.mergeFn(results) : results)); + ).then((results) => (mergeFn ? mergeFn(results) : results)); }; }; } -export function ChunkedArray(options?: { paramIndex?: number }): MethodDecorator { +export function ChunkedArray(options?: { paramIndex?: number; chunkSize?: number }): MethodDecorator { return Chunked({ ...options, mergeFn: _.flatten }); } -export function ChunkedSet(options?: { paramIndex?: number }): MethodDecorator { +export function ChunkedSet(options?: { paramIndex?: number; chunkSize?: number }): MethodDecorator { return Chunked({ ...options, mergeFn: (args: Set[]) => setUnion(...args) }); } diff --git a/server/src/dtos/asset-ids.response.dto.ts b/server/src/dtos/asset-ids.response.dto.ts index 427117518d..1065d8485e 100644 --- a/server/src/dtos/asset-ids.response.dto.ts +++ b/server/src/dtos/asset-ids.response.dto.ts @@ -23,6 +23,7 @@ export enum BulkIdErrorReason { NO_PERMISSION = 'no_permission', NOT_FOUND = 'not_found', UNKNOWN = 'unknown', + VALIDATION = 'validation', } export class BulkIdsDto { @@ -37,4 +38,5 @@ export class BulkIdResponseDto { success!: boolean; @ApiPropertyOptional({ description: 'Error reason if failed', enum: BulkIdErrorReason }) error?: BulkIdErrorReason; + errorMessage?: string; } diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index 8b38b2e124..2c2f57bbb2 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -13,7 +13,7 @@ import { } from 'src/dtos/person.dto'; import { TagResponseDto, mapTag } from 'src/dtos/tag.dto'; import { UserResponseDto, mapUser } from 'src/dtos/user.dto'; -import { AssetStatus, AssetType, AssetVisibility } from 'src/enum'; +import { AssetStatus, AssetType, AssetVisibility, ChecksumAlgorithm } from 'src/enum'; import { ImageDimensions, MaybeDehydrated } from 'src/types'; import { getDimensions } from 'src/utils/asset.util'; import { hexOrBufferToBase64 } from 'src/utils/bytes'; @@ -148,6 +148,7 @@ export type MapAsset = { updateId: string; status: AssetStatus; checksum: Buffer; + checksumAlgorithm: ChecksumAlgorithm; deviceAssetId: string; deviceId: string; duplicateId: string | null; diff --git a/server/src/dtos/database-backup.dto.ts b/server/src/dtos/database-backup.dto.ts index dc06cdc6ec..c0554f83b7 100644 --- a/server/src/dtos/database-backup.dto.ts +++ b/server/src/dtos/database-backup.dto.ts @@ -4,6 +4,7 @@ import { IsString } from 'class-validator'; export class DatabaseBackupDto { filename!: string; filesize!: number; + timezone!: string; } export class DatabaseBackupListResponseDto { diff --git a/server/src/dtos/duplicate.dto.ts b/server/src/dtos/duplicate.dto.ts index 9cd9147ec5..40b1b74c70 100644 --- a/server/src/dtos/duplicate.dto.ts +++ b/server/src/dtos/duplicate.dto.ts @@ -1,9 +1,35 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { ArrayMinSize, IsArray, ValidateNested } from 'class-validator'; import { AssetResponseDto } from 'src/dtos/asset-response.dto'; +import { ValidateUUID } from 'src/validation'; export class DuplicateResponseDto { @ApiProperty({ description: 'Duplicate group ID' }) duplicateId!: string; @ApiProperty({ description: 'Duplicate assets' }) assets!: AssetResponseDto[]; + + @ValidateUUID({ each: true, description: 'Suggested asset IDs to keep based on file size and EXIF data' }) + suggestedKeepAssetIds!: string[]; +} + +export class DuplicateResolveGroupDto { + @ValidateUUID() + duplicateId!: string; + + @ValidateUUID({ each: true, description: 'Asset IDs to keep' }) + keepAssetIds!: string[]; + + @ValidateUUID({ each: true, description: 'Asset IDs to trash or delete' }) + trashAssetIds!: string[]; +} + +export class DuplicateResolveDto { + @ApiProperty({ description: 'List of duplicate groups to resolve' }) + @ValidateNested({ each: true }) + @IsArray() + @Type(() => DuplicateResolveGroupDto) + @ArrayMinSize(1) + groups!: DuplicateResolveGroupDto[]; } diff --git a/server/src/dtos/env.dto.ts b/server/src/dtos/env.dto.ts index b04366c273..bdcf3614fd 100644 --- a/server/src/dtos/env.dto.ts +++ b/server/src/dtos/env.dto.ts @@ -42,6 +42,10 @@ export class EnvDto { @Optional() IMMICH_CONFIG_FILE?: string; + @IsString() + @Optional() + IMMICH_HELMET_FILE?: string; + @IsEnum(ImmichEnvironment) @Optional() IMMICH_ENV?: ImmichEnvironment; diff --git a/server/src/dtos/search.dto.ts b/server/src/dtos/search.dto.ts index f72ecdf8b6..196e72c37e 100644 --- a/server/src/dtos/search.dto.ts +++ b/server/src/dtos/search.dto.ts @@ -146,7 +146,7 @@ export class RandomSearchDto extends BaseSearchWithResultsDto { @ValidateBoolean({ optional: true, description: 'Include stacked assets' }) withStacked?: boolean; - @ValidateBoolean({ optional: true, description: 'Include assets with people' }) + @ValidateBoolean({ optional: true, description: 'Include people data in response' }) withPeople?: boolean; } diff --git a/server/src/enum.ts b/server/src/enum.ts index d6870372f1..920d1a459f 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -37,6 +37,11 @@ export enum AssetType { Other = 'OTHER', } +export enum ChecksumAlgorithm { + sha1File = 'sha1', // sha1 checksum of the whole file contents + sha1Path = 'sha1-path', // sha1 checksum of "path:" plus the file path, currently used in external libraries, deprecated +} + export enum AssetFileType { /** * An full/large-size image extracted/converted from RAW photos @@ -702,6 +707,7 @@ export enum DatabaseLock { BackupDatabase = 42, MaintenanceOperation = 621, MemoryCreation = 777, + VersionCheck = 800, } export enum MaintenanceAction { @@ -846,6 +852,7 @@ export enum AssetVisibility { export enum CronJob { LibraryScan = 'LibraryScan', NightlyJobs = 'NightlyJobs', + VersionCheck = 'VersionCheck', } export enum ApiTag { diff --git a/server/src/maintenance/maintenance-health.repository.ts b/server/src/maintenance/maintenance-health.repository.ts index aeef93ec51..c76cc23b1c 100644 --- a/server/src/maintenance/maintenance-health.repository.ts +++ b/server/src/maintenance/maintenance-health.repository.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { fork } from 'node:child_process'; import { dirname, join } from 'node:path'; +import { IMMICH_SERVER_START } from 'src/constants'; @Injectable() export class MaintenanceHealthRepository { @@ -20,48 +21,32 @@ export class MaintenanceHealthRepository { stdio: ['ignore', 'pipe', 'ignore', 'ipc'], }); - async function checkHealth() { - try { - const response = await fetch('http://127.0.0.1:33001/api/server/config'); - const { isOnboarded } = await response.json(); - if (isOnboarded) { - resolve(); - } else { - reject(new Error('Server health check failed, no admin exists.')); - } - } catch (error) { - reject(error); - } finally { - if (worker.exitCode === null) { - worker.kill('SIGTERM'); - } - } - } - - let output = '', - alive = false; + let output = ''; worker.stdout?.on('data', (data) => { - if (alive) { + if (worker.exitCode !== null) { return; } output += data; - if (output.includes('Immich Server is listening')) { - alive = true; - void checkHealth(); + if (output.includes(IMMICH_SERVER_START)) { + resolve(); + worker.kill('SIGTERM'); } }); - worker.on('exit', reject); - worker.on('error', reject); + worker.on('exit', (code, signal) => + reject(new Error(`Server health check failed, server exited with ${signal ?? code}`)), + ); + worker.on('error', (error) => reject(new Error(`Server health check failed, process threw: ${error}`))); setTimeout(() => { if (worker.exitCode === null) { + reject(new Error('Server health check failed, took too long to start.')); worker.kill('SIGTERM'); } - }, 20_000); + }, 180_000); }); } } diff --git a/server/src/queries/access.repository.sql b/server/src/queries/access.repository.sql index 1239260dce..810229093b 100644 --- a/server/src/queries/access.repository.sql +++ b/server/src/queries/access.repository.sql @@ -160,6 +160,16 @@ where "session"."userId" = $1 and "session"."id" in ($2) +-- AccessRepository.duplicate.checkOwnerAccess +select + "asset"."duplicateId" +from + "asset" +where + "asset"."duplicateId" in ($1) + and "asset"."ownerId" = $2 + and "asset"."deletedAt" is null + -- AccessRepository.memory.checkOwnerAccess select "memory"."id" diff --git a/server/src/queries/album.repository.sql b/server/src/queries/album.repository.sql index e3d7436c30..cc15260bdb 100644 --- a/server/src/queries/album.repository.sql +++ b/server/src/queries/album.repository.sql @@ -164,6 +164,28 @@ order by "album"."createdAt" desc, "album"."createdAt" desc +-- AlbumRepository.getByAssetIds +select + "album"."id", + "album_asset"."assetId" +from + "album" + inner join "album_asset" on "album_asset"."albumId" = "album"."id" +where + ( + "album"."ownerId" = $1 + or exists ( + select + from + "album_user" + where + "album_user"."albumId" = "album"."id" + and "album_user"."userId" = $2 + ) + ) + and "album_asset"."assetId" in ($3) + and "album"."deletedAt" is null + -- AlbumRepository.getMetadataForIds select "album_asset"."albumId" as "albumId", diff --git a/server/src/queries/asset.job.repository.sql b/server/src/queries/asset.job.repository.sql index cebb9fe95e..333d4ace81 100644 --- a/server/src/queries/asset.job.repository.sql +++ b/server/src/queries/asset.job.repository.sql @@ -249,6 +249,7 @@ where select "asset"."id", "asset"."checksum", + "asset"."checksumAlgorithm", "asset"."deviceAssetId", "asset"."deviceId", "asset"."fileCreatedAt", @@ -264,6 +265,7 @@ select "asset"."type", "asset"."width", "asset"."height", + "asset"."isEdited", ( select coalesce(json_agg(agg), '[]') @@ -435,12 +437,13 @@ select "asset_file" where "asset_file"."assetId" = "asset"."id" - and "asset_file"."type" = $1 + and "asset_file"."type" = 'preview' + and "asset_file"."isEdited" = false ) as "previewFile" from "asset" where - "asset"."id" = $2 + "asset"."id" = $1 -- AssetJobRepository.getForSyncAssets select diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index a2525c3b17..a68fde2b93 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -637,13 +637,14 @@ select "asset_file" where "asset_file"."assetId" = "asset"."id" - and "asset_file"."type" = $1 + and "asset_file"."type" = 'encoded_video' + and "asset_file"."isEdited" = false ) as "encodedVideoPath" from "asset" where - "asset"."id" = $2 - and "asset"."type" = $3 + "asset"."id" = $1 + and "asset"."type" = $2 -- AssetRepository.getForOcr select diff --git a/server/src/queries/duplicate.repository.sql b/server/src/queries/duplicate.repository.sql index 3f718f84c2..24a02e0f23 100644 --- a/server/src/queries/duplicate.repository.sql +++ b/server/src/queries/duplicate.repository.sql @@ -15,7 +15,26 @@ with inner join lateral ( select "asset".*, - "asset_exif" as "exifInfo" + to_json("asset_exif") as "exifInfo", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "tag"."id", + "tag"."value", + "tag"."createdAt", + "tag"."updatedAt", + "tag"."color", + "tag"."parentId" + from + "tag" + inner join "tag_asset" on "tag"."id" = "tag_asset"."tagId" + where + "tag_asset"."assetId" = "asset"."id" + ) as agg + ) as "tags" from "asset_exif" where @@ -29,36 +48,84 @@ with and "asset"."stackId" is null group by "asset"."duplicateId" - ), - "unique" as ( - select - "duplicateId" - from - "duplicates" - where - json_array_length("assets") = $2 - ), - "removed_unique" as ( - update "asset" - set - "duplicateId" = $3 - from - "unique" - where - "asset"."duplicateId" = "unique"."duplicateId" ) select * from "duplicates" where - not exists ( + json_array_length("assets") > $2 + +-- DuplicateRepository.cleanupSingletonGroups +with + "singletons" as ( select + "duplicateId" from - "unique" + "asset" where - "unique"."duplicateId" = "duplicates"."duplicateId" + "ownerId" = $1::uuid + and "duplicateId" is not null + and "deletedAt" is null + and "stackId" is null + group by + "duplicateId" + having + count("id") = $2 ) +update "asset" +set + "duplicateId" = $3 +from + "singletons" +where + "asset"."duplicateId" = "singletons"."duplicateId" + +-- DuplicateRepository.get +select + "asset"."duplicateId", + json_agg( + "asset2" + order by + "asset"."localDateTime" asc + ) as "assets" +from + "asset" + inner join lateral ( + select + "asset".*, + to_json("asset_exif") as "exifInfo", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "tag"."id", + "tag"."value", + "tag"."createdAt", + "tag"."updatedAt", + "tag"."color", + "tag"."parentId" + from + "tag" + inner join "tag_asset" on "tag"."id" = "tag_asset"."tagId" + where + "tag_asset"."assetId" = "asset"."id" + ) as agg + ) as "tags" + from + "asset_exif" + where + "asset_exif"."assetId" = "asset"."id" + ) as "asset2" on true +where + "asset"."visibility" in ('archive', 'timeline') + and "asset"."duplicateId" = $1::uuid + and "asset"."deletedAt" is null + and "asset"."stackId" is null +group by + "asset"."duplicateId" -- DuplicateRepository.delete update "asset" diff --git a/server/src/queries/person.repository.sql b/server/src/queries/person.repository.sql index 964aaaccee..318c151cca 100644 --- a/server/src/queries/person.repository.sql +++ b/server/src/queries/person.repository.sql @@ -176,7 +176,7 @@ select where "asset_file"."assetId" = "asset"."id" and "asset_file"."type" = 'preview' - and "asset_file"."isEdited" = $1 + and "asset_file"."isEdited" = false ) as "previewPath" from "person" @@ -184,7 +184,7 @@ from inner join "asset" on "asset_face"."assetId" = "asset"."id" left join "asset_exif" on "asset_exif"."assetId" = "asset"."id" where - "person"."id" = $2 + "person"."id" = $1 and "asset_face"."deletedAt" is null -- PersonRepository.reassignFace @@ -195,18 +195,21 @@ where "asset_face"."id" = $2 -- PersonRepository.getByName +with + "similarity_threshold" as ( + select + set_config('pg_trgm.word_similarity_threshold', '0.5', true) as "thresh" + ) select "person".* from + "similarity_threshold", "person" where - ( - "person"."ownerId" = $1 - and ( - lower("person"."name") like $2 - or lower("person"."name") like $3 - ) - ) + "person"."ownerId" = $1 + and f_unaccent ("person"."name") %> f_unaccent ($2) +order by + f_unaccent ("person"."name") <->>> f_unaccent ($3) limit $4 @@ -228,12 +231,12 @@ select from "asset_face" left join "asset" on "asset"."id" = "asset_face"."assetId" - and "asset_face"."personId" = $1 and "asset"."visibility" = 'timeline' and "asset"."deletedAt" is null where "asset_face"."deletedAt" is null and "asset_face"."isVisible" is true + and "asset_face"."personId" = $1 -- PersonRepository.getNumberOfPeople select diff --git a/server/src/queries/search.repository.sql b/server/src/queries/search.repository.sql index ef5fbe09be..701d30fa58 100644 --- a/server/src/queries/search.repository.sql +++ b/server/src/queries/search.repository.sql @@ -84,7 +84,6 @@ select from "asset" inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId" - left join "asset_exif" on "asset"."id" = "asset_exif"."assetId" where "asset"."visibility" = $1 and "asset"."fileCreatedAt" >= $2 @@ -254,6 +253,7 @@ where and "visibility" = $2 and "deletedAt" is null and "state" is not null + and "state" != $3 -- SearchRepository.getCities select distinct @@ -266,6 +266,7 @@ where and "visibility" = $2 and "deletedAt" is null and "city" is not null + and "city" != $3 -- SearchRepository.getCameraMakes select distinct @@ -278,6 +279,7 @@ where and "visibility" = $2 and "deletedAt" is null and "make" is not null + and "make" != $3 -- SearchRepository.getCameraModels select distinct @@ -290,6 +292,7 @@ where and "visibility" = $2 and "deletedAt" is null and "model" is not null + and "model" != $3 -- SearchRepository.getCameraLensModels select distinct @@ -302,3 +305,4 @@ where and "visibility" = $2 and "deletedAt" is null and "lensModel" is not null + and "lensModel" != $3 diff --git a/server/src/queries/shared.link.repository.sql b/server/src/queries/shared.link.repository.sql index f002110735..e1177bba28 100644 --- a/server/src/queries/shared.link.repository.sql +++ b/server/src/queries/shared.link.repository.sql @@ -3,37 +3,64 @@ -- SharedLinkRepository.get select "shared_link".*, - coalesce( - json_agg("a") filter ( - where - "a"."id" is not null - ), - '[]' + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "asset".*, + to_json("exifInfo") as "exifInfo" + from + "shared_link_asset" + inner join "asset" on "asset"."id" = "shared_link_asset"."assetId" + inner join lateral ( + select + "asset_exif"."assetId", + "asset_exif"."autoStackId", + "asset_exif"."bitsPerSample", + "asset_exif"."city", + "asset_exif"."colorspace", + "asset_exif"."country", + "asset_exif"."dateTimeOriginal", + "asset_exif"."description", + "asset_exif"."exifImageHeight", + "asset_exif"."exifImageWidth", + "asset_exif"."exposureTime", + "asset_exif"."fileSizeInByte", + "asset_exif"."fNumber", + "asset_exif"."focalLength", + "asset_exif"."fps", + "asset_exif"."iso", + "asset_exif"."latitude", + "asset_exif"."lensModel", + "asset_exif"."livePhotoCID", + "asset_exif"."longitude", + "asset_exif"."make", + "asset_exif"."model", + "asset_exif"."modifyDate", + "asset_exif"."orientation", + "asset_exif"."profileDescription", + "asset_exif"."projectionType", + "asset_exif"."rating", + "asset_exif"."state", + "asset_exif"."tags", + "asset_exif"."timeZone" + from + "asset_exif" + where + "asset_exif"."assetId" = "asset"."id" + ) as "exifInfo" on true + where + "shared_link"."id" = "shared_link_asset"."sharedLinkId" + and "asset"."deletedAt" is null + order by + "asset"."fileCreatedAt" asc + ) as agg ) as "assets", to_json("album") as "album" from "shared_link" - left join lateral ( - select - "asset".*, - to_json("exifInfo") as "exifInfo" - from - "shared_link_asset" - inner join "asset" on "asset"."id" = "shared_link_asset"."assetId" - inner join lateral ( - select - "asset_exif".* - from - "asset_exif" - where - "asset_exif"."assetId" = "asset"."id" - ) as "exifInfo" on true - where - "shared_link"."id" = "shared_link_asset"."sharedLinkId" - and "asset"."deletedAt" is null - order by - "asset"."fileCreatedAt" asc - ) as "a" on true left join lateral ( select "album".*, @@ -60,7 +87,36 @@ from "asset" inner join lateral ( select - "asset_exif".* + "asset_exif"."assetId", + "asset_exif"."autoStackId", + "asset_exif"."bitsPerSample", + "asset_exif"."city", + "asset_exif"."colorspace", + "asset_exif"."country", + "asset_exif"."dateTimeOriginal", + "asset_exif"."description", + "asset_exif"."exifImageHeight", + "asset_exif"."exifImageWidth", + "asset_exif"."exposureTime", + "asset_exif"."fileSizeInByte", + "asset_exif"."fNumber", + "asset_exif"."focalLength", + "asset_exif"."fps", + "asset_exif"."iso", + "asset_exif"."latitude", + "asset_exif"."lensModel", + "asset_exif"."livePhotoCID", + "asset_exif"."longitude", + "asset_exif"."make", + "asset_exif"."model", + "asset_exif"."modifyDate", + "asset_exif"."orientation", + "asset_exif"."profileDescription", + "asset_exif"."projectionType", + "asset_exif"."rating", + "asset_exif"."state", + "asset_exif"."tags", + "asset_exif"."timeZone" from "asset_exif" where @@ -74,7 +130,12 @@ from ) as "assets" on true inner join lateral ( select - "user".* + "id", + "name", + "email", + "avatarColor", + "profileImagePath", + "profileChangedAt" from "user" where @@ -95,9 +156,6 @@ where "shared_link"."type" = $3 or "album"."id" is not null ) -group by - "shared_link"."id", - "album".* order by "shared_link"."createdAt" desc @@ -134,21 +192,12 @@ from "album" inner join lateral ( select - "user"."id", - "user"."email", - "user"."createdAt", - "user"."profileImagePath", - "user"."isAdmin", - "user"."shouldChangePassword", - "user"."deletedAt", - "user"."oauthId", - "user"."updatedAt", - "user"."storageLabel", - "user"."name", - "user"."quotaSizeInBytes", - "user"."quotaUsageInBytes", - "user"."status", - "user"."profileChangedAt" + "id", + "name", + "email", + "avatarColor", + "profileImagePath", + "profileChangedAt" from "user" where @@ -267,7 +316,36 @@ from "asset" inner join lateral ( select - * + "asset_exif"."assetId", + "asset_exif"."autoStackId", + "asset_exif"."bitsPerSample", + "asset_exif"."city", + "asset_exif"."colorspace", + "asset_exif"."country", + "asset_exif"."dateTimeOriginal", + "asset_exif"."description", + "asset_exif"."exifImageHeight", + "asset_exif"."exifImageWidth", + "asset_exif"."exposureTime", + "asset_exif"."fileSizeInByte", + "asset_exif"."fNumber", + "asset_exif"."focalLength", + "asset_exif"."fps", + "asset_exif"."iso", + "asset_exif"."latitude", + "asset_exif"."lensModel", + "asset_exif"."livePhotoCID", + "asset_exif"."longitude", + "asset_exif"."make", + "asset_exif"."model", + "asset_exif"."modifyDate", + "asset_exif"."orientation", + "asset_exif"."profileDescription", + "asset_exif"."projectionType", + "asset_exif"."rating", + "asset_exif"."state", + "asset_exif"."tags", + "asset_exif"."timeZone" from "asset_exif" where diff --git a/server/src/queries/sync.repository.sql b/server/src/queries/sync.repository.sql index a468bfe322..2fd4931d65 100644 --- a/server/src/queries/sync.repository.sql +++ b/server/src/queries/sync.repository.sql @@ -582,7 +582,6 @@ where "asset_face"."updateId" < $1 and "asset_face"."updateId" > $2 and "asset"."ownerId" = $3 - and "asset_face"."isVisible" = $4 order by "asset_face"."updateId" asc diff --git a/server/src/repositories/access.repository.ts b/server/src/repositories/access.repository.ts index 533e74a311..1661e42c14 100644 --- a/server/src/repositories/access.repository.ts +++ b/server/src/repositories/access.repository.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { Kysely, sql } from 'kysely'; +import { Kysely, NotNull, sql } from 'kysely'; import { InjectKysely } from 'nestjs-kysely'; import { ChunkedSet, DummyValue, GenerateSql } from 'src/decorators'; import { AlbumUserRole, AssetVisibility } from 'src/enum'; @@ -285,6 +285,28 @@ class AuthDeviceAccess { } } +class DuplicateAccess { + constructor(private db: Kysely) {} + + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) + async checkOwnerAccess(userId: string, duplicateIds: Set) { + if (duplicateIds.size === 0) { + return new Set(); + } + + return this.db + .selectFrom('asset') + .select('asset.duplicateId') + .where('asset.duplicateId', 'in', [...duplicateIds]) + .where('asset.ownerId', '=', userId) + .where('asset.deletedAt', 'is', null) + .$narrowType<{ duplicateId: NotNull }>() + .execute() + .then((assets) => new Set(assets.map((asset) => asset.duplicateId))); + } +} + class NotificationAccess { constructor(private db: Kysely) {} @@ -488,6 +510,7 @@ export class AccessRepository { album: AlbumAccess; asset: AssetAccess; authDevice: AuthDeviceAccess; + duplicate: DuplicateAccess; memory: MemoryAccess; notification: NotificationAccess; person: PersonAccess; @@ -503,6 +526,7 @@ export class AccessRepository { this.album = new AlbumAccess(db); this.asset = new AssetAccess(db); this.authDevice = new AuthDeviceAccess(db); + this.duplicate = new DuplicateAccess(db); this.memory = new MemoryAccess(db); this.notification = new NotificationAccess(db); this.person = new PersonAccess(db); diff --git a/server/src/repositories/album.repository.ts b/server/src/repositories/album.repository.ts index f74356c924..e4d802b93c 100644 --- a/server/src/repositories/album.repository.ts +++ b/server/src/repositories/album.repository.ts @@ -125,6 +125,44 @@ export class AlbumRepository { .execute(); } + @GenerateSql({ params: [DummyValue.UUID, [DummyValue.UUID]] }) + @ChunkedSet({ paramIndex: 1 }) + async getByAssetIds(ownerId: string, assetIds: string[]): Promise> { + if (assetIds.length === 0) { + return new Map(); + } + + const results = await this.db + .selectFrom('album') + .select('album.id') + .innerJoin('album_asset', 'album_asset.albumId', 'album.id') + .where((eb) => + eb.or([ + eb('album.ownerId', '=', ownerId), + eb.exists( + eb + .selectFrom('album_user') + .whereRef('album_user.albumId', '=', 'album.id') + .where('album_user.userId', '=', ownerId), + ), + ]), + ) + .where('album_asset.assetId', 'in', assetIds) + .where('album.deletedAt', 'is', null) + .select('album_asset.assetId') + .execute(); + + // Group by assetId + const map = new Map(); + for (const row of results) { + const existing = map.get(row.assetId) ?? []; + existing.push(row.id); + map.set(row.assetId, existing); + } + + return map; + } + @GenerateSql({ params: [[DummyValue.UUID]] }) @ChunkedArray() async getMetadataForIds(ids: string[]): Promise { @@ -339,7 +377,12 @@ export class AlbumRepository { if (values.length === 0) { return; } - await this.db.insertInto('album_asset').values(values).execute(); + await this.db + .insertInto('album_asset') + .values(values) + // Allow idempotent album sync without failing on existing album memberships. + .onConflict((oc) => oc.columns(['albumId', 'assetId']).doNothing()) + .execute(); } /** diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index 2e1d02ef28..5876b934e5 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -380,8 +380,10 @@ export class AssetRepository { return this.db.insertInto('asset').values(asset).returningAll().executeTakeFirstOrThrow(); } - createAll(assets: Insertable[]) { - return this.db.insertInto('asset').values(assets).returningAll().execute(); + @ChunkedArray({ chunkSize: 4000 }) + async createAll(assets: Insertable[]) { + const ids = await this.db.insertInto('asset').values(assets).returning('id').execute(); + return ids.map(({ id }) => id); } @GenerateSql({ params: [DummyValue.UUID, { year: 2000, day: 1, month: 1 }] }) diff --git a/server/src/repositories/config.repository.ts b/server/src/repositories/config.repository.ts index 7e8082a582..fa4823362e 100644 --- a/server/src/repositories/config.repository.ts +++ b/server/src/repositories/config.repository.ts @@ -5,9 +5,11 @@ import { QueueOptions } from 'bullmq'; import { plainToInstance } from 'class-transformer'; import { validateSync } from 'class-validator'; import { Request, Response } from 'express'; +import { HelmetOptions } from 'helmet'; import { RedisOptions } from 'ioredis'; import { CLS_ID, ClsModuleOptions } from 'nestjs-cls'; import { OpenTelemetryModuleOptions } from 'nestjs-otel/lib/interfaces'; +import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { citiesFile, excludePaths, IWorker } from 'src/constants'; import { Telemetry } from 'src/decorators'; @@ -58,6 +60,10 @@ export interface EnvData { config: ClsModuleOptions; }; + helmet: { + config?: HelmetOptions; + }; + database: { config: DatabaseConnectionParams; skipMigrations: boolean; @@ -69,6 +75,10 @@ export interface EnvData { server: string; }; + versionCheck: { + url: string; + }; + network: { trustedProxies: string[]; }; @@ -143,6 +153,25 @@ const asSet = (value: string | undefined, defaults: T[]) => { return new Set(values.length === 0 ? defaults : (values as T[])); }; +const resolveHelmetFile = (helmetFile: 'true' | 'false' | string | undefined) => { + // default is off + if (!helmetFile || helmetFile === 'false') { + return; + } + + helmetFile = + helmetFile === 'true' + ? // eslint-disable-next-line unicorn/prefer-module + join(__dirname, '..', '..', 'helmet.json') + : helmetFile; + + try { + return JSON.parse(readFileSync(helmetFile).toString()) as HelmetOptions; + } catch (error) { + throw new Error(`Failed to read helmet file: ${helmetFile}`, { cause: error }); + } +}; + const getEnv = (): EnvData => { const dto = plainToInstance(EnvDto, process.env); const errors = validateSync(dto); @@ -289,8 +318,16 @@ const getEnv = (): EnvData => { vectorExtension, }, + helmet: { + config: resolveHelmetFile(dto.IMMICH_HELMET_FILE), + }, + licensePublicKey: isProd ? productionKeys : stagingKeys, + versionCheck: { + url: isProd ? 'https://version.immich.cloud/version' : 'https://version.dev.immich.cloud/version', + }, + network: { trustedProxies: dto.IMMICH_TRUSTED_PROXIES ?? ['linklocal', 'uniquelocal'], }, diff --git a/server/src/repositories/duplicate.repository.ts b/server/src/repositories/duplicate.repository.ts index 7a5931e029..6a9b4e9082 100644 --- a/server/src/repositories/duplicate.repository.ts +++ b/server/src/repositories/duplicate.repository.ts @@ -1,13 +1,19 @@ import { Injectable } from '@nestjs/common'; import { Kysely, NotNull, Selectable, ShallowDehydrateObject, sql } from 'kysely'; +import { jsonArrayFrom } from 'kysely/helpers/postgres'; import { InjectKysely } from 'nestjs-kysely'; +import { columns } from 'src/database'; import { Chunked, DummyValue, GenerateSql } from 'src/decorators'; +import { MapAsset } from 'src/dtos/asset-response.dto'; import { AssetType, VectorIndex } from 'src/enum'; import { probes } from 'src/repositories/database.repository'; import { DB } from 'src/schema'; import { AssetExifTable } from 'src/schema/tables/asset-exif.table'; import { anyUuid, asUuid, withDefaultVisibility } from 'src/utils/database'; +// Maximum number of candidate duplicates to return from vector search +const DUPLICATE_SEARCH_LIMIT = 64; + interface DuplicateSearch { assetId: string; embedding: string; @@ -34,20 +40,39 @@ export class DuplicateRepository { qb .selectFrom('asset') .$call(withDefaultVisibility) + // Use innerJoinLateral to build a composite object per asset that includes + // exifInfo and tags. This "asset2" object is then aggregated via jsonAgg. + // Tags must be included here (not via separate joins) so they appear in the + // final MapAsset[] output - needed for tag synchronization during resolution. .innerJoinLateral( (qb) => qb .selectFrom('asset_exif') .selectAll('asset') .select((eb) => - eb.table('asset_exif').$castTo>>().as('exifInfo'), + eb.fn + .toJson('asset_exif') + .$castTo>>() + .as('exifInfo'), + ) + + .select((eb) => + jsonArrayFrom( + eb + .selectFrom('tag') + .select(columns.tag) + .innerJoin('tag_asset', 'tag.id', 'tag_asset.tagId') + .whereRef('tag_asset.assetId', '=', 'asset.id'), + ).as('tags'), ) .whereRef('asset_exif.assetId', '=', 'asset.id') .as('asset2'), (join) => join.onTrue(), ) .select('asset.duplicateId') - .select((eb) => eb.fn.jsonAgg('asset2').orderBy('asset.localDateTime', 'asc').as('assets')) + .select((eb) => + eb.fn.jsonAgg('asset2').orderBy('asset.localDateTime', 'asc').$castTo().as('assets'), + ) .where('asset.ownerId', '=', asUuid(userId)) .where('asset.duplicateId', 'is not', null) .$narrowType<{ duplicateId: NotNull }>() @@ -55,29 +80,80 @@ export class DuplicateRepository { .where('asset.stackId', 'is', null) .groupBy('asset.duplicateId'), ) - .with('unique', (qb) => - qb - .selectFrom('duplicates') - .select('duplicateId') - .where((eb) => eb(eb.fn('json_array_length', ['assets']), '=', 1)), - ) - .with('removed_unique', (qb) => - qb - .updateTable('asset') - .set({ duplicateId: null }) - .from('unique') - .whereRef('asset.duplicateId', '=', 'unique.duplicateId'), - ) .selectFrom('duplicates') .selectAll() - // TODO: compare with filtering by json_array_length > 1 - .where(({ not, exists }) => - not(exists((eb) => eb.selectFrom('unique').whereRef('unique.duplicateId', '=', 'duplicates.duplicateId'))), - ) + // Filter out singleton groups (only 1 asset) directly in the query + .where((eb) => eb(eb.fn('json_array_length', ['assets']), '>', 1)) .execute() ); } + @GenerateSql({ params: [DummyValue.UUID] }) + async cleanupSingletonGroups(userId: string): Promise { + // Remove duplicateId from assets that are the only member of their duplicate group + await this.db + .with('singletons', (qb) => + qb + .selectFrom('asset') + .select('duplicateId') + .where('ownerId', '=', asUuid(userId)) + .where('duplicateId', 'is not', null) + .$narrowType<{ duplicateId: NotNull }>() + .where('deletedAt', 'is', null) + .where('stackId', 'is', null) + .groupBy('duplicateId') + .having((eb) => eb.fn.count('id'), '=', 1), + ) + .updateTable('asset') + .set({ duplicateId: null }) + .from('singletons') + .whereRef('asset.duplicateId', '=', 'singletons.duplicateId') + .execute(); + } + + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) + async get(duplicateId: string): Promise<{ duplicateId: string; assets: MapAsset[] } | undefined> { + const result = await this.db + .selectFrom('asset') + .$call(withDefaultVisibility) + // Use innerJoinLateral to build a composite object per asset that includes + // exifInfo and tags. This "asset2" object is then aggregated via jsonAgg. + // Tags must be included here (not via separate joins) so they appear in the + // final MapAsset[] output - needed for tag synchronization during resolution. + .innerJoinLateral( + (qb) => + qb + .selectFrom('asset_exif') + .selectAll('asset') + .select((eb) => eb.fn.toJson('asset_exif').as('exifInfo')) + .select((eb) => + jsonArrayFrom( + eb + .selectFrom('tag') + .select(columns.tag) + .innerJoin('tag_asset', 'tag.id', 'tag_asset.tagId') + .whereRef('tag_asset.assetId', '=', 'asset.id'), + ).as('tags'), + ) + .whereRef('asset_exif.assetId', '=', 'asset.id') + .as('asset2'), + (join) => join.onTrue(), + ) + .select('asset.duplicateId') + .select((eb) => eb.fn.jsonAgg('asset2').orderBy('asset.localDateTime', 'asc').$castTo().as('assets')) + .where('asset.duplicateId', '=', asUuid(duplicateId)) + .where('asset.deletedAt', 'is', null) + .where('asset.stackId', 'is', null) + .groupBy('asset.duplicateId') + .executeTakeFirst(); + + if (!result || !result.duplicateId) { + return; + } + + return { duplicateId: result.duplicateId, assets: result.assets }; + } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) async delete(userId: string, id: string): Promise { await this.db @@ -134,7 +210,7 @@ export class DuplicateRepository { .where('asset.id', '!=', asUuid(assetId)) .where('asset.stackId', 'is', null) .orderBy('distance') - .limit(64), + .limit(DUPLICATE_SEARCH_LIMIT), ) .selectFrom('cte') .selectAll() diff --git a/server/src/repositories/job.repository.ts b/server/src/repositories/job.repository.ts index b12accb68e..142d5e3252 100644 --- a/server/src/repositories/job.repository.ts +++ b/server/src/repositories/job.repository.ts @@ -233,6 +233,9 @@ export class JobRepository { case JobName.FacialRecognitionQueueAll: { return { jobId: JobName.FacialRecognitionQueueAll }; } + case JobName.VersionCheck: { + return { jobId: JobName.VersionCheck }; + } default: { return null; } diff --git a/server/src/repositories/oauth.repository.ts b/server/src/repositories/oauth.repository.ts index 5af5163f8f..b2e72e470a 100644 --- a/server/src/repositories/oauth.repository.ts +++ b/server/src/repositories/oauth.repository.ts @@ -1,5 +1,19 @@ import { Injectable, InternalServerErrorException } from '@nestjs/common'; -import type { UserInfoResponse } from 'openid-client' with { 'resolution-mode': 'import' }; +import { + allowInsecureRequests, + authorizationCodeGrant, + buildAuthorizationUrl, + calculatePKCECodeChallenge, + ClientSecretBasic, + ClientSecretPost, + discovery, + fetchUserInfo, + None, + randomPKCECodeVerifier, + randomState, + skipSubjectCheck, + type UserInfoResponse, +} from 'openid-client'; import { OAuthTokenEndpointAuthMethod } from 'src/enum'; import { LoggingRepository } from 'src/repositories/logging.repository'; @@ -24,8 +38,6 @@ export class OAuthRepository { } async authorize(config: OAuthConfig, redirectUrl: string, state?: string, codeChallenge?: string) { - const { buildAuthorizationUrl, randomState, randomPKCECodeVerifier, calculatePKCECodeChallenge } = - await import('openid-client'); const client = await this.getClient(config); state ??= randomState(); @@ -64,7 +76,6 @@ export class OAuthRepository { expectedState: string, codeVerifier: string, ): Promise { - const { authorizationCodeGrant, fetchUserInfo, ...oidc } = await import('openid-client'); const client = await this.getClient(config); const pkceCodeVerifier = client.serverMetadata().supportsPKCE() ? codeVerifier : undefined; @@ -77,7 +88,7 @@ export class OAuthRepository { this.logger.debug('Using ID token claims instead of userinfo endpoint'); profile = tokenClaims as OAuthProfile; } else { - profile = await fetchUserInfo(client, tokens.access_token, oidc.skipSubjectCheck); + profile = await fetchUserInfo(client, tokens.access_token, skipSubjectCheck); } if (!profile.sub) { @@ -124,7 +135,6 @@ export class OAuthRepository { timeout, }: OAuthConfig) { try { - const { allowInsecureRequests, discovery } = await import('openid-client'); return await discovery( new URL(issuerUrl), clientId, @@ -134,7 +144,7 @@ export class OAuthRepository { userinfo_signed_response_alg: profileSigningAlgorithm === 'none' ? undefined : profileSigningAlgorithm, id_token_signed_response_alg: signingAlgorithm, }, - await this.getTokenAuthMethod(tokenEndpointAuthMethod, clientSecret), + this.getTokenAuthMethod(tokenEndpointAuthMethod, clientSecret), { execute: [allowInsecureRequests], timeout, @@ -146,9 +156,7 @@ export class OAuthRepository { } } - private async getTokenAuthMethod(tokenEndpointAuthMethod: OAuthTokenEndpointAuthMethod, clientSecret?: string) { - const { None, ClientSecretPost, ClientSecretBasic } = await import('openid-client'); - + private getTokenAuthMethod(tokenEndpointAuthMethod: OAuthTokenEndpointAuthMethod, clientSecret?: string) { if (!clientSecret) { return None(); } diff --git a/server/src/repositories/ocr.repository.ts b/server/src/repositories/ocr.repository.ts index 63375cf57d..916f2643ff 100644 --- a/server/src/repositories/ocr.repository.ts +++ b/server/src/repositories/ocr.repository.ts @@ -58,6 +58,7 @@ export class OcrRepository { }) upsert(assetId: string, ocrDataList: Insertable[], searchText: string) { let query = this.db.with('deleted_ocr', (db) => db.deleteFrom('asset_ocr').where('assetId', '=', assetId)); + // eslint-disable-next-line unicorn/prefer-ternary if (ocrDataList.length > 0) { (query as any) = query .with('inserted_ocr', (db) => db.insertInto('asset_ocr').values(ocrDataList)) diff --git a/server/src/repositories/person.repository.ts b/server/src/repositories/person.repository.ts index 00156a2492..ab5fad40d1 100644 --- a/server/src/repositories/person.repository.ts +++ b/server/src/repositories/person.repository.ts @@ -9,7 +9,7 @@ import { DB } from 'src/schema'; import { AssetFaceTable } from 'src/schema/tables/asset-face.table'; import { FaceSearchTable } from 'src/schema/tables/face-search.table'; import { PersonTable } from 'src/schema/tables/person.table'; -import { removeUndefinedKeys } from 'src/utils/database'; +import { removeUndefinedKeys, withFilePath } from 'src/utils/database'; import { paginationHelper, PaginationOptions } from 'src/utils/pagination'; export interface PersonSearchOptions { @@ -282,15 +282,7 @@ export class PersonRepository { 'asset.originalPath', 'asset_exif.orientation as exifOrientation', ]) - .select((eb) => - eb - .selectFrom('asset_file') - .select('asset_file.path') - .whereRef('asset_file.assetId', '=', 'asset.id') - .where('asset_file.type', '=', sql.lit(AssetFileType.Preview)) - .where('asset_file.isEdited', '=', false) - .as('previewPath'), - ) + .select((eb) => withFilePath(eb, AssetFileType.Preview).as('previewPath')) .where('person.id', '=', id) .where('asset_face.deletedAt', 'is', null) .executeTakeFirst(); @@ -318,18 +310,15 @@ export class PersonRepository { @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING, { withHidden: true }] }) getByName(userId: string, personName: string, { withHidden }: PersonNameSearchOptions) { return this.db - .selectFrom('person') - .selectAll('person') - .where((eb) => - eb.and([ - eb('person.ownerId', '=', userId), - eb.or([ - eb(eb.fn('lower', ['person.name']), 'like', `${personName.toLowerCase()}%`), - eb(eb.fn('lower', ['person.name']), 'like', `% ${personName.toLowerCase()}%`), - ]), - ]), + .with('similarity_threshold', (db) => + db.selectNoFrom(sql`set_config('pg_trgm.word_similarity_threshold', '0.5', true)`.as('thresh')), ) - .limit(1000) + .selectFrom(['similarity_threshold', 'person']) + .selectAll('person') + .where('person.ownerId', '=', userId) + .where(() => sql`f_unaccent("person"."name") %> f_unaccent(${personName})`) + .orderBy(sql`f_unaccent("person"."name") <->>> f_unaccent(${personName})`) + .limit(100) .$if(!withHidden, (qb) => qb.where('person.isHidden', '=', false)) .execute(); } @@ -352,13 +341,13 @@ export class PersonRepository { .leftJoin('asset', (join) => join .onRef('asset.id', '=', 'asset_face.assetId') - .on('asset_face.personId', '=', personId) .on('asset.visibility', '=', sql.lit(AssetVisibility.Timeline)) .on('asset.deletedAt', 'is', null), ) .select((eb) => eb.fn.count(eb.fn('distinct', ['asset.id'])).as('count')) .where('asset_face.deletedAt', 'is', null) .where('asset_face.isVisible', 'is', true) + .where('asset_face.personId', '=', personId) .executeTakeFirst(); return { diff --git a/server/src/repositories/search.repository.ts b/server/src/repositories/search.repository.ts index 13ac254654..8f8a5be0bd 100644 --- a/server/src/repositories/search.repository.ts +++ b/server/src/repositories/search.repository.ts @@ -8,7 +8,7 @@ import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum'; import { probes } from 'src/repositories/database.repository'; import { DB } from 'src/schema'; import { AssetExifTable } from 'src/schema/tables/asset-exif.table'; -import { anyUuid, searchAssetBuilder, withExif } from 'src/utils/database'; +import { anyUuid, searchAssetBuilder, withExifInner } from 'src/utils/database'; import { paginationHelper } from 'src/utils/pagination'; import { isValidInteger } from 'src/validation'; @@ -270,7 +270,7 @@ export class SearchRepository { const orderDirection = (options.orderDirection?.toLowerCase() || 'desc') as OrderByDirection; return searchAssetBuilder(this.db, options) .selectAll('asset') - .$call(withExif) + .$call(withExifInner) .where('asset_exif.fileSizeInByte', '>', options.minFileSize || 0) .orderBy('asset_exif.fileSizeInByte', orderDirection) .limit(size) @@ -502,10 +502,7 @@ export class SearchRepository { return res.map((row) => row.lensModel!); } - private getExifField( - field: K, - userIds: string[], - ) { + private getExifField(field: 'city' | 'state' | 'country' | 'make' | 'model' | 'lensModel', userIds: string[]) { return this.db .selectFrom('asset_exif') .select(field) @@ -514,6 +511,7 @@ export class SearchRepository { .where('ownerId', '=', anyUuid(userIds)) .where('visibility', '=', AssetVisibility.Timeline) .where('deletedAt', 'is', null) - .where(field, 'is not', null); + .where(field, 'is not', null) + .where(field, '!=', ''); } } diff --git a/server/src/repositories/server-info.repository.ts b/server/src/repositories/server-info.repository.ts index 934706d5e1..85d26d6cfa 100644 --- a/server/src/repositories/server-info.repository.ts +++ b/server/src/repositories/server-info.repository.ts @@ -17,6 +17,11 @@ export interface GitHubRelease { body: string; } +export interface VersionResponse { + version: string; + published_at: string; +} + export interface ServerBuildVersions { nodejs: string; ffmpeg: string; @@ -59,17 +64,18 @@ export class ServerInfoRepository { this.logger.setContext(ServerInfoRepository.name); } - async getGitHubRelease(): Promise { + async getLatestRelease(): Promise { try { - const response = await fetch('https://api.github.com/repos/immich-app/immich/releases/latest'); + const { versionCheck } = this.configRepository.getEnv(); + const response = await fetch(versionCheck.url); if (!response.ok) { - throw new Error(`GitHub API request failed with status ${response.status}: ${await response.text()}`); + throw new Error(`Version check request failed with status ${response.status}: ${await response.text()}`); } return response.json(); } catch (error) { - throw new Error('Failed to fetch GitHub release', { cause: error }); + throw new Error('Failed to fetch latest release', { cause: error }); } } diff --git a/server/src/repositories/shared-link.repository.ts b/server/src/repositories/shared-link.repository.ts index 1ad5d7bd77..ddfe37ef35 100644 --- a/server/src/repositories/shared-link.repository.ts +++ b/server/src/repositories/shared-link.repository.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { Insertable, Kysely, Selectable, ShallowDehydrateObject, sql, Updateable } from 'kysely'; +import { ExpressionBuilder, Insertable, Kysely, Selectable, ShallowDehydrateObject, sql, Updateable } from 'kysely'; import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres'; import _ from 'lodash'; import { InjectKysely } from 'nestjs-kysely'; @@ -17,6 +17,41 @@ export type SharedLinkSearchOptions = { albumId?: string; }; +const withSharedAssets = (eb: ExpressionBuilder) => { + return eb + .selectFrom('shared_link_asset') + .whereRef('shared_link.id', '=', 'shared_link_asset.sharedLinkId') + .innerJoin('asset', 'asset.id', 'shared_link_asset.assetId') + .where('asset.deletedAt', 'is', null) + .selectAll('asset') + .orderBy('asset.fileCreatedAt', 'asc'); +}; + +export const withExifInfo = (eb: ExpressionBuilder) => { + return eb + .selectFrom('asset_exif') + .select(columns.exif) + .whereRef('asset_exif.assetId', '=', 'asset.id') + .as('exifInfo'); +}; + +const withAlbumOwner = (eb: ExpressionBuilder) => { + return eb + .selectFrom('user') + .select(columns.user) + .whereRef('user.id', '=', 'album.ownerId') + .where('user.deletedAt', 'is', null) + .as('owner'); +}; + +const withSharedLinkAlbum = (eb: ExpressionBuilder) => { + return eb + .selectFrom('album') + .selectAll('album') + .whereRef('album.id', '=', 'shared_link.albumId') + .where('album.deletedAt', 'is', null); +}; + @Injectable() export class SharedLinkRepository { constructor(@InjectKysely() private db: Kysely) {} @@ -26,35 +61,16 @@ export class SharedLinkRepository { return this.db .selectFrom('shared_link') .selectAll('shared_link') - .leftJoinLateral( - (eb) => - eb - .selectFrom('shared_link_asset') - .whereRef('shared_link.id', '=', 'shared_link_asset.sharedLinkId') - .innerJoin('asset', 'asset.id', 'shared_link_asset.assetId') - .where('asset.deletedAt', 'is', null) - .selectAll('asset') - .innerJoinLateral( - (eb) => - eb - .selectFrom('asset_exif') - .selectAll('asset_exif') - .whereRef('asset_exif.assetId', '=', 'asset.id') - .as('exifInfo'), - (join) => join.onTrue(), - ) - .select((eb) => eb.fn.toJson('exifInfo').as('exifInfo')) - .orderBy('asset.fileCreatedAt', 'asc') - .as('a'), - (join) => join.onTrue(), + .select((eb) => + jsonArrayFrom( + withSharedAssets(eb) + .innerJoinLateral(withExifInfo, (join) => join.onTrue()) + .select((eb) => eb.fn.toJson('exifInfo').as('exifInfo')), + ).as('assets'), ) .leftJoinLateral( (eb) => - eb - .selectFrom('album') - .selectAll('album') - .whereRef('album.id', '=', 'shared_link.albumId') - .where('album.deletedAt', 'is', null) + withSharedLinkAlbum(eb) .leftJoin('album_asset', 'album_asset.albumId', 'album.id') .leftJoinLateral( (eb) => @@ -63,30 +79,13 @@ export class SharedLinkRepository { .selectAll('asset') .whereRef('album_asset.assetId', '=', 'asset.id') .where('asset.deletedAt', 'is', null) - .innerJoinLateral( - (eb) => - eb - .selectFrom('asset_exif') - .selectAll('asset_exif') - .whereRef('asset_exif.assetId', '=', 'asset.id') - .as('exifInfo'), - (join) => join.onTrue(), - ) + .innerJoinLateral(withExifInfo, (join) => join.onTrue()) .select((eb) => eb.fn.toJson(eb.table('exifInfo')).as('exifInfo')) .orderBy('asset.fileCreatedAt', 'asc') .as('assets'), (join) => join.onTrue(), ) - .innerJoinLateral( - (eb) => - eb - .selectFrom('user') - .selectAll('user') - .whereRef('user.id', '=', 'album.ownerId') - .where('user.deletedAt', 'is', null) - .as('owner'), - (join) => join.onTrue(), - ) + .innerJoinLateral(withAlbumOwner, (join) => join.onTrue()) .select((eb) => eb.fn .coalesce( @@ -104,17 +103,6 @@ export class SharedLinkRepository { .as('album'), (join) => join.onTrue(), ) - .select((eb) => - eb.fn - .coalesce(eb.fn.jsonAgg('a').filterWhere('a.id', 'is not', null), sql`'[]'`) - .$castTo< - (ShallowDehydrateObject> & { - exifInfo: ShallowDehydrateObject>; - })[] - >() - .as('assets'), - ) - .groupBy(['shared_link.id', sql`"album".*`]) .select((eb) => eb.fn.toJson(eb.table('album')).$castTo | null>().as('album')) .where('shared_link.id', '=', id) .where('shared_link.userId', '=', userId) @@ -128,53 +116,13 @@ export class SharedLinkRepository { return this.db .selectFrom('shared_link') .selectAll('shared_link') + .select((eb) => jsonArrayFrom(withSharedAssets(eb).limit(1)).as('assets')) .where('shared_link.userId', '=', userId) - .select((eb) => - jsonArrayFrom( - eb - .selectFrom('shared_link_asset') - .whereRef('shared_link.id', '=', 'shared_link_asset.sharedLinkId') - .innerJoin('asset', 'asset.id', 'shared_link_asset.assetId') - .where('asset.deletedAt', 'is', null) - .selectAll('asset') - .orderBy('asset.fileCreatedAt', 'asc') - .limit(1), - ).as('assets'), - ) .leftJoinLateral( (eb) => - eb - .selectFrom('album') - .selectAll('album') - .whereRef('album.id', '=', 'shared_link.albumId') - .innerJoinLateral( - (eb) => - eb - .selectFrom('user') - .select([ - 'user.id', - 'user.email', - 'user.createdAt', - 'user.profileImagePath', - 'user.isAdmin', - 'user.shouldChangePassword', - 'user.deletedAt', - 'user.oauthId', - 'user.updatedAt', - 'user.storageLabel', - 'user.name', - 'user.quotaSizeInBytes', - 'user.quotaUsageInBytes', - 'user.status', - 'user.profileChangedAt', - ]) - .whereRef('user.id', '=', 'album.ownerId') - .where('user.deletedAt', 'is', null) - .as('owner'), - (join) => join.onTrue(), - ) + withSharedLinkAlbum(eb) + .innerJoinLateral(withAlbumOwner, (join) => join.onTrue()) .select((eb) => eb.fn.toJson('owner').as('owner')) - .where('album.deletedAt', 'is', null) .as('album'), (join) => join.onTrue(), ) @@ -283,11 +231,7 @@ export class SharedLinkRepository { .selectFrom('asset') .whereRef('asset.id', '=', 'shared_link_asset.assetId') .selectAll('asset') - .innerJoinLateral( - (eb) => - eb.selectFrom('asset_exif').whereRef('asset_exif.assetId', '=', 'asset.id').selectAll().as('exifInfo'), - (join) => join.onTrue(), - ) + .innerJoinLateral(withExifInfo, (join) => join.onTrue()) .as('assets'), (join) => join.onTrue(), ) diff --git a/server/src/repositories/sync.repository.ts b/server/src/repositories/sync.repository.ts index 91b567c537..1a48330448 100644 --- a/server/src/repositories/sync.repository.ts +++ b/server/src/repositories/sync.repository.ts @@ -489,7 +489,6 @@ class AssetFaceSync extends BaseSync { ]) .leftJoin('asset', 'asset.id', 'asset_face.assetId') .where('asset.ownerId', '=', options.userId) - .where('asset_face.isVisible', '=', true) .stream(); } } diff --git a/server/src/schema/enums.ts b/server/src/schema/enums.ts index c68f152779..f63a09c462 100644 --- a/server/src/schema/enums.ts +++ b/server/src/schema/enums.ts @@ -1,5 +1,5 @@ import { registerEnum } from '@immich/sql-tools'; -import { AssetStatus, AssetVisibility, SourceType } from 'src/enum'; +import { AssetStatus, AssetVisibility, ChecksumAlgorithm, SourceType } from 'src/enum'; export const assets_status_enum = registerEnum({ name: 'assets_status_enum', @@ -15,3 +15,8 @@ export const asset_visibility_enum = registerEnum({ name: 'asset_visibility_enum', values: Object.values(AssetVisibility), }); + +export const asset_checksum_algorithm_enum = registerEnum({ + name: 'asset_checksum_algorithm_enum', + values: Object.values(ChecksumAlgorithm), +}); diff --git a/server/src/schema/migrations/1774393726320-AssetFaceSyncReset.ts b/server/src/schema/migrations/1774393726320-AssetFaceSyncReset.ts new file mode 100644 index 0000000000..8dcd238bc0 --- /dev/null +++ b/server/src/schema/migrations/1774393726320-AssetFaceSyncReset.ts @@ -0,0 +1,10 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + // Sync query for faces was incorrect on server <=2.6.2 + await sql`DELETE FROM session_sync_checkpoint WHERE type in ('AssetFaceV1', 'AssetFaceV2')`.execute(db); +} + +export async function down(): Promise { + // Not implemented +} diff --git a/server/src/schema/migrations/1774548649115-AddChecksumAlgorithm.ts.ts b/server/src/schema/migrations/1774548649115-AddChecksumAlgorithm.ts.ts new file mode 100644 index 0000000000..477e7d0e48 --- /dev/null +++ b/server/src/schema/migrations/1774548649115-AddChecksumAlgorithm.ts.ts @@ -0,0 +1,21 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`CREATE TYPE "asset_checksum_algorithm_enum" AS ENUM ('sha1','sha1-path');`.execute(db); + await sql`ALTER TABLE "asset" ADD "checksumAlgorithm" asset_checksum_algorithm_enum;`.execute(db); + + await sql` + UPDATE "asset" + SET "checksumAlgorithm" = CASE + WHEN "isExternal" = true THEN 'sha1-path'::asset_checksum_algorithm_enum + ELSE 'sha1'::asset_checksum_algorithm_enum + END + `.execute(db); + + await sql`ALTER TABLE "asset" ALTER COLUMN "checksumAlgorithm" SET NOT NULL;`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`ALTER TABLE "asset" DROP COLUMN "checksumAlgorithm";`.execute(db); + await sql`DROP TYPE "asset_checksum_algorithm_enum";`.execute(db); +} diff --git a/server/src/schema/migrations/1775165531374-AddPersonNameTrigramIndex.ts b/server/src/schema/migrations/1775165531374-AddPersonNameTrigramIndex.ts new file mode 100644 index 0000000000..58d83be70b --- /dev/null +++ b/server/src/schema/migrations/1775165531374-AddPersonNameTrigramIndex.ts @@ -0,0 +1,11 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`CREATE INDEX "idx_person_name_trigram" ON "person" USING gin (f_unaccent("name") gin_trgm_ops);`.execute(db); + await sql`INSERT INTO "migration_overrides" ("name", "value") VALUES ('index_idx_person_name_trigram', '{"type":"index","name":"idx_person_name_trigram","sql":"CREATE INDEX \\"idx_person_name_trigram\\" ON \\"person\\" USING gin (f_unaccent(\\"name\\") gin_trgm_ops);"}'::jsonb);`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`DROP INDEX "idx_person_name_trigram";`.execute(db); + await sql`DELETE FROM "migration_overrides" WHERE "name" = 'index_idx_person_name_trigram';`.execute(db); +} diff --git a/server/src/schema/tables/asset.table.ts b/server/src/schema/tables/asset.table.ts index 8bdaa59bc6..7418dab102 100644 --- a/server/src/schema/tables/asset.table.ts +++ b/server/src/schema/tables/asset.table.ts @@ -12,8 +12,8 @@ import { UpdateDateColumn, } from '@immich/sql-tools'; import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators'; -import { AssetStatus, AssetType, AssetVisibility } from 'src/enum'; -import { asset_visibility_enum, assets_status_enum } from 'src/schema/enums'; +import { AssetStatus, AssetType, AssetVisibility, ChecksumAlgorithm } from 'src/enum'; +import { asset_checksum_algorithm_enum, asset_visibility_enum, assets_status_enum } from 'src/schema/enums'; import { asset_delete_audit } from 'src/schema/functions'; import { LibraryTable } from 'src/schema/tables/library.table'; import { StackTable } from 'src/schema/tables/stack.table'; @@ -95,6 +95,9 @@ export class AssetTable { @Column({ type: 'bytea', index: true }) checksum!: Buffer; // sha1 checksum + @Column({ enum: asset_checksum_algorithm_enum }) + checksumAlgorithm!: ChecksumAlgorithm; + @ForeignKeyColumn(() => AssetTable, { nullable: true, onUpdate: 'CASCADE', onDelete: 'SET NULL' }) livePhotoVideoId!: string | null; diff --git a/server/src/schema/tables/person.table.ts b/server/src/schema/tables/person.table.ts index 02fb85b757..35447acfd0 100644 --- a/server/src/schema/tables/person.table.ts +++ b/server/src/schema/tables/person.table.ts @@ -5,6 +5,7 @@ import { CreateDateColumn, ForeignKeyColumn, Generated, + Index, PrimaryGeneratedColumn, Table, Timestamp, @@ -16,6 +17,11 @@ import { AssetFaceTable } from 'src/schema/tables/asset-face.table'; import { UserTable } from 'src/schema/tables/user.table'; @Table('person') +@Index({ + name: 'idx_person_name_trigram', + using: 'gin', + expression: 'f_unaccent("name") gin_trgm_ops', +}) @UpdatedAtTrigger('person_updatedAt') @AfterDeleteTrigger({ scope: 'statement', diff --git a/server/src/services/api.service.spec.ts b/server/src/services/api.service.spec.ts new file mode 100644 index 0000000000..1152b89981 --- /dev/null +++ b/server/src/services/api.service.spec.ts @@ -0,0 +1,36 @@ +import { ApiService, render } from 'src/services/api.service'; + +describe(ApiService.name, () => { + describe('render', () => { + it('should correctly render open graph tags', () => { + const output = render('', { + title: 'title', + description: 'description', + imageUrl: 'https://demo.immich.app/api/assets/123', + }); + expect(output).toContain(''); + expect(output).toContain(''); + expect(output).toContain(''); + }); + + it('should escape html tags', () => { + expect( + render('', { + title: "Test", + description: 'description', + }), + ).toContain( + '', + ); + }); + + it('should escape quotes', () => { + expect( + render('', { + title: `0;url=https://example.com" http-equiv="refresh`, + description: 'description', + }), + ).toContain(''); + }); + }); +}); diff --git a/server/src/services/api.service.ts b/server/src/services/api.service.ts index 1071c75fc7..c8e6b39b21 100644 --- a/server/src/services/api.service.ts +++ b/server/src/services/api.service.ts @@ -1,19 +1,16 @@ import { Injectable, NotAcceptableException } from '@nestjs/common'; -import { Interval } from '@nestjs/schedule'; import { NextFunction, Request, Response } from 'express'; +import { escape } from 'lodash'; import { readFileSync } from 'node:fs'; -import sanitizeHtml from 'sanitize-html'; -import { ONE_HOUR } from 'src/constants'; import { ConfigRepository } from 'src/repositories/config.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { AuthService } from 'src/services/auth.service'; import { SharedLinkService } from 'src/services/shared-link.service'; -import { VersionService } from 'src/services/version.service'; import { OpenGraphTags } from 'src/utils/misc'; export const render = (index: string, meta: OpenGraphTags) => { const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) => - item ? sanitizeHtml(item, { allowedTags: [] }) : '', + item ? escape(item) : '', ); const tags = ` @@ -40,18 +37,12 @@ export class ApiService { constructor( private authService: AuthService, private sharedLinkService: SharedLinkService, - private versionService: VersionService, private configRepository: ConfigRepository, private logger: LoggingRepository, ) { this.logger.setContext(ApiService.name); } - @Interval(ONE_HOUR.as('milliseconds')) - async onVersionCheck() { - await this.versionService.handleQueueVersionCheck(); - } - ssr(excludePaths: string[]) { const { resourcePaths } = this.configRepository.getEnv(); diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index 1bf8bafdf7..3dba0c6d34 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -111,6 +111,7 @@ const validVideos = [ '.mpg', '.mts', '.mxf', + '.ts', '.vob', '.webm', '.wmv', @@ -691,6 +692,24 @@ describe(AssetMediaService.name, () => { ); expect(mocks.asset.getForThumbnail).toHaveBeenCalledWith(asset.id, AssetFileType.Thumbnail, true); }); + + it('should not include original filename if requested using a shared link with showExif false', async () => { + const asset = AssetFactory.from().file({ type: AssetFileType.Preview }).build(); + + mocks.access.asset.checkSharedLinkAccess.mockResolvedValue(new Set([asset.id])); + mocks.asset.getForThumbnail.mockResolvedValue({ ...asset, path: asset.files[0].path }); + + const auth = AuthFactory.from().sharedLink({ showExif: false }).build(); + + await expect(sut.viewThumbnail(auth, asset.id, { size: AssetMediaSize.PREVIEW })).resolves.toEqual( + new ImmichFileResponse({ + path: asset.files[0].path, + cacheControl: CacheControl.PrivateWithCache, + contentType: 'image/jpeg', + fileName: `${asset.id}_preview.jpg`, + }), + ); + }); }); describe('playbackVideo', () => { diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 10132bbb07..ddb6f412c5 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -27,6 +27,7 @@ import { AssetStatus, AssetVisibility, CacheControl, + ChecksumAlgorithm, JobName, Permission, StorageFolder, @@ -256,7 +257,9 @@ export class AssetMediaService extends BaseService { throw new NotFoundException('Asset media not found'); } - const fileName = `${getFileNameWithoutExtension(originalFileName)}_${size}${getFilenameExtension(path)}`; + const fileNameBase = + auth.sharedLink && !auth.sharedLink.showExif ? id : getFileNameWithoutExtension(originalFileName); + const fileName = `${fileNameBase}_${size}${getFilenameExtension(path)}`; return new ImmichFileResponse({ fileName, @@ -356,6 +359,7 @@ export class AssetMediaService extends BaseService { await this.addToSharedLink(auth.sharedLink, duplicateId); } + this.logger.debug(`Duplicate asset upload rejected: existing asset ${duplicateId}`); return { status: AssetMediaStatus.DUPLICATE, id: duplicateId }; } @@ -424,6 +428,7 @@ export class AssetMediaService extends BaseService { deviceId: asset.deviceId, type: asset.type, checksum: asset.checksum, + checksumAlgorithm: asset.checksumAlgorithm, fileCreatedAt: asset.fileCreatedAt, localDateTime: asset.localDateTime, fileModifiedAt: asset.fileModifiedAt, @@ -445,6 +450,7 @@ export class AssetMediaService extends BaseService { libraryId: null, checksum: file.checksum, + checksumAlgorithm: ChecksumAlgorithm.sha1File, originalPath: file.originalPath, deviceAssetId: dto.deviceAssetId, diff --git a/server/src/services/database-backup.service.spec.ts b/server/src/services/database-backup.service.spec.ts index 429e60aede..37964e7b6f 100644 --- a/server/src/services/database-backup.service.spec.ts +++ b/server/src/services/database-backup.service.spec.ts @@ -27,6 +27,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, maintenanceHealthRepositoryMock as never, @@ -187,6 +188,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, void 0 as never, @@ -400,6 +402,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, void 0 as never, @@ -474,6 +477,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, void 0 as never, @@ -536,6 +540,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, void 0 as never, @@ -663,6 +668,7 @@ describe(DatabaseBackupService.name, () => { mocks.systemMetadata as never, mocks.process, mocks.database as never, + mocks.user as never, mocks.cron as never, mocks.job as never, maintenanceHealthRepositoryMock, @@ -678,6 +684,8 @@ describe(DatabaseBackupService.name, () => { it('should successfully restore a backup', async () => { let writtenToPsql = ''; + mocks.user.hasAdmin.mockResolvedValue(true); + mocks.process.spawnDuplexStream.mockImplementationOnce(() => mockDuplex()('command', 0, 'data', '')); mocks.process.spawnDuplexStream.mockImplementationOnce(() => mockDuplex()('command', 0, 'data', '')); mocks.process.spawnDuplexStream.mockImplementationOnce(() => { @@ -740,6 +748,8 @@ describe(DatabaseBackupService.name, () => { it('should generate pg_dumpall specific SQL instructions', async () => { let writtenToPsql = ''; + mocks.user.hasAdmin.mockResolvedValue(true); + mocks.process.spawnDuplexStream.mockImplementationOnce(() => mockDuplex()('command', 0, 'data', '')); mocks.process.spawnDuplexStream.mockImplementationOnce(() => mockDuplex()('command', 0, 'data', '')); mocks.process.spawnDuplexStream.mockImplementationOnce(() => { @@ -834,7 +844,24 @@ describe(DatabaseBackupService.name, () => { expect(mocks.process.spawnDuplexStream).toHaveBeenCalledTimes(4); }); + it('should rollback if there is no admin user', async () => { + mocks.user.hasAdmin.mockResolvedValue(false); + + const progress = vitest.fn(); + await expect( + sut.restoreDatabaseBackup('development-filename.sql', progress), + ).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Server health check failed, no admin exists.]`); + + expect(progress).toHaveBeenCalledWith('backup', 0.05); + expect(progress).toHaveBeenCalledWith('migrations', 0.9); + expect(progress).toHaveBeenCalledWith('rollback', 0); + + expect(mocks.user.hasAdmin).toHaveBeenCalled(); + expect(mocks.process.spawnDuplexStream).toHaveBeenCalledTimes(4); + }); + it('should rollback if API healthcheck fails', async () => { + mocks.user.hasAdmin.mockResolvedValue(true); maintenanceHealthRepositoryMock.checkApiHealth.mockRejectedValue(new Error('Health Error')); const progress = vitest.fn(); @@ -846,6 +873,7 @@ describe(DatabaseBackupService.name, () => { expect(progress).toHaveBeenCalledWith('migrations', 0.9); expect(progress).toHaveBeenCalledWith('rollback', 0); + expect(mocks.user.hasAdmin).toHaveBeenCalled(); expect(maintenanceHealthRepositoryMock.checkApiHealth).toHaveBeenCalled(); expect(mocks.process.spawnDuplexStream).toHaveBeenCalledTimes(4); }); diff --git a/server/src/services/database-backup.service.ts b/server/src/services/database-backup.service.ts index 3c964c950c..6afc46c7da 100644 --- a/server/src/services/database-backup.service.ts +++ b/server/src/services/database-backup.service.ts @@ -20,6 +20,7 @@ import { LoggingRepository } from 'src/repositories/logging.repository'; import { ProcessRepository } from 'src/repositories/process.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; +import { UserRepository } from 'src/repositories/user.repository'; import { getConfig } from 'src/utils/config'; import { findDatabaseBackupVersion, @@ -40,6 +41,7 @@ export class DatabaseBackupService { private readonly systemMetadataRepository: SystemMetadataRepository, private readonly processRepository: ProcessRepository, private readonly databaseRepository: DatabaseRepository, + private readonly userRepository: UserRepository, @Optional() private readonly cronRepository: CronRepository, @Optional() @@ -281,6 +283,7 @@ export class DatabaseBackupService { async listBackups(): Promise { const backupsFolder = StorageCore.getBaseFolder(StorageFolder.Backups); const files = await this.storageRepository.readdir(backupsFolder); + const timezone = DateTime.local().zoneName; const validFiles = files .filter((fn) => isValidDatabaseBackupName(fn)) @@ -290,7 +293,7 @@ export class DatabaseBackupService { const backups = await Promise.all( validFiles.map(async (filename) => { const stats = await this.storageRepository.stat(path.join(backupsFolder, filename)); - return { filename, filesize: stats.size }; + return { filename, filesize: stats.size, timezone }; }), ); @@ -405,7 +408,14 @@ export class DatabaseBackupService { try { progressCb?.('migrations', 0.9); + await this.databaseRepository.runMigrations(); + + const hasAdmin = await this.userRepository.hasAdmin(); + if (!hasAdmin) { + throw new Error('Server health check failed, no admin exists.'); + } + await this.maintenanceHealthRepository.checkApiHealth(); } catch (error) { progressCb?.('rollback', 0); diff --git a/server/src/services/duplicate.service.spec.ts b/server/src/services/duplicate.service.spec.ts index 38c6833105..564cffa0bc 100644 --- a/server/src/services/duplicate.service.spec.ts +++ b/server/src/services/duplicate.service.spec.ts @@ -1,12 +1,13 @@ +import { BulkIdErrorReason } from 'src/dtos/asset-ids.response.dto'; +import { MapAsset } from 'src/dtos/asset-response.dto'; import { AssetType, AssetVisibility, JobName, JobStatus } from 'src/enum'; import { DuplicateService } from 'src/services/duplicate.service'; -import { SearchService } from 'src/services/search.service'; import { AssetFactory } from 'test/factories/asset.factory'; import { authStub } from 'test/fixtures/auth.stub'; import { getForDuplicate } from 'test/mappers'; import { newUuid } from 'test/small.factory'; import { makeStream, newTestService, ServiceMocks } from 'test/utils'; -import { beforeEach, vitest } from 'vitest'; +import { beforeEach, describe, expect, it, vitest } from 'vitest'; vitest.useFakeTimers(); @@ -26,7 +27,7 @@ const hasDupe = { duplicateId: 'duplicate-id', }; -describe(SearchService.name, () => { +describe(DuplicateService.name, () => { let sut: DuplicateService; let mocks: ServiceMocks; @@ -41,6 +42,8 @@ describe(SearchService.name, () => { describe('getDuplicates', () => { it('should get duplicates', async () => { const asset = AssetFactory.from().exif().build(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['duplicate-id'])); + mocks.duplicateRepository.cleanupSingletonGroups.mockResolvedValue(); mocks.duplicateRepository.getAll.mockResolvedValue([ { duplicateId: 'duplicate-id', @@ -51,9 +54,24 @@ describe(SearchService.name, () => { { duplicateId: 'duplicate-id', assets: [expect.objectContaining({ id: asset.id }), expect.objectContaining({ id: asset.id })], + suggestedKeepAssetIds: [asset.id], }, ]); }); + + it('should return suggestedKeepAssetIds based on file size', async () => { + const smallAsset = AssetFactory.from().exif({ fileSizeInByte: 1000 }).build(); + const largeAsset = AssetFactory.from().exif({ fileSizeInByte: 5000 }).build(); + mocks.duplicateRepository.cleanupSingletonGroups.mockResolvedValue(); + mocks.duplicateRepository.getAll.mockResolvedValue([ + { + duplicateId: 'duplicate-id', + assets: [getForDuplicate(smallAsset), getForDuplicate(largeAsset)], + }, + ]); + const result = await sut.getDuplicates(authStub.admin); + expect(result[0].suggestedKeepAssetIds).toEqual([largeAsset.id]); + }); }); describe('handleQueueSearchDuplicates', () => { @@ -131,6 +149,200 @@ describe(SearchService.name, () => { }); }); + describe('resolve', () => { + it('should handle mixed success and failure', async () => { + const asset = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1', 'group-2'])); + mocks.duplicateRepository.get.mockResolvedValueOnce(void 0); + mocks.duplicateRepository.get.mockResolvedValueOnce({ + duplicateId: 'group-2', + assets: [asset as unknown as MapAsset], + }); + + await expect( + sut.resolve(authStub.admin, { + groups: [ + { duplicateId: 'group-1', keepAssetIds: [], trashAssetIds: [] }, + { duplicateId: 'group-2', keepAssetIds: [asset.id], trashAssetIds: [] }, + ], + }), + ).resolves.toEqual([ + { id: 'group-1', success: false, error: BulkIdErrorReason.NOT_FOUND }, + { id: 'group-2', success: true }, + ]); + }); + + it('should catch and report errors', async () => { + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockRejectedValue(new Error('Database error')); + + await expect( + sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [], trashAssetIds: [] }], + }), + ).resolves.toEqual([{ id: 'group-1', success: false, error: BulkIdErrorReason.UNKNOWN }]); + }); + }); + + describe('resolveGroup (via resolve)', () => { + it('should fail if duplicate group not found', async () => { + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['missing-id'])); + mocks.duplicateRepository.get.mockResolvedValue(void 0); + + await expect( + sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'missing-id', keepAssetIds: [], trashAssetIds: [] }], + }), + ).resolves.toEqual([ + { + id: 'missing-id', + success: false, + error: BulkIdErrorReason.NOT_FOUND, + }, + ]); + }); + + it('should skip when keepAssetIds contains non-member', async () => { + const asset = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [asset as unknown as MapAsset], + }); + + await expect( + sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: ['asset-999', asset.id], trashAssetIds: [] }], + }), + ).resolves.toEqual([{ id: 'group-1', success: true }]); + }); + + it('should skip when trashAssetIds contains non-member', async () => { + const asset = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [asset as unknown as MapAsset], + }); + + await expect( + sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [asset.id], trashAssetIds: ['asset-999'] }], + }), + ).resolves.toEqual([{ id: 'group-1', success: true }]); + }); + + it('should fail if keepAssetIds and trashAssetIds overlap', async () => { + const asset1 = AssetFactory.create(); + const asset2 = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [asset1 as unknown as MapAsset, asset2 as unknown as MapAsset], + }); + + const result = await sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [asset1.id], trashAssetIds: [asset1.id] }], + }); + + expect(result[0].success).toBe(false); + expect(result[0].errorMessage).toContain('An asset cannot be in both keepAssetIds and trashAssetIds'); + }); + + it('should fail if keepAssetIds and trashAssetIds do not cover all assets', async () => { + const asset1 = AssetFactory.create(); + const asset2 = AssetFactory.create(); + const asset3 = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [asset1 as unknown as MapAsset, asset2 as unknown as MapAsset, asset3 as unknown as MapAsset], + }); + + const result = await sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(result[0].success).toBe(false); + expect(result[0].errorMessage).toContain('Every asset must be in either keepAssetIds or trashAssetIds'); + }); + + it('should fail if partial trash without keepers', async () => { + const asset1 = AssetFactory.create(); + const asset2 = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [asset1 as unknown as MapAsset, asset2 as unknown as MapAsset], + }); + + const result = await sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [], trashAssetIds: [asset1.id] }], + }); + + expect(result[0].success).toBe(false); + expect(result[0].errorMessage).toContain('Every asset must be in either keepAssetIds or trashAssetIds'); + }); + + it('should sync merged tags to asset_exif.tags', async () => { + const asset1 = AssetFactory.create(); + const asset2 = AssetFactory.create(); + mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1'])); + mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-2'])); + mocks.access.tag.checkOwnerAccess.mockResolvedValue(new Set(['tag-1', 'tag-2'])); + mocks.duplicateRepository.get.mockResolvedValue({ + duplicateId: 'group-1', + assets: [ + { + ...asset1, + tags: [ + { + id: 'tag-1', + value: 'Work', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + parentId: null, + color: null, + }, + ], + }, + { + ...asset2, + tags: [ + { + id: 'tag-2', + value: 'Travel', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + parentId: null, + color: null, + }, + ], + }, + ] as any, + }); + + const result = await sut.resolve(authStub.admin, { + groups: [{ duplicateId: 'group-1', keepAssetIds: [asset1.id], trashAssetIds: [asset2.id] }], + }); + + expect(result[0].success).toBe(true); + + // Verify tags were applied to tag_asset table + expect(mocks.tag.replaceAssetTags).toHaveBeenCalledWith(asset1.id, ['tag-1', 'tag-2']); + + // Verify merged tag values were written to asset_exif.tags so SidecarWrite preserves them + expect(mocks.asset.updateAllExif).toHaveBeenCalledWith([asset1.id], { tags: ['Work', 'Travel'] }); + + // Verify SidecarWrite was queued (to write tags to sidecar) + expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.SidecarWrite, data: { id: asset1.id } }]); + }); + + // NOTE: The following integration-style tests are covered by E2E tests instead + // to avoid complex mock setup. The validation and error-handling logic above + // is thoroughly unit tested. + }); + describe('handleSearchDuplicates', () => { beforeEach(() => { mocks.systemMetadata.get.mockResolvedValue({ diff --git a/server/src/services/duplicate.service.ts b/server/src/services/duplicate.service.ts index 618754ff74..39123e031c 100644 --- a/server/src/services/duplicate.service.ts +++ b/server/src/services/duplicate.service.ts @@ -1,24 +1,84 @@ import { Injectable } from '@nestjs/common'; import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants'; import { OnJob } from 'src/decorators'; -import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; -import { mapAsset } from 'src/dtos/asset-response.dto'; +import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; +import { MapAsset, mapAsset } from 'src/dtos/asset-response.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { DuplicateResponseDto } from 'src/dtos/duplicate.dto'; -import { AssetVisibility, JobName, JobStatus, QueueName } from 'src/enum'; +import { DuplicateResolveDto, DuplicateResolveGroupDto, DuplicateResponseDto } from 'src/dtos/duplicate.dto'; +import { AssetStatus, AssetVisibility, JobName, JobStatus, Permission, QueueName } from 'src/enum'; import { AssetDuplicateResult } from 'src/repositories/search.repository'; import { BaseService } from 'src/services/base.service'; import { JobItem, JobOf } from 'src/types'; +import { suggestDuplicateKeepAssetIds } from 'src/utils/duplicate'; import { isDuplicateDetectionEnabled } from 'src/utils/misc'; +type ResolveRequest = { + assetUpdate: { + isFavorite?: boolean; + visibility?: AssetVisibility; + }; + + exifUpdate: { + rating?: number; + latitude?: number; + longitude?: number; + description?: string; + }; + + mergedAlbumIds: string[]; + + mergedTagIds: string[]; + + mergedTagValues: string[]; +}; + +const uniqueNonEmptyLines = (values: Array): string[] => { + const unique = new Set(); + const lines: string[] = []; + for (const value of values) { + if (!value) { + continue; + } + for (const line of value.split(/\r?\n/)) { + const trimmed = line.trim(); + if (!trimmed || unique.has(trimmed)) { + continue; + } + unique.add(trimmed); + lines.push(trimmed); + } + } + return lines; +}; + +const getUniqueCoordinate = (assets: MapAsset[], key: 'latitude' | 'longitude'): number | null => { + const values = assets + .map((asset) => asset.exifInfo?.[key]) + .filter((value): value is number => Number.isFinite(value)); + + if (values.length === 0) { + return null; + } + + const unique = new Set(values); + return unique.size === 1 ? [...unique][0] : null; +}; + @Injectable() export class DuplicateService extends BaseService { async getDuplicates(auth: AuthDto): Promise { + // Clean up singleton groups (assets that are the only member of their duplicate group) + await this.duplicateRepository.cleanupSingletonGroups(auth.user.id); + const duplicates = await this.duplicateRepository.getAll(auth.user.id); - return duplicates.map(({ duplicateId, assets }) => ({ - duplicateId, - assets: assets.map((asset) => mapAsset(asset, { auth })), - })); + return duplicates.map(({ duplicateId, assets }) => { + const mappedAssets = assets.map((asset) => mapAsset(asset, { auth })); + return { + duplicateId, + assets: mappedAssets, + suggestedKeepAssetIds: suggestDuplicateKeepAssetIds(mappedAssets), + }; + }); } async delete(auth: AuthDto, id: string): Promise { @@ -29,6 +89,213 @@ export class DuplicateService extends BaseService { await this.duplicateRepository.deleteAll(auth.user.id, dto.ids); } + async resolve(auth: AuthDto, dto: DuplicateResolveDto) { + const duplicateIds = dto.groups.map(({ duplicateId }) => duplicateId); + + await this.requireAccess({ auth, permission: Permission.DuplicateDelete, ids: duplicateIds }); + + const results: BulkIdResponseDto[] = []; + + for (const group of dto.groups) { + try { + results.push(await this.resolveGroup(auth, group)); + } catch (error: Error | any) { + this.logger.error(`Error resolving duplicate group ${group.duplicateId}: ${error}`, error?.stack); + results.push({ id: group.duplicateId, success: false, error: BulkIdErrorReason.UNKNOWN }); + } + } + + return results; + } + + private async resolveGroup(auth: AuthDto, group: DuplicateResolveGroupDto): Promise { + const { duplicateId, keepAssetIds, trashAssetIds } = group; + + const duplicateGroup = await this.duplicateRepository.get(duplicateId); + if (!duplicateGroup) { + return { id: duplicateId, success: false, error: BulkIdErrorReason.NOT_FOUND }; + } + + const groupAssetIds = new Set(duplicateGroup.assets.map((a) => a.id)); + + // ignore/skip asset IDs not in the group + const idsToKeep = keepAssetIds.filter((id) => groupAssetIds.has(id)); + const idsToTrash = trashAssetIds.filter((id) => groupAssetIds.has(id)); + + for (const assetId of groupAssetIds) { + if (idsToKeep.includes(assetId) && idsToTrash.includes(assetId)) { + return { + id: duplicateId, + success: false, + error: BulkIdErrorReason.VALIDATION, + errorMessage: 'An asset cannot be in both keepAssetIds and trashAssetIds', + }; + } + + if (!idsToKeep.includes(assetId) && !idsToTrash.includes(assetId)) { + return { + id: duplicateId, + success: false, + error: BulkIdErrorReason.VALIDATION, + errorMessage: 'Every asset must be in either keepAssetIds or trashAssetIds', + }; + } + } + + if (idsToTrash.length > 0) { + const ids = await this.checkAccess({ auth, permission: Permission.AssetDelete, ids: idsToTrash }); + if (ids.size !== idsToTrash.length) { + return { + id: duplicateId, + success: false, + error: BulkIdErrorReason.NO_PERMISSION, + errorMessage: 'No permission to delete assets', + }; + } + } + + const assetAlbumMap = await this.albumRepository.getByAssetIds(auth.user.id, [...groupAssetIds]); + + const { assetUpdate, exifUpdate, mergedAlbumIds, mergedTagIds, mergedTagValues } = this.getSyncMergeResult( + duplicateGroup.assets, + assetAlbumMap, + ); + + if (mergedAlbumIds.length > 0) { + const allowedAlbumIds = await this.checkAccess({ + auth, + permission: Permission.AlbumAssetCreate, + ids: mergedAlbumIds, + }); + + const allowedShareIds = await this.checkAccess({ + auth, + permission: Permission.AssetShare, + ids: idsToKeep, + }); + + if (allowedAlbumIds.size > 0 && allowedShareIds.size > 0) { + await this.albumRepository.addAssetIdsToAlbums( + [...allowedAlbumIds].flatMap((albumId) => [...allowedShareIds].map((assetId) => ({ albumId, assetId }))), + ); + } + } + + if (mergedTagIds.length > 0) { + const allowedTagIds = await this.checkAccess({ + auth, + permission: Permission.TagAsset, + ids: mergedTagIds, + }); + + if (allowedTagIds.size > 0) { + // Replace tags for each keeper asset to ensure all merged tags are applied + await Promise.all(idsToKeep.map((assetId) => this.tagRepository.replaceAssetTags(assetId, [...allowedTagIds]))); + + // Update asset_exif.tags so the subsequent SidecarWrite + MetadataExtraction + // cycle preserves the merged tags (updateAllExif locks the property automatically) + await this.assetRepository.updateAllExif(idsToKeep, { tags: mergedTagValues }); + } + } + + if (idsToKeep.length > 0) { + const hasExifUpdate = Object.keys(exifUpdate).length > 0; + const hasTagUpdate = mergedTagIds.length > 0; + + if (hasExifUpdate) { + await this.assetRepository.updateAllExif(idsToKeep, exifUpdate); + } + + if (hasExifUpdate || hasTagUpdate) { + await this.jobRepository.queueAll(idsToKeep.map((id) => ({ name: JobName.SidecarWrite, data: { id } }))); + } + + await this.assetRepository.updateAll(idsToKeep, { duplicateId: null, ...assetUpdate }); + } + + if (idsToTrash.length > 0) { + // TODO: this is duplicated with AssetService.deleteAssets + const { trash } = await this.getConfig({ withCache: true }); + const force = !trash.enabled; + + await this.assetRepository.updateAll(idsToTrash, { + deletedAt: new Date(), + status: force ? AssetStatus.Deleted : AssetStatus.Trashed, + duplicateId: null, + }); + + await this.eventRepository.emit(force ? 'AssetDeleteAll' : 'AssetTrashAll', { + assetIds: idsToTrash, + userId: auth.user.id, + }); + } + + return { id: duplicateId, success: true }; + } + + private getSyncMergeResult(assets: MapAsset[], assetAlbumMap: Map = new Map()): ResolveRequest { + const response: ResolveRequest = { + mergedAlbumIds: [], + mergedTagIds: [], + mergedTagValues: [], + assetUpdate: {}, + exifUpdate: {}, + }; + + response.assetUpdate.isFavorite = assets.some((asset) => asset.isFavorite); + + const visibilityOrder = [AssetVisibility.Locked, AssetVisibility.Archive, AssetVisibility.Timeline]; + let visibility = visibilityOrder.find((level) => assets.some((asset) => asset.visibility === level)); + if (!visibility && assets.some((asset) => asset.visibility === AssetVisibility.Hidden)) { + visibility = AssetVisibility.Hidden; + } + if (visibility) { + response.assetUpdate.visibility = visibility; + } + + let rating = 0; + for (const asset of assets) { + const assetRating = asset.exifInfo?.rating ?? 0; + if (assetRating > rating) { + rating = assetRating; + } + } + if (rating > 0) { + response.exifUpdate.rating = rating; + } + + const descriptionLines = uniqueNonEmptyLines(assets.map((asset) => asset.exifInfo?.description)); + const description = descriptionLines.length > 0 ? descriptionLines.join('\n') : null; + if (description !== null) { + response.exifUpdate.description = description; + } + + const latitude = getUniqueCoordinate(assets, 'latitude'); + const longitude = getUniqueCoordinate(assets, 'longitude'); + if (latitude !== null && longitude !== null) { + response.exifUpdate.latitude = latitude; + response.exifUpdate.longitude = longitude; + } + + const albumIdSet = new Set(); + for (const [, albumIds] of assetAlbumMap) { + for (const albumId of albumIds) { + albumIdSet.add(albumId); + } + } + response.mergedAlbumIds = [...albumIdSet]; + + const allTags = assets.flatMap((asset) => asset.tags ?? []); + const tagIds = [...new Set(allTags.map((tag) => tag.id).filter((id): id is string => !!id))]; + const tagValues = [...new Set(allTags.map((tag) => tag.value).filter((v): v is string => !!v))]; + if (tagIds.length > 0) { + response.mergedTagIds = tagIds; + response.mergedTagValues = tagValues; + } + + return response; + } + @OnJob({ name: JobName.AssetDetectDuplicatesQueueAll, queue: QueueName.DuplicateDetection }) async handleQueueSearchDuplicates({ force }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: false }); diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index d0c2d0a785..9a2ec00815 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -560,7 +560,7 @@ describe(LibraryService.name, () => { paths: ['/data/user1/photo.jpg'], }; - mocks.asset.createAll.mockResolvedValue([asset]); + mocks.asset.createAll.mockResolvedValue([asset.id]); mocks.library.get.mockResolvedValue(library); await expect(sut.handleSyncFiles(mockLibraryJob)).resolves.toBe(JobStatus.Success); diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 841fa4743c..ce3c9ee662 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -17,7 +17,17 @@ import { ValidateLibraryImportPathResponseDto, ValidateLibraryResponseDto, } from 'src/dtos/library.dto'; -import { AssetStatus, AssetType, CronJob, DatabaseLock, ImmichWorker, JobName, JobStatus, QueueName } from 'src/enum'; +import { + AssetStatus, + AssetType, + ChecksumAlgorithm, + CronJob, + DatabaseLock, + ImmichWorker, + JobName, + JobStatus, + QueueName, +} from 'src/enum'; import { ArgOf } from 'src/repositories/event.repository'; import { AssetSyncResult } from 'src/repositories/library.repository'; import { AssetTable } from 'src/schema/tables/asset.table'; @@ -256,13 +266,7 @@ export class LibraryService extends BaseService { ), ); - const assetIds: string[] = []; - - for (let i = 0; i < assetImports.length; i += 5000) { - // Chunk the imports to avoid the postgres limit of max parameters at once - const chunk = assetImports.slice(i, i + 5000); - await this.assetRepository.createAll(chunk).then((assets) => assetIds.push(...assets.map((asset) => asset.id))); - } + const assetIds = await this.assetRepository.createAll(assetImports); const progressMessage = job.progressCounter && job.totalAssets @@ -400,6 +404,7 @@ export class LibraryService extends BaseService { ownerId, libraryId, checksum: this.cryptoRepository.hashSha1(`path:${assetPath}`), + checksumAlgorithm: ChecksumAlgorithm.sha1Path, originalPath: assetPath, fileCreatedAt: stat.mtime, diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index ea0b1e9142..2c9325c976 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -756,7 +756,13 @@ export class MediaService extends BaseService { return false; } - const name = formatLongName === 'QuickTime / MOV' ? VideoContainer.Mov : (formatName as VideoContainer); + const formatLongNameMapping: Record = { + 'QuickTime / MOV': VideoContainer.Mov, + 'Matroska / WebM': VideoContainer.Webm, + }; + + const name = (formatLongName ? formatLongNameMapping[formatLongName] : undefined) ?? (formatName as VideoContainer); + return name !== VideoContainer.Mp4 && !ffmpegConfig.acceptedContainers.includes(name); } diff --git a/server/src/services/metadata.service.spec.ts b/server/src/services/metadata.service.spec.ts index 7cb42990ea..f9d17079e3 100644 --- a/server/src/services/metadata.service.spec.ts +++ b/server/src/services/metadata.service.spec.ts @@ -7,6 +7,7 @@ import { AssetFileType, AssetType, AssetVisibility, + ChecksumAlgorithm, ExifOrientation, ImmichWorker, JobName, @@ -652,6 +653,7 @@ describe(MetadataService.name, () => { expect(mocks.assetJob.getForMetadataExtraction).toHaveBeenCalledWith(asset.id); expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), + checksumAlgorithm: ChecksumAlgorithm.sha1File, deviceAssetId: 'NONE', deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, @@ -705,6 +707,7 @@ describe(MetadataService.name, () => { expect(mocks.assetJob.getForMetadataExtraction).toHaveBeenCalledWith(asset.id); expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), + checksumAlgorithm: ChecksumAlgorithm.sha1File, deviceAssetId: 'NONE', deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, @@ -758,6 +761,7 @@ describe(MetadataService.name, () => { expect(mocks.storage.readFile).toHaveBeenCalledWith(asset.originalPath, expect.any(Object)); expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), + checksumAlgorithm: ChecksumAlgorithm.sha1File, deviceAssetId: 'NONE', deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, @@ -1641,12 +1645,32 @@ describe(MetadataService.name, () => { ); }); - it('should not overwrite existing width/height if they already exist', async () => { - const asset = AssetFactory.create({ width: 1920, height: 1080 }); + it('should overwrite existing width/height for unedited assets', async () => { + const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: false }); mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset)); mockReadTags({ ImageWidth: 1280, ImageHeight: 720 }); await sut.handleMetadataExtraction({ id: asset.id }); + expect(mocks.asset.update).toHaveBeenCalledWith( + expect.objectContaining({ + width: 1280, + height: 720, + }), + ); + }); + + it('should not overwrite existing width/height for edited assets', async () => { + const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: true }); + mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset)); + mockReadTags({ ImageWidth: 1280, ImageHeight: 720 }); + + await sut.handleMetadataExtraction({ id: asset.id }); + expect(mocks.asset.update).toHaveBeenCalledWith( + expect.objectContaining({ + width: undefined, + height: undefined, + }), + ); expect(mocks.asset.update).not.toHaveBeenCalledWith( expect.objectContaining({ width: 1280, diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index 7b87ea06a6..c2cf66ad57 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -14,6 +14,7 @@ import { AssetFileType, AssetType, AssetVisibility, + ChecksumAlgorithm, DatabaseLock, ExifOrientation, ImmichWorker, @@ -327,10 +328,9 @@ export class MetadataService extends BaseService { fileCreatedAt: dates.dateTimeOriginal ?? undefined, fileModifiedAt: stats.mtime, - // only update the dimensions if they don't already exist - // we don't want to overwrite width/height that are modified by edits - width: asset.width == null ? assetWidth : undefined, - height: asset.height == null ? assetHeight : undefined, + // Keep unedited assets in sync with the file on disk, but don't overwrite edited dimensions. + width: !asset.isEdited || asset.width == null ? assetWidth : undefined, + height: !asset.isEdited || asset.height == null ? assetHeight : undefined, }), async () => { await this.assetRepository.upsertExif(exifData, { lockedPropertiesBehavior: 'skip' }); @@ -676,6 +676,7 @@ export class MetadataService extends BaseService { fileModifiedAt: stats.mtime, localDateTime: dates.localDateTime, checksum, + checksumAlgorithm: ChecksumAlgorithm.sha1File, ownerId: asset.ownerId, originalPath: StorageCore.getAndroidMotionPath(asset, motionAssetId), originalFileName: `${parse(asset.originalFileName).name}.mp4`, diff --git a/server/src/services/person.service.spec.ts b/server/src/services/person.service.spec.ts index 5c262d892d..8b303d04f6 100644 --- a/server/src/services/person.service.spec.ts +++ b/server/src/services/person.service.spec.ts @@ -12,7 +12,13 @@ import { PersonFactory } from 'test/factories/person.factory'; import { UserFactory } from 'test/factories/user.factory'; import { authStub } from 'test/fixtures/auth.stub'; import { systemConfigStub } from 'test/fixtures/system-config.stub'; -import { getAsDetectedFace, getForAssetFace, getForDetectedFaces, getForFacialRecognitionJob } from 'test/mappers'; +import { + getAsDetectedFace, + getForAsset, + getForAssetFace, + getForDetectedFaces, + getForFacialRecognitionJob, +} from 'test/mappers'; import { newDate, newUuid } from 'test/small.factory'; import { makeStream, newTestService, ServiceMocks } from 'test/utils'; @@ -370,6 +376,86 @@ describe(PersonService.name, () => { }); }); + describe('createFace', () => { + it('should create a manual face and initialize the person feature photo creation', async () => { + const auth = AuthFactory.create(); + const asset = AssetFactory.create(); + const person = PersonFactory.create({ faceAssetId: null }); + const featureFace = AssetFaceFactory.create({ + assetId: asset.id, + personId: person.id, + sourceType: SourceType.Manual, + }); + + mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset.id])); + mocks.access.person.checkOwnerAccess.mockResolvedValue(new Set([person.id])); + mocks.asset.getById.mockResolvedValue(getForAsset(asset)); + mocks.person.getById.mockResolvedValue(person); + mocks.person.getRandomFace.mockResolvedValue(featureFace); + mocks.person.update.mockResolvedValue({ ...person, faceAssetId: featureFace.id }); + + await expect( + sut.createFace(auth, { + assetId: asset.id, + personId: person.id, + imageHeight: 500, + imageWidth: 400, + x: 10, + y: 20, + width: 100, + height: 110, + }), + ).resolves.toBeUndefined(); + + expect(mocks.asset.getById).toHaveBeenCalledWith(asset.id, { edits: true, exifInfo: true }); + expect(mocks.person.createAssetFace).toHaveBeenCalledWith({ + assetId: asset.id, + personId: person.id, + imageHeight: 500, + imageWidth: 400, + boundingBoxX1: 10, + boundingBoxX2: 110, + boundingBoxY1: 20, + boundingBoxY2: 130, + sourceType: SourceType.Manual, + }); + expect(mocks.person.getRandomFace).toHaveBeenCalledWith(person.id); + expect(mocks.person.update).toHaveBeenCalledWith({ id: person.id, faceAssetId: featureFace.id }); + expect(mocks.job.queueAll).toHaveBeenCalledWith([ + { name: JobName.PersonGenerateThumbnail, data: { id: person.id } }, + ]); + }); + + it('should not update the person feature photo if one already exists', async () => { + const auth = AuthFactory.create(); + const asset = AssetFactory.create(); + const person = PersonFactory.create({ faceAssetId: newUuid() }); + + mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset.id])); + mocks.access.person.checkOwnerAccess.mockResolvedValue(new Set([person.id])); + mocks.asset.getById.mockResolvedValue(getForAsset(asset)); + mocks.person.getById.mockResolvedValue(person); + + await expect( + sut.createFace(auth, { + assetId: asset.id, + personId: person.id, + imageHeight: 500, + imageWidth: 400, + x: 10, + y: 20, + width: 100, + height: 110, + }), + ).resolves.toBeUndefined(); + + expect(mocks.person.createAssetFace).toHaveBeenCalledOnce(); + expect(mocks.person.getRandomFace).not.toHaveBeenCalled(); + expect(mocks.person.update).not.toHaveBeenCalled(); + expect(mocks.job.queueAll).not.toHaveBeenCalled(); + }); + }); + describe('createNewFeaturePhoto', () => { it('should change person feature photo', async () => { const person = PersonFactory.create(); diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index fb04ace4f2..fde5313f4d 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -631,7 +631,11 @@ export class PersonService extends BaseService { this.requireAccess({ auth, permission: Permission.PersonRead, ids: [dto.personId] }), ]); - const asset = await this.assetRepository.getById(dto.assetId, { edits: true, exifInfo: true }); + const [asset, person] = await Promise.all([ + this.assetRepository.getById(dto.assetId, { edits: true, exifInfo: true }), + this.findOrFail(dto.personId), + ]); + if (!asset) { throw new NotFoundException('Asset not found'); } @@ -689,6 +693,10 @@ export class PersonService extends BaseService { boundingBoxY2: Math.round(bottomRight.y), sourceType: SourceType.Manual, }); + + if (!person.faceAssetId) { + await this.createNewFeaturePhoto([person.id]); + } } async deleteFace(auth: AuthDto, id: string, dto: AssetFaceDeleteDto): Promise { diff --git a/server/src/services/version.service.spec.ts b/server/src/services/version.service.spec.ts index eacae928eb..2fbe7292fa 100644 --- a/server/src/services/version.service.spec.ts +++ b/server/src/services/version.service.spec.ts @@ -2,20 +2,14 @@ import { DateTime } from 'luxon'; import { SemVer } from 'semver'; import { defaults } from 'src/config'; import { serverVersion } from 'src/constants'; -import { ImmichEnvironment, JobName, JobStatus, SystemMetadataKey } from 'src/enum'; +import { CronJob, JobName, JobStatus, SystemMetadataKey } from 'src/enum'; import { VersionService } from 'src/services/version.service'; -import { mockEnvData } from 'test/repositories/config.repository.mock'; import { factory } from 'test/small.factory'; import { newTestService, ServiceMocks } from 'test/utils'; -const mockRelease = (version: string) => ({ - id: 1, - url: 'https://api.github.com/repos/owner/repo/releases/1', - tag_name: version, - name: 'Release 1000', - created_at: DateTime.utc().toISO(), +const mockVersionResponse = (version: string) => ({ + version, published_at: DateTime.utc().toISO(), - body: '', }); describe(VersionService.name, () => { @@ -24,6 +18,8 @@ describe(VersionService.name, () => { beforeEach(() => { ({ sut, mocks } = newTestService(VersionService)); + mocks.cron.create.mockResolvedValue(); + mocks.cron.update.mockResolvedValue(); }); it('should work', () => { @@ -50,6 +46,21 @@ describe(VersionService.name, () => { await expect(sut.onBootstrap()).resolves.toBeUndefined(); expect(mocks.versionHistory.create).not.toHaveBeenCalled(); }); + + it('should create a version check cron job when the database lock is acquired', async () => { + mocks.database.tryLock.mockResolvedValue(true); + mocks.versionHistory.getLatest.mockResolvedValue({ + id: 'version-1', + createdAt: new Date(), + version: serverVersion.toString(), + }); + await sut.onBootstrap(); + expect(mocks.cron.create).toHaveBeenCalledWith( + expect.objectContaining({ + name: CronJob.VersionCheck, + }), + ); + }); }); describe('getVersion', () => { @@ -78,34 +89,32 @@ describe(VersionService.name, () => { }); describe('handVersionCheck', () => { - beforeEach(() => { - mocks.config.getEnv.mockReturnValue(mockEnvData({ environment: ImmichEnvironment.Production })); - }); - - it('should not run in dev mode', async () => { - mocks.config.getEnv.mockReturnValue(mockEnvData({ environment: ImmichEnvironment.Development })); - await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Skipped); - }); - - it('should not run if the last check was < 60 minutes ago', async () => { - mocks.systemMetadata.get.mockResolvedValue({ - checkedAt: DateTime.utc().minus({ minutes: 5 }).toISO(), - releaseVersion: '1.0.0', - }); - await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Skipped); - }); - it('should not run if version check is disabled', async () => { mocks.systemMetadata.get.mockResolvedValue({ newVersionCheck: { enabled: false } }); await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Skipped); }); - it('should run if it has been > 60 minutes', async () => { - mocks.serverInfo.getGitHubRelease.mockResolvedValue(mockRelease('v100.0.0')); - mocks.systemMetadata.get.mockResolvedValue({ - checkedAt: DateTime.utc().minus({ minutes: 65 }).toISO(), + it('should skip if the last check was less than 50 seconds ago', async () => { + mocks.systemMetadata.get.mockResolvedValueOnce(null).mockResolvedValueOnce({ + checkedAt: DateTime.utc().minus({ seconds: 30 }).toISO(), releaseVersion: '1.0.0', }); + await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Skipped); + expect(mocks.serverInfo.getLatestRelease).not.toHaveBeenCalled(); + }); + + it('should run if the last check was more than 50 seconds ago', async () => { + mocks.systemMetadata.get.mockResolvedValueOnce(null).mockResolvedValueOnce({ + checkedAt: DateTime.utc().minus({ seconds: 60 }).toISO(), + releaseVersion: '1.0.0', + }); + mocks.serverInfo.getLatestRelease.mockResolvedValue(mockVersionResponse(serverVersion.toString())); + await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Success); + expect(mocks.serverInfo.getLatestRelease).toHaveBeenCalled(); + }); + + it('should run and notify if a new version is available', async () => { + mocks.serverInfo.getLatestRelease.mockResolvedValue(mockVersionResponse('v100.0.0')); await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Success); expect(mocks.systemMetadata.set).toHaveBeenCalled(); expect(mocks.logger.log).toHaveBeenCalled(); @@ -113,7 +122,7 @@ describe(VersionService.name, () => { }); it('should not notify if the version is equal', async () => { - mocks.serverInfo.getGitHubRelease.mockResolvedValue(mockRelease(serverVersion.toString())); + mocks.serverInfo.getLatestRelease.mockResolvedValue(mockVersionResponse(serverVersion.toString())); await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Success); expect(mocks.systemMetadata.set).toHaveBeenCalledWith(SystemMetadataKey.VersionCheckState, { checkedAt: expect.any(String), @@ -122,8 +131,8 @@ describe(VersionService.name, () => { expect(mocks.websocket.clientBroadcast).not.toHaveBeenCalled(); }); - it('should handle a github error', async () => { - mocks.serverInfo.getGitHubRelease.mockRejectedValue(new Error('GitHub is down')); + it('should handle a version check error', async () => { + mocks.serverInfo.getLatestRelease.mockRejectedValue(new Error('Version service is down')); await expect(sut.handleVersionCheck()).resolves.toEqual(JobStatus.Failed); expect(mocks.systemMetadata.set).not.toHaveBeenCalled(); expect(mocks.websocket.clientBroadcast).not.toHaveBeenCalled(); diff --git a/server/src/services/version.service.ts b/server/src/services/version.service.ts index fc51481cad..ce6d6d7a6f 100644 --- a/server/src/services/version.service.ts +++ b/server/src/services/version.service.ts @@ -4,10 +4,11 @@ import semver, { SemVer } from 'semver'; import { serverVersion } from 'src/constants'; import { OnEvent, OnJob } from 'src/decorators'; import { ReleaseNotification, ServerVersionResponseDto } from 'src/dtos/server.dto'; -import { DatabaseLock, ImmichEnvironment, JobName, JobStatus, QueueName, SystemMetadataKey } from 'src/enum'; +import { CronJob, DatabaseLock, ImmichWorker, JobName, JobStatus, QueueName, SystemMetadataKey } from 'src/enum'; import { ArgOf } from 'src/repositories/event.repository'; import { BaseService } from 'src/services/base.service'; import { VersionCheckMetadata } from 'src/types'; +import { handlePromiseError } from 'src/utils/misc'; const asNotification = ({ checkedAt, releaseVersion }: VersionCheckMetadata): ReleaseNotification => { return { @@ -20,9 +21,21 @@ const asNotification = ({ checkedAt, releaseVersion }: VersionCheckMetadata): Re @Injectable() export class VersionService extends BaseService { - @OnEvent({ name: 'AppBootstrap' }) + @OnEvent({ name: 'AppBootstrap', workers: [ImmichWorker.Microservices] }) async onBootstrap(): Promise { - await this.handleVersionCheck(); + const hasLock = await this.databaseRepository.tryLock(DatabaseLock.VersionCheck); + if (hasLock) { + await this.handleVersionCheck(); + + const randomMinute = Math.floor(Math.random() * 60); + const expression = `${randomMinute} * * * *`; + this.logger.debug(`Scheduling version check for cron ${expression}`); + this.cronRepository.create({ + name: CronJob.VersionCheck, + expression, + onTick: () => handlePromiseError(this.handleQueueVersionCheck(), this.logger), + }); + } await this.databaseRepository.withLock(DatabaseLock.VersionHistory, async () => { const previous = await this.versionRepository.getLatest(); @@ -71,11 +84,6 @@ export class VersionService extends BaseService { try { this.logger.debug('Running version check'); - const { environment } = this.configRepository.getEnv(); - if (environment === ImmichEnvironment.Development) { - return JobStatus.Skipped; - } - const { newVersionCheck } = await this.getConfig({ withCache: true }); if (!newVersionCheck.enabled) { return JobStatus.Skipped; @@ -84,15 +92,13 @@ export class VersionService extends BaseService { const versionCheck = await this.systemMetadataRepository.get(SystemMetadataKey.VersionCheckState); if (versionCheck?.checkedAt) { const lastUpdate = DateTime.fromISO(versionCheck.checkedAt); - const elapsedTime = DateTime.now().diff(lastUpdate).as('minutes'); - // check once per hour (max) - if (elapsedTime < 60) { + const elapsedTime = DateTime.now().diff(lastUpdate).as('seconds'); + if (elapsedTime < 50) { return JobStatus.Skipped; } } - const { tag_name: releaseVersion, published_at: publishedAt } = - await this.serverInfoRepository.getGitHubRelease(); + const { version: releaseVersion, published_at: publishedAt } = await this.serverInfoRepository.getLatestRelease(); const metadata: VersionCheckMetadata = { checkedAt: DateTime.utc().toISO(), releaseVersion }; await this.systemMetadataRepository.set(SystemMetadataKey.VersionCheckState, metadata); diff --git a/server/src/utils/access.ts b/server/src/utils/access.ts index 2e0f7d10d0..21e8bdd66e 100644 --- a/server/src/utils/access.ts +++ b/server/src/utils/access.ts @@ -241,6 +241,11 @@ const checkOtherAccess = async (access: AccessRepository, request: OtherAccessRe return ids.has(auth.user.id) ? new Set([auth.user.id]) : new Set(); } + case Permission.DuplicateRead: + case Permission.DuplicateDelete: { + return access.duplicate.checkOwnerAccess(auth.user.id, ids); + } + case Permission.AuthDeviceDelete: { return await access.authDevice.checkOwnerAccess(auth.user.id, ids); } diff --git a/server/src/utils/database.ts b/server/src/utils/database.ts index 03998d9462..d25d99b491 100644 --- a/server/src/utils/database.ts +++ b/server/src/utils/database.ts @@ -126,12 +126,13 @@ export function withFiles(eb: ExpressionBuilder, type?: AssetFileTy ).as('files'); } -export function withFilePath(eb: ExpressionBuilder, type: AssetFileType) { +export function withFilePath(eb: ExpressionBuilder, type: AssetFileType, isEdited = false) { return eb .selectFrom('asset_file') .select('asset_file.path') .whereRef('asset_file.assetId', '=', 'asset.id') - .where('asset_file.type', '=', type); + .where('asset_file.type', '=', sql.lit(type)) + .where('asset_file.isEdited', '=', sql.lit(isEdited)); } export function withFacesAndPeople( diff --git a/server/src/utils/duplicate.spec.ts b/server/src/utils/duplicate.spec.ts new file mode 100644 index 0000000000..4c5d5ddfc4 --- /dev/null +++ b/server/src/utils/duplicate.spec.ts @@ -0,0 +1,178 @@ +import { AssetResponseDto } from 'src/dtos/asset-response.dto'; +import { AssetType, AssetVisibility } from 'src/enum'; +import { getExifCount, suggestDuplicate, suggestDuplicateKeepAssetIds } from 'src/utils/duplicate'; +import { describe, expect, it } from 'vitest'; + +const createAsset = ( + id: string, + fileSizeInByte: number | null = null, + exifFields: Record = {}, +): AssetResponseDto => ({ + id, + type: AssetType.Image, + thumbhash: null, + localDateTime: new Date().toISOString(), + duration: '0:00:00.00000', + hasMetadata: true, + width: 1920, + height: 1080, + createdAt: new Date().toISOString(), + deviceAssetId: 'device-asset-1', + deviceId: 'device-1', + ownerId: 'owner-1', + originalPath: '/path/to/asset', + originalFileName: 'asset.jpg', + fileCreatedAt: new Date().toISOString(), + fileModifiedAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + isFavorite: false, + isArchived: false, + isTrashed: false, + isOffline: false, + isEdited: false, + visibility: AssetVisibility.Timeline, + checksum: 'checksum', + exifInfo: + fileSizeInByte !== null || Object.keys(exifFields).length > 0 ? { fileSizeInByte, ...exifFields } : undefined, +}); + +describe('duplicate utils', () => { + describe('getExifCount', () => { + it('should return 0 for asset without exifInfo', () => { + const asset = createAsset('asset-1'); + asset.exifInfo = undefined; + expect(getExifCount(asset)).toBe(0); + }); + + it('should return 0 for empty exifInfo', () => { + const asset = createAsset('asset-1'); + asset.exifInfo = {}; + expect(getExifCount(asset)).toBe(0); + }); + + it('should count all truthy values in exifInfo', () => { + const asset = createAsset('asset-1', 1000, { + make: 'Canon', + model: 'EOS 5D', + dateTimeOriginal: new Date(), + timeZone: 'UTC', + latitude: 40.7128, + longitude: -74.006, + city: 'New York', + state: 'NY', + country: 'USA', + description: 'A photo', + rating: 5, + }); + // fileSizeInByte (1000) + 11 other truthy fields = 12 + expect(getExifCount(asset)).toBe(12); + }); + + it('should not count null or undefined values', () => { + const asset = createAsset('asset-1', 1000, { + make: 'Canon', + model: null, + latitude: undefined, + city: '', + rating: 0, + }); + // fileSizeInByte (1000) + make ('Canon') = 2 truthy values + // model (null), latitude (undefined), city (''), rating (0) are all falsy + expect(getExifCount(asset)).toBe(2); + }); + }); + + describe('suggestDuplicate', () => { + it('should return undefined for empty list', () => { + expect(suggestDuplicate([])).toBeUndefined(); + }); + + it('should return the single asset for list with one asset', () => { + const asset = createAsset('asset-1', 1000); + expect(suggestDuplicate([asset])).toEqual(asset); + }); + + it('should return asset with largest file size', () => { + const small = createAsset('small', 1000); + const large = createAsset('large', 5000); + const medium = createAsset('medium', 3000); + + expect(suggestDuplicate([small, large, medium])?.id).toBe('large'); + expect(suggestDuplicate([large, small, medium])?.id).toBe('large'); + expect(suggestDuplicate([medium, small, large])?.id).toBe('large'); + }); + + it('should use EXIF count as tie-breaker when file sizes are equal', () => { + const lessExif = createAsset('less-exif', 1000, { make: 'Canon' }); + const moreExif = createAsset('more-exif', 1000, { + make: 'Canon', + model: 'EOS 5D', + dateTimeOriginal: new Date(), + city: 'New York', + }); + + expect(suggestDuplicate([lessExif, moreExif])?.id).toBe('more-exif'); + expect(suggestDuplicate([moreExif, lessExif])?.id).toBe('more-exif'); + }); + + it('should handle assets with no exifInfo (treat as 0 file size)', () => { + const noExif = createAsset('no-exif'); + noExif.exifInfo = undefined; + const withExif = createAsset('with-exif', 1000); + + expect(suggestDuplicate([noExif, withExif])?.id).toBe('with-exif'); + }); + + it('should handle assets with exifInfo but no fileSizeInByte', () => { + const noFileSize = createAsset('no-file-size'); + noFileSize.exifInfo = { make: 'Canon', model: 'EOS 5D' }; + const withFileSize = createAsset('with-file-size', 1000); + + expect(suggestDuplicate([noFileSize, withFileSize])?.id).toBe('with-file-size'); + }); + + it('should return last asset when all have same file size and EXIF count', () => { + const asset1 = createAsset('asset-1', 1000, { make: 'Canon' }); + const asset2 = createAsset('asset-2', 1000, { make: 'Nikon' }); + + // Both have same file size (1000) and same EXIF count (2: fileSizeInByte + make) + // Should return the last one in the sorted array + const result = suggestDuplicate([asset1, asset2]); + // Since they're equal, the last one after sorting should be returned + expect(result).toBeDefined(); + expect(['asset-1', 'asset-2']).toContain(result?.id); + }); + + it('should prioritize file size over EXIF count', () => { + const largeWithLessExif = createAsset('large-less-exif', 5000, { make: 'Canon' }); + const smallWithMoreExif = createAsset('small-more-exif', 1000, { + make: 'Canon', + model: 'EOS 5D', + dateTimeOriginal: new Date(), + city: 'New York', + state: 'NY', + country: 'USA', + }); + + expect(suggestDuplicate([largeWithLessExif, smallWithMoreExif])?.id).toBe('large-less-exif'); + }); + }); + + describe('suggestDuplicateKeepAssetIds', () => { + it('should return empty array for empty list', () => { + expect(suggestDuplicateKeepAssetIds([])).toEqual([]); + }); + + it('should return array with single asset ID', () => { + const asset = createAsset('asset-1', 1000); + expect(suggestDuplicateKeepAssetIds([asset])).toEqual(['asset-1']); + }); + + it('should return array with best asset ID', () => { + const small = createAsset('small', 1000); + const large = createAsset('large', 5000); + + expect(suggestDuplicateKeepAssetIds([small, large])).toEqual(['large']); + }); + }); +}); diff --git a/server/src/utils/duplicate.ts b/server/src/utils/duplicate.ts new file mode 100644 index 0000000000..4f6deb2fce --- /dev/null +++ b/server/src/utils/duplicate.ts @@ -0,0 +1,60 @@ +import { AssetResponseDto } from 'src/dtos/asset-response.dto'; + +/** + * Counts all truthy values in the exifInfo object. + * This matches the client implementation in web/src/lib/utils/exif-utils.ts + * + * @param asset Asset with optional exifInfo + * @returns Count of truthy EXIF values + */ +export const getExifCount = (asset: AssetResponseDto): number => { + return Object.values(asset.exifInfo ?? {}).filter(Boolean).length; +}; + +/** + * Suggests the best duplicate asset to keep from a list of duplicates. + * This is a direct port of the client logic from web/src/lib/utils/duplicate-utils.ts + * + * The best asset is determined by the following criteria: + * 1. Largest image file size in bytes + * 2. Largest count of EXIF data (as tie-breaker) + * + * @param assets List of duplicate assets + * @returns The best asset to keep, or undefined if empty list + */ +export const suggestDuplicate = (assets: AssetResponseDto[]): AssetResponseDto | undefined => { + if (assets.length === 0) { + return undefined; + } + + // Sort by file size ascending (smallest first) + let duplicateAssets = [...assets].toSorted( + (a, b) => (a.exifInfo?.fileSizeInByte ?? 0) - (b.exifInfo?.fileSizeInByte ?? 0), + ); + + // Get the largest file size (last element after sorting) + const largestFileSize = duplicateAssets.at(-1)?.exifInfo?.fileSizeInByte ?? 0; + + // Filter to keep only assets with the largest file size + duplicateAssets = duplicateAssets.filter((asset) => (asset.exifInfo?.fileSizeInByte ?? 0) === largestFileSize); + + // If there are multiple assets with the same file size, sort by EXIF count + if (duplicateAssets.length >= 2) { + duplicateAssets = duplicateAssets.toSorted((a, b) => getExifCount(a) - getExifCount(b)); + } + + // Return the last asset (highest EXIF count among highest file size) + return duplicateAssets.at(-1); +}; + +/** + * Suggests the best duplicate asset IDs to keep from a list of duplicates. + * Returns an array with a single asset ID (the best candidate), or empty if no assets. + * + * @param assets List of duplicate assets + * @returns Array of suggested asset IDs to keep (0 or 1 element) + */ +export const suggestDuplicateKeepAssetIds = (assets: AssetResponseDto[]): string[] => { + const suggested = suggestDuplicate(assets); + return suggested ? [suggested.id] : []; +}; diff --git a/server/src/utils/fetch.spec.ts b/server/src/utils/fetch.spec.ts new file mode 100644 index 0000000000..2189e6f626 --- /dev/null +++ b/server/src/utils/fetch.spec.ts @@ -0,0 +1,18 @@ +import { serverVersion } from 'src/constants'; +import { configureUserAgent } from 'src/utils/fetch'; + +describe('fetch', () => { + it('should set the default user-agent header', async () => { + const spy = vi.fn().mockResolvedValue(new Response()); + const original = globalThis.fetch; + globalThis.fetch = spy; + + configureUserAgent(); + await globalThis.fetch('http://test.local'); + + const headers: Headers = spy.mock.calls[0][1].headers; + expect(headers.get('User-Agent')).toBe(`immich-server/${serverVersion}`); + + globalThis.fetch = original; + }); +}); diff --git a/server/src/utils/fetch.ts b/server/src/utils/fetch.ts new file mode 100644 index 0000000000..e753b29725 --- /dev/null +++ b/server/src/utils/fetch.ts @@ -0,0 +1,12 @@ +import { serverVersion } from 'src/constants'; + +export function configureUserAgent() { + const originalFetch = globalThis.fetch; + globalThis.fetch = (input, init) => { + const headers = new Headers(init?.headers); + if (!headers.has('User-Agent')) { + headers.set('User-Agent', `immich-server/${serverVersion}`); + } + return originalFetch(input, { ...init, headers }); + }; +} diff --git a/server/src/utils/mime-types.spec.ts b/server/src/utils/mime-types.spec.ts index 862ed310bc..8c20bad0aa 100644 --- a/server/src/utils/mime-types.spec.ts +++ b/server/src/utils/mime-types.spec.ts @@ -83,6 +83,7 @@ describe('mimeTypes', () => { { mimetype: 'video/mp2t', extension: '.m2t' }, { mimetype: 'video/mp2t', extension: '.m2ts' }, { mimetype: 'video/mp2t', extension: '.mts' }, + { mimetype: 'video/mp2t', extension: '.ts' }, { mimetype: 'video/mp4', extension: '.mp4' }, { mimetype: 'video/mpeg', extension: '.mpe' }, { mimetype: 'video/mpeg', extension: '.mpeg' }, diff --git a/server/src/utils/mime-types.ts b/server/src/utils/mime-types.ts index 43421e7937..5089fc36d6 100644 --- a/server/src/utils/mime-types.ts +++ b/server/src/utils/mime-types.ts @@ -114,6 +114,7 @@ const video: Record = { '.mpg': ['video/mpeg'], '.mts': ['video/mp2t'], '.mxf': ['application/mxf'], + '.ts': ['video/mp2t'], '.vob': ['video/mpeg'], '.webm': ['video/webm'], '.wmv': ['video/x-ms-wmv'], diff --git a/server/src/utils/request.spec.ts b/server/src/utils/request.spec.ts new file mode 100644 index 0000000000..f65d19f86f --- /dev/null +++ b/server/src/utils/request.spec.ts @@ -0,0 +1,29 @@ +import { getAppVersionFromUA } from 'src/utils/request'; + +describe(getAppVersionFromUA.name, () => { + it('should get the app version for android', () => { + expect(getAppVersionFromUA('immich-android/1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version for ios', () => { + expect(getAppVersionFromUA('immich-ios/1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version for unknown', () => { + expect(getAppVersionFromUA('immich-unknown/1.123.4')).toEqual('1.123.4'); + }); + + describe('legacy format', () => { + it('should get the app version from the old android format', () => { + expect(getAppVersionFromUA('Immich_Android_1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version from the old ios format', () => { + expect(getAppVersionFromUA('Immich_iOS_1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version from the old unknown format', () => { + expect(getAppVersionFromUA('Immich_Unknown_1.123.4')).toEqual('1.123.4'); + }); + }); +}); diff --git a/server/src/utils/request.ts b/server/src/utils/request.ts index c64c980520..4cd8decf45 100644 --- a/server/src/utils/request.ts +++ b/server/src/utils/request.ts @@ -7,8 +7,11 @@ export const fromChecksum = (checksum: string): Buffer => { export const fromMaybeArray = (param: T | T[]) => (Array.isArray(param) ? param[0] : param); -const getAppVersionFromUA = (ua: string) => - ua.match(/^Immich_(?:Android|iOS)_(?.+)$/)?.groups?.appVersion ?? null; +export const getAppVersionFromUA = (ua: string) => + ua.match(/^immich-(?:android|ios|unknown)\/(?.+)$/)?.groups?.appVersion ?? + // legacy format + ua.match(/^Immich_(?:Android|iOS|Unknown)_(?.+)$/)?.groups?.appVersion ?? + null; export const getUserAgentDetails = (headers: IncomingHttpHeaders) => { const userAgent = UAParser(headers['user-agent']); diff --git a/server/test/factories/asset.factory.ts b/server/test/factories/asset.factory.ts index 321a6f8ddd..9caec31d6f 100644 --- a/server/test/factories/asset.factory.ts +++ b/server/test/factories/asset.factory.ts @@ -1,5 +1,5 @@ import { Selectable } from 'kysely'; -import { AssetFileType, AssetStatus, AssetType, AssetVisibility } from 'src/enum'; +import { AssetFileType, AssetStatus, AssetType, AssetVisibility, ChecksumAlgorithm } from 'src/enum'; import { AssetTable } from 'src/schema/tables/asset.table'; import { StackTable } from 'src/schema/tables/stack.table'; import { AssetEditFactory } from 'test/factories/asset-edit.factory'; @@ -53,6 +53,7 @@ export class AssetFactory { updateId: newUuidV7(), status: AssetStatus.Active, checksum: newSha1(), + checksumAlgorithm: ChecksumAlgorithm.sha1File, deviceAssetId: '', deviceId: '', duplicateId: null, diff --git a/server/test/mappers.ts b/server/test/mappers.ts index 7f324663be..ed2c9431f3 100644 --- a/server/test/mappers.ts +++ b/server/test/mappers.ts @@ -1,4 +1,5 @@ import { Selectable, ShallowDehydrateObject } from 'kysely'; +import { MapAsset } from 'src/dtos/asset-response.dto'; import { AssetEditActionItem } from 'src/dtos/editing.dto'; import { ActivityTable } from 'src/schema/tables/activity.table'; import { AssetTable } from 'src/schema/tables/asset.table'; @@ -125,6 +126,7 @@ export const getForMemory = (memory: ReturnType) => ({ export const getForMetadataExtraction = (asset: ReturnType) => ({ id: asset.id, checksum: asset.checksum, + checksumAlgorithm: asset.checksumAlgorithm, deviceAssetId: asset.deviceAssetId, deviceId: asset.deviceId, fileCreatedAt: asset.fileCreatedAt, @@ -138,6 +140,7 @@ export const getForMetadataExtraction = (asset: ReturnType getDehydrated(face)), @@ -203,10 +206,11 @@ export const getForStack = (stack: ReturnType) => ({ })), }); -export const getForDuplicate = (asset: ReturnType) => ({ - ...getDehydrated(asset), - exifInfo: getDehydrated(asset.exifInfo), -}); +export const getForDuplicate = (asset: ReturnType) => + ({ + ...getDehydrated(asset), + exifInfo: getDehydrated(asset.exifInfo), + }) as unknown as MapAsset; export const getForSharedLink = (sharedLink: ReturnType) => ({ ...sharedLink, diff --git a/server/test/medium.factory.ts b/server/test/medium.factory.ts index a8aa00c2a3..3ac6645a6c 100644 --- a/server/test/medium.factory.ts +++ b/server/test/medium.factory.ts @@ -12,6 +12,7 @@ import { AlbumUserRole, AssetType, AssetVisibility, + ChecksumAlgorithm, MemoryType, SourceType, SyncEntityType, @@ -25,6 +26,7 @@ import { AssetEditRepository } from 'src/repositories/asset-edit.repository'; import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; +import { CronRepository } from 'src/repositories/cron.repository'; import { CryptoRepository } from 'src/repositories/crypto.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; import { EmailRepository } from 'src/repositories/email.repository'; @@ -499,6 +501,10 @@ const newMockRepository = (key: ClassConstructor) => { }); } + case CronRepository: { + return automock(CronRepository, { args: [undefined, { setContext: () => {} }], strict: false }); + } + case EmailRepository: { return automock(EmailRepository, { args: [{ setContext: () => {} }] }); } @@ -547,6 +553,7 @@ const assetInsert = (asset: Partial> = {}) => { deviceId: '', originalFileName: '', checksum: randomBytes(32), + checksumAlgorithm: ChecksumAlgorithm.sha1File, type: AssetType.Image, originalPath: '/path/to/something.jpg', ownerId: 'not-a-valid-uuid', diff --git a/server/test/medium/specs/repositories/asset-job.repository.spec.ts b/server/test/medium/specs/repositories/asset-job.repository.spec.ts index 6af3aa778f..023ed8774e 100644 --- a/server/test/medium/specs/repositories/asset-job.repository.spec.ts +++ b/server/test/medium/specs/repositories/asset-job.repository.spec.ts @@ -115,4 +115,33 @@ describe(AssetJobRepository.name, () => { ); }); }); + + describe('getForOcr', () => { + it('should not return the edited preview file', async () => { + const { ctx, sut } = setup(); + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id }); + + await ctx.newAssetFile({ + assetId: asset.id, + type: AssetFileType.Preview, + path: 'preview_edited.jpg', + isEdited: true, + }); + await ctx.newAssetFile({ + assetId: asset.id, + type: AssetFileType.Preview, + path: 'preview_unedited.jpg', + isEdited: false, + }); + + const result = await sut.getForOcr(asset.id); + + expect(result).toEqual( + expect.objectContaining({ + previewFile: 'preview_unedited.jpg', + }), + ); + }); + }); }); diff --git a/server/test/medium/specs/services/person.service.spec.ts b/server/test/medium/specs/services/person.service.spec.ts index 4cd705b5bd..39805580f6 100644 --- a/server/test/medium/specs/services/person.service.spec.ts +++ b/server/test/medium/specs/services/person.service.spec.ts @@ -5,6 +5,7 @@ import { AccessRepository } from 'src/repositories/access.repository'; import { AssetEditRepository } from 'src/repositories/asset-edit.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; +import { JobRepository } from 'src/repositories/job.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { PersonRepository } from 'src/repositories/person.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; @@ -20,7 +21,7 @@ const setup = (db?: Kysely) => { return newMediumService(PersonService, { database: db || defaultDatabase, real: [AccessRepository, DatabaseRepository, PersonRepository, AssetRepository, AssetEditRepository], - mock: [LoggingRepository, StorageRepository], + mock: [JobRepository, LoggingRepository, StorageRepository], }); }; @@ -89,6 +90,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 200 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); const auth = factory.auth({ user }); @@ -128,6 +130,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 200 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -199,6 +202,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 200 }); await ctx.newExif({ assetId: asset.id, exifImageWidth: 200, exifImageHeight: 100 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -263,6 +267,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 100 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -327,6 +332,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 150 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -400,6 +406,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 100 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -473,6 +480,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 150 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 150 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -543,6 +551,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 100 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -622,6 +631,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 100 }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ @@ -692,6 +702,7 @@ describe(PersonService.name, () => { const { person } = await ctx.newPerson({ ownerId: user.id }); const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 }); await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 100, orientation: '6' }); + ctx.getMock(JobRepository).queueAll.mockResolvedValue(); await ctx.newEdits(asset.id, { edits: [ diff --git a/server/test/medium/specs/services/search.service.spec.ts b/server/test/medium/specs/services/search.service.spec.ts index c20b64ca7c..18e03b2e48 100644 --- a/server/test/medium/specs/services/search.service.spec.ts +++ b/server/test/medium/specs/services/search.service.spec.ts @@ -1,4 +1,5 @@ import { Kysely } from 'kysely'; +import { SearchSuggestionType } from 'src/dtos/search.dto'; import { AccessRepository } from 'src/repositories/access.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; @@ -108,4 +109,25 @@ describe(SearchService.name, () => { expect(response.assets.items[0].id).toBe(unstackedAsset.id); }); }); + + describe('getSearchSuggestions', () => { + it('should filter out empty search suggestions', async () => { + const { sut, ctx } = setup(); + const { user } = await ctx.newUser(); + + const { asset } = await ctx.newAsset({ ownerId: user.id }); + await ctx.newExif({ assetId: asset.id, make: 'Canon' }); + + const { asset: assetWithEmptyMake } = await ctx.newAsset({ ownerId: user.id }); + await ctx.newExif({ assetId: assetWithEmptyMake.id, make: '' }); + + const auth = factory.auth({ user: { id: user.id } }); + const suggestions = await sut.getSearchSuggestions(auth, { + type: SearchSuggestionType.CAMERA_MAKE, + includeNull: true, + }); + + expect(suggestions).toEqual(['Canon', null]); + }); + }); }); diff --git a/server/test/medium/specs/services/shared-link.service.spec.ts b/server/test/medium/specs/services/shared-link.service.spec.ts index 5873d469a5..347e2e9506 100644 --- a/server/test/medium/specs/services/shared-link.service.spec.ts +++ b/server/test/medium/specs/services/shared-link.service.spec.ts @@ -372,6 +372,43 @@ describe(SharedLinkService.name, () => { }); describe('get', () => { + it('should return an album shared link with assets', async () => { + const { sut, ctx } = setup(); + const { user } = await ctx.newUser(); + const auth = factory.auth({ user }); + const { album } = await ctx.newAlbum({ ownerId: user.id }); + + const [{ asset: asset1 }, { asset: asset2 }] = await Promise.all([ + ctx.newAsset({ ownerId: user.id }), + ctx.newAsset({ ownerId: user.id }), + ]); + await Promise.all([ + ctx.newExif({ assetId: asset1.id, make: 'Canon' }), + ctx.newExif({ assetId: asset2.id, make: 'Canon' }), + ]); + + const sharedLinkRepo = ctx.get(SharedLinkRepository); + const sharedLink = await sharedLinkRepo.create({ + key: randomBytes(16), + id: factory.uuid(), + userId: user.id, + albumId: album.id, + allowUpload: true, + type: SharedLinkType.Album, + }); + + await sharedLinkRepo.addAssets(sharedLink.id, [asset1.id, asset2.id]); + const result = await sut.get(auth, sharedLink.id); + const assetIds = result.assets.map((asset) => asset.id); + + expect(result).toMatchObject({ + id: sharedLink.id, + album: expect.objectContaining({ id: album.id }), + }); + expect(assetIds).toHaveLength(2); + expect(assetIds).toEqual(expect.arrayContaining([asset1.id, asset2.id])); + }); + it('should not return trashed assets for an individual shared link', async () => { const { sut, ctx } = setup(); const { user } = await ctx.newUser(); diff --git a/server/test/medium/specs/services/version.service.spec.ts b/server/test/medium/specs/services/version.service.spec.ts index 3e81429382..5492f9f75b 100644 --- a/server/test/medium/specs/services/version.service.spec.ts +++ b/server/test/medium/specs/services/version.service.spec.ts @@ -1,6 +1,7 @@ import { Kysely } from 'kysely'; import { serverVersion } from 'src/constants'; import { JobName } from 'src/enum'; +import { CronRepository } from 'src/repositories/cron.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; import { JobRepository } from 'src/repositories/job.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; @@ -16,7 +17,7 @@ const setup = (db?: Kysely) => { return newMediumService(VersionService, { database: db || defaultDatabase, real: [DatabaseRepository, VersionHistoryRepository], - mock: [LoggingRepository, JobRepository], + mock: [LoggingRepository, JobRepository, CronRepository], }); }; diff --git a/server/test/repositories/access.repository.mock.ts b/server/test/repositories/access.repository.mock.ts index 208b09c120..f723113bd1 100644 --- a/server/test/repositories/access.repository.mock.ts +++ b/server/test/repositories/access.repository.mock.ts @@ -33,6 +33,10 @@ export const newAccessRepositoryMock = (): IAccessRepositoryMock => { checkOwnerAccess: vitest.fn().mockResolvedValue(new Set()), }, + duplicate: { + checkOwnerAccess: vitest.fn().mockResolvedValue(new Set()), + }, + memory: { checkOwnerAccess: vitest.fn().mockResolvedValue(new Set()), }, diff --git a/server/test/repositories/config.repository.mock.ts b/server/test/repositories/config.repository.mock.ts index 62e498372e..797c08c4db 100644 --- a/server/test/repositories/config.repository.mock.ts +++ b/server/test/repositories/config.repository.mock.ts @@ -35,11 +35,19 @@ const envData: EnvData = { vectorExtension: DatabaseExtension.Vectors, }, + helmet: { + config: {}, + }, + licensePublicKey: { client: 'client-public-key', server: 'server-public-key', }, + versionCheck: { + url: 'https://version.immich.cloud/version', + }, + network: { trustedProxies: [], }, diff --git a/server/tsconfig.build.json b/server/tsconfig.build.json index 6bdc715a11..1e66615096 100644 --- a/server/tsconfig.build.json +++ b/server/tsconfig.build.json @@ -1,4 +1,8 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "tsBuildInfoFile": "./dist/tsconfig.build.tsbuildinfo", + }, "exclude": ["dist", "node_modules", "upload", "test", "e2e", "**/*spec.ts"] } diff --git a/server/tsconfig.json b/server/tsconfig.json index fcb0ea2a97..51d57a0dbc 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -19,10 +19,12 @@ "preserveWatchOutput": true, "paths": { "src/*": ["./src/*"], + "test/*": ["./test/*"] }, - "baseUrl": "./", + "rootDir": ".", "jsx": "react", "types": ["vitest/globals"], + "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo", "noErrorTruncation": true }, "exclude": ["dist", "node_modules", "upload"] diff --git a/web/.nvmrc b/web/.nvmrc index 32f8c50de0..8e35034890 100644 --- a/web/.nvmrc +++ b/web/.nvmrc @@ -1 +1 @@ -24.13.1 +24.14.1 diff --git a/web/eslint.config.js b/web/eslint.config.js index f8e6cdd9c6..c25621f73a 100644 --- a/web/eslint.config.js +++ b/web/eslint.config.js @@ -73,6 +73,7 @@ export default typescriptEslint.config( 'eslint.config.js', 'tailwind.config.js', 'coverage', + 'vite.config.ts', ], }, typescriptEslint.configs.recommended, diff --git a/web/package.json b/web/package.json index 0288aeae6d..6cec8f50d4 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "immich-web", - "version": "2.6.2", + "version": "2.7.5", "license": "GNU Affero General Public License version 3", "type": "module", "scripts": { @@ -27,7 +27,7 @@ "@formatjs/icu-messageformat-parser": "^3.0.0", "@immich/justified-layout-wasm": "^0.4.3", "@immich/sdk": "workspace:*", - "@immich/ui": "^0.65.3", + "@immich/ui": "^0.69.0", "@mapbox/mapbox-gl-rtl-text": "0.3.0", "@mdi/js": "^7.4.47", "@photo-sphere-viewer/core": "^5.14.0", @@ -89,9 +89,9 @@ "dotenv": "^17.0.0", "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-compat": "^6.0.2", + "eslint-plugin-compat": "^7.0.0", "eslint-plugin-svelte": "^3.12.4", - "eslint-plugin-unicorn": "^63.0.0", + "eslint-plugin-unicorn": "^64.0.0", "factory.ts": "^1.4.1", "globals": "^17.0.0", "happy-dom": "^20.0.0", @@ -99,17 +99,17 @@ "prettier-plugin-organize-imports": "^4.0.0", "prettier-plugin-sort-json": "^4.1.1", "prettier-plugin-svelte": "^3.3.3", - "rollup-plugin-visualizer": "^6.0.0", - "svelte": "5.53.13", + "rollup-plugin-visualizer": "^7.0.0", + "svelte": "5.54.1", "svelte-check": "^4.1.5", "svelte-eslint-parser": "^1.3.3", "tailwindcss": "^4.2.2", - "typescript": "^5.8.3", + "typescript": "^6.0.0", "typescript-eslint": "^8.45.0", "vite": "^8.0.0", "vitest": "^4.0.0" }, "volta": { - "node": "24.13.1" + "node": "24.14.1" } } diff --git a/web/src/app.css b/web/src/app.css index 1ff3bec99b..4afc13ea0a 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -128,25 +128,24 @@ /* Track */ html::-webkit-scrollbar-track { - background: #f1f1f1; - border-radius: 16px; + background-color: var(--immich-ui-light-100); + border-radius: 4px; } /* Handle */ html::-webkit-scrollbar-thumb { - background: rgba(85, 86, 87, 0.408); - border-radius: 16px; + background-color: color-mix(in oklab, var(--immich-ui-light-600) 40%, transparent); + border-radius: 4px; } /* Handle on hover */ html::-webkit-scrollbar-thumb:hover { - background: #4250afad; - border-radius: 16px; + background-color: color-mix(in oklab, var(--immich-ui-primary-500) 70%, transparent); } body { margin: 0; - color: #3a3a3a; + color: var(--immich-ui-dark); } body.asset-viewer-open { diff --git a/web/src/lib/actions/zoom-image.ts b/web/src/lib/actions/zoom-image.ts index 35c3d3a106..07c44569cd 100644 --- a/web/src/lib/actions/zoom-image.ts +++ b/web/src/lib/actions/zoom-image.ts @@ -1,11 +1,18 @@ import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { createZoomImageWheel } from '@zoom-image/core'; -export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolean }) => { +// Minimal touch shape — avoids importing DOM TouchEvent which isn't available in all TS targets. +type TouchEventLike = { + touches: Iterable<{ clientX: number; clientY: number }> & { length: number }; + targetTouches: ArrayLike; +}; +const asTouchEvent = (event: Event) => event as unknown as TouchEventLike; + +export const zoomImageAction = (node: HTMLElement, options?: { zoomTarget?: HTMLElement }) => { const zoomInstance = createZoomImageWheel(node, { maxZoom: 10, initialState: assetViewerManager.zoomState, - zoomTarget: null, + zoomTarget: options?.zoomTarget, }); const unsubscribes = [ @@ -13,47 +20,130 @@ export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolea zoomInstance.subscribe(({ state }) => assetViewerManager.onZoomChange(state)), ]; - const onInteractionStart = (event: Event) => { - if (options?.disabled) { - event.stopImmediatePropagation(); + const controller = new AbortController(); + const { signal } = controller; + + node.addEventListener('pointerdown', () => assetViewerManager.cancelZoomAnimation(), { capture: true, signal }); + + // Intercept events in capture phase to prevent zoom-image from seeing interactions on + // overlay elements (e.g. OCR text boxes), preserving browser defaults like text selection. + const isOverlayEvent = (event: Event) => !!(event.target as HTMLElement).closest('[data-overlay-interactive]'); + const isOverlayAtPoint = (x: number, y: number) => + !!document.elementFromPoint(x, y)?.closest('[data-overlay-interactive]'); + + // Pointer event interception: track pointers that start on overlays and intercept the entire gesture. + const overlayPointers = new Set(); + const interceptedPointers = new Set(); + const interceptOverlayPointerDown = (event: PointerEvent) => { + if (isOverlayEvent(event) || isOverlayAtPoint(event.clientX, event.clientY)) { + overlayPointers.add(event.pointerId); + interceptedPointers.add(event.pointerId); + event.stopPropagation(); + } else if (overlayPointers.size > 0) { + // Split gesture (e.g. pinch with one finger on overlay) — intercept entirely. + interceptedPointers.add(event.pointerId); + event.stopPropagation(); } - assetViewerManager.cancelZoomAnimation(); }; + const interceptOverlayPointerEvent = (event: PointerEvent) => { + if (interceptedPointers.has(event.pointerId)) { + event.stopPropagation(); + } + }; + const interceptOverlayPointerEnd = (event: PointerEvent) => { + overlayPointers.delete(event.pointerId); + if (interceptedPointers.delete(event.pointerId)) { + event.stopPropagation(); + } + }; + node.addEventListener('pointerdown', interceptOverlayPointerDown, { capture: true, signal }); + node.addEventListener('pointermove', interceptOverlayPointerEvent, { capture: true, signal }); + node.addEventListener('pointerup', interceptOverlayPointerEnd, { capture: true, signal }); + node.addEventListener('pointerleave', interceptOverlayPointerEnd, { capture: true, signal }); - node.addEventListener('wheel', onInteractionStart, { capture: true }); - node.addEventListener('pointerdown', onInteractionStart, { capture: true }); + // Touch event interception for overlay touches or split gestures (pinch across container boundary). + // Once intercepted, stays intercepted until all fingers are lifted. + let touchGestureIntercepted = false; + const interceptOverlayTouchEvent = (event: Event) => { + if (touchGestureIntercepted) { + event.stopPropagation(); + return; + } + const { touches, targetTouches } = asTouchEvent(event); + if (touches && targetTouches) { + if (touches.length > targetTouches.length) { + touchGestureIntercepted = true; + event.stopPropagation(); + return; + } + for (const touch of touches) { + if (isOverlayAtPoint(touch.clientX, touch.clientY)) { + touchGestureIntercepted = true; + event.stopPropagation(); + return; + } + } + } else if (isOverlayEvent(event)) { + event.stopPropagation(); + } + }; + const resetTouchGesture = (event: Event) => { + const { touches } = asTouchEvent(event); + if (touches.length === 0) { + touchGestureIntercepted = false; + } + }; + node.addEventListener('touchstart', interceptOverlayTouchEvent, { capture: true, signal }); + node.addEventListener('touchmove', interceptOverlayTouchEvent, { capture: true, signal }); + node.addEventListener('touchend', resetTouchGesture, { capture: true, signal }); - // Suppress Safari's synthetic dblclick on double-tap. Without this, zoom-image's touchstart - // handler zooms to maxZoom (10x), then Safari's synthetic dblclick triggers photo-viewer's - // handler which conflicts. Chrome does not fire synthetic dblclick on touch. + // Wheel and dblclick interception on overlay elements. + // Dblclick also intercepted for all touch double-taps (Safari fires synthetic dblclick + // on double-tap, which conflicts with zoom-image's touch zoom handler). let lastPointerWasTouch = false; - const trackPointerType = (event: PointerEvent) => { - lastPointerWasTouch = event.pointerType === 'touch'; - }; - const suppressTouchDblClick = (event: MouseEvent) => { - if (lastPointerWasTouch) { - event.stopImmediatePropagation(); - } - }; - node.addEventListener('pointerdown', trackPointerType, { capture: true }); - node.addEventListener('dblclick', suppressTouchDblClick, { capture: true }); + node.addEventListener('pointerdown', (event) => (lastPointerWasTouch = event.pointerType === 'touch'), { + capture: true, + signal, + }); + node.addEventListener( + 'wheel', + (event) => { + if (isOverlayEvent(event)) { + event.stopPropagation(); + } + }, + { capture: true, signal }, + ); + node.addEventListener( + 'dblclick', + (event) => { + if (lastPointerWasTouch || isOverlayEvent(event)) { + event.stopImmediatePropagation(); + } + }, + { capture: true, signal }, + ); - // Allow zoomed content to render outside the container bounds + if (options?.zoomTarget) { + options.zoomTarget.style.willChange = 'transform'; + } node.style.overflow = 'visible'; - // Prevent browser handling of touch gestures so zoom-image can manage them node.style.touchAction = 'none'; return { - update(newOptions?: { disabled?: boolean }) { + update(newOptions?: { zoomTarget?: HTMLElement }) { options = newOptions; + if (newOptions?.zoomTarget !== undefined) { + zoomInstance.setState({ zoomTarget: newOptions.zoomTarget }); + } }, destroy() { + controller.abort(); + if (options?.zoomTarget) { + options.zoomTarget.style.willChange = ''; + } for (const unsubscribe of unsubscribes) { unsubscribe(); } - node.removeEventListener('wheel', onInteractionStart, { capture: true }); - node.removeEventListener('pointerdown', onInteractionStart, { capture: true }); - node.removeEventListener('pointerdown', trackPointerType, { capture: true }); - node.removeEventListener('dblclick', suppressTouchDblClick, { capture: true }); zoomInstance.cleanup(); }, }; diff --git a/web/src/lib/components/AdaptiveImage.svelte b/web/src/lib/components/AdaptiveImage.svelte index fad4d49d1b..90c9328cf8 100644 --- a/web/src/lib/components/AdaptiveImage.svelte +++ b/web/src/lib/components/AdaptiveImage.svelte @@ -7,7 +7,7 @@ import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { getAssetUrls } from '$lib/utils'; import { AdaptiveImageLoader, type QualityList } from '$lib/utils/adaptive-image-loader.svelte'; - import { scaleToCover, scaleToFit } from '$lib/utils/container-utils'; + import { scaleToCover, scaleToFit, type Size } from '$lib/utils/container-utils'; import { getAltText } from '$lib/utils/thumbnail-util'; import { toTimelineAsset } from '$lib/utils/timeline-util'; import type { AssetResponseDto, SharedLinkResponseDto } from '@immich/sdk'; @@ -17,10 +17,7 @@ asset: AssetResponseDto; sharedLink?: SharedLinkResponseDto; objectFit?: 'contain' | 'cover'; - container: { - width: number; - height: number; - }; + container: Size; onUrlChange?: (url: string) => void; onImageReady?: () => void; onError?: () => void; @@ -149,81 +146,66 @@ (quality.preview === 'success' ? previewElement : undefined) ?? (quality.thumbnail === 'success' ? thumbnailElement : undefined); }); - - const zoomTransform = $derived.by(() => { - const { currentZoom, currentPositionX, currentPositionY } = assetViewerManager.zoomState; - if (currentZoom === 1 && currentPositionX === 0 && currentPositionY === 0) { - return undefined; - } - return `translate(${currentPositionX}px, ${currentPositionY}px) scale(${currentZoom})`; - });
{@render backdrop?.()} - -
-
- {#if show.alphaBackground} - - {/if} +
+ {#if show.alphaBackground} + + {/if} - {#if show.thumbhash} - {#if asset.thumbhash} - - - {:else if show.spinner} - - {/if} + {#if show.thumbhash} + {#if asset.thumbhash} + + + {:else if show.spinner} + {/if} + {/if} - {#if show.thumbnail} - - {/if} + {#if show.thumbnail} + + {/if} - {#if show.brokenAsset} - - {/if} + {#if show.brokenAsset} + + {/if} - {#if show.preview} - - {/if} + {#if show.preview} + + {/if} - {#if show.original} - - {/if} -
+ {#if show.original} + + {/if}
diff --git a/web/src/lib/components/LinkToDocs.svelte b/web/src/lib/components/LinkToDocs.svelte new file mode 100644 index 0000000000..604b1ac14b --- /dev/null +++ b/web/src/lib/components/LinkToDocs.svelte @@ -0,0 +1,16 @@ + + + + {#snippet children({ message })} + {message} + {/snippet} + diff --git a/web/src/lib/components/ToastAction.svelte b/web/src/lib/components/ToastAction.svelte deleted file mode 100644 index 5dc430f323..0000000000 --- a/web/src/lib/components/ToastAction.svelte +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {#if button} -
- -
- {/if} -
-
diff --git a/web/src/lib/components/admin-settings/NewVersionCheckSettings.svelte b/web/src/lib/components/admin-settings/NewVersionCheckSettings.svelte index d8a79d6236..1e791c0b78 100644 --- a/web/src/lib/components/admin-settings/NewVersionCheckSettings.svelte +++ b/web/src/lib/components/admin-settings/NewVersionCheckSettings.svelte @@ -16,7 +16,7 @@
diff --git a/web/src/lib/components/album-page/album-map.svelte b/web/src/lib/components/album-page/album-map.svelte index c161bac552..623ac48ded 100644 --- a/web/src/lib/components/album-page/album-map.svelte +++ b/web/src/lib/components/album-page/album-map.svelte @@ -1,7 +1,8 @@ diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte index 19634d5aa4..55e80ae983 100644 --- a/web/src/lib/components/album-page/album-viewer.svelte +++ b/web/src/lib/components/album-page/album-viewer.svelte @@ -5,19 +5,18 @@ import SelectAllAssets from '$lib/components/timeline/actions/SelectAllAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { handleDownloadAlbum } from '$lib/services/album.service'; import { getGlobalActions } from '$lib/services/app.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store'; import { mediaQueryManager } from '$lib/stores/media-query-manager.svelte'; import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { handlePromiseError } from '$lib/utils'; - import { cancelMultiselect } from '$lib/utils/asset-utils'; import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader'; - import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@immich/sdk'; + import type { AlbumResponseDto, SharedLinkResponseDto } from '@immich/sdk'; import { ActionButton, IconButton, Logo } from '@immich/ui'; import { mdiDownload, mdiFileImagePlusOutline, mdiPresentationPlay } from '@mdi/js'; import { t } from 'svelte-i18n'; @@ -27,21 +26,17 @@ interface Props { sharedLink: SharedLinkResponseDto; - user?: UserResponseDto | undefined; } - let { sharedLink, user = undefined }: Props = $props(); + let { sharedLink }: Props = $props(); const album = sharedLink.album as AlbumResponseDto; - let { isViewing: showAssetViewer, setAssetId } = assetViewingStore; let { slideshowState, slideshowNavigation } = slideshowStore; const options = $derived({ albumId: album.id, order: album.order }); let timelineManager = $state() as TimelineManager; - const assetInteraction = new AssetInteraction(); - dragAndDropFilesStore.subscribe((value) => { if (value.isDragging && value.files.length > 0) { handlePromiseError(fileUploadHandler({ files: value.files, albumId: album.id })); @@ -53,9 +48,11 @@ const asset = $slideshowNavigation === SlideshowNavigation.Shuffle ? await timelineManager.getRandomAsset() - : timelineManager.months[0]?.dayGroups[0]?.viewerAssets[0]?.asset; + : timelineManager.months[0]?.timelineDays[0]?.viewerAssets[0]?.asset; if (asset) { - handlePromiseError(setAssetId(asset.id).then(() => ($slideshowState = SlideshowState.PlaySlideshow))); + handlePromiseError( + assetViewerManager.setAssetId(asset.id).then(() => ($slideshowState = SlideshowState.PlaySlideshow)), + ); } }; @@ -66,15 +63,15 @@ use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: () => { - if (!$showAssetViewer && assetInteraction.selectionActive) { - cancelMultiselect(assetInteraction); + if (!assetViewerManager.isViewing && assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); } }, }} />
- +

@@ -98,13 +95,9 @@

- {#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - + {#if assetMultiSelectManager.selectionActive} + + {#if sharedLink.allowDownload} {/if} diff --git a/web/src/lib/components/asset-viewer/activity-status.svelte b/web/src/lib/components/asset-viewer/activity-status.svelte index 6bd90fc5f0..617f89bc29 100644 --- a/web/src/lib/components/asset-viewer/activity-status.svelte +++ b/web/src/lib/components/asset-viewer/activity-status.svelte @@ -2,7 +2,7 @@ import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { locale } from '$lib/stores/preferences.store'; import type { ActivityResponseDto } from '@immich/sdk'; - import { Icon } from '@immich/ui'; + import { Button } from '@immich/ui'; import { mdiCommentOutline, mdiThumbUp, mdiThumbUpOutline } from '@mdi/js'; interface Props { @@ -16,21 +16,32 @@ let { isLiked, numberOfComments, numberOfLikes, disabled, onFavorite }: Props = $props(); -
- - +
+ +
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 eee2dc325c..860c38d71c 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 @@ -8,6 +8,7 @@ import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte'; import RatingAction from '$lib/components/asset-viewer/actions/rating-action.svelte'; import RemoveAssetFromStack from '$lib/components/asset-viewer/actions/remove-asset-from-stack.svelte'; + import RemoveFromAlbumAction from '$lib/components/timeline/actions/RemoveFromAlbumAction.svelte'; import RestoreAction from '$lib/components/asset-viewer/actions/restore-action.svelte'; import SetAlbumCoverAction from '$lib/components/asset-viewer/actions/set-album-cover-action.svelte'; import SetFeaturedPhotoAction from '$lib/components/asset-viewer/actions/set-person-featured-action.svelte'; @@ -15,14 +16,15 @@ import SetStackPrimaryAsset from '$lib/components/asset-viewer/actions/set-stack-primary-asset.svelte'; import SetVisibilityAction from '$lib/components/asset-viewer/actions/set-visibility-action.svelte'; import UnstackAction from '$lib/components/asset-viewer/actions/unstack-action.svelte'; + import LoadingDots from '$lib/components/LoadingDots.svelte'; import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { languageManager } from '$lib/managers/language-manager.svelte'; import { Route } from '$lib/route'; import { getGlobalActions } from '$lib/services/app.service'; import { getAssetActions } from '$lib/services/asset.service'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { user } from '$lib/stores/user.store'; import { getSharedLink, withoutIcons } from '$lib/utils'; import type { OnUndoDelete } from '$lib/utils/actions'; @@ -36,8 +38,6 @@ type StackResponseDto, } from '@immich/sdk'; import { ActionButton, CommandPaletteDefaultProvider, Tooltip, type ActionItem } from '@immich/ui'; - import LoadingDots from '$lib/components/LoadingDots.svelte'; - import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { mdiArrowLeft, mdiArrowRight, @@ -60,6 +60,7 @@ onUndoDelete?: OnUndoDelete; onPlaySlideshow: () => void; onClose?: () => void; + onRemoveFromAlbum?: (assetIds: string[]) => void; playOriginalVideo: boolean; setPlayOriginalVideo: (value: boolean) => void; } @@ -75,11 +76,13 @@ onUndoDelete = undefined, onPlaySlideshow, onClose, + onRemoveFromAlbum, playOriginalVideo = false, setPlayOriginalVideo, }: Props = $props(); const isOwner = $derived($user && asset.ownerId === $user?.id); + const isAlbumOwner = $derived($user && album?.ownerId === $user?.id); const isLocked = $derived(asset.visibility === AssetVisibility.Locked); const smartSearchEnabled = $derived(featureFlagsManager.value.smartSearch); @@ -89,7 +92,7 @@ title: $t('go_back'), type: $t('assets'), icon: languageManager.rtl ? mdiArrowRight : mdiArrowLeft, - $if: () => !!onClose && !isFaceEditMode.value, + $if: () => !!onClose && !assetViewerManager.isFaceEditMode, onAction: () => onClose?.(), shortcuts: [{ key: 'Escape' }], }); @@ -101,13 +104,16 @@
-
+
{#if assetViewerManager.isImageLoading} {#snippet child({ props })} @@ -120,10 +126,10 @@ - - + + @@ -154,6 +160,9 @@ {/if} + {#if album && (isOwner || isAlbumOwner)} + + {/if} {#if isOwner} diff --git a/web/src/lib/components/asset-viewer/asset-viewer.spec.ts b/web/src/lib/components/asset-viewer/asset-viewer.spec.ts index a1f50da86a..acb1d03714 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.spec.ts +++ b/web/src/lib/components/asset-viewer/asset-viewer.spec.ts @@ -1,5 +1,6 @@ import { getAnimateMock } from '$lib/__mocks__/animate.mock'; import { getResizeObserverMock } from '$lib/__mocks__/resize-observer.mock'; +import { SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { preferences as preferencesStore, resetSavedUser, user as userStore } from '$lib/stores/user.store'; import { renderWithTooltips } from '$tests/helpers'; import { updateAsset } from '@immich/sdk'; @@ -41,6 +42,7 @@ describe('AssetViewer', () => { }); afterEach(() => { + slideshowStore.slideshowState.set(SlideshowState.None); resetSavedUser(); vi.clearAllMocks(); }); diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 3f7b048c8f..db1fd2b511 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -14,8 +14,6 @@ import { editManager, EditToolType } from '$lib/managers/edit/edit-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import { getAssetActions } from '$lib/services/asset.service'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { ocrManager } from '$lib/stores/ocr.svelte'; import { alwaysLoadOriginalVideo } from '$lib/stores/preferences.store'; import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; @@ -71,6 +69,7 @@ onAction?: OnAction; onUndoDelete?: OnUndoDelete; onClose?: (asset: AssetResponseDto) => void; + onRemoveFromAlbum?: (assetIds: string[]) => void; onRandom?: () => Promise<{ id: string } | undefined>; } @@ -86,10 +85,10 @@ onAction, onUndoDelete, onClose, + onRemoveFromAlbum, onRandom, }: Props = $props(); - const { setAssetId } = assetViewingStore; const { restartProgress: restartSlideshowProgress, stopProgress: stopSlideshowProgress, @@ -188,7 +187,7 @@ if (editManager.hasAppliedEdits) { const refreshedAsset = await getAssetInfo({ id: asset.id }); onAssetChange?.(refreshedAsset); - assetViewingStore.setAsset(refreshedAsset); + assetViewerManager.setAsset(refreshedAsset); } assetViewerManager.closeEditor(); }; @@ -239,7 +238,7 @@ } if ($slideshowRepeat && slideshowStartAssetId) { - await setAssetId(slideshowStartAssetId); + await assetViewerManager.setAssetId(slideshowStartAssetId); $restartSlideshowProgress = true; return; } @@ -255,7 +254,7 @@ let assetViewerHtmlElement = $state(); const slideshowHistory = new SlideshowHistory((asset) => { - handlePromiseError(setAssetId(asset.id).then(() => ($restartSlideshowProgress = true))); + handlePromiseError(assetViewerManager.setAssetId(asset.id).then(() => ($restartSlideshowProgress = true))); }); const handleVideoStarted = () => { @@ -277,7 +276,6 @@ const handleStopSlideshow = async () => { try { if (document.fullscreenElement) { - document.body.style.cursor = ''; await document.exitFullscreen(); } } catch (error) { @@ -339,7 +337,7 @@ onAction?.(action); }; - let isFullScreen = $derived(fullscreenElement !== null); + let isFullScreen = $derived(!!fullscreenElement); $effect(() => { if (album && !album.isActivityEnabled && activityManager.commentCount === 0) { @@ -478,6 +476,7 @@ {onUndoDelete} onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)} onClose={onClose ? () => onClose(asset) : undefined} + {onRemoveFromAlbum} {playOriginalVideo} {setPlayOriginalVideo} /> @@ -485,7 +484,7 @@ {/if} {#if $slideshowState != SlideshowState.None} -
+
{/if} - {#if $slideshowState === SlideshowState.None && showNavigation && !assetViewerManager.isShowEditor && !isFaceEditMode.value && previousAsset} + {#if $slideshowState === SlideshowState.None && showNavigation && !assetViewerManager.isShowEditor && !assetViewerManager.isFaceEditMode && previousAsset}
navigateAsset('previous')} />
@@ -564,13 +563,13 @@ {/if} {#if showOcrButton} -
+
{/if}
- {#if $slideshowState === SlideshowState.None && showNavigation && !assetViewerManager.isShowEditor && !isFaceEditMode.value && nextAsset} + {#if $slideshowState === SlideshowState.None && showNavigation && !assetViewerManager.isShowEditor && !assetViewerManager.isFaceEditMode && nextAsset}
navigateAsset('next')} />
@@ -580,17 +579,16 @@
{#if showDetailPanel} -
- -
+ {:else if assetViewerManager.isShowEditor} -
- -
+ {/if}
{/if} diff --git a/web/src/lib/components/asset-viewer/detail-panel-location.svelte b/web/src/lib/components/asset-viewer/detail-panel-location.svelte index 1a3779f528..15ea4d94ca 100644 --- a/web/src/lib/components/asset-viewer/detail-panel-location.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel-location.svelte @@ -1,24 +1,20 @@ - +
diff --git a/web/src/lib/components/asset-viewer/editor/transform-tool/transform-tool.svelte b/web/src/lib/components/asset-viewer/editor/transform-tool/transform-tool.svelte index a45cb5d998..54ab126dfa 100644 --- a/web/src/lib/components/asset-viewer/editor/transform-tool/transform-tool.svelte +++ b/web/src/lib/components/asset-viewer/editor/transform-tool/transform-tool.svelte @@ -1,4 +1,5 @@ + rotateImage(90) }, + { shortcut: { key: '[' }, onShortcut: () => rotateImage(-90) }, + ]} +/> +

{$t('editor_orientation')}

diff --git a/web/src/lib/components/asset-viewer/face-editor/face-editor.svelte b/web/src/lib/components/asset-viewer/face-editor/face-editor.svelte index f2b9c2e157..2418e5bf85 100644 --- a/web/src/lib/components/asset-viewer/face-editor/face-editor.svelte +++ b/web/src/lib/components/asset-viewer/face-editor/face-editor.svelte @@ -1,24 +1,24 @@ - +
- +

{$t('select_person_to_tag')}

- +
@@ -344,6 +415,12 @@ {/if}
- + + +
diff --git a/web/src/lib/components/asset-viewer/ocr-bounding-box.svelte b/web/src/lib/components/asset-viewer/ocr-bounding-box.svelte index d5551b9cc5..c2ee1ba193 100644 --- a/web/src/lib/components/asset-viewer/ocr-bounding-box.svelte +++ b/web/src/lib/components/asset-viewer/ocr-bounding-box.svelte @@ -1,4 +1,5 @@ -
-
- {ocrBox.text} -
+
+ {ocrBox.text}
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 926383d9c2..12c4b45541 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 @@ -19,6 +19,7 @@ import { ResolutionPlugin } from '@photo-sphere-viewer/resolution-plugin'; import { SettingsPlugin } from '@photo-sphere-viewer/settings-plugin'; import '@photo-sphere-viewer/settings-plugin/index.css'; + import { escape } from 'lodash-es'; import { onDestroy, onMount } from 'svelte'; // Adapted as well as possible from classlist 'border-solid border-white border-3 rounded-lg' @@ -128,10 +129,8 @@ } const boxes = getOcrBoundingBoxes(ocrData, { - contentWidth: viewer.state.textureData.panoData.croppedWidth, - contentHeight: viewer.state.textureData.panoData.croppedHeight, - offsetX: 0, - offsetY: 0, + width: viewer.state.textureData.panoData.croppedWidth, + height: viewer.state.textureData.panoData.croppedHeight, }); for (const [index, box] of boxes.entries()) { @@ -140,7 +139,7 @@ const fontSize = (1.4 * width) / box.text.length; // fits almost all strings within the box, depends on font family const transform = `matrix3d(${matrix.join(',')})`; - const content = `
${box.text}
`; + const content = `
${escape(box.text)}
`; if (updateOnly) { markersPlugin.updateMarker({ diff --git a/web/src/lib/components/asset-viewer/photo-viewer.svelte b/web/src/lib/components/asset-viewer/photo-viewer.svelte index 4a6a02cb4a..a3c560ef8d 100644 --- a/web/src/lib/components/asset-viewer/photo-viewer.svelte +++ b/web/src/lib/components/asset-viewer/photo-viewer.svelte @@ -8,16 +8,15 @@ import AssetViewerEvents from '$lib/components/AssetViewerEvents.svelte'; import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { castManager } from '$lib/managers/cast-manager.svelte'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { ocrManager } from '$lib/stores/ocr.svelte'; import { boundingBoxesArray, type Faces } from '$lib/stores/people.store'; import { SlideshowLook, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { handlePromiseError } from '$lib/utils'; import { canCopyImageToClipboard, copyImageToClipboard } from '$lib/utils/asset-utils'; - import { getNaturalSize, scaleToFit, type ContentMetrics } from '$lib/utils/container-utils'; + import { getNaturalSize, scaleToFit, type Size } from '$lib/utils/container-utils'; import { handleError } from '$lib/utils/handle-error'; import { getOcrBoundingBoxes } from '$lib/utils/ocr-utils'; - import { getBoundingBox } from '$lib/utils/people-utils'; + import { getBoundingBox, type BoundingBox } from '$lib/utils/people-utils'; import { type SharedLinkResponseDto } from '@immich/sdk'; import { toastManager } from '@immich/ui'; import { onDestroy, untrack } from 'svelte'; @@ -25,14 +24,14 @@ import { t } from 'svelte-i18n'; import type { AssetCursor } from './asset-viewer.svelte'; - interface Props { + type Props = { cursor: AssetCursor; element?: HTMLDivElement; sharedLink?: SharedLinkResponseDto; onReady?: () => void; onError?: () => void; onSwipe?: (event: SwipeCustomEvent) => void; - } + }; let { cursor, element = $bindable(), sharedLink, onReady, onError, onSwipe }: Props = $props(); @@ -67,23 +66,27 @@ height: containerHeight, }); - const overlayMetrics = $derived.by((): ContentMetrics => { + const overlaySize = $derived.by((): Size => { if (!assetViewerManager.imgRef || !visibleImageReady) { - return { contentWidth: 0, contentHeight: 0, offsetX: 0, offsetY: 0 }; + return { width: 0, height: 0 }; } - const natural = getNaturalSize(assetViewerManager.imgRef); - const scaled = scaleToFit(natural, { width: containerWidth, height: containerHeight }); - - return { - contentWidth: scaled.width, - contentHeight: scaled.height, - offsetX: 0, - offsetY: 0, - }; + return scaleToFit(getNaturalSize(assetViewerManager.imgRef), { width: containerWidth, height: containerHeight }); }); - const ocrBoxes = $derived(ocrManager.showOverlay ? getOcrBoundingBoxes(ocrManager.data, overlayMetrics) : []); + const highlightedBoxes = $derived(getBoundingBox($boundingBoxesArray, overlaySize)); + const isHighlighting = $derived(highlightedBoxes.length > 0); + + let visibleBoxes = $state([]); + let visibleBoundingBoxes = $state([]); + $effect(() => { + if (isHighlighting) { + visibleBoxes = highlightedBoxes; + visibleBoundingBoxes = $boundingBoxesArray; + } + }); + + const ocrBoxes = $derived(ocrManager.showOverlay ? getOcrBoundingBoxes(ocrManager.data, overlaySize) : []); const onCopy = async () => { if (!canCopyImageToClipboard() || !assetViewerManager.imgRef) { @@ -106,7 +109,7 @@ const onPlaySlideshow = () => ($slideshowState = SlideshowState.PlaySlideshow); $effect(() => { - if (isFaceEditMode.value && assetViewerManager.zoom > 1) { + if (assetViewerManager.isFaceEditMode && assetViewerManager.zoom > 1) { onZoom(); } }); @@ -151,6 +154,8 @@ $slideshowState !== SlideshowState.None && $slideshowLook === SlideshowLook.BlurredBackground && !!asset.thumbhash, ); + let adaptiveImage = $state(); + const faceToNameMap = $derived.by(() => { // eslint-disable-next-line svelte/prefer-svelte-reactivity const map = new Map(); @@ -166,7 +171,7 @@ const handleImageMouseMove = (event: MouseEvent) => { $boundingBoxesArray = []; - if (!assetViewerManager.imgRef || !element || isFaceEditMode.value || ocrManager.showOverlay) { + if (!assetViewerManager.imgRef || !element || assetViewerManager.isFaceEditMode || ocrManager.showOverlay) { return; } @@ -181,7 +186,7 @@ const mouseX = (event.clientX - containerRect.left - contentOffsetX * currentZoom - currentPositionX) / currentZoom; const mouseY = (event.clientY - containerRect.top - contentOffsetY * currentZoom - currentPositionY) / currentZoom; - const faceBoxes = getBoundingBox(faces, overlayMetrics); + const faceBoxes = getBoundingBox(faces, overlaySize); for (const [index, box] of faceBoxes.entries()) { if (mouseX >= box.left && mouseX <= box.left + box.width && mouseY >= box.top && mouseY <= box.top + box.height) { @@ -215,7 +220,7 @@ ondblclick={onZoom} onmousemove={handleImageMouseMove} onmouseleave={handleImageMouseLeave} - use:zoomImageAction={{ disabled: isFaceEditMode.value || ocrManager.showOverlay }} + use:zoomImageAction={{ zoomTarget: adaptiveImage }} {...useSwipe((event) => onSwipe?.(event))} > {#snippet backdrop()} {#if blurredSlideshow} @@ -243,21 +249,37 @@ {/if} {/snippet} {#snippet overlays()} - {#each getBoundingBox($boundingBoxesArray, overlayMetrics) as boundingbox, index (boundingbox.id)} -
- {#if faceToNameMap.get($boundingBoxesArray[index])} +
+ + + + + {#each visibleBoxes as box (box.id)} + + {/each} + + + + + {#each visibleBoxes as boundingbox, index (boundingbox.id)}
- {faceToNameMap.get($boundingBoxesArray[index])} -
- {/if} - {/each} + class="absolute border-solid border-white border-3 rounded-lg" + style="top: {boundingbox.top}px; left: {boundingbox.left}px; height: {boundingbox.height}px; width: {boundingbox.width}px;" + >
+ {#if faceToNameMap.get(visibleBoundingBoxes[index])} +
+ {faceToNameMap.get(visibleBoundingBoxes[index])} +
+ {/if} + {/each} +
{#each ocrBoxes as ocrBox (ocrBox.id)} @@ -265,7 +287,7 @@ {/snippet} - {#if isFaceEditMode.value && assetViewerManager.imgRef} + {#if assetViewerManager.isFaceEditMode && assetViewerManager.imgRef} {/if}
diff --git a/web/src/lib/components/asset-viewer/slideshow-bar.svelte b/web/src/lib/components/asset-viewer/slideshow-bar.svelte index 21f99952c3..8cdcbcda56 100644 --- a/web/src/lib/components/asset-viewer/slideshow-bar.svelte +++ b/web/src/lib/components/asset-viewer/slideshow-bar.svelte @@ -85,6 +85,7 @@ }); onDestroy(() => { + setCursorStyle(''); if (unsubscribeRestart) { unsubscribeRestart(); } 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 e53414be07..915d5ceb58 100644 --- a/web/src/lib/components/asset-viewer/video-native-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-native-viewer.svelte @@ -3,7 +3,7 @@ import VideoRemoteViewer from '$lib/components/asset-viewer/video-remote-viewer.svelte'; import { assetViewerFadeDuration } from '$lib/constants'; import { castManager } from '$lib/managers/cast-manager.svelte'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { autoPlayVideo, loopVideo as loopVideoPreference, @@ -115,7 +115,7 @@ let containerHeight = $state(0); $effect(() => { - if (isFaceEditMode.value) { + if (assetViewerManager.isFaceEditMode) { videoPlayer?.pause(); } }); @@ -172,7 +172,7 @@
{/if} - {#if isFaceEditMode.value} + {#if assetViewerManager.isFaceEditMode} {/if} {/if} diff --git a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte index a54ad911fd..3ee633a603 100644 --- a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte @@ -16,6 +16,7 @@ circle?: boolean; hidden?: boolean; border?: boolean; + highlighted?: boolean; hiddenIconClass?: string; class?: ClassValue; brokenAssetClass?: ClassValue; @@ -34,6 +35,7 @@ circle = false, hidden = false, border = false, + highlighted = false, hiddenIconClass = 'text-white', onComplete = undefined, class: imageClass = '', @@ -60,6 +62,8 @@ shadow && 'shadow-lg', (circle || !heightStyle) && 'aspect-square', border && 'border-3 border-immich-dark-primary/80 hover:border-immich-primary', + 'transition-shadow duration-150', + highlighted && 'ring-4 ring-immich-primary dark:ring-immich-dark-primary', ]); let style = $derived( diff --git a/web/src/lib/components/assets/thumbnail/thumbnail.svelte b/web/src/lib/components/assets/thumbnail/thumbnail.svelte index 64b5a835ed..3413e912b0 100644 --- a/web/src/lib/components/assets/thumbnail/thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/thumbnail.svelte @@ -19,6 +19,7 @@ mdiCheckCircle, mdiFileGifBox, mdiHeart, + mdiMagnifyPlusOutline, mdiMotionPauseOutline, mdiMotionPlayOutline, mdiRotate360, @@ -46,6 +47,7 @@ dimmed?: boolean; albumUsers?: UserResponseDto[]; onClick?: (asset: TimelineAsset) => void; + onPreview?: (asset: TimelineAsset) => void; onSelect?: (asset: TimelineAsset) => void; onMouseEvent?: (event: { isMouseOver: boolean; selectedGroupIndex: number }) => void; } @@ -65,6 +67,7 @@ showStackedIcon = true, albumUsers = [], onClick = undefined, + onPreview = undefined, onSelect = undefined, onMouseEvent = undefined, imageClass = '', @@ -208,7 +211,11 @@
{/if} + + {#if mouseOver && onPreview} + + {/if} +
0 && + searchedPeople.length < maximumLengthSearchPeople && + searchName.startsWith(searchWord) + ) { search(); return; } diff --git a/web/src/lib/components/faces-page/person-side-panel.svelte b/web/src/lib/components/faces-page/person-side-panel.svelte index cad29706a4..ddeddb1ed2 100644 --- a/web/src/lib/components/faces-page/person-side-panel.svelte +++ b/web/src/lib/components/faces-page/person-side-panel.svelte @@ -3,7 +3,6 @@ import { timeBeforeShowLoadingSpinner } from '$lib/constants'; import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { boundingBoxesArray } from '$lib/stores/people.store'; import { getPeopleThumbnailUrl, handlePromiseError } from '$lib/utils'; import { handleError } from '$lib/utils/handle-error'; @@ -179,7 +178,7 @@ peopleWithFaces = peopleWithFaces.filter((f) => f.id !== face.id); - await assetViewingStore.setAssetId(assetId); + await assetViewerManager.setAssetId(assetId); } catch (error) { handleError(error, $t('error_delete_face')); } @@ -226,6 +225,7 @@ {:else} {#each peopleWithFaces as face, index (face.id)} {@const personName = face.person ? face.person?.name : $t('face_unassigned')} + {@const isHighlighted = $boundingBoxesArray.some((b) => b.id === face.id)}
({ + getDatabaseBackupActions: () => ({ + Download: { type: 'command', title: 'Download', onAction: vi.fn() }, + Delete: { type: 'command', title: 'Delete', onAction: vi.fn() }, + }), + handleRestoreDatabaseBackup: vi.fn(), +})); + +describe('MaintenanceBackupEntry', () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2026-03-24T12:00:00Z')); + locale.set('en'); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it('renders relative backup time using the user timezone instead of UTC', () => { + const backupTimestamp = '20260324T110000'; + + const expectedRelativeTime = DateTime.fromFormat(backupTimestamp, "yyyyMMdd'T'HHmmss", { + zone: 'Asia/Tokyo', + }) + .toLocal() + .toRelative({ locale: 'en' }); + + const utcRelativeTime = DateTime.fromFormat(backupTimestamp, "yyyyMMdd'T'HHmmss", { + zone: 'UTC', + }) + .toLocal() + .toRelative({ locale: 'en' }); + + expect(expectedRelativeTime).toBeTruthy(); + expect(expectedRelativeTime).not.toEqual(utcRelativeTime); + + renderWithTooltips(MaintenanceBackupEntry, { + expectedVersion: '1.2.3', + filename: 'immich-db-backup-20260324T110000-v1.2.3-snapshot.sql.gz', + filesize: 1024, + timezone: 'Asia/Tokyo', + }); + + expect(screen.getByText(expectedRelativeTime!)).toBeInTheDocument(); + }); +}); diff --git a/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte b/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte index fd3420d199..5aa00d210e 100644 --- a/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte +++ b/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte @@ -13,16 +13,17 @@ filename: string; filesize: number; expectedVersion: string; + timezone?: string; }; - const { filename, filesize, expectedVersion }: Props = $props(); + const { filename, filesize, expectedVersion, timezone }: Props = $props(); const filesizeText = $derived(getBytesWithUnit(filesize, 1)); const backupDateTime = $derived.by(() => { const dateMatch = filename.match(/\d+T\d+/); if (dateMatch) { - return DateTime.fromFormat(dateMatch[0], "yyyyMMdd'T'HHmmss", { zone: 'utc' }).toLocal(); + return DateTime.fromFormat(dateMatch[0], "yyyyMMdd'T'HHmmss", { zone: timezone }).toLocal(); } return null; }); diff --git a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte index 45b475c22a..fbadcef31c 100644 --- a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte +++ b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte @@ -51,12 +51,13 @@ const unknownDateKey = $t('unknown_date'); for (const backup of backups) { + const timezone = backup.timezone; const dateMatch = backup.filename.match(/\d+T\d+/); let dateKey: string; let dt: DateTime; if (dateMatch) { - dt = DateTime.fromFormat(dateMatch[0], "yyyyMMdd'T'HHmmss", { zone: 'utc' }); + dt = DateTime.fromFormat(dateMatch[0], "yyyyMMdd'T'HHmmss", { zone: timezone }); dateKey = dt.toFormat('LLLL d, yyyy'); } else { dt = DateTime.fromMillis(0); @@ -128,6 +129,7 @@ filename={backup.filename} filesize={backup.filesize} expectedVersion={props.expectedVersion} + timezone={backup.timezone} /> {/each} diff --git a/web/src/lib/components/memory-page/memory-viewer.svelte b/web/src/lib/components/memory-page/memory-viewer.svelte index c86385b8d9..3aa68c5825 100644 --- a/web/src/lib/components/memory-page/memory-viewer.svelte +++ b/web/src/lib/components/memory-page/memory-viewer.svelte @@ -19,17 +19,16 @@ import TagAction from '$lib/components/timeline/actions/TagAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import { QueryParameter } from '$lib/constants'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; + import { memoryManager, type MemoryAsset } from '$lib/managers/memory-manager.svelte'; import type { TimelineAsset, Viewport } from '$lib/managers/timeline-manager/types'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; - import { memoryStore, type MemoryAsset } from '$lib/stores/memory.store.svelte'; import { locale, videoViewerMuted, videoViewerVolume } from '$lib/stores/preferences.store'; import { preferences } from '$lib/stores/user.store'; import { getAssetMediaUrl, handlePromiseError, memoryLaneTitle } from '$lib/utils'; - import { cancelMultiselect } from '$lib/utils/asset-utils'; import { fromISODateTimeUTC, toTimelineAsset } from '$lib/utils/timeline-util'; import { AssetMediaSize, AssetTypeEnum, getAssetInfo } from '@immich/sdk'; import { ActionButton, IconButton, toastManager } from '@immich/ui'; @@ -77,17 +76,15 @@ let isSaved = $derived(current?.memory.isSaved); let viewerHeight = $state(0); - const { isViewing } = assetViewingStore; const viewport: Viewport = $state({ width: 0, height: 0 }); // need to include padding in the viewport for gallery const galleryViewport: Viewport = $derived({ height: viewport.height, width: viewport.width - 32 }); - const assetInteraction = new AssetInteraction(); let progressBarController: Tween | undefined = $state(undefined); let videoPlayer: HTMLVideoElement | undefined = $state(); const asHref = (asset: { id: string }) => `?${QueryParameter.ID}=${asset.id}`; const handleNavigate = async (asset?: { id: string }) => { - if ($isViewing) { + if (assetViewerManager.isViewing) { return asset; } @@ -118,7 +115,7 @@ const handlePreviousMemory = () => handleNavigate(current?.previousMemory?.assets[0]); const handleEscape = async () => goto(Route.photos()); const handleSelectAll = () => - assetInteraction.selectAssets(current?.memory.assets.map((a) => toTimelineAsset(a)) || []); + assetMultiSelectManager.selectAssets(current?.memory.assets.map((a) => toTimelineAsset(a)) || []); const handleAction = async (callingContext: string, action: 'reset' | 'pause' | 'play') => { // leaving these log statements here as comments. Very useful to figure out what's going on during dev! @@ -187,7 +184,7 @@ if (!current) { return; } - memoryStore.hideAssetsFromMemory(ids); + memoryManager.hideAssetsFromMemory(ids); init(page); }; @@ -196,7 +193,7 @@ return; } - await memoryStore.deleteAssetFromMemory(current.asset.id); + await memoryManager.deleteAssetFromMemory(current.asset.id); init(page); }; @@ -205,7 +202,7 @@ return; } - await memoryStore.deleteMemory(current.memory.id); + await memoryManager.deleteMemory(current.memory.id); toastManager.primary($t('removed_memory')); init(page); }; @@ -216,7 +213,7 @@ } const newSavedState = !current.memory.isSaved; - await memoryStore.updateMemorySaved(current.memory.id, newSavedState); + await memoryManager.updateMemorySaved(current.memory.id, newSavedState); toastManager.primary(newSavedState ? $t('added_to_favorites') : $t('removed_from_favorites')); init(page); }; @@ -254,11 +251,11 @@ const loadFromParams = (page: Page | NavigationTarget | null) => { const assetId = page?.params?.assetId ?? page?.url.searchParams.get(QueryParameter.ID) ?? undefined; - return memoryStore.getMemoryAsset(assetId); + return memoryManager.getMemoryAsset(assetId); }; const init = (target: Page | NavigationTarget | null) => { - if (memoryStore.memories.length === 0) { + if (memoryManager.memories.length === 0) { return handlePromiseError(goto(Route.photos())); } @@ -281,7 +278,7 @@ if (playerInitialized || isVideoAssetButPlayerHasNotLoadedYet) { return; } - if ($isViewing) { + if (assetViewerManager.isViewing) { handlePromiseError(handleAction('initPlayer[AssetViewOpen]', 'pause')); } else if (isVideo) { // Image assets will start playing when the image is loaded. Only autostart video assets. @@ -291,7 +288,7 @@ }; afterNavigate(({ from, to }) => { - memoryStore.ready().then( + memoryManager.ready().then( () => { let target; if (to?.params?.assetId) { @@ -326,7 +323,7 @@ handleNextAsset() }, @@ -337,14 +334,10 @@ ]} /> -{#if assetInteraction.selectionActive} +{#if assetMultiSelectManager.selectionActive}
- cancelMultiselect(assetInteraction)} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + + {@const Actions = getAssetBulkActions($t)} - + - - {#if $preferences.tags.enabled && assetInteraction.isAllUserOwned} + + {#if $preferences.tags.enabled && assetMultiSelectManager.isAllUserOwned} {/if} @@ -670,7 +667,7 @@ assets={currentTimelineAssets} {viewerAssets} viewport={galleryViewport} - {assetInteraction} + assetInteraction={assetMultiSelectManager} slidingWindowOffset={viewerHeight} arrowNavigation={false} /> diff --git a/web/src/lib/components/onboarding-page/onboarding-server-privacy.svelte b/web/src/lib/components/onboarding-page/onboarding-server-privacy.svelte index c299d0bc35..e1c4d9765d 100644 --- a/web/src/lib/components/onboarding-page/onboarding-server-privacy.svelte +++ b/web/src/lib/components/onboarding-page/onboarding-server-privacy.svelte @@ -24,7 +24,7 @@ />
diff --git a/web/src/lib/components/pages/SharedLinkPage.svelte b/web/src/lib/components/pages/SharedLinkPage.svelte index c6270d2de3..01a97fffe7 100644 --- a/web/src/lib/components/pages/SharedLinkPage.svelte +++ b/web/src/lib/components/pages/SharedLinkPage.svelte @@ -3,7 +3,7 @@ import IndividualSharedViewer from '$lib/components/share-page/individual-shared-viewer.svelte'; import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte'; import ThemeButton from '$lib/components/shared-components/theme-button.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { user } from '$lib/stores/user.store'; import { setSharedLink } from '$lib/utils'; import { handleError } from '$lib/utils/handle-error'; @@ -31,7 +31,6 @@ const { data }: Props = $props(); - let { gridScrollTarget } = assetViewingStore; let { sharedLink, passwordRequired, key, slug, meta } = $state(data); let { title, description } = $state(meta); let isOwned = $derived($user ? $user.id === sharedLink?.userId : false); @@ -48,7 +47,7 @@ $t('shared_photos_and_videos_count', { values: { assetCount: sharedLink.assets.length } }); await tick(); await navigate( - { targetRoute: 'current', assetId: null, assetGridRouteSearchParams: $gridScrollTarget }, + { targetRoute: 'current', assetId: null, assetGridRouteSearchParams: assetViewerManager.gridScrollTarget }, { forceNavigate: true, replaceState: true }, ); } catch (error) { diff --git a/web/src/lib/components/share-page/individual-shared-viewer.svelte b/web/src/lib/components/share-page/individual-shared-viewer.svelte index ec58bd7ea3..b746c60d87 100644 --- a/web/src/lib/components/share-page/individual-shared-viewer.svelte +++ b/web/src/lib/components/share-page/individual-shared-viewer.svelte @@ -5,14 +5,14 @@ import RemoveFromSharedLink from '$lib/components/timeline/actions/RemoveFromSharedLinkAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import { AssetAction } from '$lib/constants'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import type { Viewport } from '$lib/managers/timeline-manager/types'; import { Route } from '$lib/route'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store'; import { mediaQueryManager } from '$lib/stores/media-query-manager.svelte'; import { handlePromiseError } from '$lib/utils'; - import { cancelMultiselect, downloadArchive } from '$lib/utils/asset-utils'; + import { downloadArchive } from '$lib/utils/asset-utils'; import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader'; import { handleError } from '$lib/utils/handle-error'; import { toTimelineAsset } from '$lib/utils/timeline-util'; @@ -31,7 +31,6 @@ let { sharedLink = $bindable(), isOwned }: Props = $props(); const viewport: Viewport = $state({ width: 0, height: 0 }); - const assetInteraction = new AssetInteraction(); let assets = $derived(sharedLink.assets); @@ -59,7 +58,7 @@ }; const handleSelectAll = () => { - assetInteraction.selectAssets(assets.map((asset) => toTimelineAsset(asset))); + assetMultiSelectManager.selectAssets(assets.map((asset) => toTimelineAsset(asset))); }; const handleAction = async (action: Action) => { @@ -76,15 +75,12 @@ {#if sharedLink?.allowUpload || assets.length > 1}
- +
- {#if assetInteraction.selectionActive} - cancelMultiselect(assetInteraction)} - > + {#if assetMultiSelectManager.selectionActive} + toTimelineAsset(a))); }; - const deselectAllAssets = () => { - cancelMultiselect(assetInteraction); - }; - const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Shift') { event.preventDefault(); @@ -153,18 +143,18 @@ // Select/deselect already loaded assets if (deselect) { - for (const candidate of assetInteraction.assetSelectionCandidates) { + for (const candidate of assetInteraction.candidates) { assetInteraction.removeAssetFromMultiselectGroup(candidate.id); } assetInteraction.removeAssetFromMultiselectGroup(asset.id); } else { - for (const candidate of assetInteraction.assetSelectionCandidates) { + for (const candidate of assetInteraction.candidates) { assetInteraction.selectAsset(candidate); } assetInteraction.selectAsset(asset); } - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); assetInteraction.setAssetSelectionStart(deselect ? null : asset); }; @@ -180,7 +170,7 @@ return; } - const startAsset = assetInteraction.assetSelectionStart; + const startAsset = assetInteraction.startAsset; if (!startAsset) { return; } @@ -202,13 +192,13 @@ }; const onDelete = () => { - const hasTrashedAsset = assetInteraction.selectedAssets.some((asset) => asset.isTrashed); + const hasTrashedAsset = assetInteraction.assets.some((asset) => asset.isTrashed); handlePromiseError(trashOrDelete(hasTrashedAsset)); }; const trashOrDelete = async (force: boolean = false) => { const forceOrNoTrash = force || !featureFlagsManager.value.trash; - const selectedAssets = assetInteraction.selectedAssets; + const selectedAssets = assetInteraction.assets; if ($showDeleteModal && forceOrNoTrash) { const confirmed = await modalManager.show(AssetDeleteConfirmModal, { size: selectedAssets.length }); @@ -224,17 +214,17 @@ onReload, ); - assetInteraction.clearMultiselect(); + assetInteraction.clear(); }; const toggleArchive = async () => { const ids = await archiveAssets( - assetInteraction.selectedAssets, + assetInteraction.assets, assetInteraction.isAllArchived ? AssetVisibility.Timeline : AssetVisibility.Archive, ); if (ids) { assets = assets.filter((asset) => !ids.includes(asset.id)); - deselectAllAssets(); + assetInteraction.clear(); } }; @@ -256,7 +246,7 @@ const shortcutList = $derived( (() => { - if ($isViewerOpen) { + if (assetViewerManager.isViewing) { return []; } @@ -274,8 +264,8 @@ if (assetInteraction.selectionActive) { shortcuts.push( - { shortcut: { key: 'Escape' }, onShortcut: deselectAllAssets }, - { shortcut: { key: 'D', ctrl: true }, onShortcut: deselectAllAssets }, + { shortcut: { key: 'Escape' }, onShortcut: () => assetInteraction.clear() }, + { shortcut: { key: 'D', ctrl: true }, onShortcut: () => assetInteraction.clear() }, ); if (allowDeletion) { shortcuts.push( @@ -335,13 +325,13 @@ $effect(() => { if (!lastAssetMouseEvent) { - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); } }); $effect(() => { if (!shiftKeyIsDown) { - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); } }); @@ -351,10 +341,10 @@ } }); - const assetCursor = $derived({ - current: $viewingAsset, - nextAsset: getNextAsset(navigationAssets, $viewingAsset), - previousAsset: getPreviousAsset(navigationAssets, $viewingAsset), + const assetCursor = $derived({ + current: assetViewerManager.asset!, + nextAsset: getNextAsset(navigationAssets, assetViewerManager.asset), + previousAsset: getPreviousAsset(navigationAssets, assetViewerManager.asset), }); @@ -386,6 +376,7 @@ void navigateToAsset(asset); }} onSelect={() => handleSelectAssets(currentAsset)} + onPreview={assetInteraction.selectionActive ? () => void navigateToAsset(asset) : undefined} onMouseEvent={() => assetMouseEventHandler(currentAsset)} {showArchiveIcon} asset={currentAsset} @@ -408,7 +399,7 @@ {/if} -{#if $isViewerOpen} +{#if assetViewerManager.isViewing} {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); handlePromiseError(navigate({ targetRoute: 'current', assetId: null })); }} /> diff --git a/web/src/lib/components/shared-components/map/MapTimelinePanel.svelte b/web/src/lib/components/shared-components/map/MapTimelinePanel.svelte index 859a811985..dba6128ab1 100644 --- a/web/src/lib/components/shared-components/map/MapTimelinePanel.svelte +++ b/web/src/lib/components/shared-components/map/MapTimelinePanel.svelte @@ -18,11 +18,11 @@ import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; import Portal from '$lib/elements/Portal.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { mapSettings } from '$lib/stores/preferences.store'; - import { preferences, user } from '$lib/stores/user.store'; + import { preferences } from '$lib/stores/user.store'; import { updateStackedAssetInTimeline, updateUnstackedAssetInTimeline, @@ -44,9 +44,8 @@ let { bbox, selectedClusterIds, assetCount, onClose }: Props = $props(); - const assetInteraction = new AssetInteraction(); let timelineManager = $state() as TimelineManager; - let selectedAssets = $derived(assetInteraction.selectedAssets); + let selectedAssets = $derived(assetMultiSelectManager.assets); let isAssetStackSelected = $derived(selectedAssets.length === 1 && !!selectedAssets[0].stack); let isLinkActionAvailable = $derived.by(() => { const isLivePhoto = selectedAssets.length === 1 && !!selectedAssets[0].livePhotoVideoId; @@ -55,7 +54,7 @@ selectedAssets.some((asset) => asset.isImage) && selectedAssets.some((asset) => asset.isVideo); - return assetInteraction.isAllUserOwned && (isLivePhoto || isLivePhotoCandidate); + return assetMultiSelectManager.isAllUserOwned && (isLivePhoto || isLivePhotoCandidate); }); const handleLink: OnLink = ({ still, motion }) => { @@ -70,11 +69,11 @@ const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const handleEscape = () => { - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const timelineBoundingBox = $derived( @@ -91,7 +90,7 @@ $effect.pre(() => { void timelineOptions; - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }); @@ -112,35 +111,31 @@ enableRouting={false} options={timelineOptions} onEscape={handleEscape} - {assetInteraction} + assetInteraction={assetMultiSelectManager} showArchiveIcon />
-{#if assetInteraction.selectionActive} - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} +{#if assetMultiSelectManager.selectionActive} + {@const Actions = getAssetBulkActions($t)} - assetInteraction.clearMultiselect()} - > + - + - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} /> - {#if assetInteraction.selectedAssets.length > 1 || isAssetStackSelected} + {#if assetMultiSelectManager.assets.length > 1 || isAssetStackSelected} updateStackedAssetInTimeline(timelineManager, result)} @@ -150,7 +145,7 @@ {#if isLinkActionAvailable} @@ -160,7 +155,7 @@ timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> {#if $preferences.tags.enabled} 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 a5fae6c3f3..891331eaed 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 @@ -184,6 +184,7 @@ localStorage.setItem('searchQueryType', type); currentSearchType = type; showSearchTypeDropdown = false; + input?.focus(); }; const onsubmit = (event: Event) => { @@ -306,43 +307,46 @@ />
- {#if searchStore.isSearchEnabled} -
0} - > -
- +
0} + > +
+ - {#if showSearchTypeDropdown} -
- {#each searchTypes as searchType (searchType.value)} - - {/each} -
- {/if} -
+ onclick={() => selectSearchType(searchType.value)} + > + {searchType.label()} + + {/each} +
+ {/if}
- {/if} +
{#if showClearIcon}
diff --git a/web/src/lib/components/shared-components/side-bar/storage-space.svelte b/web/src/lib/components/shared-components/side-bar/storage-space.svelte index 5453ad8f58..43718e9db2 100644 --- a/web/src/lib/components/shared-components/side-bar/storage-space.svelte +++ b/web/src/lib/components/shared-components/side-bar/storage-space.svelte @@ -4,38 +4,18 @@ import { userInteraction } from '$lib/stores/user.svelte'; import { requestServerInfo } from '$lib/utils/auth'; import { getByteUnitString } from '$lib/utils/byte-units'; - import { LoadingSpinner } from '@immich/ui'; + import { LoadingSpinner, Meter } from '@immich/ui'; import { onMount } from 'svelte'; import { t } from 'svelte-i18n'; - let usageClasses = $state(''); - let hasQuota = $derived($user?.quotaSizeInBytes !== null); let availableBytes = $derived((hasQuota ? $user?.quotaSizeInBytes : userInteraction.serverInfo?.diskSizeRaw) || 0); let usedBytes = $derived((hasQuota ? $user?.quotaUsageInBytes : userInteraction.serverInfo?.diskUseRaw) || 0); - let usedPercentage = $derived(Math.min(Math.round((usedBytes / availableBytes) * 100), 100)); - const onUpdate = () => { - usageClasses = getUsageClass(); - }; - - const getUsageClass = () => { - if (usedPercentage >= 95) { - return 'bg-red-500'; - } - - if (usedPercentage > 80) { - return 'bg-yellow-500'; - } - - return 'bg-primary'; - }; - - $effect(() => { - if ($user) { - onUpdate(); - } - }); + const thresholds = [ + { from: 0.8, className: 'bg-warning' }, + { from: 0.95, className: 'bg-danger' }, + ]; onMount(async () => { if (userInteraction.serverInfo && $user) { @@ -46,7 +26,7 @@
-

{$t('storage')}

- {#if userInteraction.serverInfo} -

- {$t('storage_usage', { + - -

-
-
+ value={usedBytes / availableBytes} + {thresholds} + /> {:else} -
- -
+

{$t('storage')}

+ {/if}
diff --git a/web/src/lib/components/timeline/AssetLayout.svelte b/web/src/lib/components/timeline/AssetLayout.svelte index 8b06d9b72b..4ecf71f517 100644 --- a/web/src/lib/components/timeline/AssetLayout.svelte +++ b/web/src/lib/components/timeline/AssetLayout.svelte @@ -1,5 +1,6 @@
- {#each filterIntersecting(viewerAssets) as viewerAsset (viewerAsset.id)} + {#each filterIsInOrNearViewport(viewerAssets) as viewerAsset (viewerAsset.id)} {@const position = viewerAsset.position!} {@const asset = viewerAsset.asset!} diff --git a/web/src/lib/components/timeline/AssetSelectControlBar.svelte b/web/src/lib/components/timeline/AssetSelectControlBar.svelte index e722ce90c8..07fd1688a9 100644 --- a/web/src/lib/components/timeline/AssetSelectControlBar.svelte +++ b/web/src/lib/components/timeline/AssetSelectControlBar.svelte @@ -1,32 +1,23 @@ - - - + {#snippet leading()}

{assets.length}

diff --git a/web/src/lib/components/timeline/Month.svelte b/web/src/lib/components/timeline/Month.svelte index 91073a0a5f..28996b204a 100644 --- a/web/src/lib/components/timeline/Month.svelte +++ b/web/src/lib/components/timeline/Month.svelte @@ -1,11 +1,11 @@ -{#each filterIntersecting(monthGroup.dayGroups) as dayGroup, groupIndex (dayGroup.day)} - {@const isDayGroupSelected = assetInteraction.selectedGroup.has(dayGroup.groupTitle)} +{#each filterIsInOrNearViewport(timelineMonth.timelineDays) as timelineDay, groupIndex (timelineDay.day)} + {@const isTimelineDaySelected = assetInteraction.selectedGroup.has(timelineDay.groupTitle)}
(hoveredDayGroup = dayGroup.groupTitle)} - onmouseleave={() => (hoveredDayGroup = null)} + style:inset-inline-start={timelineDay.start + 'px'} + style:top={timelineDay.top + 'px'} + onmouseenter={() => (hoveredTimelineDay = timelineDay.groupTitle)} + onmouseleave={() => (hoveredTimelineDay = null)} >
{#if !singleSelect}
onDayGroupSelect(dayGroup, assetsSnapshot(dayGroup.getAssets()))} - onkeydown={() => onDayGroupSelect(dayGroup, assetsSnapshot(dayGroup.getAssets()))} + class:w-8={hoveredTimelineDay === timelineDay.groupTitle || + assetInteraction.selectedGroup.has(timelineDay.groupTitle)} + onclick={() => onTimelineDaySelect(timelineDay, assetsSnapshot(timelineDay.getAssets()))} + onkeydown={() => onTimelineDaySelect(timelineDay, assetsSnapshot(timelineDay.getAssets()))} > - {#if isDayGroupSelected} + {#if isTimelineDaySelected} {:else} @@ -87,20 +93,20 @@
{/if} - - {dayGroup.groupTitle} + + {timelineDay.groupTitle}
{#snippet thumbnail({ asset, position })} - {@render thumbnailWithGroup({ asset, position, dayGroup, groupIndex })} + {@render thumbnailWithGroup({ asset, position, timelineDay, groupIndex })} {/snippet}
diff --git a/web/src/lib/components/timeline/Scrubber.svelte b/web/src/lib/components/timeline/Scrubber.svelte index c6f81eb1ce..99aec0e429 100644 --- a/web/src/lib/components/timeline/Scrubber.svelte +++ b/web/src/lib/components/timeline/Scrubber.svelte @@ -92,7 +92,7 @@ scrubberWidth = usingMobileDevice ? MOBILE_WIDTH : DESKTOP_WIDTH; }); - const toScrollFromMonthGroupPercentage = ( + const toScrollFromTimelineMonthPercentage = ( scrubberMonth: ViewportTopMonth, scrubberMonthPercent: number, scrubOverallPercent: number, @@ -125,7 +125,7 @@ } }; const scrollY = $derived( - toScrollFromMonthGroupPercentage(viewportTopMonth, viewportTopMonthScrollPercent, timelineScrollPercent), + toScrollFromTimelineMonthPercentage(viewportTopMonth, viewportTopMonthScrollPercent, timelineScrollPercent), ); const timelineFullHeight = $derived(timelineManager.scrubberTimelineHeight); const relativeTopOffset = $derived(toScrollY(timelineTopOffset / timelineFullHeight)); @@ -281,12 +281,12 @@ const boundingClientRect = bestElement.boundingClientRect; const sy = boundingClientRect.y; const relativeY = y - sy; - const monthGroupPercentY = relativeY / boundingClientRect.height; + const timelineMonthPercentY = relativeY / boundingClientRect.height; return { isOnPaddingTop: false, isOnPaddingBottom: false, segment, - monthGroupPercentY, + timelineMonthPercentY, }; } @@ -309,7 +309,7 @@ isOnPaddingTop, isOnPaddingBottom, segment: undefined, - monthGroupPercentY: 0, + timelineMonthPercentY: 0, }; }; @@ -328,7 +328,7 @@ const upper = rect?.height - (PADDING_TOP + PADDING_BOTTOM); hoverY = clamp(clientY - rect?.top - PADDING_TOP, lower, upper); const x = rect!.left + rect!.width / 2; - const { segment, monthGroupPercentY, isOnPaddingTop, isOnPaddingBottom } = getActive(x, clientY); + const { segment, timelineMonthPercentY, isOnPaddingTop, isOnPaddingBottom } = getActive(x, clientY); activeSegment = segment; isHoverOnPaddingTop = isOnPaddingTop; isHoverOnPaddingBottom = isOnPaddingBottom; @@ -336,7 +336,7 @@ const scrubData = { scrubberMonth: segmentDate, overallScrollPercent: toTimelineY(hoverY), - scrubberMonthScrollPercent: monthGroupPercentY, + scrubberMonthScrollPercent: timelineMonthPercentY, }; if (wasDragging === false && isDragging) { void startScrub?.(scrubData); diff --git a/web/src/lib/components/timeline/Timeline.svelte b/web/src/lib/components/timeline/Timeline.svelte index d6ce722c96..bcef9f3260 100644 --- a/web/src/lib/components/timeline/Timeline.svelte +++ b/web/src/lib/components/timeline/Timeline.svelte @@ -11,14 +11,14 @@ import HotModuleReload from '$lib/elements/HotModuleReload.svelte'; import Portal from '$lib/elements/Portal.svelte'; import Skeleton from '$lib/elements/Skeleton.svelte'; - import type { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte'; + import type { AssetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; + import type { TimelineDay } from '$lib/managers/timeline-manager/timeline-day.svelte'; import { isIntersecting } from '$lib/managers/timeline-manager/internal/intersection-support.svelte'; - import type { MonthGroup } from '$lib/managers/timeline-manager/month-group.svelte'; + import type { TimelineMonth } from '$lib/managers/timeline-manager/timeline-month.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset, TimelineManagerOptions, ViewportTopMonth } from '$lib/managers/timeline-manager/types'; import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte'; - import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { mediaQueryManager } from '$lib/stores/media-query-manager.svelte'; import { isAssetViewerRoute, navigate } from '$lib/utils/navigation'; import { getTimes, type ScrubberListener } from '$lib/utils/timeline-util'; @@ -36,7 +36,7 @@ enableRouting: boolean; timelineManager?: TimelineManager; options?: TimelineManagerOptions; - assetInteraction: AssetInteraction; + assetInteraction: AssetMultiSelectManager; removeAction?: AssetAction.UNARCHIVE | AssetAction.ARCHIVE | AssetAction.SET_VISIBILITY_TIMELINE | null; withStacked?: boolean; showArchiveIcon?: boolean; @@ -52,7 +52,7 @@ onThumbnailClick?: ( asset: TimelineAsset, timelineManager: TimelineManager, - dayGroup: DayGroup, + timelineDay: TimelineDay, onClick: ( timelineManager: TimelineManager, assets: TimelineAsset[], @@ -88,10 +88,7 @@ onDestroy(() => timelineManager.destroy()); $effect(() => options && void timelineManager.updateOptions(options)); - let { isViewing: showAssetViewer, asset: viewingAsset, gridScrollTarget } = assetViewingStore; - let scrollableElement: HTMLElement | undefined = $state(); - let timelineElement: HTMLElement | undefined = $state(); let invisible = $state(true); // The percentage of scroll through the month that is currently intersecting the top boundary of the viewport. @@ -124,10 +121,11 @@ timelineManager.scrollableElement = scrollableElement; }); - const getAssetPosition = (assetId: string, monthGroup: MonthGroup) => monthGroup.findAssetAbsolutePosition(assetId); + const getAssetPosition = (assetId: string, timelineMonth: TimelineMonth) => + timelineMonth.findAssetAbsolutePosition(assetId); - const scrollToAssetPosition = (assetId: string, monthGroup: MonthGroup) => { - const position = getAssetPosition(assetId, monthGroup); + const scrollToAssetPosition = (assetId: string, timelineMonth: TimelineMonth) => { + const position = getAssetPosition(assetId, timelineMonth); if (!position) { return; @@ -179,11 +177,11 @@ // the performance benefits of deferred layouts while still supporting deep linking // to assets at the end of the timeline. timelineManager.isScrollingOnLoad = true; - const monthGroup = await timelineManager.findMonthGroupForAsset({ id: assetId }); - if (!monthGroup) { + const timelineMonth = await timelineManager.findTimelineMonthForAsset({ id: assetId }); + if (!timelineMonth) { return false; } - scrollToAssetPosition(assetId, monthGroup); + scrollToAssetPosition(assetId, timelineMonth); return true; } finally { timelineManager.isScrollingOnLoad = false; @@ -191,11 +189,11 @@ }; const scrollToAsset = (asset: TimelineAsset) => { - const monthGroup = timelineManager.getMonthGroupByAssetId(asset.id); - if (!monthGroup) { + const timelineMonth = timelineManager.getTimelineMonthByAssetId(asset.id); + if (!timelineMonth) { return false; } - scrollToAssetPosition(asset.id, monthGroup); + scrollToAssetPosition(asset.id, timelineMonth); return true; }; @@ -209,7 +207,7 @@ timelineManager.viewportWidth = rect.width; } } - const scrollTarget = $gridScrollTarget?.at; + const scrollTarget = assetViewerManager.gridScrollTarget?.at; let scrolled = false; if (scrollTarget) { scrolled = await scrollAndLoadAsset(scrollTarget); @@ -265,10 +263,10 @@ } }); - const scrollToSegmentPercentage = (segmentTop: number, segmentHeight: number, monthGroupScrollPercent: number) => { + const scrollToSegmentPercentage = (segmentTop: number, segmentHeight: number, timelineMonthScrollPercent: number) => { const topOffset = segmentTop; const maxScrollPercent = timelineManager.maxScrollPercent; - const delta = segmentHeight * monthGroupScrollPercent; + const delta = segmentHeight * timelineMonthScrollPercent; const scrollToTop = (topOffset + delta) * maxScrollPercent; timelineManager.scrollTo(scrollToTop); @@ -297,13 +295,13 @@ scrubberMonthScrollPercent, ); } else { - const monthGroup = timelineManager.months.find( + const timelineMonth = timelineManager.months.find( ({ yearMonth: { year, month } }) => year === scrubberMonth.year && month === scrubberMonth.month, ); - if (!monthGroup) { + if (!timelineMonth) { return; } - scrollToSegmentPercentage(monthGroup.top, monthGroup.height, scrubberMonthScrollPercent); + scrollToSegmentPercentage(timelineMonth.top, timelineMonth.height, scrubberMonthScrollPercent); } }; @@ -328,28 +326,28 @@ const monthsLength = timelineManager.months.length; for (let i = -1; i < monthsLength + 1; i++) { - let monthGroup: ViewportTopMonth; - let monthGroupHeight: number; + let timelineMonth: ViewportTopMonth; + let timelineMonthHeight: number; if (i === -1) { // lead-in - monthGroup = 'lead-in'; - monthGroupHeight = timelineManager.topSectionHeight; + timelineMonth = 'lead-in'; + timelineMonthHeight = timelineManager.topSectionHeight; } else if (i === monthsLength) { // lead-out - monthGroup = 'lead-out'; - monthGroupHeight = timelineManager.bottomSectionHeight; + timelineMonth = 'lead-out'; + timelineMonthHeight = timelineManager.bottomSectionHeight; } else { - monthGroup = timelineManager.months[i].yearMonth; - monthGroupHeight = timelineManager.months[i].height; + timelineMonth = timelineManager.months[i].yearMonth; + timelineMonthHeight = timelineManager.months[i].height; } - let next = top - monthGroupHeight * maxScrollPercent; + let next = top - timelineMonthHeight * maxScrollPercent; // instead of checking for < 0, add a little wiggle room for subpixel resolution - if (next < -1 && monthGroup) { - viewportTopMonth = monthGroup; + if (next < -1 && timelineMonth) { + viewportTopMonth = timelineMonth; // allowing next to be at least 1 may cause percent to go negative, so ensure positive percentage - viewportTopMonthScrollPercent = Math.max(0, top / (monthGroupHeight * maxScrollPercent)); + viewportTopMonthScrollPercent = Math.max(0, top / (timelineMonthHeight * maxScrollPercent)); // compensate for lost precision/rounding errors advance to the next bucket, if present if (viewportTopMonthScrollPercent > 0.9999 && i + 1 < monthsLength - 1) { @@ -393,8 +391,8 @@ lastAssetMouseEvent = asset; }; - const handleGroupSelect = (dayGroup: DayGroup, assets: TimelineAsset[]) => { - const group = dayGroup.groupTitle; + const handleGroupSelect = (timelineDay: TimelineDay, assets: TimelineAsset[]) => { + const group = timelineDay.groupTitle; if (assetInteraction.selectedGroup.has(group)) { assetInteraction.removeGroupFromMultiselectGroup(group); for (const asset of assets) { @@ -407,7 +405,7 @@ } } - assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.selectedAssets.length; + assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.assets.length; }; const onSelectAssets = async (asset: TimelineAsset) => { @@ -416,35 +414,35 @@ } onSelect(asset); - const rangeSelection = assetInteraction.assetSelectionCandidates.length > 0; + const rangeSelection = assetInteraction.candidates.length > 0; const deselect = assetInteraction.hasSelectedAsset(asset.id); // Select/deselect already loaded assets if (deselect) { - for (const candidate of assetInteraction.assetSelectionCandidates) { + for (const candidate of assetInteraction.candidates) { assetInteraction.removeAssetFromMultiselectGroup(candidate.id); } assetInteraction.removeAssetFromMultiselectGroup(asset.id); } else { - for (const candidate of assetInteraction.assetSelectionCandidates) { + for (const candidate of assetInteraction.candidates) { handleSelectAsset(candidate); } handleSelectAsset(asset); } - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); - if (assetInteraction.assetSelectionStart && rangeSelection) { - const startBucket = timelineManager.getMonthGroupByAssetId(assetInteraction.assetSelectionStart.id); - const endBucket = timelineManager.getMonthGroupByAssetId(asset.id); + if (assetInteraction.startAsset && rangeSelection) { + const startBucket = timelineManager.getTimelineMonthByAssetId(assetInteraction.startAsset.id); + const endBucket = timelineManager.getTimelineMonthByAssetId(asset.id); if (!startBucket || !endBucket) { return; } - const monthGroups = timelineManager.months; - const startBucketIndex = monthGroups.indexOf(startBucket); - const endBucketIndex = monthGroups.indexOf(endBucket); + const timelineMonths = timelineManager.months; + const startBucketIndex = timelineMonths.indexOf(startBucket); + const endBucketIndex = timelineMonths.indexOf(endBucket); if (startBucketIndex === -1 || endBucketIndex === -1) { return; @@ -455,9 +453,9 @@ // Select/deselect assets in range (start,end) for (let index = rangeStartIndex + 1; index < rangeEndIndex; index++) { - const monthGroup = monthGroups[index]; - await timelineManager.loadMonthGroup(monthGroup.yearMonth); - for (const monthAsset of monthGroup.assetsIterator()) { + const timelineMonth = timelineMonths[index]; + await timelineManager.loadTimelineMonth(timelineMonth.yearMonth); + for (const monthAsset of timelineMonth.assetsIterator()) { if (deselect) { assetInteraction.removeAssetFromMultiselectGroup(monthAsset.id); } else { @@ -468,15 +466,15 @@ // Update date group selection in range [start,end] for (let index = rangeStartIndex; index <= rangeEndIndex; index++) { - const monthGroup = monthGroups[index]; + const timelineMonth = timelineMonths[index]; // Split month group into day groups and check each group - for (const dayGroup of monthGroup.dayGroups) { - const dayGroupTitle = dayGroup.groupTitle; - if (dayGroup.getAssets().every((a) => assetInteraction.hasSelectedAsset(a.id))) { - assetInteraction.addGroupToMultiselectGroup(dayGroupTitle); + for (const timelineDay of timelineMonth.timelineDays) { + const timelineDayTitle = timelineDay.groupTitle; + if (timelineDay.getAssets().every((a) => assetInteraction.hasSelectedAsset(a.id))) { + assetInteraction.addGroupToMultiselectGroup(timelineDayTitle); } else { - assetInteraction.removeGroupFromMultiselectGroup(dayGroupTitle); + assetInteraction.removeGroupFromMultiselectGroup(timelineDayTitle); } } } @@ -490,7 +488,7 @@ return; } - const startAsset = assetInteraction.assetSelectionStart; + const startAsset = assetInteraction.startAsset; if (!startAsset) { return; } @@ -501,13 +499,13 @@ $effect(() => { if (!lastAssetMouseEvent) { - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); } }); $effect(() => { if (!shiftKeyIsDown) { - assetInteraction.clearAssetSelectionCandidates(); + assetInteraction.clearCandidates(); } }); @@ -518,31 +516,33 @@ }); $effect(() => { - if ($showAssetViewer) { - const { localDateTime } = getTimes($viewingAsset.fileCreatedAt, DateTime.local().offset / 60); - void timelineManager.loadMonthGroup({ year: localDateTime.year, month: localDateTime.month }); + if (assetViewerManager.asset && assetViewerManager.isViewing) { + const { localDateTime } = getTimes(assetViewerManager.asset.fileCreatedAt, DateTime.local().offset / 60); + void timelineManager.loadTimelineMonth({ year: localDateTime.year, month: localDateTime.month }); } }); const assetSelectHandler = ( timelineManager: TimelineManager, asset: TimelineAsset, - assetsInDayGroup: TimelineAsset[], + assetsInTimelineDay: TimelineAsset[], groupTitle: string, ) => { void onSelectAssets(asset); // Check if all assets are selected in a group to toggle the group selection's icon - let selectedAssetsInGroupCount = assetsInDayGroup.filter(({ id }) => assetInteraction.hasSelectedAsset(id)).length; + let selectedAssetsInGroupCount = assetsInTimelineDay.filter(({ id }) => + assetInteraction.hasSelectedAsset(id), + ).length; // if all assets are selected in a group, add the group to selected group - if (selectedAssetsInGroupCount === assetsInDayGroup.length) { + if (selectedAssetsInGroupCount === assetsInTimelineDay.length) { assetInteraction.addGroupToMultiselectGroup(groupTitle); } else { assetInteraction.removeGroupFromMultiselectGroup(groupTitle); } - assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.selectedAssets.length; + assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.assets.length; }; const _onClick = ( @@ -565,7 +565,7 @@ onAfterUpdate={() => { const asset = page.url.searchParams.get('at'); if (asset) { - $gridScrollTarget = { at: asset }; + assetViewerManager.gridScrollTarget = { at: asset }; } void scrollAfterNavigate(); }} @@ -644,23 +644,23 @@ {/if}
- {#each timelineManager.months as monthGroup (monthGroup.viewId)} - {@const display = monthGroup.intersecting} - {@const absoluteHeight = monthGroup.top} + {#each timelineManager.months as timelineMonth (timelineMonth.viewId)} + {@const isInOrNearViewport = timelineMonth.isInOrNearViewport} + {@const absoluteHeight = timelineMonth.top} - {#if !monthGroup.isLoaded} + {#if !timelineMonth.isLoaded}
- +
- {:else if display} + {:else if isInOrNearViewport}
- {#snippet thumbnail({ asset, position, dayGroup, groupIndex })} + {#snippet thumbnail({ asset, position, timelineDay, groupIndex })} {@const isAssetSelectionCandidate = assetInteraction.hasSelectionCandidate(asset.id)} {@const isAssetSelected = assetInteraction.hasSelectedAsset(asset.id) || timelineManager.albumAssets.has(asset.id)} @@ -686,19 +686,22 @@ {groupIndex} onClick={(asset) => { if (typeof onThumbnailClick === 'function') { - onThumbnailClick(asset, timelineManager, dayGroup, _onClick); + onThumbnailClick(asset, timelineManager, timelineDay, _onClick); } else { - _onClick(timelineManager, dayGroup.getAssets(), dayGroup.groupTitle, asset); + _onClick(timelineManager, timelineDay.getAssets(), timelineDay.groupTitle, asset); } }} onSelect={() => { if (isSelectionMode || assetInteraction.selectionActive) { - assetSelectHandler(timelineManager, asset, dayGroup.getAssets(), dayGroup.groupTitle); + assetSelectHandler(timelineManager, asset, timelineDay.getAssets(), timelineDay.groupTitle); return; } void onSelectAssets(asset); }} onMouseEvent={() => handleSelectAssetCandidates(asset)} + onPreview={isSelectionMode || assetInteraction.selectionActive + ? (asset) => void navigate({ targetRoute: 'current', assetId: asset.id }) + : undefined} selected={isAssetSelected} selectionCandidate={isAssetSelectionCandidate} disabled={isAssetDisabled} @@ -722,7 +725,7 @@ - {#if $showAssetViewer} + {#if assetViewerManager.isViewing} {/if} @@ -733,7 +736,7 @@ scrollbar-width: none; } - .month-group { + .timeline-month { contain: layout size paint; transform-style: flat; backface-visibility: hidden; diff --git a/web/src/lib/components/timeline/TimelineAssetViewer.svelte b/web/src/lib/components/timeline/TimelineAssetViewer.svelte index bd4ead6def..47144dcca9 100644 --- a/web/src/lib/components/timeline/TimelineAssetViewer.svelte +++ b/web/src/lib/components/timeline/TimelineAssetViewer.svelte @@ -2,11 +2,11 @@ import type { Action } from '$lib/components/asset-viewer/actions/action'; import type { AssetCursor } from '$lib/components/asset-viewer/asset-viewer.svelte'; import { AssetAction } from '$lib/constants'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { assetCacheManager } from '$lib/managers/AssetCacheManager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { websocketEvents } from '$lib/stores/websocket'; import { handlePromiseError } from '$lib/utils'; import { updateStackedAssetInTimeline, updateUnstackedAssetInTimeline } from '$lib/utils/actions'; @@ -18,8 +18,6 @@ import { onDestroy, onMount, untrack } from 'svelte'; import { t } from 'svelte-i18n'; - let { asset: viewingAsset, gridScrollTarget } = assetViewingStore; - interface Props { timelineManager: TimelineManager; invisible: boolean; @@ -65,7 +63,7 @@ }; let assetCursor = $state({ - current: $viewingAsset, + current: assetViewerManager.asset!, previousAsset: undefined, nextAsset: undefined, }); @@ -82,9 +80,10 @@ //TODO: replace this with async derived in svelte 6 $effect(() => { - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - $viewingAsset; - untrack(() => handlePromiseError(loadCloseAssets($viewingAsset))); + const asset = assetViewerManager.asset; + if (asset) { + untrack(() => handlePromiseError(loadCloseAssets(asset))); + } }); const handleRandom = async () => { @@ -99,8 +98,26 @@ const handleClose = async (asset: { id: string }) => { invisible = true; - $gridScrollTarget = { at: asset.id }; - await navigate({ targetRoute: 'current', assetId: null, assetGridRouteSearchParams: $gridScrollTarget }); + assetViewerManager.gridScrollTarget = { at: asset.id }; + await navigate({ + targetRoute: 'current', + assetId: null, + assetGridRouteSearchParams: assetViewerManager.gridScrollTarget, + }); + }; + + const handleRemoveFromAlbum = async (assetIds: string[]) => { + timelineManager.removeAssets(assetIds); + + if (!assetIds.includes(assetCursor.current.id)) { + return; + } + + // keep the cleanup workflow in viewer by moving to adjacent asset first + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + (await navigateToAsset(assetCursor?.nextAsset)) || + (await navigateToAsset(assetCursor?.previousAsset)) || + (await handleClose(assetCursor.current)); }; const handlePreAction = async (action: Action) => { @@ -188,7 +205,7 @@ const restoredAsset = assets[0]; const asset = await getAssetInfo({ ...authManager.params, id: restoredAsset.id }); - assetViewingStore.setAsset(asset); + assetViewerManager.setAsset(asset); await navigate({ targetRoute: 'current', assetId: restoredAsset.id }); }; @@ -232,6 +249,7 @@ }} onUndoDelete={handleUndoDelete} onRandom={handleRandom} + onRemoveFromAlbum={handleRemoveFromAlbum} onClose={handleClose} /> {/await} diff --git a/web/src/lib/components/timeline/actions/ArchiveAction.svelte b/web/src/lib/components/timeline/actions/ArchiveAction.svelte index 95c586ede4..26545d5ccf 100644 --- a/web/src/lib/components/timeline/actions/ArchiveAction.svelte +++ b/web/src/lib/components/timeline/actions/ArchiveAction.svelte @@ -1,18 +1,18 @@ diff --git a/web/src/lib/components/timeline/actions/ChangeDescriptionAction.svelte b/web/src/lib/components/timeline/actions/ChangeDescriptionAction.svelte index 883e43aa50..2fb8dcc5a0 100644 --- a/web/src/lib/components/timeline/actions/ChangeDescriptionAction.svelte +++ b/web/src/lib/components/timeline/actions/ChangeDescriptionAction.svelte @@ -1,8 +1,8 @@ diff --git a/web/src/lib/components/timeline/actions/ChangeLocationAction.svelte b/web/src/lib/components/timeline/actions/ChangeLocationAction.svelte index 08d27bf793..5d9fdc139d 100644 --- a/web/src/lib/components/timeline/actions/ChangeLocationAction.svelte +++ b/web/src/lib/components/timeline/actions/ChangeLocationAction.svelte @@ -1,48 +1,39 @@ {#if menuItem} - (isShowChangeLocation = true)} - /> -{/if} -{#if isShowChangeLocation} - + {/if} diff --git a/web/src/lib/components/timeline/actions/CreateSharedLinkAction.svelte b/web/src/lib/components/timeline/actions/CreateSharedLinkAction.svelte index 8af880ed33..318318c432 100644 --- a/web/src/lib/components/timeline/actions/CreateSharedLinkAction.svelte +++ b/web/src/lib/components/timeline/actions/CreateSharedLinkAction.svelte @@ -1,14 +1,12 @@ diff --git a/web/src/lib/components/timeline/actions/DeleteAssetsAction.svelte b/web/src/lib/components/timeline/actions/DeleteAssetsAction.svelte index e643bae512..16fa72a75d 100644 --- a/web/src/lib/components/timeline/actions/DeleteAssetsAction.svelte +++ b/web/src/lib/components/timeline/actions/DeleteAssetsAction.svelte @@ -1,10 +1,10 @@ diff --git a/web/src/lib/components/timeline/actions/DownloadAction.svelte b/web/src/lib/components/timeline/actions/DownloadAction.svelte index 509aa3a0d7..0a9ab89df8 100644 --- a/web/src/lib/components/timeline/actions/DownloadAction.svelte +++ b/web/src/lib/components/timeline/actions/DownloadAction.svelte @@ -1,15 +1,15 @@ diff --git a/web/src/lib/components/timeline/actions/FavoriteAction.svelte b/web/src/lib/components/timeline/actions/FavoriteAction.svelte index d970a16b8d..b60740d471 100644 --- a/web/src/lib/components/timeline/actions/FavoriteAction.svelte +++ b/web/src/lib/components/timeline/actions/FavoriteAction.svelte @@ -1,7 +1,7 @@ diff --git a/web/src/lib/components/timeline/actions/RestoreAction.svelte b/web/src/lib/components/timeline/actions/RestoreAction.svelte index 48094825f6..946167fb61 100644 --- a/web/src/lib/components/timeline/actions/RestoreAction.svelte +++ b/web/src/lib/components/timeline/actions/RestoreAction.svelte @@ -1,6 +1,6 @@ {#if withText} - + {:else} - + {/if} diff --git a/web/src/lib/components/timeline/actions/SetVisibilityAction.svelte b/web/src/lib/components/timeline/actions/SetVisibilityAction.svelte index c1fa1c53ab..3806dc5325 100644 --- a/web/src/lib/components/timeline/actions/SetVisibilityAction.svelte +++ b/web/src/lib/components/timeline/actions/SetVisibilityAction.svelte @@ -1,7 +1,7 @@ diff --git a/web/src/lib/components/timeline/actions/TagAction.svelte b/web/src/lib/components/timeline/actions/TagAction.svelte index 63748cd214..e4887441e3 100644 --- a/web/src/lib/components/timeline/actions/TagAction.svelte +++ b/web/src/lib/components/timeline/actions/TagAction.svelte @@ -1,11 +1,11 @@ diff --git a/web/src/lib/components/timeline/actions/TimelineKeyboardActions.svelte b/web/src/lib/components/timeline/actions/TimelineKeyboardActions.svelte index a5fa34289b..d6cb1c170b 100644 --- a/web/src/lib/components/timeline/actions/TimelineKeyboardActions.svelte +++ b/web/src/lib/components/timeline/actions/TimelineKeyboardActions.svelte @@ -5,6 +5,8 @@ setFocusToAsset as setFocusAssetInit, setFocusTo as setFocusToInit, } from '$lib/components/timeline/actions/focus-actions'; + import type { AssetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; @@ -13,30 +15,26 @@ import NavigateToDateModal from '$lib/modals/NavigateToDateModal.svelte'; import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte'; import { Route } from '$lib/route'; - import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { showDeleteModal } from '$lib/stores/preferences.store'; import { searchStore } from '$lib/stores/search.svelte'; import { handlePromiseError } from '$lib/utils'; import { deleteAssets, updateStackedAssetInTimeline } from '$lib/utils/actions'; - import { archiveAssets, cancelMultiselect, selectAllAssets, stackAssets } from '$lib/utils/asset-utils'; + import { archiveAssets, selectAllAssets, stackAssets } from '$lib/utils/asset-utils'; import { AssetVisibility } from '@immich/sdk'; import { isModalOpen, modalManager } from '@immich/ui'; type Props = { timelineManager: TimelineManager; - assetInteraction: AssetInteraction; + assetInteraction: AssetMultiSelectManager; onEscape?: () => void; scrollToAsset: (asset: TimelineAsset) => boolean; }; let { timelineManager = $bindable(), assetInteraction, onEscape, scrollToAsset }: Props = $props(); - const { isViewing: showAssetViewer } = assetViewingStore; - const trashOrDelete = async (forceRequested?: boolean) => { const force = forceRequested || !featureFlagsManager.value.trash; - const selectedAssets = assetInteraction.selectedAssets; + const selectedAssets = assetInteraction.assets; if ($showDeleteModal && force) { const confirmed = await modalManager.show(AssetDeleteConfirmModal, { size: selectedAssets.length }); @@ -54,16 +52,16 @@ selectedAssets, force ? undefined : (assets) => timelineManager.upsertAssets(assets), ); - assetInteraction.clearMultiselect(); + assetInteraction.clear(); }; const onDelete = () => { - const hasTrashedAsset = assetInteraction.selectedAssets.some((asset) => asset.isTrashed); + const hasTrashedAsset = assetInteraction.assets.some((asset) => asset.isTrashed); handlePromiseError(trashOrDelete(hasTrashedAsset)); }; const onStackAssets = async () => { - const result = await stackAssets(assetInteraction.selectedAssets); + const result = await stackAssets(assetInteraction.assets); updateStackedAssetInTimeline(timelineManager, result); @@ -72,18 +70,14 @@ const toggleArchive = async () => { const visibility = assetInteraction.isAllArchived ? AssetVisibility.Timeline : AssetVisibility.Archive; - const ids = await archiveAssets(assetInteraction.selectedAssets, visibility); + const ids = await archiveAssets(assetInteraction.assets, visibility); timelineManager.update(ids, (asset) => (asset.visibility = visibility)); eventManager.emit('AssetsArchive', ids); - deselectAllAssets(); + assetInteraction.clear(); }; let shiftKeyIsDown = $state(false); - const deselectAllAssets = () => { - cancelMultiselect(assetInteraction); - }; - const onKeyDown = (event: KeyboardEvent) => { if (searchStore.isSearchEnabled) { return; @@ -127,7 +121,7 @@ $effect(() => { if (isEmpty) { - assetInteraction.clearMultiselect(); + assetInteraction.clear(); } }); @@ -142,7 +136,7 @@ }; const shortcutList = $derived.by(() => { - if (searchStore.isSearchEnabled || $showAssetViewer || isModalOpen()) { + if (searchStore.isSearchEnabled || assetViewerManager.isViewing || isModalOpen()) { return []; } @@ -168,7 +162,7 @@ shortcuts.push( { shortcut: { key: 'Delete' }, onShortcut: onDelete }, { shortcut: { key: 'Delete', shift: true }, onShortcut: () => trashOrDelete(true) }, - { shortcut: { key: 'D', ctrl: true }, onShortcut: () => deselectAllAssets() }, + { shortcut: { key: 'D', ctrl: true }, onShortcut: () => assetInteraction.clear() }, { shortcut: { key: 's' }, onShortcut: () => onStackAssets() }, { shortcut: { key: 'a', shift: true }, onShortcut: toggleArchive }, ); diff --git a/web/src/lib/components/user-settings-page/PinCodeChangeForm.svelte b/web/src/lib/components/user-settings-page/PinCodeChangeForm.svelte index f230a01ba5..afab0c6819 100644 --- a/web/src/lib/components/user-settings-page/PinCodeChangeForm.svelte +++ b/web/src/lib/components/user-settings-page/PinCodeChangeForm.svelte @@ -1,9 +1,8 @@ - -
- {#if label} - - {/if} -
- {#each { length: pinLength } as _, index (index)} - handleInput(event, index)} - aria-label={`PIN digit ${index + 1} of ${pinLength}${label ? ` for ${label}` : ''}`} - /> - {/each} -
-
diff --git a/web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte b/web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte index aba2dc01f4..094b50813b 100644 --- a/web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte +++ b/web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte @@ -2,11 +2,10 @@ import { shortcuts } from '$lib/actions/shortcut'; import DuplicateAsset from '$lib/components/utilities-page/duplicates/duplicate-asset.svelte'; import Portal from '$lib/elements/Portal.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { handlePromiseError } from '$lib/utils'; import { getNextAsset, getPreviousAsset } from '$lib/utils/asset-utils'; - import { suggestDuplicate } from '$lib/utils/duplicate-utils'; import { navigate } from '$lib/utils/navigation'; import { getAssetInfo, type AssetResponseDto } from '@immich/sdk'; import { Button } from '@immich/ui'; @@ -17,30 +16,31 @@ interface Props { assets: AssetResponseDto[]; + suggestedKeepAssetIds: string[]; onResolve: (duplicateAssetIds: string[], trashIds: string[]) => void; onStack: (assets: AssetResponseDto[]) => void; } - let { assets, onResolve, onStack }: Props = $props(); - const { isViewing: showAssetViewer, asset: viewingAsset, setAsset } = assetViewingStore; - + let { assets, suggestedKeepAssetIds, onResolve, onStack }: Props = $props(); // eslint-disable-next-line svelte/no-unnecessary-state-wrap let selectedAssetIds = $state(new SvelteSet()); let trashCount = $derived(assets.length - selectedAssetIds.size); onMount(() => { - const suggestedAsset = suggestDuplicate(assets); - - if (!suggestedAsset) { - selectedAssetIds = new SvelteSet(assets[0].id); + if (suggestedKeepAssetIds.length > 0) { + for (const id of suggestedKeepAssetIds) { + selectedAssetIds.add(id); + } return; } - selectedAssetIds.add(suggestedAsset.id); + if (assets.length > 0) { + selectedAssetIds.add(assets[0].id); + } }); onDestroy(() => { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); }); const onRandom = async () => { @@ -71,7 +71,7 @@ const onViewAsset = async ({ id }: AssetResponseDto) => { const asset = await getAssetInfo({ ...authManager.params, id }); - setAsset(asset); + assetViewerManager.setAsset(asset); await navigate({ targetRoute: 'current', assetId: asset.id }); }; @@ -86,9 +86,9 @@ }; const assetCursor = $derived({ - current: $viewingAsset, - nextAsset: getNextAsset(assets, $viewingAsset), - previousAsset: getPreviousAsset(assets, $viewingAsset), + current: assetViewerManager.asset!, + nextAsset: getNextAsset(assets, assetViewerManager.asset), + previousAsset: getPreviousAsset(assets, assetViewerManager.asset), }); @@ -166,7 +166,7 @@
-{#if $showAssetViewer} +{#if assetViewerManager.isViewing} {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} 1} {onRandom} onClose={() => { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); handlePromiseError(navigate({ targetRoute: 'current', assetId: null })); }} /> diff --git a/web/src/lib/index.spec.ts b/web/src/lib/index.spec.ts index bda5a9e722..20f1244d50 100644 --- a/web/src/lib/index.spec.ts +++ b/web/src/lib/index.spec.ts @@ -1,4 +1,4 @@ -import { cleanClass } from '$lib'; +import { cleanClass, isDefined } from '$lib'; describe('cleanClass', () => { it('should return a string of class names', () => { @@ -13,3 +13,19 @@ describe('cleanClass', () => { expect(cleanClass('class1', ['class2', 'class3'])).toBe('class1 class2 class3'); }); }); + +describe('isDefined', () => { + it('should return false for null', () => { + expect(isDefined(null)).toBe(false); + }); + + it('should return false for undefined', () => { + expect(isDefined(undefined)).toBe(false); + }); + + it('should return true for everything else', () => { + for (const value of [0, 1, 2, true, false, {}, 'foo', 'bar', []]) { + expect(isDefined(value)).toBe(true); + } + }); +}); diff --git a/web/src/lib/index.ts b/web/src/lib/index.ts index b4fc195626..e659dadd46 100644 --- a/web/src/lib/index.ts +++ b/web/src/lib/index.ts @@ -14,3 +14,5 @@ export const cleanClass = (...classNames: unknown[]) => { .join(' '), ); }; + +export const isDefined = (value: T): value is NonNullable => value !== null && value !== undefined; diff --git a/web/src/lib/managers/VirtualScrollManager/VirtualScrollManager.svelte.ts b/web/src/lib/managers/VirtualScrollManager/VirtualScrollManager.svelte.ts index 12526527b7..fdbc86a7db 100644 --- a/web/src/lib/managers/VirtualScrollManager/VirtualScrollManager.svelte.ts +++ b/web/src/lib/managers/VirtualScrollManager/VirtualScrollManager.svelte.ts @@ -138,7 +138,7 @@ export abstract class VirtualScrollManager { return this.viewportWidth === 0 || this.viewportHeight === 0; } - protected updateIntersections(): void {} + protected updateViewportProximities(): void {} protected updateViewportGeometry(_: boolean) {} @@ -156,12 +156,12 @@ export abstract class VirtualScrollManager { const scrollTop = this.scrollTop; if (this.#scrollTop !== scrollTop) { this.#scrollTop = scrollTop; - this.updateIntersections(); + this.updateViewportProximities(); } } refreshLayout() { - this.updateIntersections(); + this.updateViewportProximities(); } destroy(): void {} diff --git a/web/src/lib/stores/asset-interaction.svelte.spec.ts b/web/src/lib/managers/asset-multi-select-manager.svelte.spec.ts similarity index 53% rename from web/src/lib/stores/asset-interaction.svelte.spec.ts rename to web/src/lib/managers/asset-multi-select-manager.svelte.spec.ts index 86e859f57e..f3948ce9ef 100644 --- a/web/src/lib/stores/asset-interaction.svelte.spec.ts +++ b/web/src/lib/managers/asset-multi-select-manager.svelte.spec.ts @@ -1,42 +1,42 @@ -import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; +import { AssetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { resetSavedUser, user } from '$lib/stores/user.store'; import { AssetVisibility } from '@immich/sdk'; import { timelineAssetFactory } from '@test-data/factories/asset-factory'; import { userAdminFactory } from '@test-data/factories/user-factory'; -describe('AssetInteraction', () => { - let assetInteraction: AssetInteraction; +describe('AssetMultiSelectManager', () => { + let sut: AssetMultiSelectManager; beforeEach(() => { - assetInteraction = new AssetInteraction(); + sut = new AssetMultiSelectManager(); }); it('calculates derived values from selection', () => { - assetInteraction.selectAsset( + sut.selectAsset( timelineAssetFactory.build({ isFavorite: true, visibility: AssetVisibility.Archive, isTrashed: true }), ); - assetInteraction.selectAsset( + sut.selectAsset( timelineAssetFactory.build({ isFavorite: true, visibility: AssetVisibility.Timeline, isTrashed: false }), ); - expect(assetInteraction.selectionActive).toBe(true); - expect(assetInteraction.isAllTrashed).toBe(false); - expect(assetInteraction.isAllArchived).toBe(false); - expect(assetInteraction.isAllFavorite).toBe(true); + expect(sut.selectionActive).toBe(true); + expect(sut.isAllTrashed).toBe(false); + expect(sut.isAllArchived).toBe(false); + expect(sut.isAllFavorite).toBe(true); }); it('updates isAllUserOwned when the active user changes', () => { const [user1, user2] = userAdminFactory.buildList(2); - assetInteraction.selectAsset(timelineAssetFactory.build({ ownerId: user1.id })); + sut.selectAsset(timelineAssetFactory.build({ ownerId: user1.id })); const cleanup = $effect.root(() => { - expect(assetInteraction.isAllUserOwned).toBe(false); + expect(sut.isAllUserOwned).toBe(false); user.set(user1); - expect(assetInteraction.isAllUserOwned).toBe(true); + expect(sut.isAllUserOwned).toBe(true); user.set(user2); - expect(assetInteraction.isAllUserOwned).toBe(false); + expect(sut.isAllUserOwned).toBe(false); }); cleanup(); diff --git a/web/src/lib/managers/asset-multi-select-manager.svelte.ts b/web/src/lib/managers/asset-multi-select-manager.svelte.ts new file mode 100644 index 0000000000..6bdea33094 --- /dev/null +++ b/web/src/lib/managers/asset-multi-select-manager.svelte.ts @@ -0,0 +1,105 @@ +import { eventManager } from '$lib/managers/event-manager.svelte'; +import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; +import { user } from '$lib/stores/user.store'; +import { AssetVisibility, type UserAdminResponseDto } from '@immich/sdk'; +import { SvelteMap, SvelteSet } from 'svelte/reactivity'; +import { fromStore } from 'svelte/store'; + +export type AssetMultiSelectOptions = { + resetOnNavigate?: boolean; +}; +export class AssetMultiSelectManager { + #selectedMap = new SvelteMap(); + #user = fromStore(user); + #userId = $derived(this.#user.current?.id); + + selectAll = $state(false); + startAsset = $state(null); + + selectedGroup = new SvelteSet(); + + candidates = $state([]); + + selectionActive = $derived(this.#selectedMap.size > 0); + + assets = $derived(Array.from(this.#selectedMap.values())); + ownedAssets = $derived(this.#userId ? this.assets.filter((asset) => asset.ownerId === this.#userId) : this.assets); + + isAllTrashed = $derived(this.assets.every((asset) => asset.isTrashed)); + isAllArchived = $derived(this.assets.every((asset) => asset.visibility === AssetVisibility.Archive)); + isAllFavorite = $derived(this.assets.every((asset) => asset.isFavorite)); + isAllUserOwned = $derived(this.assets.every((asset) => asset.ownerId === this.#userId)); + + #unsubscribe?: () => void; + + constructor(options?: AssetMultiSelectOptions) { + const { resetOnNavigate = false } = options ?? {}; + if (resetOnNavigate) { + this.#unsubscribe = eventManager.on({ AppNavigate: () => this.clear() }); + } + } + + destroy() { + this.#unsubscribe?.(); + } + + getOwnedAssets() { + return this.#userId ? this.assets.filter((asset) => asset.ownerId === this.#userId) : this.assets; + } + + hasSelectedAsset(assetId: string) { + return this.#selectedMap.has(assetId); + } + + hasSelectionCandidate(assetId: string) { + return this.candidates.some((asset) => asset.id === assetId); + } + + selectAsset(asset: TimelineAsset) { + this.#selectedMap.set(asset.id, asset); + } + + selectAssets(assets: TimelineAsset[]) { + for (const asset of assets) { + this.selectAsset(asset); + } + } + + removeAssetFromMultiselectGroup(assetId: string) { + this.#selectedMap.delete(assetId); + } + + addGroupToMultiselectGroup(group: string) { + this.selectedGroup.add(group); + } + + removeGroupFromMultiselectGroup(group: string) { + this.selectedGroup.delete(group); + } + + setAssetSelectionStart(asset: TimelineAsset | null) { + this.startAsset = asset; + } + + setAssetSelectionCandidates(assets: TimelineAsset[]) { + this.candidates = assets; + } + + clearCandidates() { + this.candidates = []; + } + + clear() { + this.selectAll = false; + + // Multi-selection + this.#selectedMap.clear(); + this.selectedGroup.clear(); + + // Range selection + this.candidates = []; + this.startAsset = null; + } +} + +export const assetMultiSelectManager = new AssetMultiSelectManager({ resetOnNavigate: true }); diff --git a/web/src/lib/managers/asset-viewer-manager.svelte.ts b/web/src/lib/managers/asset-viewer-manager.svelte.ts index 0bab3aff80..157ed31243 100644 --- a/web/src/lib/managers/asset-viewer-manager.svelte.ts +++ b/web/src/lib/managers/asset-viewer-manager.svelte.ts @@ -1,7 +1,10 @@ +import { authManager } from '$lib/managers/auth-manager.svelte'; import type { ImageLoaderStatus } from '$lib/utils/adaptive-image-loader.svelte'; import { canCopyImageToClipboard } from '$lib/utils/asset-utils'; import { BaseEventManager } from '$lib/utils/base-event-manager.svelte'; +import type { AssetGridRouteSearchParams } from '$lib/utils/navigation'; import { PersistedLocalStorage } from '$lib/utils/persisted'; +import { getAssetInfo, type AssetResponseDto } from '@immich/sdk'; import type { ZoomImageWheelState } from '@zoom-image/core'; import { cubicOut } from 'svelte/easing'; @@ -21,7 +24,7 @@ export type Events = { Copy: []; }; -export class AssetViewerManager extends BaseEventManager { +class AssetViewerManager extends BaseEventManager { #zoomState = $state(createDefaultZoomState()); #animationFrameId: number | null = null; @@ -39,6 +42,18 @@ export class AssetViewerManager extends BaseEventManager { isShowActivityPanel = $state(false); isPlayingMotionPhoto = $state(false); isShowEditor = $state(false); + #isFaceEditMode = $state(false); + #viewingAssetStoreState = $state(); + #viewState = $state(false); + gridScrollTarget = $state(); + + get asset() { + return this.#viewingAssetStoreState; + } + + get isViewing() { + return this.#viewState; + } get isImageLoading() { return this.#isImageLoading; @@ -48,6 +63,10 @@ export class AssetViewerManager extends BaseEventManager { return isShowDetailPanel.current; } + get isFaceEditMode() { + return this.#isFaceEditMode; + } + get zoomState() { return this.#zoomState; } @@ -145,6 +164,29 @@ export class AssetViewerManager extends BaseEventManager { closeEditor() { this.isShowEditor = false; } + + toggleFaceEditMode() { + this.#isFaceEditMode = !this.#isFaceEditMode; + } + + closeFaceEditMode() { + this.#isFaceEditMode = false; + } + + setAsset(asset: AssetResponseDto) { + this.#viewingAssetStoreState = asset; + this.#viewState = true; + } + + async setAssetId(id: string): Promise { + const asset = await getAssetInfo({ ...authManager.params, id }); + this.setAsset(asset); + return asset; + } + + showAssetViewer(show: boolean) { + this.#viewState = show; + } } export const assetViewerManager = new AssetViewerManager(); diff --git a/web/src/lib/managers/edit/transform-manager.svelte.ts b/web/src/lib/managers/edit/transform-manager.svelte.ts index 652cd0bee9..6b5901003e 100644 --- a/web/src/lib/managers/edit/transform-manager.svelte.ts +++ b/web/src/lib/managers/edit/transform-manager.svelte.ts @@ -203,7 +203,7 @@ class TransformManager implements EditToolManager { passive: true, }); - globalThis.addEventListener('mousemove', (e) => transformManager.handleMouseMove(e), { passive: true }); + globalThis.addEventListener('mousemove', (e: MouseEvent) => transformManager.handleMouseMove(e), { passive: true }); const transformEdits = edits.filter((e) => e.action === 'rotate' || e.action === 'mirror'); diff --git a/web/src/lib/managers/event-manager.svelte.ts b/web/src/lib/managers/event-manager.svelte.ts index 25e1b3c45b..61c1d3cbfa 100644 --- a/web/src/lib/managers/event-manager.svelte.ts +++ b/web/src/lib/managers/event-manager.svelte.ts @@ -20,6 +20,7 @@ import type { export type Events = { AppInit: []; + AppNavigate: []; AuthLogin: [LoginResponseDto]; AuthLogout: []; diff --git a/web/src/lib/managers/geolocation.manager.svelte.ts b/web/src/lib/managers/geolocation.manager.svelte.ts new file mode 100644 index 0000000000..d5b2c43912 --- /dev/null +++ b/web/src/lib/managers/geolocation.manager.svelte.ts @@ -0,0 +1,15 @@ +import type { LatLng } from '$lib/types'; + +class GeolocationManager { + #lastPoint = $state(); + + get lastPoint() { + return this.#lastPoint; + } + + onSelected(point: LatLng) { + this.#lastPoint = point; + } +} + +export const geolocationManager = new GeolocationManager(); diff --git a/web/src/lib/stores/memory.store.svelte.ts b/web/src/lib/managers/memory-manager.svelte.ts similarity index 98% rename from web/src/lib/stores/memory.store.svelte.ts rename to web/src/lib/managers/memory-manager.svelte.ts index cdd6af9606..9e34ff2d0e 100644 --- a/web/src/lib/stores/memory.store.svelte.ts +++ b/web/src/lib/managers/memory-manager.svelte.ts @@ -21,7 +21,7 @@ export type MemoryAsset = MemoryIndex & { nextMemory?: MemoryResponseDto; }; -class MemoryStoreSvelte { +class MemoryManager { #loading: Promise | undefined; constructor() { @@ -135,4 +135,4 @@ class MemoryStoreSvelte { } } -export const memoryStore = new MemoryStoreSvelte(); +export const memoryManager = new MemoryManager(); diff --git a/web/src/lib/managers/timeline-manager/group-insertion-cache.svelte.ts b/web/src/lib/managers/timeline-manager/group-insertion-cache.svelte.ts index 566b11b8b7..050b034d54 100644 --- a/web/src/lib/managers/timeline-manager/group-insertion-cache.svelte.ts +++ b/web/src/lib/managers/timeline-manager/group-insertion-cache.svelte.ts @@ -1,64 +1,64 @@ import { setDifference, type TimelineDate } from '$lib/utils/timeline-util'; import { AssetOrder } from '@immich/sdk'; -import type { DayGroup } from './day-group.svelte'; -import type { MonthGroup } from './month-group.svelte'; +import type { TimelineDay } from './timeline-day.svelte'; +import type { TimelineMonth } from './timeline-month.svelte'; import type { TimelineAsset } from './types'; export class GroupInsertionCache { #lookupCache: { - [year: number]: { [month: number]: { [day: number]: DayGroup } }; + [year: number]: { [month: number]: { [day: number]: TimelineDay } }; } = {}; unprocessedAssets: TimelineAsset[] = []; // eslint-disable-next-line svelte/prefer-svelte-reactivity - changedDayGroups = new Set(); + changedTimelineDays = new Set(); // eslint-disable-next-line svelte/prefer-svelte-reactivity - newDayGroups = new Set(); + newTimelineDays = new Set(); - getDayGroup({ year, month, day }: TimelineDate): DayGroup | undefined { + getTimelineDay({ year, month, day }: TimelineDate): TimelineDay | undefined { return this.#lookupCache[year]?.[month]?.[day]; } - setDayGroup(dayGroup: DayGroup, { year, month, day }: TimelineDate) { + setTimelineDay(timelineDay: TimelineDay, { year, month, day }: TimelineDate) { if (!this.#lookupCache[year]) { this.#lookupCache[year] = {}; } if (!this.#lookupCache[year][month]) { this.#lookupCache[year][month] = {}; } - this.#lookupCache[year][month][day] = dayGroup; + this.#lookupCache[year][month][day] = timelineDay; } - get existingDayGroups() { - return setDifference(this.changedDayGroups, this.newDayGroups); + get existingTimelineDays() { + return setDifference(this.changedTimelineDays, this.newTimelineDays); } get updatedBuckets() { // eslint-disable-next-line svelte/prefer-svelte-reactivity - const updated = new Set(); - for (const group of this.changedDayGroups) { - updated.add(group.monthGroup); + const updated = new Set(); + for (const group of this.changedTimelineDays) { + updated.add(group.timelineMonth); } return updated; } - get bucketsWithNewDayGroups() { + get bucketsWithNewTimelineDays() { // eslint-disable-next-line svelte/prefer-svelte-reactivity - const updated = new Set(); - for (const group of this.newDayGroups) { - updated.add(group.monthGroup); + const updated = new Set(); + for (const group of this.newTimelineDays) { + updated.add(group.timelineMonth); } return updated; } - sort(monthGroup: MonthGroup, sortOrder: AssetOrder = AssetOrder.Desc) { - for (const group of this.changedDayGroups) { + sort(timelineMonth: TimelineMonth, sortOrder: AssetOrder = AssetOrder.Desc) { + for (const group of this.changedTimelineDays) { group.sortAssets(sortOrder); } - for (const group of this.newDayGroups) { + for (const group of this.newTimelineDays) { group.sortAssets(sortOrder); } - if (this.newDayGroups.size > 0) { - monthGroup.sortDayGroups(); + if (this.newTimelineDays.size > 0) { + timelineMonth.sortTimelineDays(); } } } diff --git a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts index 3c6f2d8256..bb3ae72c81 100644 --- a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts @@ -1,73 +1,69 @@ import { TUNABLES } from '$lib/utils/tunables'; -import type { MonthGroup } from '../month-group.svelte'; import { TimelineManager } from '../timeline-manager.svelte'; +import type { TimelineMonth } from '../timeline-month.svelte'; const { TIMELINE: { INTERSECTION_EXPAND_TOP, INTERSECTION_EXPAND_BOTTOM }, } = TUNABLES; -export function updateIntersectionMonthGroup(timelineManager: TimelineManager, month: MonthGroup) { - const actuallyIntersecting = calculateMonthGroupIntersecting(timelineManager, month, 0, 0); - let preIntersecting = false; - if (!actuallyIntersecting) { - preIntersecting = calculateMonthGroupIntersecting( - timelineManager, - month, - INTERSECTION_EXPAND_TOP, - INTERSECTION_EXPAND_BOTTOM, - ); +export function isIntersecting(regionTop: number, regionBottom: number, otherTop: number, otherBottom: number) { + return ( + (regionTop >= otherTop && regionTop < otherBottom) || + (regionBottom >= otherTop && regionBottom < otherBottom) || + (regionTop < otherTop && regionBottom >= otherBottom) + ); +} + +export enum ViewportProximity { + FarFromViewport, + NearViewport, + InViewport, +} + +export function isInViewport(state: ViewportProximity): boolean { + return state === ViewportProximity.InViewport; +} + +export function isInOrNearViewport(state: ViewportProximity): boolean { + return state !== ViewportProximity.FarFromViewport; +} + +function calculateViewportProximity(regionTop: number, regionBottom: number, windowTop: number, windowBottom: number) { + if (regionBottom < windowTop - INTERSECTION_EXPAND_TOP || regionTop >= windowBottom + INTERSECTION_EXPAND_BOTTOM) { + return ViewportProximity.FarFromViewport; } - month.intersecting = actuallyIntersecting || preIntersecting; - month.actuallyIntersecting = actuallyIntersecting; - if (preIntersecting || actuallyIntersecting) { + + if (regionBottom < windowTop || regionTop >= windowBottom) { + return ViewportProximity.NearViewport; + } + + return ViewportProximity.InViewport; +} + +export function updateTimelineMonthViewportProximity(timelineManager: TimelineManager, month: TimelineMonth) { + const proximity = calculateViewportProximity( + month.top, + month.top + month.height, + timelineManager.visibleWindow.top, + timelineManager.visibleWindow.bottom, + ); + + month.viewportProximity = proximity; + if (isInOrNearViewport(proximity)) { timelineManager.clearDeferredLayout(month); } } -/** - * General function to check if a rectangular region intersects with a window. - * @param regionTop - Top position of the region to check - * @param regionBottom - Bottom position of the region to check - * @param windowTop - Top position of the window - * @param windowBottom - Bottom position of the window - * @returns true if the region intersects with the window - */ -export function isIntersecting(regionTop: number, regionBottom: number, windowTop: number, windowBottom: number) { - return ( - (regionTop >= windowTop && regionTop < windowBottom) || - (regionBottom >= windowTop && regionBottom < windowBottom) || - (regionTop < windowTop && regionBottom >= windowBottom) - ); -} - -export function calculateMonthGroupIntersecting( - timelineManager: TimelineManager, - monthGroup: MonthGroup, - expandTop: number, - expandBottom: number, -) { - const monthGroupTop = monthGroup.top; - const monthGroupBottom = monthGroupTop + monthGroup.height; - const topWindow = timelineManager.visibleWindow.top - expandTop; - const bottomWindow = timelineManager.visibleWindow.bottom + expandBottom; - - return isIntersecting(monthGroupTop, monthGroupBottom, topWindow, bottomWindow); -} - -/** - * Calculate intersection for viewer assets with additional parameters like header height - */ -export function calculateViewerAssetIntersecting( +export function calculateViewerAssetViewportProximity( timelineManager: TimelineManager, positionTop: number, positionHeight: number, - expandTop: number = INTERSECTION_EXPAND_TOP, - expandBottom: number = INTERSECTION_EXPAND_BOTTOM, ) { - const topWindow = timelineManager.visibleWindow.top - timelineManager.headerHeight - expandTop; - const bottomWindow = timelineManager.visibleWindow.bottom + timelineManager.headerHeight + expandBottom; - - const positionBottom = positionTop + positionHeight; - - return isIntersecting(positionTop, positionBottom, topWindow, bottomWindow); + const headerHeight = timelineManager.headerHeight; + return calculateViewportProximity( + positionTop, + positionTop + positionHeight, + timelineManager.visibleWindow.top - headerHeight, + timelineManager.visibleWindow.bottom + headerHeight, + ); } diff --git a/web/src/lib/managers/timeline-manager/internal/layout-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/layout-support.svelte.ts index 232c67a6ba..fc2902bb63 100644 --- a/web/src/lib/managers/timeline-manager/internal/layout-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/layout-support.svelte.ts @@ -1,8 +1,8 @@ -import type { MonthGroup } from '../month-group.svelte'; import { TimelineManager } from '../timeline-manager.svelte'; +import type { TimelineMonth } from '../timeline-month.svelte'; import type { UpdateGeometryOptions } from '../types'; -export function updateGeometry(timelineManager: TimelineManager, month: MonthGroup, options: UpdateGeometryOptions) { +export function updateGeometry(timelineManager: TimelineManager, month: TimelineMonth, options: UpdateGeometryOptions) { const { invalidateHeight, noDefer = false } = options; if (invalidateHeight) { month.isHeightActual = false; @@ -17,49 +17,49 @@ export function updateGeometry(timelineManager: TimelineManager, month: MonthGro } return; } - layoutMonthGroup(timelineManager, month, noDefer); + layoutTimelineMonth(timelineManager, month, noDefer); } -export function layoutMonthGroup(timelineManager: TimelineManager, month: MonthGroup, noDefer: boolean = false) { +export function layoutTimelineMonth(timelineManager: TimelineManager, month: TimelineMonth, noDefer: boolean = false) { let cumulativeHeight = 0; let cumulativeWidth = 0; let currentRowHeight = 0; - let dayGroupRow = 0; - let dayGroupCol = 0; + let timelineDayRow = 0; + let timelineDayCol = 0; const options = timelineManager.justifiedLayoutOptions; - for (const dayGroup of month.dayGroups) { - dayGroup.layout(options, noDefer); + for (const timelineDay of month.timelineDays) { + timelineDay.layout(options, noDefer); // Calculate space needed for this item (including gap if not first in row) - const spaceNeeded = dayGroup.width + (dayGroupCol > 0 ? timelineManager.gap : 0); + const spaceNeeded = timelineDay.width + (timelineDayCol > 0 ? timelineManager.gap : 0); const fitsInCurrentRow = cumulativeWidth + spaceNeeded <= timelineManager.viewportWidth; if (fitsInCurrentRow) { - dayGroup.row = dayGroupRow; - dayGroup.col = dayGroupCol++; - dayGroup.start = cumulativeWidth; - dayGroup.top = cumulativeHeight; + timelineDay.row = timelineDayRow; + timelineDay.col = timelineDayCol++; + timelineDay.start = cumulativeWidth; + timelineDay.top = cumulativeHeight; - cumulativeWidth += dayGroup.width + timelineManager.gap; + cumulativeWidth += timelineDay.width + timelineManager.gap; } else { // Move to next row cumulativeHeight += currentRowHeight; cumulativeWidth = 0; - dayGroupRow++; - dayGroupCol = 0; + timelineDayRow++; + timelineDayCol = 0; // Position at start of new row - dayGroup.row = dayGroupRow; - dayGroup.col = dayGroupCol; - dayGroup.start = 0; - dayGroup.top = cumulativeHeight; + timelineDay.row = timelineDayRow; + timelineDay.col = timelineDayCol; + timelineDay.start = 0; + timelineDay.top = cumulativeHeight; - dayGroupCol++; - cumulativeWidth += dayGroup.width + timelineManager.gap; + timelineDayCol++; + cumulativeWidth += timelineDay.width + timelineManager.gap; } - currentRowHeight = dayGroup.height + timelineManager.headerHeight; + currentRowHeight = timelineDay.height + timelineManager.headerHeight; } // Add the height of the final row diff --git a/web/src/lib/managers/timeline-manager/internal/load-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/load-support.svelte.ts index 859e818583..2d57192db2 100644 --- a/web/src/lib/managers/timeline-manager/internal/load-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/load-support.svelte.ts @@ -1,21 +1,21 @@ import { authManager } from '$lib/managers/auth-manager.svelte'; import { toISOYearMonthUTC } from '$lib/utils/timeline-util'; import { getTimeBucket } from '@immich/sdk'; -import type { MonthGroup } from '../month-group.svelte'; import { TimelineManager } from '../timeline-manager.svelte'; +import type { TimelineMonth } from '../timeline-month.svelte'; import type { TimelineManagerOptions } from '../types'; export async function loadFromTimeBuckets( timelineManager: TimelineManager, - monthGroup: MonthGroup, + timelineMonth: TimelineMonth, options: TimelineManagerOptions, signal: AbortSignal, ): Promise { - if (monthGroup.getFirstAsset()) { + if (timelineMonth.getFirstAsset()) { return; } - const timeBucket = toISOYearMonthUTC(monthGroup.yearMonth); + const timeBucket = toISOYearMonthUTC(timelineMonth.yearMonth); const bucketResponse = await getTimeBucket( { ...authManager.params, @@ -46,10 +46,10 @@ export async function loadFromTimeBuckets( } } - const unprocessedAssets = monthGroup.addAssets(bucketResponse, true); + const unprocessedAssets = timelineMonth.addAssets(bucketResponse, true); if (unprocessedAssets.length > 0) { console.error( - `Warning: getTimeBucket API returning assets not in requested month: ${monthGroup.yearMonth.month}, ${JSON.stringify( + `Warning: getTimeBucket API returning assets not in requested month: ${timelineMonth.yearMonth.month}, ${JSON.stringify( unprocessedAssets.map((unprocessed) => ({ id: unprocessed.id, localDateTime: unprocessed.localDateTime, diff --git a/web/src/lib/managers/timeline-manager/internal/search-support.svelte.spec.ts b/web/src/lib/managers/timeline-manager/internal/search-support.svelte.spec.ts index 2b8ca930eb..de0cad2213 100644 --- a/web/src/lib/managers/timeline-manager/internal/search-support.svelte.spec.ts +++ b/web/src/lib/managers/timeline-manager/internal/search-support.svelte.spec.ts @@ -1,74 +1,86 @@ import { describe, expect, it } from 'vitest'; -import type { MonthGroup } from '../month-group.svelte'; -import { findClosestGroupForDate } from './search-support.svelte'; +import type { TimelineMonth } from '../timeline-month.svelte'; +import { findClosestTimelineMonthForDate } from './search-support.svelte'; -function createMockMonthGroup(year: number, month: number): MonthGroup { +function createMockTimelineMonth(year: number, month: number): TimelineMonth { return { yearMonth: { year, month }, - } as MonthGroup; + } as TimelineMonth; } -describe('findClosestGroupForDate', () => { +describe('findClosestTimelineMonthForDate', () => { it('should return undefined for empty months array', () => { - const result = findClosestGroupForDate([], { year: 2024, month: 1 }); + const result = findClosestTimelineMonthForDate([], { year: 2024, month: 1 }); expect(result).toBeUndefined(); }); it('should return the only month when there is only one month', () => { - const months = [createMockMonthGroup(2024, 6)]; - const result = findClosestGroupForDate(months, { year: 2025, month: 1 }); + const months = [createMockTimelineMonth(2024, 6)]; + const result = findClosestTimelineMonthForDate(months, { year: 2025, month: 1 }); expect(result?.yearMonth).toEqual({ year: 2024, month: 6 }); }); it('should return exact match when available', () => { - const months = [createMockMonthGroup(2024, 1), createMockMonthGroup(2024, 6), createMockMonthGroup(2024, 12)]; - const result = findClosestGroupForDate(months, { year: 2024, month: 6 }); + const months = [ + createMockTimelineMonth(2024, 1), + createMockTimelineMonth(2024, 6), + createMockTimelineMonth(2024, 12), + ]; + const result = findClosestTimelineMonthForDate(months, { year: 2024, month: 6 }); expect(result?.yearMonth).toEqual({ year: 2024, month: 6 }); }); it('should find closest month when target is between two months', () => { - const months = [createMockMonthGroup(2024, 1), createMockMonthGroup(2024, 6), createMockMonthGroup(2024, 12)]; - const result = findClosestGroupForDate(months, { year: 2024, month: 4 }); + const months = [ + createMockTimelineMonth(2024, 1), + createMockTimelineMonth(2024, 6), + createMockTimelineMonth(2024, 12), + ]; + const result = findClosestTimelineMonthForDate(months, { year: 2024, month: 4 }); expect(result?.yearMonth).toEqual({ year: 2024, month: 6 }); }); it('should handle year boundaries correctly (2023-12 vs 2024-01)', () => { - const months = [createMockMonthGroup(2023, 12), createMockMonthGroup(2024, 2)]; - const result = findClosestGroupForDate(months, { year: 2024, month: 1 }); + const months = [createMockTimelineMonth(2023, 12), createMockTimelineMonth(2024, 2)]; + const result = findClosestTimelineMonthForDate(months, { year: 2024, month: 1 }); // 2024-01 is 1 month from 2023-12 and 1 month from 2024-02 // Should return first encountered with min distance (2023-12) expect(result?.yearMonth).toEqual({ year: 2023, month: 12 }); }); it('should correctly calculate distance across years', () => { - const months = [createMockMonthGroup(2022, 6), createMockMonthGroup(2024, 6)]; - const result = findClosestGroupForDate(months, { year: 2023, month: 6 }); + const months = [createMockTimelineMonth(2022, 6), createMockTimelineMonth(2024, 6)]; + const result = findClosestTimelineMonthForDate(months, { year: 2023, month: 6 }); // Both are exactly 12 months away, should return first encountered expect(result?.yearMonth).toEqual({ year: 2022, month: 6 }); }); it('should handle target before all months', () => { - const months = [createMockMonthGroup(2024, 6), createMockMonthGroup(2024, 12)]; - const result = findClosestGroupForDate(months, { year: 2024, month: 1 }); + const months = [createMockTimelineMonth(2024, 6), createMockTimelineMonth(2024, 12)]; + const result = findClosestTimelineMonthForDate(months, { year: 2024, month: 1 }); expect(result?.yearMonth).toEqual({ year: 2024, month: 6 }); }); it('should handle target after all months', () => { - const months = [createMockMonthGroup(2024, 1), createMockMonthGroup(2024, 6)]; - const result = findClosestGroupForDate(months, { year: 2025, month: 1 }); + const months = [createMockTimelineMonth(2024, 1), createMockTimelineMonth(2024, 6)]; + const result = findClosestTimelineMonthForDate(months, { year: 2025, month: 1 }); expect(result?.yearMonth).toEqual({ year: 2024, month: 6 }); }); it('should handle multiple years correctly', () => { - const months = [createMockMonthGroup(2020, 1), createMockMonthGroup(2022, 1), createMockMonthGroup(2024, 1)]; - const result = findClosestGroupForDate(months, { year: 2023, month: 1 }); + const months = [ + createMockTimelineMonth(2020, 1), + createMockTimelineMonth(2022, 1), + createMockTimelineMonth(2024, 1), + ]; + const result = findClosestTimelineMonthForDate(months, { year: 2023, month: 1 }); // 2023-01 is 12 months from 2022-01 and 12 months from 2024-01 expect(result?.yearMonth).toEqual({ year: 2022, month: 1 }); }); it('should prefer closer month when one is clearly closer', () => { - const months = [createMockMonthGroup(2024, 1), createMockMonthGroup(2024, 10)]; - const result = findClosestGroupForDate(months, { year: 2024, month: 11 }); + const months = [createMockTimelineMonth(2024, 1), createMockTimelineMonth(2024, 10)]; + const result = findClosestTimelineMonthForDate(months, { year: 2024, month: 11 }); // 2024-11 is 1 month from 2024-10 and 10 months from 2024-01 expect(result?.yearMonth).toEqual({ year: 2024, month: 10 }); }); diff --git a/web/src/lib/managers/timeline-manager/internal/search-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/search-support.svelte.ts index f881c6e7fc..68e2d355a9 100644 --- a/web/src/lib/managers/timeline-manager/internal/search-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/search-support.svelte.ts @@ -1,8 +1,8 @@ import { plainDateTimeCompare, type TimelineYearMonth } from '$lib/utils/timeline-util'; import { AssetOrder, type AssetResponseDto } from '@immich/sdk'; import { DateTime } from 'luxon'; -import type { MonthGroup } from '../month-group.svelte'; import { TimelineManager } from '../timeline-manager.svelte'; +import type { TimelineMonth } from '../timeline-month.svelte'; import type { AssetDescriptor, Direction, TimelineAsset } from '../types'; export async function getAssetWithOffset( @@ -11,44 +11,44 @@ export async function getAssetWithOffset( interval: 'asset' | 'day' | 'month' | 'year' = 'asset', direction: Direction, ): Promise { - const monthGroup = await timelineManager.findMonthGroupForAsset(assetDescriptor); - if (!monthGroup) { + const timelineMonth = await timelineManager.findTimelineMonthForAsset(assetDescriptor); + if (!timelineMonth) { return; } - const asset = monthGroup.findAssetById(assetDescriptor); + const asset = timelineMonth.findAssetById(assetDescriptor); if (!asset) { return; } switch (interval) { case 'asset': { - return getAssetByAssetOffset(timelineManager, asset, monthGroup, direction); + return getAssetByAssetOffset(timelineManager, asset, timelineMonth, direction); } case 'day': { - return getAssetByDayOffset(timelineManager, asset, monthGroup, direction); + return getAssetByDayOffset(timelineManager, asset, timelineMonth, direction); } case 'month': { - return getAssetByMonthOffset(timelineManager, monthGroup, direction); + return getAssetByMonthOffset(timelineManager, timelineMonth, direction); } case 'year': { - return getAssetByYearOffset(timelineManager, monthGroup, direction); + return getAssetByYearOffset(timelineManager, timelineMonth, direction); } } } -export function findMonthGroupForAsset(timelineManager: TimelineManager, id: string) { +export function findTimelineMonthForAsset(timelineManager: TimelineManager, id: string) { for (const month of timelineManager.months) { const asset = month.findAssetById({ id }); if (asset) { - return { monthGroup: month, asset }; + return { timelineMonth: month, asset }; } } } -export function getMonthGroupByDate( +export function getTimelineMonthByDate( timelineManager: TimelineManager, targetYearMonth: TimelineYearMonth, -): MonthGroup | undefined { +): TimelineMonth | undefined { return timelineManager.months.find( (month) => month.yearMonth.year === targetYearMonth.year && month.yearMonth.month === targetYearMonth.month, ); @@ -57,13 +57,13 @@ export function getMonthGroupByDate( async function getAssetByAssetOffset( timelineManager: TimelineManager, asset: TimelineAsset, - monthGroup: MonthGroup, + timelineMonth: TimelineMonth, direction: Direction, ) { - const dayGroup = monthGroup.findDayGroupForAsset(asset); + const timelineDay = timelineMonth.findTimelineDayForAsset(asset); for await (const targetAsset of timelineManager.assetsIterator({ - startMonthGroup: monthGroup, - startDayGroup: dayGroup, + startTimelineMonth: timelineMonth, + startTimelineDay: timelineDay, startAsset: asset, direction, })) { @@ -76,13 +76,13 @@ async function getAssetByAssetOffset( async function getAssetByDayOffset( timelineManager: TimelineManager, asset: TimelineAsset, - monthGroup: MonthGroup, + timelineMonth: TimelineMonth, direction: Direction, ) { - const dayGroup = monthGroup.findDayGroupForAsset(asset); + const timelineDay = timelineMonth.findTimelineDayForAsset(asset); for await (const targetAsset of timelineManager.assetsIterator({ - startMonthGroup: monthGroup, - startDayGroup: dayGroup, + startTimelineMonth: timelineMonth, + startTimelineDay: timelineDay, startAsset: asset, direction, })) { @@ -92,45 +92,50 @@ async function getAssetByDayOffset( } } -async function getAssetByMonthOffset(timelineManager: TimelineManager, month: MonthGroup, direction: Direction) { - for (const targetMonth of timelineManager.monthGroupIterator({ startMonthGroup: month, direction })) { +async function getAssetByMonthOffset(timelineManager: TimelineManager, month: TimelineMonth, direction: Direction) { + for (const targetMonth of timelineManager.timelineMonthIterator({ startTimelineMonth: month, direction })) { if (targetMonth.yearMonth.month !== month.yearMonth.month) { - const { value, done } = await timelineManager.assetsIterator({ startMonthGroup: targetMonth, direction }).next(); + const { value, done } = await timelineManager + .assetsIterator({ startTimelineMonth: targetMonth, direction }) + .next(); return done ? undefined : value; } } } -async function getAssetByYearOffset(timelineManager: TimelineManager, month: MonthGroup, direction: Direction) { - for (const targetMonth of timelineManager.monthGroupIterator({ startMonthGroup: month, direction })) { +async function getAssetByYearOffset(timelineManager: TimelineManager, month: TimelineMonth, direction: Direction) { + for (const targetMonth of timelineManager.timelineMonthIterator({ startTimelineMonth: month, direction })) { if (targetMonth.yearMonth.year !== month.yearMonth.year) { - const { value, done } = await timelineManager.assetsIterator({ startMonthGroup: targetMonth, direction }).next(); + const { value, done } = await timelineManager + .assetsIterator({ startTimelineMonth: targetMonth, direction }) + .next(); return done ? undefined : value; } } } export async function retrieveRange(timelineManager: TimelineManager, start: AssetDescriptor, end: AssetDescriptor) { - let { asset: startAsset, monthGroup: startMonthGroup } = findMonthGroupForAsset(timelineManager, start.id) ?? {}; - if (!startMonthGroup || !startAsset) { + let { asset: startAsset, timelineMonth: startTimelineMonth } = + findTimelineMonthForAsset(timelineManager, start.id) ?? {}; + if (!startTimelineMonth || !startAsset) { return []; } - let { asset: endAsset, monthGroup: endMonthGroup } = findMonthGroupForAsset(timelineManager, end.id) ?? {}; - if (!endMonthGroup || !endAsset) { + let { asset: endAsset, timelineMonth: endTimelineMonth } = findTimelineMonthForAsset(timelineManager, end.id) ?? {}; + if (!endTimelineMonth || !endAsset) { return []; } const assetOrder: AssetOrder = timelineManager.getAssetOrder(); if (plainDateTimeCompare(assetOrder === AssetOrder.Desc, startAsset.localDateTime, endAsset.localDateTime) < 0) { [startAsset, endAsset] = [endAsset, startAsset]; // eslint-disable-next-line no-useless-assignment - [startMonthGroup, endMonthGroup] = [endMonthGroup, startMonthGroup]; + [startTimelineMonth, endTimelineMonth] = [endTimelineMonth, startTimelineMonth]; } const range: TimelineAsset[] = []; - const startDayGroup = startMonthGroup.findDayGroupForAsset(startAsset); + const startTimelineDay = startTimelineMonth.findTimelineDayForAsset(startAsset); for await (const targetAsset of timelineManager.assetsIterator({ - startMonthGroup, - startDayGroup, + startTimelineMonth, + startTimelineDay, startAsset, })) { range.push(targetAsset); @@ -141,7 +146,7 @@ export async function retrieveRange(timelineManager: TimelineManager, start: Ass return range; } -export function findMonthGroupForDate(timelineManager: TimelineManager, targetYearMonth: TimelineYearMonth) { +export function findTimelineMonthForDate(timelineManager: TimelineManager, targetYearMonth: TimelineYearMonth) { for (const month of timelineManager.months) { const { year, month: monthNum } = month.yearMonth; if (monthNum === targetYearMonth.month && year === targetYearMonth.year) { @@ -150,10 +155,10 @@ export function findMonthGroupForDate(timelineManager: TimelineManager, targetYe } } -export function findClosestGroupForDate(months: MonthGroup[], targetYearMonth: TimelineYearMonth) { +export function findClosestTimelineMonthForDate(months: TimelineMonth[], targetYearMonth: TimelineYearMonth) { const targetDate = DateTime.fromObject({ year: targetYearMonth.year, month: targetYearMonth.month }); - let closestMonth: MonthGroup | undefined; + let closestMonth: TimelineMonth | undefined; let minDifference = Number.MAX_SAFE_INTEGER; for (const month of months) { diff --git a/web/src/lib/managers/timeline-manager/day-group.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts similarity index 86% rename from web/src/lib/managers/timeline-manager/day-group.svelte.ts rename to web/src/lib/managers/timeline-manager/timeline-day.svelte.ts index 75793f598e..ec4d0188ab 100644 --- a/web/src/lib/managers/timeline-manager/day-group.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts @@ -5,12 +5,12 @@ import { getJustifiedLayoutFromAssets } from '$lib/utils/layout-utils'; import { plainDateTimeCompare } from '$lib/utils/timeline-util'; import { SvelteSet } from 'svelte/reactivity'; -import type { MonthGroup } from './month-group.svelte'; +import type { TimelineMonth } from './timeline-month.svelte'; import type { Direction, MoveAsset, TimelineAsset } from './types'; import { ViewerAsset } from './viewer-asset.svelte'; -export class DayGroup { - readonly monthGroup: MonthGroup; +export class TimelineDay { + readonly timelineMonth: TimelineMonth; readonly index: number; readonly groupTitle: string; readonly day: number; @@ -18,7 +18,7 @@ export class DayGroup { height = $state(0); width = $state(0); - intersecting = $derived.by(() => this.viewerAssets.some((viewAsset) => viewAsset.intersecting)); + isInOrNearViewport = $derived.by(() => this.viewerAssets.some((viewAsset) => viewAsset.isInOrNearViewport)); #top: number = $state(0); #start: number = $state(0); @@ -26,9 +26,9 @@ export class DayGroup { #col = $state(0); #deferredLayout = false; - constructor(monthGroup: MonthGroup, index: number, day: number, groupTitle: string) { + constructor(timelineMonth: TimelineMonth, index: number, day: number, groupTitle: string) { this.index = index; - this.monthGroup = monthGroup; + this.timelineMonth = timelineMonth; this.day = day; this.groupTitle = groupTitle; } @@ -128,7 +128,7 @@ export class DayGroup { } unprocessedIds.delete(assetId); processedIds.add(assetId); - if (remove || this.monthGroup.timelineManager.isExcluded(asset)) { + if (remove || this.timelineMonth.timelineManager.isExcluded(asset)) { this.viewerAssets.splice(index, 1); changedGeometry = true; } @@ -137,7 +137,7 @@ export class DayGroup { } layout(options: CommonLayoutOptions, noDefer: boolean) { - if (!noDefer && !this.monthGroup.intersecting && !this.monthGroup.timelineManager.isScrollingOnLoad) { + if (!noDefer && !this.timelineMonth.isInOrNearViewport && !this.timelineMonth.timelineManager.isScrollingOnLoad) { this.#deferredLayout = true; return; } @@ -151,7 +151,7 @@ export class DayGroup { } } - get absoluteDayGroupTop() { - return this.monthGroup.top + this.#top; + get absoluteTimelineDayTop() { + return this.timelineMonth.top + this.#top; } } diff --git a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts index 943b5d12a8..6abb170cf7 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts @@ -1,9 +1,10 @@ import { sdkMock } from '$lib/__mocks__/sdk.mock'; -import { getMonthGroupByDate } from '$lib/managers/timeline-manager/internal/search-support.svelte'; +import { eventManager } from '$lib/managers/event-manager.svelte'; +import { getTimelineMonthByDate } from '$lib/managers/timeline-manager/internal/search-support.svelte'; import { AbortError } from '$lib/utils'; import { fromISODateTimeUTCToObject } from '$lib/utils/timeline-util'; import { AssetVisibility, type AssetResponseDto, type TimeBucketAssetResponseDto } from '@immich/sdk'; -import { timelineAssetFactory, toResponseDto } from '@test-data/factories/asset-factory'; +import { assetFactory, timelineAssetFactory, toResponseDto } from '@test-data/factories/asset-factory'; import { tick } from 'svelte'; import { TimelineManager } from './timeline-manager.svelte'; import type { TimelineAsset } from './types'; @@ -94,7 +95,7 @@ describe('TimelineManager', () => { }); }); - describe('loadMonthGroup', () => { + describe('loadTimelineMonth', () => { let timelineManager: TimelineManager; const bucketAssets: Record = { '2024-01-03T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) => @@ -130,47 +131,47 @@ describe('TimelineManager', () => { }); it('loads a month', async () => { - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(0); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(0); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); }); it('ignores invalid months', async () => { - await timelineManager.loadMonthGroup({ year: 2023, month: 1 }); + await timelineManager.loadTimelineMonth({ year: 2023, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(0); }); it('cancels month loading', async () => { - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })!; - void timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })!; + void timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); const abortSpy = vi.spyOn(month!.loader!.cancelToken!, 'abort'); month?.cancel(); expect(abortSpy).toBeCalledTimes(1); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); }); it('prevents loading months multiple times', async () => { await Promise.all([ - timelineManager.loadMonthGroup({ year: 2024, month: 1 }), - timelineManager.loadMonthGroup({ year: 2024, month: 1 }), + timelineManager.loadTimelineMonth({ year: 2024, month: 1 }), + timelineManager.loadTimelineMonth({ year: 2024, month: 1 }), ]); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); }); it('allows loading a canceled month', async () => { - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })!; - const loadPromise = timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })!; + const loadPromise = timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); month.cancel(); await loadPromise; expect(month?.getAssets().length).toEqual(0); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); expect(month!.getAssets().length).toEqual(3); }); }); @@ -240,7 +241,7 @@ describe('TimelineManager', () => { ); timelineManager.upsertAssets([assetOne, assetTwo, assetThree]); - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 }); expect(month).not.toBeNull(); expect(month?.getAssets().length).toEqual(3); expect(month?.getAssets()[0].id).toEqual(assetOne.id); @@ -345,15 +346,15 @@ describe('TimelineManager', () => { timelineManager.upsertAssets([asset]); expect(timelineManager.months.length).toEqual(1); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })).not.toBeUndefined(); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(1); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })).not.toBeUndefined(); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(1); timelineManager.upsertAssets([updatedAsset]); expect(timelineManager.months.length).toEqual(2); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })).not.toBeUndefined(); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(0); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 3 })).not.toBeUndefined(); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 3 })?.getAssets().length).toEqual(1); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })).not.toBeUndefined(); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(0); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 3 })).not.toBeUndefined(); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 3 })?.getAssets().length).toEqual(1); }); it('yearMonth is not a shared reference with asset.localDateTime (reference bug)', () => { @@ -364,7 +365,7 @@ describe('TimelineManager', () => { ); timelineManager.upsertAssets([asset]); - const januaryMonth = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })!; + const januaryMonth = getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 })!; const monthYearMonth = januaryMonth.yearMonth; const originalMonth = monthYearMonth.month; @@ -442,6 +443,48 @@ describe('TimelineManager', () => { }); }); + describe('AssetUpdate events', () => { + let timelineManager: TimelineManager; + + beforeEach(async () => { + timelineManager = new TimelineManager(); + sdkMock.getTimeBuckets.mockResolvedValue([]); + + await timelineManager.updateViewport({ width: 1588, height: 1000 }); + await timelineManager.updateOptions({ albumId: 'album-id' }); + }); + + afterEach(() => { + timelineManager.destroy(); + }); + + it('ignores unknown assets for album timelines', () => { + eventManager.emit('AssetUpdate', assetFactory.build()); + + expect(timelineManager.assetCount).toEqual(0); + expect(timelineManager.months).toHaveLength(0); + }); + + it('updates existing assets in the timeline', () => { + const existing = deriveLocalDateTimeFromFileCreatedAt(timelineAssetFactory.build({ isFavorite: false })); + + timelineManager.upsertAssets([existing]); + eventManager.emit( + 'AssetUpdate', + assetFactory.build({ + id: existing.id, + ownerId: existing.ownerId, + isFavorite: true, + isTrashed: existing.isTrashed, + visibility: existing.visibility, + }), + ); + + expect(timelineManager.assetCount).toEqual(1); + expect(timelineManager.months[0].getFirstAsset().isFavorite).toEqual(true); + }); + }); + describe('removeAssets', () => { let timelineManager: TimelineManager; @@ -568,8 +611,8 @@ describe('TimelineManager', () => { }); it('returns previous assetId', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 1 }); const a = month!.getAssets()[0]; const b = month!.getAssets()[1]; @@ -578,11 +621,11 @@ describe('TimelineManager', () => { }); it('returns previous assetId spanning multiple months', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 2 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 3 }); - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 2 }); - const previousMonth = getMonthGroupByDate(timelineManager, { year: 2024, month: 3 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 2 }); + const previousMonth = getTimelineMonthByDate(timelineManager, { year: 2024, month: 3 }); const a = month!.getAssets()[0]; const b = previousMonth!.getAssets()[0]; const previous = await timelineManager.getLaterAsset(a); @@ -590,23 +633,23 @@ describe('TimelineManager', () => { }); it('loads previous month', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); - const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 2 }); - const previousMonth = getMonthGroupByDate(timelineManager, { year: 2024, month: 3 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 2 }); + const month = getTimelineMonthByDate(timelineManager, { year: 2024, month: 2 }); + const previousMonth = getTimelineMonthByDate(timelineManager, { year: 2024, month: 3 }); const a = month!.getFirstAsset(); const b = previousMonth!.getFirstAsset(); - const loadMonthGroupSpy = vi.spyOn(month!.loader!, 'execute'); + const loadTimelineMonthSpy = vi.spyOn(month!.loader!, 'execute'); const previousMonthSpy = vi.spyOn(previousMonth!.loader!, 'execute'); const previous = await timelineManager.getLaterAsset(a); expect(previous).toEqual(b); - expect(loadMonthGroupSpy).toBeCalledTimes(0); + expect(loadTimelineMonthSpy).toBeCalledTimes(0); expect(previousMonthSpy).toBeCalledTimes(0); }); it('skips removed assets', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 1 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 2 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 3 }); const [assetOne, assetTwo, assetThree] = await getAssets(timelineManager); timelineManager.removeAssets([assetTwo.id]); @@ -614,12 +657,12 @@ describe('TimelineManager', () => { }); it('returns null when no more assets', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadTimelineMonth({ year: 2024, month: 3 }); expect(await timelineManager.getLaterAsset(timelineManager.months[0].getFirstAsset())).toBeUndefined(); }); }); - describe('getMonthGroupIndexByAssetId', () => { + describe('getTimelineMonthIndexByAssetId', () => { let timelineManager: TimelineManager; beforeEach(async () => { @@ -630,8 +673,8 @@ describe('TimelineManager', () => { }); it('returns null for invalid months', () => { - expect(getMonthGroupByDate(timelineManager, { year: -1, month: -1 })).toBeUndefined(); - expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 3 })).toBeUndefined(); + expect(getTimelineMonthByDate(timelineManager, { year: -1, month: -1 })).toBeUndefined(); + expect(getTimelineMonthByDate(timelineManager, { year: 2024, month: 3 })).toBeUndefined(); }); it('returns the month index', () => { @@ -647,10 +690,10 @@ describe('TimelineManager', () => { ); timelineManager.upsertAssets([assetOne, assetTwo]); - expect(timelineManager.getMonthGroupByAssetId(assetTwo.id)?.yearMonth.year).toEqual(2024); - expect(timelineManager.getMonthGroupByAssetId(assetTwo.id)?.yearMonth.month).toEqual(2); - expect(timelineManager.getMonthGroupByAssetId(assetOne.id)?.yearMonth.year).toEqual(2024); - expect(timelineManager.getMonthGroupByAssetId(assetOne.id)?.yearMonth.month).toEqual(1); + expect(timelineManager.getTimelineMonthByAssetId(assetTwo.id)?.yearMonth.year).toEqual(2024); + expect(timelineManager.getTimelineMonthByAssetId(assetTwo.id)?.yearMonth.month).toEqual(2); + expect(timelineManager.getTimelineMonthByAssetId(assetOne.id)?.yearMonth.year).toEqual(2024); + expect(timelineManager.getTimelineMonthByAssetId(assetOne.id)?.yearMonth.month).toEqual(1); }); it('ignores removed months', () => { @@ -667,8 +710,8 @@ describe('TimelineManager', () => { timelineManager.upsertAssets([assetOne, assetTwo]); timelineManager.removeAssets([assetTwo.id]); - expect(timelineManager.getMonthGroupByAssetId(assetOne.id)?.yearMonth.year).toEqual(2024); - expect(timelineManager.getMonthGroupByAssetId(assetOne.id)?.yearMonth.month).toEqual(1); + expect(timelineManager.getTimelineMonthByAssetId(assetOne.id)?.yearMonth.year).toEqual(2024); + expect(timelineManager.getTimelineMonthByAssetId(assetOne.id)?.yearMonth.month).toEqual(1); }); }); diff --git a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts index 38c593bd00..215360b8f9 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts @@ -2,15 +2,15 @@ import { VirtualScrollManager } from '$lib/managers/VirtualScrollManager/Virtual import { authManager } from '$lib/managers/auth-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import { GroupInsertionCache } from '$lib/managers/timeline-manager/group-insertion-cache.svelte'; -import { updateIntersectionMonthGroup } from '$lib/managers/timeline-manager/internal/intersection-support.svelte'; +import { updateTimelineMonthViewportProximity } from '$lib/managers/timeline-manager/internal/intersection-support.svelte'; import { updateGeometry } from '$lib/managers/timeline-manager/internal/layout-support.svelte'; import { loadFromTimeBuckets } from '$lib/managers/timeline-manager/internal/load-support.svelte'; import { - findClosestGroupForDate, - findMonthGroupForAsset as findMonthGroupForAssetUtil, - findMonthGroupForDate, + findClosestTimelineMonthForDate, + findTimelineMonthForAsset as findTimelineMonthForAssetUtil, + findTimelineMonthForDate, getAssetWithOffset, - getMonthGroupByDate, + getTimelineMonthByDate, retrieveRange as retrieveRangeUtil, } from '$lib/managers/timeline-manager/internal/search-support.svelte'; import { WebsocketSupport } from '$lib/managers/timeline-manager/internal/websocket-support.svelte'; @@ -26,9 +26,9 @@ import { import { AssetOrder, getAssetInfo, getTimeBuckets, type AssetResponseDto } from '@immich/sdk'; import { clamp, isEqual } from 'lodash-es'; import { SvelteDate, SvelteSet } from 'svelte/reactivity'; -import { DayGroup } from './day-group.svelte'; import { isMismatched, updateObject } from './internal/utils.svelte'; -import { MonthGroup } from './month-group.svelte'; +import { TimelineDay } from './timeline-day.svelte'; +import { TimelineMonth } from './timeline-month.svelte'; import type { AssetDescriptor, Direction, @@ -40,7 +40,7 @@ import type { } from './types'; type ViewportTopMonthIntersection = { - month: MonthGroup | undefined; + month: TimelineMonth | undefined; // Where viewport top intersects month (0 = month top, 1 = month bottom) viewportTopRatioInMonth: number; // Where month bottom is in viewport (0 = viewport top, 1 = viewport bottom) @@ -67,7 +67,7 @@ export class TimelineManager extends VirtualScrollManager { isInitialized = $state(false); isScrollingOnLoad = false; - months: MonthGroup[] = $state([]); + months: TimelineMonth[] = $state([]); albumAssets: Set = new SvelteSet(); scrubberMonths: ScrubberMonth[] = $state([]); scrubberTimelineHeight: number = $state(0); @@ -91,7 +91,7 @@ export class TimelineManager extends VirtualScrollManager { static #INIT_OPTIONS = {}; #websocketSupport: WebsocketSupport | undefined; #options: TimelineManagerOptions = TimelineManager.#INIT_OPTIONS; - #updatingIntersections = false; + #updatingViewportProximities = false; #scrollableElement: HTMLElement | undefined = $state(); #showAssetOwners = new PersistedLocalStorage('album-show-asset-owners', false); #unsubscribes: Array<() => void> = []; @@ -113,7 +113,7 @@ export class TimelineManager extends VirtualScrollManager { this.#unsubscribes.push( eventManager.on({ - AssetUpdate: (asset: AssetResponseDto) => this.upsertAssets([toTimelineAsset(asset)]), + AssetUpdate: (asset: AssetResponseDto) => this.#updateAssets([toTimelineAsset(asset)]), }), ); } @@ -137,24 +137,27 @@ export class TimelineManager extends VirtualScrollManager { } async *assetsIterator(options?: { - startMonthGroup?: MonthGroup; - startDayGroup?: DayGroup; + startTimelineMonth?: TimelineMonth; + startTimelineDay?: TimelineDay; startAsset?: TimelineAsset; direction?: Direction; }) { const direction = options?.direction ?? 'earlier'; - let { startDayGroup, startAsset } = options ?? {}; - for (const monthGroup of this.monthGroupIterator({ direction, startMonthGroup: options?.startMonthGroup })) { - await this.loadMonthGroup(monthGroup.yearMonth, { cancelable: false }); - yield* monthGroup.assetsIterator({ startDayGroup, startAsset, direction }); - startDayGroup = startAsset = undefined; + let { startTimelineDay, startAsset } = options ?? {}; + for (const timelineMonth of this.timelineMonthIterator({ + direction, + startTimelineMonth: options?.startTimelineMonth, + })) { + await this.loadTimelineMonth(timelineMonth.yearMonth, { cancelable: false }); + yield* timelineMonth.assetsIterator({ startTimelineDay, startAsset, direction }); + startTimelineDay = startAsset = undefined; } } - *monthGroupIterator(options?: { direction?: Direction; startMonthGroup?: MonthGroup }) { + *timelineMonthIterator(options?: { direction?: Direction; startTimelineMonth?: TimelineMonth }) { const isEarlier = options?.direction === 'earlier'; - let startIndex = options?.startMonthGroup - ? this.months.indexOf(options.startMonthGroup) + let startIndex = options?.startTimelineMonth + ? this.months.indexOf(options.startTimelineMonth) : isEarlier ? 0 : this.months.length - 1; @@ -181,7 +184,7 @@ export class TimelineManager extends VirtualScrollManager { this.#websocketSupport = undefined; } - #calculateMonthBottomViewportRatio(month: MonthGroup | undefined) { + #calculateMonthBottomViewportRatio(month: TimelineMonth | undefined) { if (!month) { return 0; } @@ -191,24 +194,28 @@ export class TimelineManager extends VirtualScrollManager { return clamp(bottomOfMonthInViewport / windowHeight, 0, 1); } - #calculateVewportTopRatioInMonth(month: MonthGroup | undefined) { + #calculateVewportTopRatioInMonth(month: TimelineMonth | undefined) { if (!month) { return 0; } return clamp((this.visibleWindow.top - month.top) / month.height, 0, 1); } - override updateIntersections() { - if (this.#updatingIntersections || !this.isInitialized || this.visibleWindow.bottom === this.visibleWindow.top) { + override updateViewportProximities() { + if ( + this.#updatingViewportProximities || + !this.isInitialized || + this.visibleWindow.bottom === this.visibleWindow.top + ) { return; } - this.#updatingIntersections = true; + this.#updatingViewportProximities = true; for (const month of this.months) { - updateIntersectionMonthGroup(this, month); + updateTimelineMonthViewportProximity(this, month); } - const month = this.months.find((month) => month.actuallyIntersecting); + const month = this.months.find((month) => month.isInViewport); const viewportTopRatioInMonth = this.#calculateVewportTopRatioInMonth(month); const monthBottomViewportRatio = this.#calculateMonthBottomViewportRatio(month); @@ -218,20 +225,20 @@ export class TimelineManager extends VirtualScrollManager { viewportTopRatioInMonth, }; - this.#updatingIntersections = false; + this.#updatingViewportProximities = false; } - clearDeferredLayout(month: MonthGroup) { - const hasDeferred = month.dayGroups.some((group) => group.deferredLayout); + clearDeferredLayout(month: TimelineMonth) { + const hasDeferred = month.timelineDays.some((group) => group.deferredLayout); if (hasDeferred) { updateGeometry(this, month, { invalidateHeight: true, noDefer: true }); - for (const group of month.dayGroups) { + for (const group of month.timelineDays) { group.deferredLayout = false; } } } - async #initializeMonthGroups() { + async #initializeTimelineMonths() { const timebuckets = await getTimeBuckets({ ...authManager.params, ...this.#options, @@ -239,7 +246,7 @@ export class TimelineManager extends VirtualScrollManager { this.months = timebuckets.map((timeBucket) => { const date = new SvelteDate(timeBucket.timeBucket); - return new MonthGroup( + return new TimelineMonth( this, { year: date.getUTCFullYear(), month: date.getUTCMonth() + 1 }, timeBucket.count, @@ -276,7 +283,7 @@ export class TimelineManager extends VirtualScrollManager { this.albumAssets.clear(); await this.initTask.execute(async () => { this.#options = options; - await this.#initializeMonthGroups(); + await this.#initializeTimelineMonths(); }, true); } @@ -317,7 +324,7 @@ export class TimelineManager extends VirtualScrollManager { for (const month of this.months) { updateGeometry(this, month, { invalidateHeight: changedWidth }); } - this.updateIntersections(); + this.updateViewportProximities(); if (changedWidth) { this.#createScrubberMonths(); } @@ -328,32 +335,32 @@ export class TimelineManager extends VirtualScrollManager { assetCount: month.assetsCount, year: month.yearMonth.year, month: month.yearMonth.month, - title: month.monthGroupTitle, + title: month.title, height: month.height, })); this.scrubberTimelineHeight = this.totalViewerHeight; } - async loadMonthGroup(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }): Promise { + async loadTimelineMonth(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }): Promise { let cancelable = true; if (options) { cancelable = options.cancelable; } - const monthGroup = getMonthGroupByDate(this, yearMonth); - if (!monthGroup) { + const timelineMonth = getTimelineMonthByDate(this, yearMonth); + if (!timelineMonth) { return; } - if (monthGroup.loader?.executed) { + if (timelineMonth.loader?.executed) { return; } - const executionStatus = await monthGroup.loader?.execute(async (signal: AbortSignal) => { - await loadFromTimeBuckets(this, monthGroup, this.#options, signal); + const executionStatus = await timelineMonth.loader?.execute(async (signal: AbortSignal) => { + await loadFromTimeBuckets(this, timelineMonth, this.#options, signal); }, cancelable); if (executionStatus === 'LOADED') { - updateGeometry(this, monthGroup, { invalidateHeight: false }); - this.updateIntersections(); + updateGeometry(this, timelineMonth, { invalidateHeight: false }); + this.updateViewportProximities(); } } @@ -363,15 +370,15 @@ export class TimelineManager extends VirtualScrollManager { this.addAssetsUpsertSegments([...notExcluded]); } - async findMonthGroupForAsset(asset: AssetDescriptor | AssetResponseDto) { + async findTimelineMonthForAsset(asset: AssetDescriptor | AssetResponseDto) { if (!this.isInitialized) { await this.initTask.waitUntilExecution(); } const { id } = asset; - let { monthGroup } = findMonthGroupForAssetUtil(this, id) ?? {}; - if (monthGroup) { - return monthGroup; + let { timelineMonth } = findTimelineMonthForAssetUtil(this, id) ?? {}; + if (timelineMonth) { + return timelineMonth; } const response = isAssetResponseDto(asset) @@ -386,20 +393,20 @@ export class TimelineManager extends VirtualScrollManager { return; } - monthGroup = await this.#loadMonthGroupAtTime(timelineAsset.localDateTime, { cancelable: false }); - if (monthGroup?.findAssetById({ id })) { - return monthGroup; + timelineMonth = await this.#loadTimelineMonthAtTime(timelineAsset.localDateTime, { cancelable: false }); + if (timelineMonth?.findAssetById({ id })) { + return timelineMonth; } } - async #loadMonthGroupAtTime(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }) { - await this.loadMonthGroup(yearMonth, options); - return getMonthGroupByDate(this, yearMonth); + async #loadTimelineMonthAtTime(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }) { + await this.loadTimelineMonth(yearMonth, options); + return getTimelineMonthByDate(this, yearMonth); } - getMonthGroupByAssetId(assetId: string) { - const monthGroupInfo = findMonthGroupForAssetUtil(this, assetId); - return monthGroupInfo?.monthGroup; + getTimelineMonthByAssetId(assetId: string) { + const timelineMonthInfo = findTimelineMonthForAssetUtil(this, assetId); + return timelineMonthInfo?.timelineMonth; } // note: the `index` input is expected to be in the range [0, assetCount). This @@ -410,7 +417,7 @@ export class TimelineManager extends VirtualScrollManager { let accumulatedCount = 0; - let randomMonth: MonthGroup | undefined = undefined; + let randomMonth: TimelineMonth | undefined = undefined; for (const month of this.months) { if (randomAssetIndex < accumulatedCount + month.assetsCount) { randomMonth = month; @@ -422,10 +429,10 @@ export class TimelineManager extends VirtualScrollManager { if (!randomMonth) { return; } - await this.loadMonthGroup(randomMonth.yearMonth, { cancelable: false }); + await this.loadTimelineMonth(randomMonth.yearMonth, { cancelable: false }); - let randomDay: DayGroup | undefined = undefined; - for (const day of randomMonth.dayGroups) { + let randomDay: TimelineDay | undefined = undefined; + for (const day of randomMonth.timelineDays) { if (randomAssetIndex < accumulatedCount + day.viewerAssets.length) { randomDay = day; break; @@ -455,10 +462,10 @@ export class TimelineManager extends VirtualScrollManager { } protected upsertSegmentForAsset(asset: TimelineAsset) { - let month = getMonthGroupByDate(this, asset.localDateTime); + let month = getTimelineMonthByDate(this, asset.localDateTime); if (!month) { - month = new MonthGroup(this, asset.localDateTime, 1, true, this.#options.order); + month = new TimelineMonth(this, asset.localDateTime, 1, true, this.#options.order); this.months.push(month); } return month; @@ -504,7 +511,7 @@ export class TimelineManager extends VirtualScrollManager { return { updated: new Set(), notUpdated: ids, changedGeometry: false }; } // eslint-disable-next-line svelte/prefer-svelte-reactivity - const changedMonthGroups = new Set(); + const changedTimelineMonths = new Set(); // eslint-disable-next-line svelte/prefer-svelte-reactivity let notUpdated = new Set(ids); // eslint-disable-next-line svelte/prefer-svelte-reactivity @@ -519,7 +526,7 @@ export class TimelineManager extends VirtualScrollManager { assetsToMoveSegments.push(result.moveAssets); } if (result.changedGeometry) { - changedMonthGroups.add(month); + changedTimelineMonths.add(month); } notUpdated = setDifference(notUpdated, result.processedIds); for (const id of result.processedIds) { @@ -533,12 +540,12 @@ export class TimelineManager extends VirtualScrollManager { } } this.addAssetsUpsertSegments(assetsToAdd); - const changedGeometry = changedMonthGroups.size > 0; - for (const month of changedMonthGroups) { + const changedGeometry = changedTimelineMonths.size > 0; + for (const month of changedTimelineMonths) { updateGeometry(this, month, { invalidateHeight: true }); } if (changedGeometry) { - this.updateIntersections(); + this.updateViewportProximities(); } return { updated, notUpdated, changedGeometry }; } @@ -547,7 +554,7 @@ export class TimelineManager extends VirtualScrollManager { for (const month of this.months) { updateGeometry(this, month, { invalidateHeight: true }); } - this.updateIntersections(); + this.updateViewportProximities(); } getFirstAsset(): TimelineAsset | undefined { @@ -569,20 +576,20 @@ export class TimelineManager extends VirtualScrollManager { } async getClosestAssetToDate(dateTime: TimelineDateTime) { - let monthGroup = findMonthGroupForDate(this, dateTime); - if (!monthGroup) { + let timelineMonth = findTimelineMonthForDate(this, dateTime); + if (!timelineMonth) { // if exact match not found, find closest - monthGroup = findClosestGroupForDate(this.months, dateTime); - if (!monthGroup) { + timelineMonth = findClosestTimelineMonthForDate(this.months, dateTime); + if (!timelineMonth) { return; } } - await this.loadMonthGroup(dateTime, { cancelable: false }); - const asset = monthGroup.findClosest(dateTime); + await this.loadTimelineMonth(dateTime, { cancelable: false }); + const asset = timelineMonth.findClosest(dateTime); if (asset) { return asset; } - for await (const asset of this.assetsIterator({ startMonthGroup: monthGroup })) { + for await (const asset of this.assetsIterator({ startTimelineMonth: timelineMonth })) { return asset; } } @@ -614,18 +621,18 @@ export class TimelineManager extends VirtualScrollManager { } protected postUpsert(context: GroupInsertionCache): void { - for (const group of context.existingDayGroups) { + for (const group of context.existingTimelineDays) { group.sortAssets(this.#options.order); } - for (const monthGroup of context.bucketsWithNewDayGroups) { - monthGroup.sortDayGroups(); + for (const timelineMonth of context.bucketsWithNewTimelineDays) { + timelineMonth.sortTimelineDays(); } for (const month of context.updatedBuckets) { - month.sortDayGroups(); + month.sortTimelineDays(); updateGeometry(this, month, { invalidateHeight: true }); } - this.updateIntersections(); + this.updateViewportProximities(); } } diff --git a/web/src/lib/managers/timeline-manager/month-group.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts similarity index 72% rename from web/src/lib/managers/timeline-manager/month-group.svelte.ts rename to web/src/lib/managers/timeline-manager/timeline-month.svelte.ts index b41deb5785..8d97a18131 100644 --- a/web/src/lib/managers/timeline-manager/month-group.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts @@ -4,7 +4,7 @@ import { CancellableTask } from '$lib/utils/cancellable-task'; import { handleError } from '$lib/utils/handle-error'; import { formatGroupTitle, - formatMonthGroupTitle, + formatTimelineMonthTitle, fromTimelinePlainDate, fromTimelinePlainDateTime, fromTimelinePlainYearMonth, @@ -17,18 +17,22 @@ import { import { t } from 'svelte-i18n'; import { get } from 'svelte/store'; +import { + ViewportProximity, + isInOrNearViewport as isInOrNearViewportUtil, + isInViewport as isInViewportUtil, +} from '$lib/managers/timeline-manager/internal/intersection-support.svelte'; import { SvelteSet } from 'svelte/reactivity'; -import { DayGroup } from './day-group.svelte'; import { GroupInsertionCache } from './group-insertion-cache.svelte'; +import { TimelineDay } from './timeline-day.svelte'; import type { TimelineManager } from './timeline-manager.svelte'; import type { AssetDescriptor, Direction, MoveAsset, TimelineAsset } from './types'; import { ViewerAsset } from './viewer-asset.svelte'; -export class MonthGroup { - #intersecting: boolean = $state(false); - actuallyIntersecting: boolean = $state(false); +export class TimelineMonth { + #viewportProximity: ViewportProximity = $state(ViewportProximity.FarFromViewport); isLoaded: boolean = $state(false); - dayGroups: DayGroup[] = $state([]); + timelineDays: TimelineDay[] = $state([]); readonly timelineManager: TimelineManager; #height: number = $state(0); @@ -40,13 +44,13 @@ export class MonthGroup { assetsCount: number = $derived( this.isLoaded - ? this.dayGroups.reduce((accumulator, g) => accumulator + g.viewerAssets.length, 0) + ? this.timelineDays.reduce((accumulator, g) => accumulator + g.viewerAssets.length, 0) : this.#initialCount, ); loader: CancellableTask | undefined; isHeightActual: boolean = $state(false); - readonly monthGroupTitle: string; + readonly title: string; readonly yearMonth: TimelineYearMonth; constructor( @@ -61,14 +65,14 @@ export class MonthGroup { this.#sortOrder = order; this.yearMonth = { year: yearMonth.year, month: yearMonth.month }; - this.monthGroupTitle = formatMonthGroupTitle(fromTimelinePlainYearMonth(yearMonth)); + this.title = formatTimelineMonthTitle(fromTimelinePlainYearMonth(yearMonth)); this.loader = new CancellableTask( () => { this.isLoaded = true; }, () => { - this.dayGroups = []; + this.timelineDays = []; this.isLoaded = false; }, this.#handleLoadError, @@ -78,42 +82,49 @@ export class MonthGroup { } } - set intersecting(newValue: boolean) { - const old = this.#intersecting; + set viewportProximity(newValue: ViewportProximity) { + const old = this.#viewportProximity; if (old === newValue) { return; } - this.#intersecting = newValue; - if (newValue) { - void this.timelineManager.loadMonthGroup(this.yearMonth); + this.#viewportProximity = newValue; + if (isInOrNearViewportUtil(newValue)) { + void this.timelineManager.loadTimelineMonth(this.yearMonth); } else { this.cancel(); } } - get intersecting() { - return this.#intersecting; + get isInOrNearViewport() { + return isInOrNearViewportUtil(this.#viewportProximity); } - get lastDayGroup() { - return this.dayGroups.at(-1); + get isInViewport() { + return isInViewportUtil(this.#viewportProximity); + } + + get lastTimelineDay() { + return this.timelineDays.at(-1); } getFirstAsset() { - return this.dayGroups[0]?.getFirstAsset(); + return this.timelineDays[0]?.getFirstAsset(); } getAssets() { // eslint-disable-next-line unicorn/no-array-reduce - return this.dayGroups.reduce((accumulator: TimelineAsset[], g: DayGroup) => accumulator.concat(g.getAssets()), []); + return this.timelineDays.reduce( + (accumulator: TimelineAsset[], g: TimelineDay) => accumulator.concat(g.getAssets()), + [], + ); } - sortDayGroups() { + sortTimelineDays() { if (this.#sortOrder === AssetOrder.Asc) { - return this.dayGroups.sort((a, b) => a.day - b.day); + return this.timelineDays.sort((a, b) => a.day - b.day); } - return this.dayGroups.sort((a, b) => b.day - a.day); + return this.timelineDays.sort((a, b) => b.day - a.day); } runAssetCallback(ids: Set, callback: (asset: TimelineAsset) => void | { remove?: boolean }) { @@ -125,15 +136,15 @@ export class MonthGroup { changedGeometry: false, }; } - const { dayGroups } = this; + const { timelineDays } = this; let combinedChangedGeometry = false; let idsToProcess = new SvelteSet(ids); const idsProcessed = new SvelteSet(); const combinedMoveAssets: MoveAsset[][] = []; - let index = dayGroups.length; + let index = timelineDays.length; while (index--) { if (idsToProcess.size > 0) { - const group = dayGroups[index]; + const group = timelineDays[index]; const { moveAssets, processedIds, changedGeometry } = group.runAssetCallback(ids, callback); if (moveAssets.length > 0) { combinedMoveAssets.push(moveAssets); @@ -144,7 +155,7 @@ export class MonthGroup { } combinedChangedGeometry = combinedChangedGeometry || changedGeometry; if (group.viewerAssets.length === 0) { - dayGroups.splice(index, 1); + timelineDays.splice(index, 1); combinedChangedGeometry = true; } } @@ -207,12 +218,12 @@ export class MonthGroup { return addContext.unprocessedAssets; } - for (const group of addContext.existingDayGroups) { + for (const group of addContext.existingTimelineDays) { group.sortAssets(this.#sortOrder); } - if (addContext.newDayGroups.size > 0) { - this.sortDayGroups(); + if (addContext.newTimelineDays.size > 0) { + this.sortTimelineDays(); } addContext.sort(this, this.#sortOrder); @@ -229,20 +240,20 @@ export class MonthGroup { return; } - let dayGroup = addContext.getDayGroup(localDateTime) || this.findDayGroupByDay(localDateTime.day); - if (dayGroup) { - addContext.setDayGroup(dayGroup, localDateTime); + let timelineDay = addContext.getTimelineDay(localDateTime) || this.findTimelineDayByDay(localDateTime.day); + if (timelineDay) { + addContext.setTimelineDay(timelineDay, localDateTime); } else { const groupTitle = formatGroupTitle(fromTimelinePlainDate(localDateTime)); - dayGroup = new DayGroup(this, this.dayGroups.length, localDateTime.day, groupTitle); - this.dayGroups.push(dayGroup); - addContext.setDayGroup(dayGroup, localDateTime); - addContext.newDayGroups.add(dayGroup); + timelineDay = new TimelineDay(this, this.timelineDays.length, localDateTime.day, groupTitle); + this.timelineDays.push(timelineDay); + addContext.setTimelineDay(timelineDay, localDateTime); + addContext.newTimelineDays.add(timelineDay); } - const viewerAsset = new ViewerAsset(dayGroup, timelineAsset); - dayGroup.viewerAssets.push(viewerAsset); - addContext.changedDayGroups.add(dayGroup); + const viewerAsset = new ViewerAsset(timelineDay, timelineAsset); + timelineDay.viewerAssets.push(viewerAsset); + addContext.changedTimelineDays.add(timelineDay); } get viewId() { @@ -258,9 +269,9 @@ export class MonthGroup { const index = timelineManager.months.indexOf(this); const heightDelta = height - this.#height; this.#height = height; - const prevMonthGroup = timelineManager.months[index - 1]; - if (prevMonthGroup) { - const newTop = prevMonthGroup.#top + prevMonthGroup.#height; + const previousTimelineMonth = timelineManager.months[index - 1]; + if (previousTimelineMonth) { + const newTop = previousTimelineMonth.#top + previousTimelineMonth.#height; if (this.#top !== newTop) { this.#top = newTop; } @@ -269,10 +280,10 @@ export class MonthGroup { return; } for (let cursor = index + 1; cursor < timelineManager.months.length; cursor++) { - const monthGroup = this.timelineManager.months[cursor]; - const newTop = monthGroup.#top + heightDelta; - if (monthGroup.#top !== newTop) { - monthGroup.#top = newTop; + const timelineMonth = this.timelineManager.months[cursor]; + const newTop = timelineMonth.#top + heightDelta; + if (timelineMonth.#top !== newTop) { + timelineMonth.#top = newTop; } } if (!timelineManager.viewportTopMonthIntersection) { @@ -304,21 +315,21 @@ export class MonthGroup { handleError(error, _$t('errors.failed_to_load_assets')); } - findDayGroupForAsset(asset: TimelineAsset) { - for (const group of this.dayGroups) { + findTimelineDayForAsset(asset: TimelineAsset) { + for (const group of this.timelineDays) { if (group.viewerAssets.some((viewerAsset) => viewerAsset.id === asset.id)) { return group; } } } - findDayGroupByDay(day: number) { - return this.dayGroups.find((group) => group.day === day); + findTimelineDayByDay(day: number) { + return this.timelineDays.find((group) => group.day === day); } findAssetAbsolutePosition(assetId: string) { this.timelineManager.clearDeferredLayout(this); - for (const group of this.dayGroups) { + for (const group of this.timelineDays) { const viewerAsset = group.viewerAssets.find((viewAsset) => viewAsset.id === assetId); if (viewerAsset) { if (!viewerAsset.position) { @@ -333,18 +344,18 @@ export class MonthGroup { } } - *assetsIterator(options?: { startDayGroup?: DayGroup; startAsset?: TimelineAsset; direction?: Direction }) { + *assetsIterator(options?: { startTimelineDay?: TimelineDay; startAsset?: TimelineAsset; direction?: Direction }) { const direction = options?.direction ?? 'earlier'; let { startAsset } = options ?? {}; const isEarlier = direction === 'earlier'; - let groupIndex = options?.startDayGroup - ? this.dayGroups.indexOf(options.startDayGroup) + let groupIndex = options?.startTimelineDay + ? this.timelineDays.indexOf(options.startTimelineDay) : isEarlier ? 0 - : this.dayGroups.length - 1; + : this.timelineDays.length - 1; - while (groupIndex >= 0 && groupIndex < this.dayGroups.length) { - const group = this.dayGroups[groupIndex]; + while (groupIndex >= 0 && groupIndex < this.timelineDays.length) { + const group = this.timelineDays[groupIndex]; yield* group.assetsIterator({ startAsset, direction }); startAsset = undefined; groupIndex += isEarlier ? 1 : -1; diff --git a/web/src/lib/managers/timeline-manager/utils.svelte.ts b/web/src/lib/managers/timeline-manager/utils.svelte.ts index 2aba6470ee..efc94206ea 100644 --- a/web/src/lib/managers/timeline-manager/utils.svelte.ts +++ b/web/src/lib/managers/timeline-manager/utils.svelte.ts @@ -2,3 +2,7 @@ import type { TimelineAsset } from './types'; export const assetSnapshot = (asset: TimelineAsset): TimelineAsset => $state.snapshot(asset); export const assetsSnapshot = (assets: TimelineAsset[]) => assets.map((asset) => $state.snapshot(asset)); + +export function filterIsInOrNearViewport(items: T[]) { + return items.filter(({ isInOrNearViewport }) => isInOrNearViewport); +} diff --git a/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts b/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts index 161cc049f1..3eba6c9a04 100644 --- a/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts +++ b/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts @@ -1,28 +1,36 @@ import type { CommonPosition } from '$lib/utils/layout-utils'; -import type { DayGroup } from './day-group.svelte'; -import { calculateViewerAssetIntersecting } from './internal/intersection-support.svelte'; +import { + ViewportProximity, + calculateViewerAssetViewportProximity, + isInOrNearViewport, +} from './internal/intersection-support.svelte'; +import type { TimelineDay } from './timeline-day.svelte'; import type { TimelineAsset } from './types'; export class ViewerAsset { - readonly #group: DayGroup; + readonly #group: TimelineDay; - intersecting = $derived.by(() => { + #viewportProximity = $derived.by(() => { if (!this.position) { - return false; + return ViewportProximity.FarFromViewport; } - const store = this.#group.monthGroup.timelineManager; - const positionTop = this.#group.absoluteDayGroupTop + this.position.top; + const store = this.#group.timelineMonth.timelineManager; + const positionTop = this.#group.absoluteTimelineDayTop + this.position.top; - return calculateViewerAssetIntersecting(store, positionTop, this.position.height); + return calculateViewerAssetViewportProximity(store, positionTop, this.position.height); }); + get isInOrNearViewport() { + return isInOrNearViewport(this.#viewportProximity); + } + position: CommonPosition | undefined = $state.raw(); asset: TimelineAsset = $state(); id: string = $derived(this.asset.id); - constructor(group: DayGroup, asset: TimelineAsset) { + constructor(group: TimelineDay, asset: TimelineAsset) { this.#group = group; this.asset = asset; } diff --git a/web/src/lib/modals/AssetChangeDateModal.spec.ts b/web/src/lib/modals/AssetChangeDateModal.spec.ts new file mode 100644 index 0000000000..fc23f75651 --- /dev/null +++ b/web/src/lib/modals/AssetChangeDateModal.spec.ts @@ -0,0 +1,67 @@ +import { getAnimateMock } from '$lib/__mocks__/animate.mock'; +import { getIntersectionObserverMock } from '$lib/__mocks__/intersection-observer.mock'; +import { getVisualViewportMock } from '$lib/__mocks__/visual-viewport.mock'; +import { fireEvent, render, screen, waitFor } from '@testing-library/svelte'; +import { DateTime } from 'luxon'; +import { afterAll, beforeEach, describe, expect, test, vi } from 'vitest'; +import AssetChangeDateModal from './AssetChangeDateModal.svelte'; + +describe('AssetChangeDateModal component', () => { + const initialDate = DateTime.fromISO('2026-03-19T23:31:30.112'); + const initialTimeZone = 'Europe/Lisbon'; + const onClose = vi.fn(); + + const getDateInput = async () => (await screen.findByDisplayValue('2026-03-19T23:31:30.112')) as HTMLInputElement; + const getTimeZoneInput = () => screen.getByRole('combobox', { name: /timezone/i }) as HTMLInputElement; + + beforeEach(() => { + vi.stubGlobal('IntersectionObserver', getIntersectionObserverMock()); + vi.stubGlobal('visualViewport', getVisualViewportMock()); + vi.resetAllMocks(); + Element.prototype.animate = getAnimateMock(); + }); + + afterAll(async () => { + await waitFor(() => { + expect(document.body.style.pointerEvents).not.toBe('none'); + }); + }); + + test('preserves the selected timezone when changing the datetime', async () => { + render(AssetChangeDateModal, { + props: { + initialDate, + initialTimeZone, + timezoneInput: true, + asset: { id: 'asset-id' } as never, + onClose, + }, + }); + + const timezoneInput = getTimeZoneInput(); + const datetimeInput = await getDateInput(); + + const initialTimezoneValue = timezoneInput.value; + + await fireEvent.focus(timezoneInput); + await fireEvent.input(timezoneInput, { target: { value: 'Pacific/Pitcairn' } }); + + const option = await screen.findByText(/Pacific\/Pitcairn/i); + await fireEvent.click(option); + + expect(timezoneInput.value).toBe('Pacific/Pitcairn (-08:00)'); + expect(timezoneInput.value).not.toBe(initialTimezoneValue); + + const beforeDatetime = datetimeInput.value; + + await fireEvent.input(datetimeInput, { + target: { value: '2026-03-19T23:31:31.113' }, + }); + await fireEvent.change(datetimeInput, { + target: { value: '2026-03-19T23:31:31.113' }, + }); + + expect(datetimeInput.value).not.toBe(beforeDatetime); + expect(timezoneInput.value).toBe('Pacific/Pitcairn (-08:00)'); + }); +}); diff --git a/web/src/lib/modals/AssetChangeDateModal.svelte b/web/src/lib/modals/AssetChangeDateModal.svelte index ec4cb0f077..fe9d1baf25 100644 --- a/web/src/lib/modals/AssetChangeDateModal.svelte +++ b/web/src/lib/modals/AssetChangeDateModal.svelte @@ -23,10 +23,7 @@ let selectedDate = $state(initialDate.toFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")); const timezones = $derived(getTimezones(selectedDate)); - // svelte-ignore state_referenced_locally - let lastSelectedTimezone = $state(getPreferredTimeZone(initialDate, initialTimeZone, timezones)); - // the offsets (and validity) for time zones may change if the date is changed, which is why we recompute the list - let selectedOption = $derived(getPreferredTimeZone(initialDate, initialTimeZone, timezones, lastSelectedTimezone)); + let selectedOption = $state(getPreferredTimeZone(initialDate, initialTimeZone, getTimezones(selectedDate))); const onSubmit = async () => { if (!date.isValid || !selectedOption) { @@ -45,6 +42,12 @@ } }; + const updateSelectedDate = (value: string) => { + selectedDate = value; + + selectedOption = getPreferredTimeZone(initialDate, initialTimeZone, getTimezones(value), selectedOption); + }; + // when changing the time zone, assume the configured date/time is meant for that time zone (instead of updating it) const date = $derived(DateTime.fromISO(selectedDate, { zone: selectedOption?.value, setZone: true })); @@ -59,7 +62,12 @@ size="small" > - + selectedDate, updateSelectedDate} + /> {#if timezoneInput}
diff --git a/web/src/lib/modals/CreateFaceModal.svelte b/web/src/lib/modals/CreateFaceModal.svelte new file mode 100644 index 0000000000..fa845cba2d --- /dev/null +++ b/web/src/lib/modals/CreateFaceModal.svelte @@ -0,0 +1,91 @@ + + + + {$t('create_person_subtitle')} + {#if previewUrl} + +
+ {$t('preview')} + {#if isSubmitting} +
+ +
+ {/if} +
+
+ {/if} + + + + +
diff --git a/web/src/lib/modals/DuplicatesInformationModal.svelte b/web/src/lib/modals/DuplicatesInformationModal.svelte deleted file mode 100644 index b32165a1ae..0000000000 --- a/web/src/lib/modals/DuplicatesInformationModal.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
-

{$t('deduplication_info_description')}

-
    -
  1. {$t('deduplication_criteria_1')}
  2. -
  3. {$t('deduplication_criteria_2')}
  4. -
-
-
-
diff --git a/web/src/lib/components/shared-components/change-location.svelte b/web/src/lib/modals/GeolocationPointPickerModal.svelte similarity index 85% rename from web/src/lib/components/shared-components/change-location.svelte rename to web/src/lib/modals/GeolocationPointPickerModal.svelte index 1abb2dacce..87b1df081a 100644 --- a/web/src/lib/components/shared-components/change-location.svelte +++ b/web/src/lib/modals/GeolocationPointPickerModal.svelte @@ -1,30 +1,27 @@ {#snippet prompt()}

{$t('update_location_action_prompt', { values: { count: assetCount } })}

-

- {$t('latitude')}: {location.latitude}

-

- {$t('longitude')}: {location.longitude}

+

- {$t('latitude')}: {point.lat}

+

- {$t('longitude')}: {point.lng}

{/snippet}
diff --git a/web/src/lib/route.ts b/web/src/lib/route.ts index 5a59ec704c..4cb1965122 100644 --- a/web/src/lib/route.ts +++ b/web/src/lib/route.ts @@ -42,6 +42,12 @@ const asQueryString = ( return items.length === 0 ? '' : `?${items.join('&')}`; }; +const DOCS_BASE = 'https://docs.immich.app'; + +export const Docs = { + duplicates: () => `${DOCS_BASE}/features/duplicates-utility`, +}; + export const Route = { // auth login: (params?: { continue?: string; autoLaunch?: 0 | 1 }) => '/auth/login' + asQueryString(params), diff --git a/web/src/lib/services/album.service.ts b/web/src/lib/services/album.service.ts index 6ccd67584e..3a70d72478 100644 --- a/web/src/lib/services/album.service.ts +++ b/web/src/lib/services/album.service.ts @@ -1,5 +1,4 @@ import { goto } from '$app/navigation'; -import ToastAction from '$lib/components/ToastAction.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; @@ -138,16 +137,8 @@ const notifyAddToAlbum = ($t: MessageFormatter, albumId: string, assetIds: strin description = $t('assets_were_part_of_album_count', { values: { count: duplicateCount } }); } - toastManager.custom( - { - component: ToastAction, - props: { - title: $t('info'), - color: 'primary', - description, - button: { text: $t('view_album'), color: 'primary', onClick: () => goto(Route.viewAlbum({ id: albumId })) }, - }, - }, + toastManager.primary( + { description, button: { label: $t('view_album'), onclick: () => goto(Route.viewAlbum({ id: albumId })) } }, { timeout: 5000 }, ); }; @@ -229,18 +220,9 @@ export const handleUpdateAlbum = async ({ id }: { id: string }, dto: UpdateAlbum try { const response = await updateAlbumInfo({ id, updateAlbumDto: dto }); eventManager.emit('AlbumUpdate', response); - toastManager.custom({ - component: ToastAction, - props: { - color: 'primary', - title: $t('success'), - description: $t('album_info_updated'), - button: { - text: $t('view_album'), - color: 'primary', - onClick: () => goto(Route.viewAlbum({ id })), - }, - }, + toastManager.primary({ + description: $t('album_info_updated'), + button: { label: $t('view_album'), onclick: () => goto(Route.viewAlbum({ id })) }, }); return true; diff --git a/web/src/lib/services/asset.service.spec.ts b/web/src/lib/services/asset.service.spec.ts index 170f5d2f23..b63df86479 100644 --- a/web/src/lib/services/asset.service.spec.ts +++ b/web/src/lib/services/asset.service.spec.ts @@ -78,7 +78,7 @@ describe('AssetService', () => { const asset = assetFactory.build({ originalFileName: 'asset.heic', livePhotoVideoId: '1' }); await handleDownloadAsset(asset, { edited: false }); expect($t).toHaveBeenNthCalledWith(1, 'downloading_asset_filename', { values: { filename: 'asset.heic' } }); - expect($t).toHaveBeenNthCalledWith(2, 'downloading_asset_filename', { values: { filename: 'asset.mov' } }); + expect($t).toHaveBeenNthCalledWith(2, 'downloading_asset_filename', { values: { filename: 'asset-motion.mov' } }); expect(toastManager.primary).toHaveBeenCalledWith('formatter'); }); }); diff --git a/web/src/lib/services/asset.service.ts b/web/src/lib/services/asset.service.ts index 76ac0b7fc0..a5fd76983a 100644 --- a/web/src/lib/services/asset.service.ts +++ b/web/src/lib/services/asset.service.ts @@ -1,13 +1,12 @@ import { ProjectionType } from '$lib/constants'; +import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import AssetAddToAlbumModal from '$lib/modals/AssetAddToAlbumModal.svelte'; import AssetTagModal from '$lib/modals/AssetTagModal.svelte'; import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte'; -import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { user as authUser, preferences } from '$lib/stores/user.store'; -import type { AssetControlContext } from '$lib/types'; import { getAssetMediaUrl, getSharedLink, sleep } from '$lib/utils'; import { downloadUrl } from '$lib/utils/asset-utils'; import { handleError } from '$lib/utils/handle-error'; @@ -49,14 +48,14 @@ import { import type { MessageFormatter } from 'svelte-i18n'; import { get } from 'svelte/store'; -export const getAssetBulkActions = ($t: MessageFormatter, ctx: AssetControlContext) => { - const ownedAssets = ctx.getOwnedAssets(); +export const getAssetBulkActions = ($t: MessageFormatter) => { + const ownedAssets = assetMultiSelectManager.ownedAssets; const assetIds = ownedAssets.map((asset) => asset.id); const isAllVideos = ownedAssets.every((asset) => asset.isVideo); const onAction = async (name: AssetJobName) => { await handleRunAssetJob({ name, assetIds }); - ctx.clearSelect(); + assetMultiSelectManager.clear(); }; const AddToAlbum: ActionItem = { @@ -229,9 +228,7 @@ export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) = icon: mdiFaceRecognition, type: $t('assets'), $if: () => isOwner && asset.type === AssetTypeEnum.Image && !asset.isTrashed, - onAction: () => { - isFaceEditMode.value = !isFaceEditMode.value; - }, + onAction: () => assetViewerManager.toggleFaceEditMode(), shortcuts: { key: 'p' }, }; @@ -248,6 +245,7 @@ export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) = !asset.originalPath.toLowerCase().endsWith('.gif') && !asset.originalPath.toLowerCase().endsWith('.svg'), onAction: () => assetViewerManager.openEditor(), + shortcuts: [{ key: 'e' }], }; const RefreshFacesJob: ActionItem = { @@ -318,8 +316,14 @@ export const handleDownloadAsset = async (asset: AssetResponseDto, { edited }: { if (asset.livePhotoVideoId) { const motionAsset = await getAssetInfo({ ...authManager.params, id: asset.livePhotoVideoId }); if (!isAndroidMotionVideo(motionAsset) || get(preferences)?.download.includeEmbeddedVideos) { + const motionFilename = motionAsset.originalFileName; + const lastDotIndex = motionFilename.lastIndexOf('.'); + const motionDownloadFilename = + lastDotIndex > 0 + ? `${motionFilename.slice(0, lastDotIndex)}-motion${motionFilename.slice(lastDotIndex)}` + : `${motionFilename}-motion`; assets.push({ - filename: motionAsset.originalFileName, + filename: motionDownloadFilename, id: asset.livePhotoVideoId, cacheKey: motionAsset.thumbhash, }); diff --git a/web/src/lib/stores/album-asset-selection.store.ts b/web/src/lib/stores/album-asset-selection.store.ts deleted file mode 100644 index a99e2baaca..0000000000 --- a/web/src/lib/stores/album-asset-selection.store.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { writable } from 'svelte/store'; - -function createAlbumAssetSelectionStore() { - const isAlbumAssetSelectionOpen = writable(false); - return { - isAlbumAssetSelectionOpen, - }; -} - -export const albumAssetSelectionStore = createAlbumAssetSelectionStore(); diff --git a/web/src/lib/stores/asset-editor.store.ts b/web/src/lib/stores/asset-editor.store.ts deleted file mode 100644 index cc764cf7ad..0000000000 --- a/web/src/lib/stores/asset-editor.store.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { writable } from 'svelte/store'; - -//-----other -export const lastChosenLocation = writable<{ lng: number; lat: number } | null>(null); diff --git a/web/src/lib/stores/asset-interaction.svelte.ts b/web/src/lib/stores/asset-interaction.svelte.ts deleted file mode 100644 index 48c8080269..0000000000 --- a/web/src/lib/stores/asset-interaction.svelte.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; -import { user } from '$lib/stores/user.store'; -import type { AssetControlContext } from '$lib/types'; -import { AssetVisibility, type UserAdminResponseDto } from '@immich/sdk'; -import { SvelteMap, SvelteSet } from 'svelte/reactivity'; -import { fromStore } from 'svelte/store'; - -export class AssetInteraction { - private selectedAssetsMap = new SvelteMap(); - selectedAssets = $derived(Array.from(this.selectedAssetsMap.values())); - selectAll = $state(false); - hasSelectedAsset(assetId: string) { - return this.selectedAssetsMap.has(assetId); - } - selectedGroup = new SvelteSet(); - assetSelectionCandidates = $state([]); - hasSelectionCandidate(assetId: string) { - return this.assetSelectionCandidates.some((asset) => asset.id === assetId); - } - assetSelectionStart = $state(null); - selectionActive = $derived(this.selectedAssetsMap.size > 0); - - private user = fromStore(user); - private userId = $derived(this.user.current?.id); - - asControlContext(): AssetControlContext { - return { - getOwnedAssets: () => this.selectedAssets.filter((asset) => asset.ownerId === this.userId), - getAssets: () => this.selectedAssets, - clearSelect: () => this.clearMultiselect(), - }; - } - - isAllTrashed = $derived(this.selectedAssets.every((asset) => asset.isTrashed)); - isAllArchived = $derived(this.selectedAssets.every((asset) => asset.visibility === AssetVisibility.Archive)); - isAllFavorite = $derived(this.selectedAssets.every((asset) => asset.isFavorite)); - isAllUserOwned = $derived(this.selectedAssets.every((asset) => asset.ownerId === this.userId)); - - selectAsset(asset: TimelineAsset) { - this.selectedAssetsMap.set(asset.id, asset); - } - - selectAssets(assets: TimelineAsset[]) { - for (const asset of assets) { - this.selectAsset(asset); - } - } - - removeAssetFromMultiselectGroup(assetId: string) { - this.selectedAssetsMap.delete(assetId); - } - - addGroupToMultiselectGroup(group: string) { - this.selectedGroup.add(group); - } - - removeGroupFromMultiselectGroup(group: string) { - this.selectedGroup.delete(group); - } - - setAssetSelectionStart(asset: TimelineAsset | null) { - this.assetSelectionStart = asset; - } - - setAssetSelectionCandidates(assets: TimelineAsset[]) { - this.assetSelectionCandidates = assets; - } - - clearAssetSelectionCandidates() { - this.assetSelectionCandidates = []; - } - - clearMultiselect() { - this.selectAll = false; - - // Multi-selection - this.selectedAssetsMap.clear(); - this.selectedGroup.clear(); - - // Range selection - this.assetSelectionCandidates = []; - this.assetSelectionStart = null; - } -} diff --git a/web/src/lib/stores/asset-viewing.store.ts b/web/src/lib/stores/asset-viewing.store.ts deleted file mode 100644 index 3cd2cd9579..0000000000 --- a/web/src/lib/stores/asset-viewing.store.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { authManager } from '$lib/managers/auth-manager.svelte'; -import { type AssetGridRouteSearchParams } from '$lib/utils/navigation'; -import { getAssetInfo, type AssetResponseDto } from '@immich/sdk'; -import { readonly, writable } from 'svelte/store'; - -function createAssetViewingStore() { - const viewingAssetStoreState = writable(); - const viewState = writable(false); - const gridScrollTarget = writable(); - - const setAsset = (asset: AssetResponseDto) => { - viewingAssetStoreState.set(asset); - viewState.set(true); - }; - - const setAssetId = async (id: string): Promise => { - const asset = await getAssetInfo({ ...authManager.params, id }); - setAsset(asset); - return asset; - }; - - const showAssetViewer = (show: boolean) => { - viewState.set(show); - }; - - return { - asset: readonly(viewingAssetStoreState), - isViewing: viewState, - gridScrollTarget, - setAsset, - setAssetId, - showAssetViewer, - }; -} - -export const assetViewingStore = createAssetViewingStore(); diff --git a/web/src/lib/stores/face-edit.svelte.ts b/web/src/lib/stores/face-edit.svelte.ts deleted file mode 100644 index 0b2f436099..0000000000 --- a/web/src/lib/stores/face-edit.svelte.ts +++ /dev/null @@ -1 +0,0 @@ -export const isFaceEditMode = $state({ value: false }); diff --git a/web/src/lib/stores/preferences.store.ts b/web/src/lib/stores/preferences.store.ts index e863d5a446..0873337e1f 100644 --- a/web/src/lib/stores/preferences.store.ts +++ b/web/src/lib/stores/preferences.store.ts @@ -49,7 +49,7 @@ const defaultMapSettings = { const persistedObject = (key: string, defaults: T) => persisted(key, defaults, { serializer: { - parse: (text) => ({ ...defaultMapSettings, ...JSON.parse(text ?? null) }), + parse: (text) => ({ ...defaults, ...JSON.parse(text ?? null) }), stringify: JSON.stringify, }, }); diff --git a/web/src/lib/stores/upload.ts b/web/src/lib/stores/upload.ts index b36a2e5e70..46eb5f1623 100644 --- a/web/src/lib/stores/upload.ts +++ b/web/src/lib/stores/upload.ts @@ -85,11 +85,6 @@ function createUploadStore() { if (assetToRemove) { stats.update((stats) => { switch (assetToRemove.state) { - case UploadState.DONE: { - stats.success--; - break; - } - case UploadState.DUPLICATED: { stats.duplicates--; break; @@ -99,9 +94,12 @@ function createUploadStore() { stats.errors--; break; } + + case UploadState.DONE: { + break; + } } - stats.total--; return stats; }); } diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index 25524f1eea..619195711a 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -5,6 +5,8 @@ import type { ActionItem } from '@immich/ui'; import type { DateTime } from 'luxon'; import type { SvelteSet } from 'svelte/reactivity'; +export type LatLng = { lng: number; lat: number }; + export interface ReleaseEvent { isAvailable: boolean; /** ISO8601 */ diff --git a/web/src/lib/utils/actions.ts b/web/src/lib/utils/actions.ts index 05de75d3bc..46265a78bb 100644 --- a/web/src/lib/utils/actions.ts +++ b/web/src/lib/utils/actions.ts @@ -1,4 +1,3 @@ -import ToastAction from '$lib/components/ToastAction.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import type { StackResponse } from '$lib/utils/asset-utils'; @@ -32,24 +31,15 @@ export const deleteAssets = async ( await deleteBulk({ assetBulkDeleteDto: { ids, force } }); onAssetDelete(ids); - toastManager.custom( + toastManager.primary( { - component: ToastAction, - props: { - title: $t('success'), - description: force - ? $t('assets_permanently_deleted_count', { values: { count: ids.length } }) - : $t('assets_trashed_count', { values: { count: ids.length } }), - color: 'success', - button: - onUndoDelete && !force - ? { - color: 'secondary', - text: $t('undo'), - onClick: () => undoDeleteAssets(onUndoDelete, assets), - } - : undefined, - }, + description: force + ? $t('assets_permanently_deleted_count', { values: { count: ids.length } }) + : $t('assets_trashed_count', { values: { count: ids.length } }), + button: + onUndoDelete && !force + ? { label: $t('undo'), color: 'secondary', onclick: () => undoDeleteAssets(onUndoDelete, assets) } + : undefined, }, { timeout: 5000 }, ); diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts index f82377b63f..86c014f74a 100644 --- a/web/src/lib/utils/asset-utils.ts +++ b/web/src/lib/utils/asset-utils.ts @@ -1,9 +1,8 @@ -import ToastAction from '$lib/components/ToastAction.svelte'; +import type { AssetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { downloadManager } from '$lib/managers/download-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; -import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { preferences } from '$lib/stores/user.store'; import { downloadRequest, withError } from '$lib/utils'; import { getByteUnitString } from '$lib/utils/byte-units'; @@ -326,16 +325,11 @@ export const stackAssets = async (assets: { id: string }[], showNotification = t try { const stack = await createStack({ stackCreateDto: { assetIds: assets.map(({ id }) => id) } }); if (showNotification) { - toastManager.custom({ - component: ToastAction, - props: { - title: $t('success'), - description: $t('stacked_assets_count', { values: { count: stack.assets.length } }), - color: 'success', - button: { - text: $t('view_stack'), - onClick: () => navigate({ targetRoute: 'current', assetId: stack.primaryAssetId }), - }, + toastManager.primary({ + description: $t('stacked_assets_count', { values: { count: stack.assets.length } }), + button: { + label: $t('view_stack'), + onclick: () => navigate({ targetRoute: 'current', assetId: stack.primaryAssetId }), }, }); } @@ -394,7 +388,7 @@ export const keepThisDeleteOthers = async (keepAsset: AssetResponseDto, stack: S } }; -export const selectAllAssets = async (timelineManager: TimelineManager, assetInteraction: AssetInteraction) => { +export const selectAllAssets = async (timelineManager: TimelineManager, assetInteraction: AssetMultiSelectManager) => { if (assetInteraction.selectAll) { // Selection is already ongoing return; @@ -402,18 +396,18 @@ export const selectAllAssets = async (timelineManager: TimelineManager, assetInt assetInteraction.selectAll = true; try { - for (const monthGroup of timelineManager.months) { - if (!monthGroup.isLoaded) { - await timelineManager.loadMonthGroup(monthGroup.yearMonth); + for (const timelineMonth of timelineManager.months) { + if (!timelineMonth.isLoaded) { + await timelineManager.loadTimelineMonth(timelineMonth.yearMonth); } if (!assetInteraction.selectAll) { - assetInteraction.clearMultiselect(); + assetInteraction.clear(); break; // Cancelled } - assetInteraction.selectAssets([...monthGroup.assetsIterator()]); + assetInteraction.selectAssets([...timelineMonth.assetsIterator()]); - for (const dateGroup of monthGroup.dayGroups) { + for (const dateGroup of timelineMonth.timelineDays) { assetInteraction.addGroupToMultiselectGroup(dateGroup.groupTitle); } } @@ -424,11 +418,6 @@ export const selectAllAssets = async (timelineManager: TimelineManager, assetInt } }; -export const cancelMultiselect = (assetInteraction: AssetInteraction) => { - assetInteraction.selectAll = false; - assetInteraction.clearMultiselect(); -}; - export const toggleArchive = async (asset: AssetResponseDto) => { const $t = get(t); try { diff --git a/web/src/lib/utils/cancellable-task.spec.ts b/web/src/lib/utils/cancellable-task.spec.ts index 97d63684f8..27e4678d4f 100644 --- a/web/src/lib/utils/cancellable-task.spec.ts +++ b/web/src/lib/utils/cancellable-task.spec.ts @@ -161,6 +161,30 @@ describe('CancellableTask', () => { expect(task.executed).toBe(true); }); + it('should return CANCELED when concurrent caller is waiting and task is canceled', async () => { + const task = new CancellableTask(); + let resolveTask: () => void; + const taskPromise = new Promise((resolve) => { + resolveTask = resolve; + }); + const taskFn = async (signal: AbortSignal) => { + await taskPromise; + if (signal.aborted) { + throw new DOMException('Aborted', 'AbortError'); + } + }; + + const promise1 = task.execute(taskFn, true); + const promise2 = task.execute(taskFn, true); + + task.cancel(); + resolveTask!(); + + const [result1, result2] = await Promise.all([promise1, promise2]); + expect(result1).toBe('CANCELED'); + expect(result2).toBe('CANCELED'); + }); + it('should not cancel if task is already executed', async () => { const task = new CancellableTask(); const taskFn = vi.fn(async () => {}); diff --git a/web/src/lib/utils/cancellable-task.ts b/web/src/lib/utils/cancellable-task.ts index f5f4d7830b..c8cd9db4c0 100644 --- a/web/src/lib/utils/cancellable-task.ts +++ b/web/src/lib/utils/cancellable-task.ts @@ -64,8 +64,12 @@ export class CancellableTask { if (this.cancellable && !cancellable) { this.cancellable = cancellable; } - await this.complete; - return 'WAITED'; + try { + await this.complete; + return 'WAITED'; + } catch { + return 'CANCELED'; + } } this.cancellable = cancellable; const cancelToken = (this.cancelToken = new AbortController()); @@ -86,7 +90,9 @@ export class CancellableTask { this.#transitionToErrored(error); return 'ERRORED'; } finally { - this.cancelToken = null; + if (this.cancelToken === cancelToken) { + this.cancelToken = null; + } } } diff --git a/web/src/lib/utils/container-utils.spec.ts b/web/src/lib/utils/container-utils.spec.ts index 802ed24e40..d6a1efbe6a 100644 --- a/web/src/lib/utils/container-utils.spec.ts +++ b/web/src/lib/utils/container-utils.spec.ts @@ -1,4 +1,11 @@ -import { getContentMetrics, getNaturalSize, scaleToFit } from '$lib/utils/container-utils'; +import { + getContentMetrics, + getNaturalSize, + mapNormalizedRectToContent, + mapNormalizedToContent, + scaleToCover, + scaleToFit, +} from '$lib/utils/container-utils'; const mockImage = (props: { naturalWidth: number; @@ -92,3 +99,81 @@ describe('getNaturalSize', () => { expect(getNaturalSize(video)).toEqual({ width: 1920, height: 1080 }); }); }); + +describe('scaleToCover', () => { + it('should scale up to cover container when image is smaller', () => { + expect(scaleToCover({ width: 400, height: 300 }, { width: 800, height: 600 })).toEqual({ + width: 800, + height: 600, + }); + }); + + it('should use height scale when image is wider than container', () => { + expect(scaleToCover({ width: 2000, height: 1000 }, { width: 800, height: 600 })).toEqual({ + width: 1200, + height: 600, + }); + }); + + it('should use width scale when image is taller than container', () => { + expect(scaleToCover({ width: 1000, height: 2000 }, { width: 800, height: 600 })).toEqual({ + width: 800, + height: 1600, + }); + }); +}); + +describe('mapNormalizedToContent', () => { + const metrics = { contentWidth: 800, contentHeight: 400, offsetX: 0, offsetY: 100 }; + + it('should map top-left corner', () => { + expect(mapNormalizedToContent({ x: 0, y: 0 }, metrics)).toEqual({ x: 0, y: 100 }); + }); + + it('should map bottom-right corner', () => { + expect(mapNormalizedToContent({ x: 1, y: 1 }, metrics)).toEqual({ x: 800, y: 500 }); + }); + + it('should map center point', () => { + expect(mapNormalizedToContent({ x: 0.5, y: 0.5 }, metrics)).toEqual({ x: 400, y: 300 }); + }); + + it('should apply offsets correctly for letterboxed content', () => { + const letterboxed = { contentWidth: 300, contentHeight: 600, offsetX: 250, offsetY: 0 }; + expect(mapNormalizedToContent({ x: 0, y: 0 }, letterboxed)).toEqual({ x: 250, y: 0 }); + expect(mapNormalizedToContent({ x: 1, y: 1 }, letterboxed)).toEqual({ x: 550, y: 600 }); + }); + + it('should accept Size (zero offsets)', () => { + const size = { width: 800, height: 400 }; + expect(mapNormalizedToContent({ x: 0, y: 0 }, size)).toEqual({ x: 0, y: 0 }); + expect(mapNormalizedToContent({ x: 1, y: 1 }, size)).toEqual({ x: 800, y: 400 }); + expect(mapNormalizedToContent({ x: 0.5, y: 0.5 }, size)).toEqual({ x: 400, y: 200 }); + }); +}); + +describe('mapNormalizedRectToContent', () => { + const metrics = { contentWidth: 800, contentHeight: 400, offsetX: 0, offsetY: 100 }; + + it('should map a normalized rect to content pixel coordinates', () => { + const rect = mapNormalizedRectToContent({ x: 0.25, y: 0.25 }, { x: 0.75, y: 0.75 }, metrics); + expect(rect).toEqual({ left: 200, top: 200, width: 400, height: 200 }); + }); + + it('should map full image rect', () => { + const rect = mapNormalizedRectToContent({ x: 0, y: 0 }, { x: 1, y: 1 }, metrics); + expect(rect).toEqual({ left: 0, top: 100, width: 800, height: 400 }); + }); + + it('should handle letterboxed content with horizontal offsets', () => { + const letterboxed = { contentWidth: 300, contentHeight: 600, offsetX: 250, offsetY: 0 }; + const rect = mapNormalizedRectToContent({ x: 0, y: 0 }, { x: 1, y: 1 }, letterboxed); + expect(rect).toEqual({ left: 250, top: 0, width: 300, height: 600 }); + }); + + it('should accept Size (zero offsets)', () => { + const size = { width: 800, height: 400 }; + const rect = mapNormalizedRectToContent({ x: 0.25, y: 0.25 }, { x: 0.75, y: 0.75 }, size); + expect(rect).toEqual({ left: 200, top: 100, width: 400, height: 200 }); + }); +}); diff --git a/web/src/lib/utils/container-utils.ts b/web/src/lib/utils/container-utils.ts index ffa2fae769..36e260fcc7 100644 --- a/web/src/lib/utils/container-utils.ts +++ b/web/src/lib/utils/container-utils.ts @@ -1,14 +1,35 @@ -export interface ContentMetrics { +// Coordinate spaces used throughout the viewer: +// +// "Normalized": 0–1 range, (0,0) = top-left, (1,1) = bottom-right. Resolution-independent. +// Example: OCR coordinates, or face coords after dividing by metadata dimensions. +// +// "Content": pixel position within the container after scaling (scaleToFit/scaleToCover) +// and centering. Used for DOM overlay positioning (face boxes, OCR text). +// +// "Natural": pixel position in the original full-resolution image file (e.g. 4000×3000). +// Used when cropping or drawing on the source image. +// +// "Metadata pixel space": coordinates from face detection / OCR models, in pixels relative +// to face.imageWidth/imageHeight. Divide by those dimensions to get normalized coords. + +export type Point = { + x: number; + y: number; +}; + +export type Size = { + width: number; + height: number; +}; + +export type ContentMetrics = { contentWidth: number; contentHeight: number; offsetX: number; offsetY: number; -} +}; -export const scaleToCover = ( - dimensions: { width: number; height: number }, - container: { width: number; height: number }, -): { width: number; height: number } => { +export const scaleToCover = (dimensions: Size, container: Size): Size => { const scaleX = container.width / dimensions.width; const scaleY = container.height / dimensions.height; const scale = Math.max(scaleX, scaleY); @@ -18,10 +39,7 @@ export const scaleToCover = ( }; }; -export const scaleToFit = ( - dimensions: { width: number; height: number }, - container: { width: number; height: number }, -): { width: number; height: number } => { +export const scaleToFit = (dimensions: Size, container: Size): Size => { const scaleX = container.width / dimensions.width; const scaleY = container.height / dimensions.height; const scale = Math.min(scaleX, scaleY); @@ -31,14 +49,14 @@ export const scaleToFit = ( }; }; -const getElementSize = (element: HTMLImageElement | HTMLVideoElement): { width: number; height: number } => { +const getElementSize = (element: HTMLImageElement | HTMLVideoElement): Size => { if (element instanceof HTMLVideoElement) { return { width: element.clientWidth, height: element.clientHeight }; } return { width: element.width, height: element.height }; }; -export const getNaturalSize = (element: HTMLImageElement | HTMLVideoElement): { width: number; height: number } => { +export const getNaturalSize = (element: HTMLImageElement | HTMLVideoElement): Size => { if (element instanceof HTMLVideoElement) { return { width: element.videoWidth, height: element.videoHeight }; } @@ -56,3 +74,38 @@ export const getContentMetrics = (element: HTMLImageElement | HTMLVideoElement): offsetY: (client.height - contentHeight) / 2, }; }; + +export function mapNormalizedToContent(point: Point, sizeOrMetrics: Size | ContentMetrics): Point { + if ('contentWidth' in sizeOrMetrics) { + return { + x: point.x * sizeOrMetrics.contentWidth + sizeOrMetrics.offsetX, + y: point.y * sizeOrMetrics.contentHeight + sizeOrMetrics.offsetY, + }; + } + return { + x: point.x * sizeOrMetrics.width, + y: point.y * sizeOrMetrics.height, + }; +} + +export type Rect = { + top: number; + left: number; + width: number; + height: number; +}; + +export function mapNormalizedRectToContent( + topLeft: Point, + bottomRight: Point, + sizeOrMetrics: Size | ContentMetrics, +): Rect { + const tl = mapNormalizedToContent(topLeft, sizeOrMetrics); + const br = mapNormalizedToContent(bottomRight, sizeOrMetrics); + return { + top: tl.y, + left: tl.x, + width: br.x - tl.x, + height: br.y - tl.y, + }; +} diff --git a/web/src/lib/utils/context.ts b/web/src/lib/utils/context.ts index 080017a2d3..733b8e6eb9 100644 --- a/web/src/lib/utils/context.ts +++ b/web/src/lib/utils/context.ts @@ -1,4 +1,3 @@ -import type { AssetControlContext } from '$lib/types'; import { getContext, setContext } from 'svelte'; export function createContext(key: string | symbol = Symbol()) { @@ -7,5 +6,3 @@ export function createContext(key: string | symbol = Symbol()) { set: (context: T) => setContext(key, context), }; } - -export const { get: getAssetControlContext, set: setAssetControlContext } = createContext(); diff --git a/web/src/lib/utils/duplicate-utils.spec.ts b/web/src/lib/utils/duplicate-utils.spec.ts deleted file mode 100644 index 4fa427989a..0000000000 --- a/web/src/lib/utils/duplicate-utils.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { suggestDuplicate } from '$lib/utils/duplicate-utils'; -import type { AssetResponseDto } from '@immich/sdk'; - -describe('choosing a duplicate', () => { - it('picks the asset with the largest file size', () => { - const assets = [ - { exifInfo: { fileSizeInByte: 300 } }, - { exifInfo: { fileSizeInByte: 200 } }, - { exifInfo: { fileSizeInByte: 100 } }, - ]; - expect(suggestDuplicate(assets as AssetResponseDto[])).toEqual(assets[0]); - }); - - it('picks the asset with the most exif data if multiple assets have the same file size', () => { - const assets = [ - { exifInfo: { fileSizeInByte: 200, rating: 5, fNumber: 1 } }, - { exifInfo: { fileSizeInByte: 200, rating: 5 } }, - { exifInfo: { fileSizeInByte: 100, rating: 5 } }, - ]; - expect(suggestDuplicate(assets as AssetResponseDto[])).toEqual(assets[0]); - }); - - it('returns undefined for an empty array', () => { - const assets: AssetResponseDto[] = []; - expect(suggestDuplicate(assets)).toBeUndefined(); - }); - - it('handles assets with no exifInfo', () => { - const assets = [{ exifInfo: { fileSizeInByte: 200 } }, {}]; - expect(suggestDuplicate(assets as AssetResponseDto[])).toEqual(assets[0]); - }); - - it('handles assets with exifInfo but no fileSizeInByte', () => { - const assets = [{ exifInfo: { rating: 5, fNumber: 1 } }, { exifInfo: { rating: 5 } }]; - expect(suggestDuplicate(assets as AssetResponseDto[])).toEqual(assets[0]); - }); -}); diff --git a/web/src/lib/utils/duplicate-utils.ts b/web/src/lib/utils/duplicate-utils.ts deleted file mode 100644 index 1c783a3667..0000000000 --- a/web/src/lib/utils/duplicate-utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getExifCount } from '$lib/utils/exif-utils'; -import type { AssetResponseDto } from '@immich/sdk'; -import { sortBy } from 'lodash-es'; - -/** - * Suggests the best duplicate asset to keep from a list of duplicates. - * - * The best asset is determined by the following criteria: - * - Largest image file size in bytes - * - Largest count of exif data - * - * @param assets List of duplicate assets - * @returns The best asset to keep - */ -export const suggestDuplicate = (assets: AssetResponseDto[]): AssetResponseDto | undefined => { - let duplicateAssets = sortBy(assets, (asset) => asset.exifInfo?.fileSizeInByte ?? 0); - - // Update the list to only include assets with the largest file size - duplicateAssets = duplicateAssets.filter( - (asset) => asset.exifInfo?.fileSizeInByte === duplicateAssets.at(-1)?.exifInfo?.fileSizeInByte, - ); - - // If there are multiple assets with the same file size, sort the list by the count of exif data - if (duplicateAssets.length >= 2) { - duplicateAssets = sortBy(duplicateAssets, getExifCount); - } - - // Return the last asset in the list - return duplicateAssets.pop(); -}; diff --git a/web/src/lib/utils/ocr-utils.spec.ts b/web/src/lib/utils/ocr-utils.spec.ts index c3ce70394d..c88936fddf 100644 --- a/web/src/lib/utils/ocr-utils.spec.ts +++ b/web/src/lib/utils/ocr-utils.spec.ts @@ -1,5 +1,5 @@ import type { OcrBoundingBox } from '$lib/stores/ocr.svelte'; -import type { ContentMetrics } from '$lib/utils/container-utils'; +import type { Size } from '$lib/utils/container-utils'; import { getOcrBoundingBoxes } from '$lib/utils/ocr-utils'; describe('getOcrBoundingBoxes', () => { @@ -21,9 +21,9 @@ describe('getOcrBoundingBoxes', () => { text: 'hello', }, ]; - const metrics: ContentMetrics = { contentWidth: 1000, contentHeight: 500, offsetX: 0, offsetY: 0 }; + const imageSize: Size = { width: 1000, height: 500 }; - const boxes = getOcrBoundingBoxes(ocrData, metrics); + const boxes = getOcrBoundingBoxes(ocrData, imageSize); expect(boxes).toHaveLength(1); expect(boxes[0].id).toBe('box1'); @@ -37,7 +37,7 @@ describe('getOcrBoundingBoxes', () => { ]); }); - it('should apply offsets for letterboxed images', () => { + it('should map full-image box to full display area', () => { const ocrData: OcrBoundingBox[] = [ { id: 'box1', @@ -55,21 +55,20 @@ describe('getOcrBoundingBoxes', () => { text: 'test', }, ]; - const metrics: ContentMetrics = { contentWidth: 600, contentHeight: 400, offsetX: 100, offsetY: 50 }; + const imageSize: Size = { width: 600, height: 400 }; - const boxes = getOcrBoundingBoxes(ocrData, metrics); + const boxes = getOcrBoundingBoxes(ocrData, imageSize); expect(boxes[0].points).toEqual([ - { x: 100, y: 50 }, - { x: 700, y: 50 }, - { x: 700, y: 450 }, - { x: 100, y: 450 }, + { x: 0, y: 0 }, + { x: 600, y: 0 }, + { x: 600, y: 400 }, + { x: 0, y: 400 }, ]); }); it('should return empty array for empty input', () => { - const metrics: ContentMetrics = { contentWidth: 800, contentHeight: 600, offsetX: 0, offsetY: 0 }; - expect(getOcrBoundingBoxes([], metrics)).toEqual([]); + expect(getOcrBoundingBoxes([], { width: 800, height: 600 })).toEqual([]); }); it('should handle multiple boxes', () => { @@ -105,9 +104,9 @@ describe('getOcrBoundingBoxes', () => { text: 'second', }, ]; - const metrics: ContentMetrics = { contentWidth: 200, contentHeight: 200, offsetX: 0, offsetY: 0 }; + const imageSize: Size = { width: 200, height: 200 }; - const boxes = getOcrBoundingBoxes(ocrData, metrics); + const boxes = getOcrBoundingBoxes(ocrData, imageSize); expect(boxes).toHaveLength(2); expect(boxes[0].text).toBe('first'); diff --git a/web/src/lib/utils/ocr-utils.ts b/web/src/lib/utils/ocr-utils.ts index c483eb9551..2bf23bff2d 100644 --- a/web/src/lib/utils/ocr-utils.ts +++ b/web/src/lib/utils/ocr-utils.ts @@ -1,23 +1,19 @@ import type { OcrBoundingBox } from '$lib/stores/ocr.svelte'; -import type { ContentMetrics } from '$lib/utils/container-utils'; +import { mapNormalizedToContent, type Point, type Size } from '$lib/utils/container-utils'; import { clamp } from 'lodash-es'; - -export type Point = { - x: number; - y: number; -}; +export type { Point } from '$lib/utils/container-utils'; const distance = (p1: Point, p2: Point) => Math.hypot(p2.x - p1.x, p2.y - p1.y); export type VerticalMode = 'none' | 'cjk' | 'rotated'; -export interface OcrBox { +export type OcrBox = { id: string; points: Point[]; text: string; confidence: number; verticalMode: VerticalMode; -} +}; const CJK_PATTERN = /[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uAC00-\uD7AF\uFF00-\uFFEF]/; @@ -38,7 +34,7 @@ const getVerticalMode = (width: number, height: number, text: string): VerticalM * @param points - Array of 4 corner points of the bounding box * @returns 4x4 matrix to transform the div with text onto the polygon defined by the corner points, and size to set on the source div. */ -export const calculateBoundingBoxMatrix = (points: Point[]): { matrix: number[]; width: number; height: number } => { +export const calculateBoundingBoxMatrix = (points: Point[]): Size & { matrix: number[] } => { const [topLeft, topRight, bottomRight, bottomLeft] = points; const width = Math.max(distance(topLeft, topRight), distance(bottomLeft, bottomRight)); @@ -163,7 +159,7 @@ export const calculateFittedFontSize = ( return clamp(Math.min(scaleFromWidth, scaleFromHeight), MIN_FONT_SIZE, MAX_FONT_SIZE); }; -export const getOcrBoundingBoxes = (ocrData: OcrBoundingBox[], metrics: ContentMetrics): OcrBox[] => { +export const getOcrBoundingBoxes = (ocrData: OcrBoundingBox[], imageSize: Size): OcrBox[] => { const boxes: OcrBox[] = []; for (const ocr of ocrData) { const points = [ @@ -171,10 +167,7 @@ export const getOcrBoundingBoxes = (ocrData: OcrBoundingBox[], metrics: ContentM { x: ocr.x2, y: ocr.y2 }, { x: ocr.x3, y: ocr.y3 }, { x: ocr.x4, y: ocr.y4 }, - ].map((point) => ({ - x: point.x * metrics.contentWidth + metrics.offsetX, - y: point.y * metrics.contentHeight + metrics.offsetY, - })); + ].map((point) => mapNormalizedToContent(point, imageSize)); const boxWidth = Math.max(distance(points[0], points[1]), distance(points[3], points[2])); const boxHeight = Math.max(distance(points[0], points[3]), distance(points[1], points[2])); @@ -188,7 +181,7 @@ export const getOcrBoundingBoxes = (ocrData: OcrBoundingBox[], metrics: ContentM }); } - const rowThreshold = metrics.contentHeight * 0.02; + const rowThreshold = imageSize.height * 0.02; boxes.sort((a, b) => { const yDifference = a.points[0].y - b.points[0].y; if (Math.abs(yDifference) < rowThreshold) { diff --git a/web/src/lib/utils/people-utils.spec.ts b/web/src/lib/utils/people-utils.spec.ts index 80371bd9c4..f27a1855b5 100644 --- a/web/src/lib/utils/people-utils.spec.ts +++ b/web/src/lib/utils/people-utils.spec.ts @@ -1,5 +1,5 @@ import type { Faces } from '$lib/stores/people.store'; -import type { ContentMetrics } from '$lib/utils/container-utils'; +import type { Size } from '$lib/utils/container-utils'; import { getBoundingBox } from '$lib/utils/people-utils'; const makeFace = (overrides: Partial = {}): Faces => ({ @@ -16,21 +16,21 @@ const makeFace = (overrides: Partial = {}): Faces => ({ describe('getBoundingBox', () => { it('should scale face coordinates to display dimensions', () => { const face = makeFace(); - const metrics: ContentMetrics = { contentWidth: 800, contentHeight: 600, offsetX: 0, offsetY: 0 }; + const imageSize: Size = { width: 800, height: 600 }; - const boxes = getBoundingBox([face], metrics); + const boxes = getBoundingBox([face], imageSize); expect(boxes).toHaveLength(1); expect(boxes[0]).toEqual({ id: 'face-1', - top: Math.round(600 * (750 / 3000)), - left: Math.round(800 * (1000 / 4000)), - width: Math.round(800 * (2000 / 4000) - 800 * (1000 / 4000)), - height: Math.round(600 * (1500 / 3000) - 600 * (750 / 3000)), + top: 600 * (750 / 3000), + left: 800 * (1000 / 4000), + width: 800 * (2000 / 4000) - 800 * (1000 / 4000), + height: 600 * (1500 / 3000) - 600 * (750 / 3000), }); }); - it('should apply offsets for letterboxed display', () => { + it('should map full-image face to full display area', () => { const face = makeFace({ imageWidth: 1000, imageHeight: 1000, @@ -39,49 +39,21 @@ describe('getBoundingBox', () => { boundingBoxX2: 1000, boundingBoxY2: 1000, }); - const metrics: ContentMetrics = { contentWidth: 600, contentHeight: 600, offsetX: 100, offsetY: 0 }; + const imageSize: Size = { width: 600, height: 600 }; - const boxes = getBoundingBox([face], metrics); + const boxes = getBoundingBox([face], imageSize); expect(boxes[0]).toEqual({ id: 'face-1', top: 0, - left: 100, + left: 0, width: 600, height: 600, }); }); - it('should handle zoom by pre-scaled metrics', () => { - const face = makeFace({ - imageWidth: 1000, - imageHeight: 1000, - boundingBoxX1: 0, - boundingBoxY1: 0, - boundingBoxX2: 500, - boundingBoxY2: 500, - }); - const metrics: ContentMetrics = { - contentWidth: 1600, - contentHeight: 1200, - offsetX: -200, - offsetY: -100, - }; - - const boxes = getBoundingBox([face], metrics); - - expect(boxes[0]).toEqual({ - id: 'face-1', - top: -100, - left: -200, - width: 800, - height: 600, - }); - }); - it('should return empty array for empty faces', () => { - const metrics: ContentMetrics = { contentWidth: 800, contentHeight: 600, offsetX: 0, offsetY: 0 }; - expect(getBoundingBox([], metrics)).toEqual([]); + expect(getBoundingBox([], { width: 800, height: 600 })).toEqual([]); }); it('should handle multiple faces', () => { @@ -89,9 +61,8 @@ describe('getBoundingBox', () => { makeFace({ id: 'face-1', boundingBoxX1: 0, boundingBoxY1: 0, boundingBoxX2: 1000, boundingBoxY2: 1000 }), makeFace({ id: 'face-2', boundingBoxX1: 2000, boundingBoxY1: 1500, boundingBoxX2: 3000, boundingBoxY2: 2500 }), ]; - const metrics: ContentMetrics = { contentWidth: 800, contentHeight: 600, offsetX: 0, offsetY: 0 }; - const boxes = getBoundingBox(faces, metrics); + const boxes = getBoundingBox(faces, { width: 800, height: 600 }); expect(boxes).toHaveLength(2); expect(boxes[0].left).toBeLessThan(boxes[1].left); diff --git a/web/src/lib/utils/people-utils.ts b/web/src/lib/utils/people-utils.ts index b8fb8973e6..f7f9f4ee42 100644 --- a/web/src/lib/utils/people-utils.ts +++ b/web/src/lib/utils/people-utils.ts @@ -1,37 +1,21 @@ import type { Faces } from '$lib/stores/people.store'; import { getAssetMediaUrl } from '$lib/utils'; -import type { ContentMetrics } from '$lib/utils/container-utils'; +import { mapNormalizedRectToContent, type Rect, type Size } from '$lib/utils/container-utils'; import { AssetTypeEnum, type AssetFaceResponseDto } from '@immich/sdk'; -export interface BoundingBox { - id: string; - top: number; - left: number; - width: number; - height: number; -} +export type BoundingBox = Rect & { id: string }; -export const getBoundingBox = (faces: Faces[], metrics: ContentMetrics): BoundingBox[] => { +export const getBoundingBox = (faces: Faces[], imageSize: Size): BoundingBox[] => { const boxes: BoundingBox[] = []; for (const face of faces) { - const scaleX = metrics.contentWidth / face.imageWidth; - const scaleY = metrics.contentHeight / face.imageHeight; + const rect = mapNormalizedRectToContent( + { x: face.boundingBoxX1 / face.imageWidth, y: face.boundingBoxY1 / face.imageHeight }, + { x: face.boundingBoxX2 / face.imageWidth, y: face.boundingBoxY2 / face.imageHeight }, + imageSize, + ); - const coordinates = { - x1: scaleX * face.boundingBoxX1 + metrics.offsetX, - x2: scaleX * face.boundingBoxX2 + metrics.offsetX, - y1: scaleY * face.boundingBoxY1 + metrics.offsetY, - y2: scaleY * face.boundingBoxY2 + metrics.offsetY, - }; - - boxes.push({ - id: face.id, - top: Math.round(coordinates.y1), - left: Math.round(coordinates.x1), - width: Math.round(coordinates.x2 - coordinates.x1), - height: Math.round(coordinates.y2 - coordinates.y1), - }); + boxes.push({ id: face.id, ...rect }); } return boxes; diff --git a/web/src/lib/utils/persisted.ts b/web/src/lib/utils/persisted.ts index 73eb4de5db..008352ac8f 100644 --- a/web/src/lib/utils/persisted.ts +++ b/web/src/lib/utils/persisted.ts @@ -46,11 +46,25 @@ type PersistedLocalStorageOptions = { parse(text: string): T; }; valid?: (value: T | unknown) => value is T; + upgrade?: 'merge' | ((value: T) => T); }; +const merge = (defaultValue: T) => { + return (value: T): T => { + if (typeof value === 'object') { + value = { ...defaultValue, ...value } as T; + } + + return value; + }; +}; + +const identity = (value: T): T => value; + export class PersistedLocalStorage extends PersistedBase { constructor(key: string, defaultValue: T, options: PersistedLocalStorageOptions = {}) { const valid = options.valid || (() => true); + const upgrade = options.upgrade === 'merge' ? merge(defaultValue) : identity; const serializer = options.serializer || JSON; super(key, defaultValue, { @@ -69,7 +83,7 @@ export class PersistedLocalStorage extends PersistedBase { return; } - return parsed; + return upgrade(parsed); }, write: (key: string, value: T) => { if (browser) { diff --git a/web/src/lib/utils/timeline-util.ts b/web/src/lib/utils/timeline-util.ts index d7dc5d6aa4..f40158b44a 100644 --- a/web/src/lib/utils/timeline-util.ts +++ b/web/src/lib/utils/timeline-util.ts @@ -100,7 +100,7 @@ export const toISOYearMonthUTC = ({ year, month }: TimelineYearMonth): string => return `${yearFull}-${monthFull}-01T00:00:00.000Z`; }; -export function formatMonthGroupTitle(_date: DateTime): string { +export function formatTimelineMonthTitle(_date: DateTime): string { if (!_date.isValid) { return _date.toString(); } diff --git a/web/src/routes/(user)/+layout.svelte b/web/src/routes/(user)/+layout.svelte index e6e349fe91..983d25eced 100644 --- a/web/src/routes/(user)/+layout.svelte +++ b/web/src/routes/(user)/+layout.svelte @@ -1,30 +1,28 @@ -
+
{@render children?.()}
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 9a2d36ed95..285a50ef57 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 @@ -29,6 +29,7 @@ import Timeline from '$lib/components/timeline/Timeline.svelte'; import { AlbumPageViewMode } from '$lib/constants'; import { activityManager } from '$lib/managers/activity-manager.svelte'; + import { assetMultiSelectManager, AssetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { eventManager } from '$lib/managers/event-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; @@ -45,12 +46,9 @@ } from '$lib/services/album.service'; import { getGlobalActions } from '$lib/services/app.service'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { preferences, user } from '$lib/stores/user.store'; import { handlePromiseError } from '$lib/utils'; - import { cancelMultiselect } from '$lib/utils/asset-utils'; import { handleError } from '$lib/utils/handle-error'; import { isAlbumsRoute, navigate, type AssetGridRouteSearchParams } from '$lib/utils/navigation'; import { AlbumUserRole, AssetVisibility, getAlbumInfo, updateAlbumInfo, type AlbumResponseDto } from '@immich/sdk'; @@ -86,19 +84,13 @@ } let { data = $bindable() }: Props = $props(); - - let { isViewing: showAssetViewer, setAssetId, gridScrollTarget } = assetViewingStore; let { slideshowState, slideshowNavigation } = slideshowStore; - let oldAt: AssetGridRouteSearchParams | null | undefined = $state(); - let viewMode: AlbumPageViewMode = $state(AlbumPageViewMode.VIEW); - let timelineManager = $state() as TimelineManager; let showAlbumUsers = $derived(timelineManager?.showAssetOwners ?? false); - const assetInteraction = new AssetInteraction(); - const timelineInteraction = new AssetInteraction(); + const timelineMultiSelectManager = new AssetMultiSelectManager(); const handleFavorite = async () => { try { @@ -112,9 +104,11 @@ const asset = $slideshowNavigation === SlideshowNavigation.Shuffle ? await timelineManager.getRandomAsset() - : timelineManager.months[0]?.dayGroups[0]?.viewerAssets[0]?.asset; + : timelineManager.months[0]?.timelineDays[0]?.viewerAssets[0]?.asset; if (asset) { - handlePromiseError(setAssetId(asset.id).then(() => ($slideshowState = SlideshowState.PlaySlideshow))); + handlePromiseError( + assetViewerManager.setAssetId(asset.id).then(() => ($slideshowState = SlideshowState.PlaySlideshow)), + ); } }; @@ -128,11 +122,11 @@ await handleCloseSelectAssets(); return; } - if ($showAssetViewer) { + if (assetViewerManager.isViewing) { return; } - if (assetInteraction.selectionActive) { - cancelMultiselect(assetInteraction); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } await goto(Route.albums()); @@ -153,13 +147,13 @@ }; const handleCloseSelectAssets = async () => { - timelineInteraction.clearMultiselect(); + timelineMultiSelectManager.clear(); await setModeToView(); }; const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const handleRemoveAssets = async (assetIds: string[]) => { @@ -180,13 +174,13 @@ await updateThumbnail(assetId); viewMode = AlbumPageViewMode.VIEW; - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const updateThumbnailUsingCurrentSelection = async () => { - if (assetInteraction.selectedAssets.length === 1) { - const [firstAsset] = assetInteraction.selectedAssets; - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.assets.length === 1) { + const [firstAsset] = assetMultiSelectManager.assets; + assetMultiSelectManager.clear(); await updateThumbnail(firstAsset.id); } }; @@ -240,7 +234,7 @@ const isShared = $derived(viewMode === AlbumPageViewMode.SELECT_ASSETS ? false : album.albumUsers.length > 0); $effect(() => { - if ($showAssetViewer || !isShared) { + if (assetViewerManager.isViewing || !isShared) { return; } @@ -252,7 +246,9 @@ let isOwned = $derived($user.id == album.ownerId); let showActivityStatus = $derived( - album.albumUsers.length > 0 && !$showAssetViewer && (album.isActivityEnabled || activityManager.commentCount > 0), + album.albumUsers.length > 0 && + !assetViewerManager.isViewing && + (album.isActivityEnabled || activityManager.commentCount > 0), ); let isEditor = $derived( album.albumUsers.find(({ user: { id } }) => id === $user.id)?.role === AlbumUserRole.Editor || @@ -273,7 +269,7 @@ } }; const currentAssetIntersection = $derived( - viewMode === AlbumPageViewMode.SELECT_ASSETS ? timelineInteraction : assetInteraction, + viewMode === AlbumPageViewMode.SELECT_ASSETS ? timelineMultiSelectManager : assetMultiSelectManager, ); const onSharedLinkCreate = async () => { @@ -293,7 +289,7 @@ } await refreshAlbum(); - timelineInteraction.clearMultiselect(); + timelineMultiSelectManager.clear(); await setModeToView(); }; @@ -315,14 +311,14 @@ const { Cast } = $derived(getGlobalActions($t)); const { Share } = $derived(getAlbumActions($t, album)); - const { AddAssets, Upload } = $derived(getAlbumAssetsActions($t, album, timelineInteraction.selectedAssets)); + const { AddAssets, Upload } = $derived(getAlbumAssetsActions($t, album, timelineMultiSelectManager.assets)); const Close = $derived({ title: $t('go_back'), type: $t('command'), icon: mdiArrowLeft, onAction: handleEscape, - $if: () => !$showAssetViewer, + $if: () => !assetViewerManager.isViewing, shortcuts: { key: 'Escape' }, }); @@ -355,6 +351,7 @@ {showArchiveIcon} {onSelect} onEscape={handleEscape} + withStacked={true} > {#if viewMode !== AlbumPageViewMode.SELECT_ASSETS} {#if viewMode !== AlbumPageViewMode.SELECT_THUMBNAIL} @@ -441,8 +438,8 @@ {/if} - {#if showActivityStatus && !activityManager.isLoading} -
+ {#if showActivityStatus} +
- {#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + {#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} - + - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} > {/if} - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> {/if} - {#if assetInteraction.selectedAssets.length === 1} + {#if assetMultiSelectManager.assets.length === 1} {/if} - {#if $preferences.tags.enabled && assetInteraction.isAllUserOwned} + {#if $preferences.tags.enabled && assetMultiSelectManager.isAllUserOwned} {/if} - {#if isOwned || assetInteraction.isAllUserOwned} + {#if isOwned || assetMultiSelectManager.isAllUserOwned} {/if} - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} {/if} @@ -518,7 +512,7 @@ onclick={async () => { timelineManager.suspendTransitions = true; viewMode = AlbumPageViewMode.SELECT_ASSETS; - oldAt = { at: $gridScrollTarget?.at }; + oldAt = { at: assetViewerManager.gridScrollTarget?.at }; await navigate( { targetRoute: 'current', assetId: null, assetGridRouteSearchParams: { at: null } }, { replaceState: true }, @@ -597,10 +591,10 @@ {#snippet leading()}

- {#if !timelineInteraction.selectionActive} + {#if !timelineMultiSelectManager.selectionActive} {$t('add_to_album')} {:else} - {$t('selected_count', { values: { count: timelineInteraction.selectedAssets.length } })} + {$t('selected_count', { values: { count: timelineMultiSelectManager.assets.length } })} {/if}

{/snippet} @@ -621,7 +615,7 @@ {/if} {/if}
- {#if album.albumUsers.length > 0 && album && assetViewerManager.isShowActivityPanel && $user && !$showAssetViewer} + {#if album.albumUsers.length > 0 && album && assetViewerManager.isShowActivityPanel && $user && !assetViewerManager.isViewing}
() as TimelineManager; const options = { visibility: AssetVisibility.Archive }; - const assetInteraction = new AssetInteraction(); - const handleEscape = () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } }; const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; - + @@ -60,22 +58,19 @@ -{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} +{#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> - + timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} /> 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 b13146aab6..4bbc021b96 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 @@ -15,9 +15,9 @@ import TagAction from '$lib/components/timeline/actions/TagAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { preferences } from '$lib/stores/user.store'; import { ActionButton, CommandPaletteDefaultProvider } from '@immich/ui'; import { mdiDotsVertical } from '@mdi/js'; @@ -33,28 +33,26 @@ let timelineManager = $state() as TimelineManager; const options = { isFavorite: true, withStacked: true }; - const assetInteraction = new AssetInteraction(); - const handleEscape = () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } }; const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; - + {#snippet empty()} @@ -64,16 +62,13 @@ -{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} +{#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} timelineManager.removeAssets(assetIds)} /> - + @@ -82,7 +77,7 @@ timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> {#if $preferences.tags.enabled} diff --git a/web/src/routes/(user)/folders/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/folders/[[photos=photos]]/[[assetId=id]]/+page.svelte index 3cafdcbc5b..97c1bfafdf 100644 --- a/web/src/routes/(user)/folders/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/folders/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -16,16 +16,16 @@ import DeleteAssets from '$lib/components/timeline/actions/DeleteAssetsAction.svelte'; import DownloadAction from '$lib/components/timeline/actions/DownloadAction.svelte'; import FavoriteAction from '$lib/components/timeline/actions/FavoriteAction.svelte'; + import SetVisibilityAction from '$lib/components/timeline/actions/SetVisibilityAction.svelte'; import TagAction from '$lib/components/timeline/actions/TagAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import SkipLink from '$lib/elements/SkipLink.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import type { Viewport } from '$lib/managers/timeline-manager/types'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { foldersStore } from '$lib/stores/folders.svelte'; import { preferences } from '$lib/stores/user.store'; - import { cancelMultiselect } from '$lib/utils/asset-utils'; import { toTimelineAsset } from '$lib/utils/timeline-util'; import { joinPaths } from '$lib/utils/tree-utils'; import { ActionButton, CommandPaletteDefaultProvider, IconButton, Text } from '@immich/ui'; @@ -40,36 +40,38 @@ let { data }: Props = $props(); const viewport: Viewport = $state({ width: 0, height: 0 }); - const assetInteraction = new AssetInteraction(); const handleNavigateToFolder = (folderName: string) => navigateToView(joinPaths(data.tree.path, folderName)); const getLinkForPath = (path: string) => Route.folders({ path }); - afterNavigate(function clearAssetSelection() { - // Clear the asset selection when we navigate (like going to another folder) - cancelMultiselect(assetInteraction); + afterNavigate(() => { + assetMultiSelectManager.clear(); }); - function navigateToView(path: string) { + const navigateToView = (path: string) => { return goto(getLinkForPath(path), { keepFocus: true, noScroll: true }); - } + }; - async function triggerAssetUpdate() { - cancelMultiselect(assetInteraction); + const triggerAssetUpdate = async () => { + assetMultiSelectManager.clear(); if (data.tree.path) { await foldersStore.refreshAssetsByPath(data.tree.path); } await invalidateAll(); - } + }; - function handleSelectAllAssets() { + const handleSetVisibility = () => { + void triggerAssetUpdate(); + }; + + const handleSelectAllAssets = () => { if (!data.pathAssets) { return; } - assetInteraction.selectAssets(data.pathAssets.map((asset) => toTimelineAsset(asset))); - } + assetMultiSelectManager.selectAssets(data.pathAssets.map((asset) => toTimelineAsset(asset))); + }; @@ -100,7 +102,7 @@
-{#if assetInteraction.selectionActive} +{#if assetMultiSelectManager.selectionActive}
- cancelMultiselect(assetInteraction)} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + + {@const Actions = getAssetBulkActions($t)} 0) { for (const id of ids) { @@ -148,8 +147,9 @@ - - {#if $preferences.tags.enabled && assetInteraction.isAllUserOwned} + + + {#if $preferences.tags.enabled && assetMultiSelectManager.isAllUserOwned} {/if} 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 931c19341b..a01b47884c 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 @@ -13,10 +13,10 @@ import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; import { AssetAction } from '$lib/constants'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { Route } from '$lib/route'; import { getUserActions } from '$lib/services/user.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { AssetVisibility } from '@immich/sdk'; import { mdiDotsVertical } from '@mdi/js'; import { t } from 'svelte-i18n'; @@ -31,17 +31,15 @@ let timelineManager = $state() as TimelineManager; const options = { visibility: AssetVisibility.Locked }; - const assetInteraction = new AssetInteraction(); - const handleEscape = () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } }; const handleMoveOffLockedFolder = (assetIds: string[]) => { - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); timelineManager.removeAssets(assetIds); }; @@ -57,14 +55,14 @@ @@ -75,12 +73,9 @@ -{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - +{#if assetMultiSelectManager.selectionActive} + + 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 69d18d1bd5..84ba42088d 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 @@ -5,9 +5,9 @@ import type { SelectionBBox } from '$lib/components/shared-components/map/types'; import { timeToLoadTheMap } from '$lib/constants'; import Portal from '$lib/elements/Portal.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { Route } from '$lib/route'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { handlePromiseError } from '$lib/utils'; import { delay } from '$lib/utils/asset-utils'; import { navigate } from '$lib/utils/navigation'; @@ -20,9 +20,6 @@ } let { data }: Props = $props(); - - let { isViewing: showAssetViewer, asset: viewingAsset, setAssetId } = assetViewingStore; - let selectedClusterIds = $state.raw(new Set()); let selectedClusterBBox = $state.raw(); let isTimelinePanelVisible = $state(false); @@ -34,7 +31,7 @@ } onDestroy(() => { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); }); if (!featureFlagsManager.value.map) { @@ -42,7 +39,7 @@ } async function onViewAssets(assetIds: string[]) { - await setAssetId(assetIds[0]); + await assetViewerManager.setAssetId(assetIds[0]); closeTimelinePanel(); } @@ -50,7 +47,7 @@ selectedClusterIds = new Set(assetIds); selectedClusterBBox = bbox; isTimelinePanelVisible = true; - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); handlePromiseError(navigate({ targetRoute: 'current', assetId: null })); } @@ -89,13 +86,13 @@
- {#if $showAssetViewer} + {#if assetViewerManager.isViewing} {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); handlePromiseError(navigate({ targetRoute: 'current', assetId: null })); }} isShared={false} diff --git a/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte index 2412c0e0c9..9a06fd5d5a 100644 --- a/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -5,9 +5,9 @@ import DownloadAction from '$lib/components/timeline/actions/DownloadAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { AssetVisibility } from '@immich/sdk'; import { ActionButton, CommandPaletteDefaultProvider } from '@immich/ui'; import { mdiArrowLeft } from '@mdi/js'; @@ -26,26 +26,21 @@ withStacked: true, }); - const assetInteraction = new AssetInteraction(); - const handleEscape = () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } };
- +
-{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} +{#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} diff --git a/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte index a891c01b3e..0ae1f8bb66 100644 --- a/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -26,13 +26,13 @@ import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; import { PersonPageViewMode, QueryParameter, SessionStorageKey } from '$lib/constants'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import PersonMergeSuggestionModal from '$lib/modals/PersonMergeSuggestionModal.svelte'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; import { getPersonActions } from '$lib/services/person.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { locale } from '$lib/stores/preferences.store'; import { preferences } from '$lib/stores/user.store'; import { websocketEvents } from '$lib/stores/websocket'; @@ -65,7 +65,6 @@ let timelineManager = $state() as TimelineManager; const options = $derived({ visibility: AssetVisibility.Timeline, personId: data.person.id }); - const assetInteraction = new AssetInteraction(); let viewMode: PersonPageViewMode = $state(PersonPageViewMode.VIEW_ASSETS); let isEditingName = $state(false); @@ -106,8 +105,8 @@ }); const handleEscape = async () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } @@ -127,8 +126,8 @@ }); const handleUnmerge = () => { - timelineManager.removeAssets(assetInteraction.selectedAssets.map((a) => a.id)); - assetInteraction.clearMultiselect(); + timelineManager.removeAssets(assetMultiSelectManager.assets.map((a) => a.id)); + assetMultiSelectManager.clear(); viewMode = PersonPageViewMode.VIEW_ASSETS; }; @@ -154,7 +153,7 @@ handleError(error, $t('errors.unable_to_set_feature_photo')); } - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); viewMode = PersonPageViewMode.VIEW_ASSETS; }; @@ -283,7 +282,7 @@ const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const onPersonUpdate = async (response: PersonResponseDto) => { @@ -347,7 +346,7 @@ {person} bind:timelineManager {options} - {assetInteraction} + assetInteraction={assetMultiSelectManager} isSelectionMode={viewMode === PersonPageViewMode.SELECT_PERSON} singleSelect={viewMode === PersonPageViewMode.SELECT_PERSON} onSelect={handleSelectFeaturePhoto} @@ -458,18 +457,15 @@
- {#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + {#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} - + timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} /> @@ -484,10 +480,10 @@ timelineManager.update(ids, (asset) => (asset.visibility = visibility))} /> - {#if $preferences.tags.enabled && assetInteraction.isAllUserOwned} + {#if $preferences.tags.enabled && assetMultiSelectManager.isAllUserOwned} {/if} @@ -522,7 +518,7 @@ {#if viewMode === PersonPageViewMode.UNASSIGN_ASSETS} a.id)} + assetIds={assetMultiSelectManager.assets.map((a) => a.id)} personAssets={person} onClose={() => (viewMode = PersonPageViewMode.VIEW_ASSETS)} onConfirm={handleUnmerge} diff --git a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte index 31a991fa8f..b1aaa69725 100644 --- a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte @@ -1,5 +1,4 @@ - + -{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} +{#if assetMultiSelectManager.selectionActive} + + {@const Actions = getAssetBulkActions($t)} - + - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} /> - {#if assetInteraction.selectedAssets.length > 1 || isAssetStackSelected} + {#if assetMultiSelectManager.assets.length > 1 || isAssetStackSelected} updateStackedAssetInTimeline(timelineManager, result)} @@ -151,7 +138,7 @@ {#if isLinkActionAvailable} diff --git a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte index 4f050b8629..cbdfa73b37 100644 --- a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -19,15 +19,14 @@ import TagAction from '$lib/components/timeline/actions/TagAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import { QueryParameter } from '$lib/constants'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import type { Viewport } from '$lib/managers/timeline-manager/types'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { lang, locale } from '$lib/stores/preferences.store'; import { preferences } from '$lib/stores/user.store'; import { handlePromiseError } from '$lib/utils'; - import { cancelMultiselect } from '$lib/utils/asset-utils'; import { parseUtcDate } from '$lib/utils/date-time'; import { handleError } from '$lib/utils/handle-error'; import { isAlbumsRoute, isPeopleRoute } from '$lib/utils/navigation'; @@ -62,8 +61,6 @@ let scrollY = $state(0); let scrollYHistory = 0; - const assetInteraction = new AssetInteraction(); - type SearchTerms = MetadataSearchDto & Pick; let searchQuery = $derived(page.url.searchParams.get(QueryParameter.QUERY)); let smartSearchEnabled = $derived(featureFlagsManager.value.smartSearch); @@ -112,12 +109,12 @@ }; const handleSetVisibility = (assetIds: string[]) => { - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); onAssetDelete(assetIds); }; const handleSelectAll = () => { - assetInteraction.selectAssets(searchResultAssets.map((asset) => toTimelineAsset(asset))); + assetMultiSelectManager.selectAssets(searchResultAssets.map((asset) => toTimelineAsset(asset))); }; async function onSearchQueryUpdate() { @@ -226,7 +223,7 @@ } const onAlbumAddAssets = ({ assetIds }: { assetIds: string[] }) => { - cancelMultiselect(assetInteraction); + assetMultiSelectManager.clear(); if (terms.isNotInAlbum) { const assetIdSet = new Set(assetIds); @@ -294,7 +291,7 @@ {#if searchResultAssets.length > 0}
- {#if assetInteraction.selectionActive} + {#if assetMultiSelectManager.selectionActive}
- cancelMultiselect(assetInteraction)} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + + {@const Actions = getAssetBulkActions($t)} @@ -338,9 +332,9 @@ onclick={handleSelectAll} /> - {#if assetInteraction.isAllUserOwned} + {#if assetMultiSelectManager.isAllUserOwned} { for (const id of ids) { const asset = searchResultAssets.find((asset) => asset.id === id); @@ -357,7 +351,7 @@ - + {#if $preferences.tags.enabled} diff --git a/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte index fefd8dd032..90efd3bac8 100644 --- a/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -22,12 +22,12 @@ import TagAction from '$lib/components/timeline/actions/TagAction.svelte'; import { AssetAction } from '$lib/constants'; import SkipLink from '$lib/elements/SkipLink.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { Route } from '$lib/route'; import { getAssetBulkActions } from '$lib/services/asset.service'; import { getTagActions } from '$lib/services/tag.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { preferences, user } from '$lib/stores/user.store'; + import { preferences } from '$lib/stores/user.store'; import { joinPaths, TreeNode } from '$lib/utils/tree-utils'; import { getAllTags, type TagResponseDto } from '@immich/sdk'; import { ActionButton, CommandPaletteDefaultProvider, Text } from '@immich/ui'; @@ -41,8 +41,6 @@ let { data }: Props = $props(); - const assetInteraction = new AssetInteraction(); - let tags = $derived(data.tags); const tree = $derived(TreeNode.fromTags(tags)); const tag = $derived(tree.traverse(data.path)); @@ -58,7 +56,7 @@ const handleSetVisibility = (assetIds: string[]) => { timelineManager.removeAssets(assetIds); - assetInteraction.clearMultiselect(); + assetMultiSelectManager.clear(); }; const onRefresh = async () => { @@ -99,7 +97,7 @@ enableRouting={true} bind:timelineManager {options} - {assetInteraction} + assetInteraction={assetMultiSelectManager} removeAction={AssetAction.UNARCHIVE} > {#snippet empty()} @@ -113,20 +111,16 @@
- {#if assetInteraction.selectionActive} + {#if assetMultiSelectManager.selectionActive}
- assetInteraction.clearMultiselect()} - > - {@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())} + + {@const Actions = getAssetBulkActions($t)} - + timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))} > diff --git a/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte index 8f7be29004..18b793c566 100644 --- a/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -8,12 +8,12 @@ import SelectAllAssets from '$lib/components/timeline/actions/SelectAllAction.svelte'; import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte'; + import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { serverConfigManager } from '$lib/managers/server-config-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { Route } from '$lib/route'; import { getTrashActions } from '$lib/services/trash.service'; - import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { handlePromiseError } from '$lib/utils'; import { t } from 'svelte-i18n'; import type { PageData } from './$types'; @@ -27,15 +27,13 @@ let timelineManager = $state() as TimelineManager; const options = { isTrashed: true }; - const assetInteraction = new AssetInteraction(); - if (!featureFlagsManager.value.trash) { handlePromiseError(goto(Route.photos())); } const handleEscape = () => { - if (assetInteraction.selectionActive) { - assetInteraction.clearMultiselect(); + if (assetMultiSelectManager.selectionActive) { + assetMultiSelectManager.clear(); return; } }; @@ -45,12 +43,18 @@ {#if featureFlagsManager.value.trash} - +

{$t('trashed_items_will_be_permanently_deleted_after', { values: { days: serverConfigManager.value.trashDays }, @@ -63,12 +67,9 @@ {/if} -{#if assetInteraction.selectionActive} - assetInteraction.clearMultiselect()} - > - +{#if assetMultiSelectManager.selectionActive} + + timelineManager.removeAssets(assetIds)} /> timelineManager.removeAssets(assetIds)} /> diff --git a/web/src/routes/(user)/utilities/duplicates/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/utilities/duplicates/[[photos=photos]]/[[assetId=id]]/+page.svelte index c7c0c146ad..148ad08a02 100644 --- a/web/src/routes/(user)/utilities/duplicates/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/utilities/duplicates/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -3,24 +3,21 @@ import { page } from '$app/state'; import { shortcuts } from '$lib/actions/shortcut'; import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; + import LinkToDocs from '$lib/components/LinkToDocs.svelte'; import DuplicatesCompareControl from '$lib/components/utilities-page/duplicates/duplicates-compare-control.svelte'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; - import DuplicatesInformationModal from '$lib/modals/DuplicatesInformationModal.svelte'; import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte'; import { Route } from '$lib/route'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { locale } from '$lib/stores/preferences.store'; - import { stackAssets } from '$lib/utils/asset-utils'; - import { suggestDuplicate } from '$lib/utils/duplicate-utils'; import { handleError } from '$lib/utils/handle-error'; import type { AssetResponseDto } from '@immich/sdk'; - import { deleteAssets, deleteDuplicates, updateAssets } from '@immich/sdk'; + import { createStack, deleteDuplicates, resolveDuplicates, updateAssets } from '@immich/sdk'; import { Button, HStack, IconButton, modalManager, Text, toastManager } from '@immich/ui'; import { mdiCheckOutline, mdiChevronLeft, mdiChevronRight, - mdiInformationOutline, mdiKeyboard, mdiPageFirst, mdiPageLast, @@ -57,7 +54,6 @@ }; let duplicates = $state(data.duplicates); - const { isViewing: showAssetViewer } = assetViewingStore; const correctDuplicatesIndex = (index: number) => { return Math.max(0, Math.min(index, duplicates.length - 1)); @@ -99,34 +95,48 @@ }; const handleResolve = async (duplicateId: string, duplicateAssetIds: string[], trashIds: string[]) => { + const forceDelete = !featureFlagsManager.value.trash; + const shouldConfirmDelete = trashIds.length > 0 && forceDelete; + return withConfirmation( async () => { - await deleteAssets({ assetBulkDeleteDto: { ids: trashIds, force: !featureFlagsManager.value.trash } }); - await updateAssets({ assetBulkUpdateDto: { ids: duplicateAssetIds, duplicateId: null } }); + const keepAssetIds = duplicateAssetIds.filter((id) => !trashIds.includes(id)); + + const response = await resolveDuplicates({ + duplicateResolveDto: { + groups: [{ duplicateId, keepAssetIds, trashAssetIds: trashIds }], + }, + }); + + const { success, error, errorMessage } = response[0]; + if (!success) { + throw new Error(errorMessage || error); + } duplicates = duplicates.filter((duplicate) => duplicate.duplicateId !== duplicateId); deletedNotification(trashIds.length); await navigateToIndex(duplicatesIndex); }, - trashIds.length > 0 && !featureFlagsManager.value.trash ? $t('delete_duplicates_confirmation') : undefined, - trashIds.length > 0 && !featureFlagsManager.value.trash ? $t('permanently_delete') : undefined, + shouldConfirmDelete ? $t('delete_duplicates_confirmation') : undefined, + shouldConfirmDelete ? $t('permanently_delete') : undefined, ); }; const handleStack = async (duplicateId: string, assets: AssetResponseDto[]) => { - await stackAssets(assets, false); - const duplicateAssetIds = assets.map((asset) => asset.id); - await updateAssets({ assetBulkUpdateDto: { ids: duplicateAssetIds, duplicateId: null } }); + const assetIds = assets.map((asset) => asset.id); + await createStack({ stackCreateDto: { assetIds } }); + await updateAssets({ assetBulkUpdateDto: { ids: assetIds, duplicateId: null } }); duplicates = duplicates.filter((duplicate) => duplicate.duplicateId !== duplicateId); await navigateToIndex(duplicatesIndex); }; const handleDeduplicateAll = async () => { - const idsToKeep = duplicates.map((group) => suggestDuplicate(group.assets)).map((asset) => asset?.id); - const idsToDelete = duplicates.flatMap((group, i) => - group.assets.map((asset) => asset.id).filter((asset) => asset !== idsToKeep[i]), - ); + // Use server-provided suggestedKeepAssetIds from each group + const idsToDelete = duplicates.flatMap((group) => { + const keepIds = new Set(group.suggestedKeepAssetIds); + return group.assets.map((asset) => asset.id).filter((id) => !keepIds.has(id)); + }); let prompt, confirmText; if (featureFlagsManager.value.trash) { @@ -139,14 +149,26 @@ return withConfirmation( async () => { - await deleteAssets({ assetBulkDeleteDto: { ids: idsToDelete, force: !featureFlagsManager.value.trash } }); - await updateAssets({ - assetBulkUpdateDto: { - ids: [...idsToDelete, ...idsToKeep.filter((id): id is string => !!id)], - duplicateId: null, + // Resolve all groups in a single batch request + const response = await resolveDuplicates({ + duplicateResolveDto: { + groups: duplicates.map((group) => { + const keepIds = new Set(group.suggestedKeepAssetIds); + return { + duplicateId: group.duplicateId, + keepAssetIds: group.suggestedKeepAssetIds, + trashAssetIds: group.assets.map((asset) => asset.id).filter((id) => !keepIds.has(id)), + }; + }), }, }); + // Count failures and show appropriate message + const failedCount = response.filter(({ success }) => !success).length; + if (failedCount > 0) { + toastManager.danger($t('errors.unable_to_resolve_duplicate')); + } + duplicates = []; deletedNotification(idsToDelete.length); @@ -186,7 +208,7 @@ {/snippet} -

+
{#if duplicates && duplicates.length > 0} -
-
-

{$t('duplicates_description')}

-
- modalManager.show(DuplicatesInformationModal)} - /> -
+ +

{$t('duplicates_description')}

+
{#key duplicates[duplicatesIndex].duplicateId} handleResolve(duplicates[duplicatesIndex].duplicateId, duplicateAssetIds, trashIds)} onStack={(assets) => handleStack(duplicates[duplicatesIndex].duplicateId, assets)} diff --git a/web/src/routes/(user)/utilities/geolocation/+page.svelte b/web/src/routes/(user)/utilities/geolocation/+page.svelte index 9c8ad035f4..7a577bd8cf 100644 --- a/web/src/routes/(user)/utilities/geolocation/+page.svelte +++ b/web/src/routes/(user)/utilities/geolocation/+page.svelte @@ -1,16 +1,17 @@ @@ -148,11 +144,17 @@ title="latitude, longitude" class="rounded-3xl font-mono text-sm text-primary px-2 py-1 transition-all duration-100 ease-in-out {locationUpdated ? 'bg-primary/90 text-light font-semibold scale-105' - : ''}">{location.latitude.toFixed(3)}, {location.longitude.toFixed(3)} + {#if point} + {point.lat.toFixed(3)}, {point.lng.toFixed(3)} + {:else} + {$t('none')} + {/if} +
- @@ -169,11 +171,11 @@ leadingIcon={mdiMapMarkerMultipleOutline} size="small" color="primary" - disabled={assetInteraction.selectedAssets.length === 0} + disabled={assetMultiSelectManager.assets.length === 0} onclick={() => handleUpdate()} >
@@ -190,7 +192,7 @@ enableRouting={true} bind:timelineManager {options} - {assetInteraction} + assetInteraction={assetMultiSelectManager} removeAction={AssetAction.ARCHIVE} onEscape={handleEscape} withStacked diff --git a/web/src/routes/(user)/utilities/large-files/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/utilities/large-files/[[photos=photos]]/[[assetId=id]]/+page.svelte index f668e6e970..9d87eee922 100644 --- a/web/src/routes/(user)/utilities/large-files/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/utilities/large-files/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -3,7 +3,7 @@ import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; import LargeAssetData from '$lib/components/utilities-page/large-assets/large-asset-data.svelte'; import Portal from '$lib/elements/Portal.svelte'; - import { assetViewingStore } from '$lib/stores/asset-viewing.store'; + import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte'; import { handlePromiseError } from '$lib/utils'; import { getNextAsset, getPreviousAsset } from '$lib/utils/asset-utils'; import { navigate } from '$lib/utils/navigation'; @@ -19,10 +19,10 @@ let assets = $derived(data.assets); let asset = $derived(data.asset); - const { isViewing: showAssetViewer, asset: viewingAsset, setAsset } = assetViewingStore; + $effect(() => { if (asset) { - setAsset(asset); + assetViewerManager.setAsset(asset); } }); @@ -39,7 +39,7 @@ const onAction = (payload: Action) => { if (payload.type == 'trash') { assets = assets.filter((a) => a.id != payload.asset.id); - $showAssetViewer = false; + assetViewerManager.showAssetViewer(false); } }; @@ -48,9 +48,9 @@ }; const assetCursor = $derived({ - current: $viewingAsset, - nextAsset: getNextAsset(assets, $viewingAsset), - previousAsset: getPreviousAsset(assets, $viewingAsset), + current: assetViewerManager.asset!, + nextAsset: getNextAsset(assets, assetViewerManager.asset), + previousAsset: getPreviousAsset(assets, assetViewerManager.asset), }); @@ -68,7 +68,7 @@
-{#if $showAssetViewer} +{#if assetViewerManager.isViewing} {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} { - assetViewingStore.showAssetViewer(false); + assetViewerManager.showAssetViewer(false); handlePromiseError(navigate({ targetRoute: 'current', assetId: null })); }} /> diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 046d5ce068..8139fb94c8 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -52,7 +52,7 @@ prompt_default: $t('are_you_sure_to_do_this'), show_password: $t('show_password'), hide_password: $t('hide_password'), - dark_theme: $t('dark_theme'), + dark_theme: themeManager.isDark ? $t('light_theme') : $t('dark_theme'), open_menu: $t('open'), command_palette_prompt_default: $t('command_palette_prompt'), command_palette_to_select: $t('command_palette_to_select'), @@ -99,6 +99,9 @@ if (isAssetViewerRoute(from) && isAssetViewerRoute(to)) { return; } + + eventManager.emit('AppNavigate'); + showNavigationLoadingBar = true; }); diff --git a/web/src/routes/admin/users/[id]/+layout.svelte b/web/src/routes/admin/users/[id]/+layout.svelte index db86d05e72..c4aa9e3914 100644 --- a/web/src/routes/admin/users/[id]/+layout.svelte +++ b/web/src/routes/admin/users/[id]/+layout.svelte @@ -23,6 +23,7 @@ Heading, Icon, MenuItemType, + Meter, Stack, Text, } from '@immich/ui'; @@ -49,30 +50,21 @@ const { children, data }: Props = $props(); const { user, userPreferences, userStatistics, userSessions } = $derived(data); - const TiB = 1024 ** 4; - const usage = $derived(user.quotaUsageInBytes ?? 0); - let [statsUsage, statsUsageUnit] = $derived(getBytesWithUnit(usage, usage > TiB ? 2 : 0)); const usedBytes = $derived(user.quotaUsageInBytes ?? 0); - const availableBytes = $derived(user.quotaSizeInBytes ?? 1); - let usedPercentage = $derived(Math.min(Math.round((usedBytes / availableBytes) * 100), 100)); + const availableBytes = $derived(user.quotaSizeInBytes ?? 0); + const TiB = 1024 ** 4; + const [statsUsage, statsUsageUnit] = $derived(getBytesWithUnit(usedBytes, usedBytes > TiB ? 2 : 0)); let editedLocale = $derived(findLocale($locale).code); - let createAtDate: Date = $derived(new Date(user.createdAt)); - let updatedAtDate: Date = $derived(new Date(user.updatedAt)); - let userCreatedAtDateAndTime: string = $derived(createDateFormatter(editedLocale).formatDateTime(createAtDate)); - let userUpdatedAtDateAndTime: string = $derived(createDateFormatter(editedLocale).formatDateTime(updatedAtDate)); + let createAtDate = $derived(new Date(user.createdAt)); + let updatedAtDate = $derived(new Date(user.updatedAt)); + let userCreatedAtDateAndTime = $derived(createDateFormatter(editedLocale).formatDateTime(createAtDate)); + let userUpdatedAtDateAndTime = $derived(createDateFormatter(editedLocale).formatDateTime(updatedAtDate)); - const getUsageClass = () => { - if (usedPercentage >= 95) { - return 'bg-red-500'; - } - - if (usedPercentage > 80) { - return 'bg-yellow-500'; - } - - return 'bg-primary'; - }; + const storageUsageThresholds = [ + { from: 0.8, className: 'bg-warning' }, + { from: 0.95, className: 'bg-danger' }, + ]; const { ResetPassword, ResetPinCode, Update, Delete, Restore } = $derived(getUserAdminActions($t, user)); @@ -170,37 +162,26 @@ {#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0} - - {$t('storage_usage', { + + value={usedBytes / availableBytes} + thresholds={storageUsageThresholds} + /> {:else} {$t('unlimited')} {/if} - - {#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0} -
-

{$t('storage')}

-
-
-
-
- {/if}
diff --git a/web/src/routes/auth/pin-prompt/+page.svelte b/web/src/routes/auth/pin-prompt/+page.svelte index c14d4cf423..a0f8bdcc36 100644 --- a/web/src/routes/auth/pin-prompt/+page.svelte +++ b/web/src/routes/auth/pin-prompt/+page.svelte @@ -2,11 +2,10 @@ import { goto } from '$app/navigation'; import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte'; import PinCodeCreateForm from '$lib/components/user-settings-page/PinCodeCreateForm.svelte'; - import PincodeInput from '$lib/components/user-settings-page/PinCodeInput.svelte'; import { Route } from '$lib/route'; import { handleError } from '$lib/utils/handle-error'; import { unlockAuthSession } from '@immich/sdk'; - import { Button, Icon } from '@immich/ui'; + import { Button, Icon, PinInput } from '@immich/ui'; import { mdiLockOpenVariantOutline, mdiLockOutline, mdiLockSmart } from '@mdi/js'; import { t } from 'svelte-i18n'; import { fade } from 'svelte/transition'; @@ -55,15 +54,7 @@

{$t('enter_your_pin_code_subtitle')}

- + {:else}
diff --git a/web/static/robots.txt b/web/static/robots.txt index 9be576a0f5..6ffa7087cd 100644 --- a/web/static/robots.txt +++ b/web/static/robots.txt @@ -1,6 +1,7 @@ # Allow social media access og Tags User-agent: * Allow: /share/ +Allow: /s/ Allow: /api/assets/ # https://www.robotstxt.org/robotstxt.html diff --git a/web/tsconfig.json b/web/tsconfig.json index afebee51ad..795edd526e 100644 --- a/web/tsconfig.json +++ b/web/tsconfig.json @@ -8,11 +8,13 @@ "moduleResolution": "bundler", "noImplicitOverride": true, "resolveJsonModule": true, + "rootDir": ".", "skipLibCheck": true, "sourceMap": true, "strict": true, "target": "es2022", "types": ["vitest/globals"] }, + "exclude": ["vite.config.ts"], "extends": "./.svelte-kit/tsconfig.json" }