diff --git a/.github/ISSUE_TEMPLATE/bug_feature_question.md b/.github/ISSUE_TEMPLATE/bug_feature_question.md deleted file mode 100644 index 23d24e3..0000000 --- a/.github/ISSUE_TEMPLATE/bug_feature_question.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -name: '๐Ÿ› Bug / ๐Ÿ’ก Feature / โ“ Question' -about: 'Report a bug, request a feature, or ask a question about BentoPDF' -title: '(Bug) , (Feature) , or (Question) ' -labels: ['needs triage'] -assignees: [] ---- - -## Type of Issue - -Please check one: - -- [ ] ๐Ÿ› Bug Report -- [ ] ๐Ÿ’ก Feature Request -- [ ] โ“ Question / Help - ---- - -## Description - -Provide a clear and concise description of the issue, feature request, or question. - ---- - -## Steps to Reproduce (for Bugs) - -1. Go to '...' -2. Run '...' -3. Observe error: '...' - -**Expected Behavior:** -Describe what you expected BentoPDF to do. - -**Actual Behavior:** -Describe what actually happened, including error messages. - ---- - -## Feature Request Details (if applicable) - -- What functionality are you requesting? -- Why is this useful? -- Any example or context to illustrate it? - ---- - -## Question Details (if applicable) - -- What is your question? -- What have you tried so far? -- Any relevant code snippet or scenario? - ---- - -## Screenshots / Logs (if applicable) - -Attach any screenshots, logs, or stack traces that help explain the problem or question. - ---- - -## Environment - -- **OS:** (e.g., macOS 14.0 / Ubuntu 22.04 / Windows 11) -- **Dependencies / setup details (if any):** - ---- - -## ๐Ÿ’ญ Additional Context - -Any other information, suggestions, or references that might help maintainers. - ---- - -โœ… **Title Format Reminder:** - -- `(Bug) Text alignment incorrect on multi-line paragraphs` -- `(Feature) Add support for custom PDF metadata` -- `(Question) How to embed custom fonts?` - ---- diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..b638cfd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,122 @@ +name: ๐Ÿ› Bug Report +description: Report a bug in BentoPDF +title: "(Bug) " +labels: ["bug", "needs triage"] +body: + - type: markdown + attributes: + value: | + ## โš ๏ธ Important Notice + **Bug reports without logs or a sample file demonstrating the issue will not be investigated.** + Please help us help you by providing the information needed to reproduce and fix the problem. + + - type: textarea + id: description + attributes: + label: Description + description: Provide a clear and concise description of the bug. + placeholder: What happened? What did you expect to happen? + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: How can we reproduce this issue? + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. Upload file '...' + 4. See error + validations: + required: true + + - type: textarea + id: console-logs + attributes: + label: Console Logs + description: Open browser DevTools (F12 โ†’ Console tab) and paste any errors here. + placeholder: Paste console logs here... + render: shell + validations: + required: true + + - type: textarea + id: sample-file + attributes: + label: Sample PDF or File + description: | + Attach a sample PDF that reproduces the issue, or describe how to create one. + If you cannot share the original, create a minimal example that shows the problem. + placeholder: Drag and drop your file here, or describe how to reproduce with any PDF... + validations: + required: true + + - type: dropdown + id: browser + attributes: + label: Browser + description: Which browser are you using? + options: + - Chrome + - Firefox + - Safari + - Edge + - Brave + - Other + validations: + required: true + + - type: input + id: browser-version + attributes: + label: Browser Version + description: e.g., Chrome 120, Firefox 121 + placeholder: "120" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + options: + - macOS + - Windows + - Linux + - iOS + - Android + - Other + validations: + required: true + + - type: input + id: bentopdf-version + attributes: + label: BentoPDF Version + description: Check the footer or package.json + placeholder: "1.15.4" + validations: + required: false + + - type: textarea + id: additional + attributes: + label: Additional Context + description: Any other information that might help us debug this issue. + placeholder: Screenshots, network errors, stack traces, etc. + validations: + required: false + + - type: checkboxes + id: checklist + attributes: + label: Pre-submission Checklist + options: + - label: I have included console logs from the browser DevTools + required: true + - label: I have attached a sample file or described how to reproduce the issue + required: true + - label: I have searched existing issues to ensure this is not a duplicate + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3c041ab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: ๐Ÿ’ฌ Discord Community + url: https://discord.gg/Bgq3Ay3f2w + about: Join our Discord for quick questions and community support + - name: ๐Ÿ“– Documentation + url: https://github.com/nicholaschen09/BentoPDF#readme + about: Check the README for setup and usage instructions diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..9797c6a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,39 @@ +name: ๐Ÿ’ก Feature Request +description: Suggest a new feature for BentoPDF +title: "(Feature) " +labels: ["enhancement", "needs triage"] +body: + - type: textarea + id: description + attributes: + label: Feature Description + description: What functionality are you requesting? + placeholder: Describe the feature you'd like to see... + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use Case + description: Why is this feature useful? What problem does it solve? + placeholder: Explain why you need this feature... + validations: + required: true + + - type: textarea + id: examples + attributes: + label: Examples + description: Any examples, mockups, or references to illustrate the feature? + placeholder: Links to similar features, screenshots, etc. + validations: + required: false + + - type: textarea + id: additional + attributes: + label: Additional Context + description: Any other information about the feature request. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 0000000..ac5e905 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,30 @@ +name: โ“ Question +description: Ask a question about BentoPDF +title: "(Question) " +labels: ["question"] +body: + - type: textarea + id: question + attributes: + label: Question + description: What would you like to know? + placeholder: Your question here... + validations: + required: true + + - type: textarea + id: tried + attributes: + label: What have you tried? + description: What solutions have you already attempted? + placeholder: Describe what you've tried so far... + validations: + required: false + + - type: textarea + id: context + attributes: + label: Additional Context + description: Any relevant code snippets, screenshots, or scenarios. + validations: + required: false diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 1e8c87f..b11f990 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -51,11 +51,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - docker-build-and-push: + # Build each platform natively in parallel, then merge manifests + build-amd64: runs-on: ubuntu-latest if: github.repository == 'alam00000/bentopdf' permissions: - contents: write + contents: read packages: write strategy: matrix: @@ -70,18 +71,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} - - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: @@ -89,7 +81,7 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract version and determine release type + - name: Extract version id: version run: | if [[ $GITHUB_REF == refs/tags/v* ]]; then @@ -104,8 +96,7 @@ jobs: echo "is_release=false" >> $GITHUB_OUTPUT fi - # Build and push for releases (with 'latest' tag) - - name: Build and push ${{ matrix.mode.name }} image (release) + - name: Build and push amd64 ${{ matrix.mode.name }} (release) if: steps.version.outputs.is_release == 'true' uses: docker/build-push-action@v6 with: @@ -113,18 +104,12 @@ jobs: build-args: | SIMPLE_MODE=${{ matrix.mode.simple_mode }} tags: | - bentopdf/bentopdf${{ matrix.mode.suffix }}:latest - bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} - bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} - ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest - ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} - ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 + platforms: linux/amd64 + cache-from: type=gha,scope=amd64-${{ matrix.mode.name }} + cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }} - # Build and push for main branch (with 'edge' tag) - - name: Build and push ${{ matrix.mode.name }} image (edge) + - name: Build and push amd64 ${{ matrix.mode.name }} (edge) if: steps.version.outputs.is_release == 'false' uses: docker/build-push-action@v6 with: @@ -132,10 +117,208 @@ jobs: build-args: | SIMPLE_MODE=${{ matrix.mode.simple_mode }} tags: | - bentopdf/bentopdf${{ matrix.mode.suffix }}:edge - bentopdf/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} - ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge - ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 + platforms: linux/amd64 + cache-from: type=gha,scope=amd64-${{ matrix.mode.name }} + cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }} + + build-arm64: + runs-on: ubuntu-24.04-arm # Native ARM64 runner + permissions: + contents: read + packages: write + strategy: + matrix: + mode: + - name: default + simple_mode: false + suffix: "" + - name: simple + simple_mode: true + suffix: "-simple" + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract version + id: version + run: | + if [[ $GITHUB_REF == refs/tags/v* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT + echo "is_release=true" >> $GITHUB_OUTPUT + else + SHORT_SHA=${GITHUB_SHA::7} + echo "version=edge" >> $GITHUB_OUTPUT + echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "is_release=false" >> $GITHUB_OUTPUT + fi + + - name: Build and push arm64 ${{ matrix.mode.name }} (release) + if: steps.version.outputs.is_release == 'true' + uses: docker/build-push-action@v6 + with: + push: true + build-args: | + SIMPLE_MODE=${{ matrix.mode.simple_mode }} + tags: | + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + platforms: linux/arm64 + cache-from: type=gha,scope=arm64-${{ matrix.mode.name }} + cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }} + + - name: Build and push arm64 ${{ matrix.mode.name }} (edge) + if: steps.version.outputs.is_release == 'false' + uses: docker/build-push-action@v6 + with: + push: true + build-args: | + SIMPLE_MODE=${{ matrix.mode.simple_mode }} + tags: | + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64 + platforms: linux/arm64 + cache-from: type=gha,scope=arm64-${{ matrix.mode.name }} + cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }} + + # Merge GHCR manifests after both platforms are built + merge-manifests-ghcr: + runs-on: ubuntu-latest + needs: [build-amd64, build-arm64] + permissions: + packages: write + strategy: + matrix: + mode: + - name: default + suffix: "" + - name: simple + suffix: "-simple" + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract version + id: version + run: | + if [[ $GITHUB_REF == refs/tags/v* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT + echo "is_release=true" >> $GITHUB_OUTPUT + else + SHORT_SHA=${GITHUB_SHA::7} + echo "version=edge" >> $GITHUB_OUTPUT + echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "is_release=false" >> $GITHUB_OUTPUT + fi + + - name: Create and push GHCR manifest (release) + if: steps.version.outputs.is_release == 'true' + run: | + docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + - name: Create and push GHCR manifest (edge) + if: steps.version.outputs.is_release == 'false' + run: | + docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64 + + docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64 + + # Copy images from GHCR to DockerHub + push-to-dockerhub: + runs-on: ubuntu-latest + needs: [merge-manifests-ghcr] + continue-on-error: true + permissions: + contents: read + packages: read + strategy: + matrix: + mode: + - name: default + suffix: "" + - name: simple + suffix: "-simple" + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Extract version + id: version + run: | + if [[ $GITHUB_REF == refs/tags/v* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT + echo "is_release=true" >> $GITHUB_OUTPUT + else + SHORT_SHA=${GITHUB_SHA::7} + echo "version=edge" >> $GITHUB_OUTPUT + echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "is_release=false" >> $GITHUB_OUTPUT + fi + + - name: Copy images to DockerHub (release) + if: steps.version.outputs.is_release == 'true' + run: | + docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:latest \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64 + + - name: Copy images to DockerHub (edge) + if: steps.version.outputs.is_release == 'false' + run: | + docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64 + + docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \ + ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64 diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 4788759..3013709 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -59,6 +59,9 @@ jobs: with: # Upload entire repository path: dist + name: github-pages-deployment - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 + with: + artifact_name: github-pages-deployment diff --git a/.gitignore b/.gitignore index c4f76c1..469392d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,10 @@ coverage/ #backup .seo-backup -libreoffice-wasm-package \ No newline at end of file +libreoffice-wasm-package + +# helm chart +bentopdf-*.tgz + +# test +dist-test \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..1a21bcc --- /dev/null +++ b/.htaccess @@ -0,0 +1,139 @@ +RewriteEngine On +RewriteBase / + +# ============================================ +# 1. SECURITY HEADERS (UPDATED FOR CDN COMPATIBILITY) +# ============================================ + +Header always set X-Frame-Options "SAMEORIGIN" +Header always set X-Content-Type-Options "nosniff" +Header always set X-XSS-Protection "1; mode=block" +Header always set Referrer-Policy "strict-origin-when-cross-origin" +Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" +Header always set Cross-Origin-Opener-Policy "same-origin" +Header always set Cross-Origin-Embedder-Policy "require-corp" + + +# ============================================ +# 2. BROWSER CACHING +# ============================================ + +ExpiresActive On +ExpiresByType image/jpeg "access plus 1 year" +ExpiresByType image/png "access plus 1 year" +ExpiresByType image/gif "access plus 1 year" +ExpiresByType image/webp "access plus 1 year" +ExpiresByType image/svg+xml "access plus 1 year" +ExpiresByType image/x-icon "access plus 1 year" +ExpiresByType font/woff2 "access plus 1 year" +ExpiresByType font/woff "access plus 1 year" +ExpiresByType font/ttf "access plus 1 year" +ExpiresByType text/css "access plus 1 month" +ExpiresByType application/javascript "access plus 1 month" +ExpiresByType application/wasm "access plus 1 year" +ExpiresByType application/gzip "access plus 1 year" +ExpiresByType text/html "access plus 0 seconds" + + +# ============================================ +# 3. COMPRESSION (STANDARD) +# ============================================ +SetEnvIfNoCase Request_URI "\.gz$" no-gzip +SetEnvIfNoCase Request_URI "\.br$" no-gzip +SetEnvIfNoCase Request_URI "\.wasm$" no-gzip + + +AddOutputFilterByType DEFLATE text/plain +AddOutputFilterByType DEFLATE text/html +AddOutputFilterByType DEFLATE text/xml +AddOutputFilterByType DEFLATE text/css +AddOutputFilterByType DEFLATE application/xml +AddOutputFilterByType DEFLATE application/xhtml+xml +AddOutputFilterByType DEFLATE application/rss+xml +AddOutputFilterByType DEFLATE application/javascript +AddOutputFilterByType DEFLATE application/x-javascript +AddOutputFilterByType DEFLATE application/json +AddOutputFilterByType DEFLATE image/svg+xml +AddOutputFilterByType DEFLATE font/woff +AddOutputFilterByType DEFLATE font/ttf + + +# ============================================ +# 4. MIME TYPES & SPECIAL FILE HANDLING +# ============================================ +AddType application/javascript .js .mjs +AddType application/wasm .wasm +AddType font/woff2 .woff2 +AddType font/woff .woff +AddType image/webp .webp + + +ForceType application/wasm +Header set Content-Encoding "gzip" +Header set Cross-Origin-Resource-Policy "cross-origin" +Header append Vary Accept-Encoding + + + +ForceType application/octet-stream +Header set Content-Encoding "gzip" +Header append Vary Accept-Encoding + + +# ============================================ +# 5. REDIRECTS & ROUTING +# ============================================ +# Canonical WWW +RewriteCond %{HTTP_HOST} ^bentopdf\.com [NC] +RewriteRule ^(.*)$ https://www.bentopdf.com/$1 [L,R=301] + +# Force HTTPS +RewriteCond %{HTTPS} off +RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] + +# Remove trailing slash (except for language root directories) +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_URI} !^/(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/$ +RewriteCond %{REQUEST_URI} (.+)/$ +RewriteRule ^ %1 [R=301,L] + +# Existing files/dirs - serve directly +RewriteCond %{REQUEST_FILENAME} -f [OR] +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^ - [L] + +# ============================================ +# 5.1. LANGUAGE ROUTES (MUST BE BEFORE .html extension rule) +# ============================================ +# English prefix redirects to root +RewriteRule ^en/?$ / [R=301,L] +RewriteRule ^en/(.+)$ /$1 [R=301,L] + +# Language prefix root (e.g., /de/ -> /de/index.html) +RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L] + +# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html) +RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L] + +# ============================================ +# 5.5. DOCS ROUTING (VitePress) +# ============================================ +RewriteCond %{REQUEST_URI} ^/docs +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME}\.html -f +RewriteRule ^(.*)$ $1.html [L] + +# ============================================ +# 6. ADD .HTML EXTENSION IF FILE EXISTS (ROOT LEVEL ONLY) +# ============================================ +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] + +# ============================================ +# 7. ERROR PAGES +# ============================================ +ErrorDocument 404 /404.html diff --git a/404.html b/404.html index cf1ed3e..b1a8fbc 100644 --- a/404.html +++ b/404.html @@ -62,125 +62,7 @@ - + {{> navbar }}
@@ -210,7 +92,7 @@ class="flex flex-col sm:flex-row gap-4 justify-center items-center" > Back to Home @@ -274,171 +156,7 @@
- + {{> footer }} diff --git a/Dockerfile b/Dockerfile index defc4d9..e129421 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,12 +3,16 @@ ARG BASE_URL= # Build stage -FROM node:20-alpine AS builder +FROM public.ecr.aws/docker/library/node:20-alpine AS builder WORKDIR /app COPY package*.json ./ COPY vendor ./vendor ENV HUSKY=0 -RUN npm ci +RUN npm config set fetch-retries 5 && \ + npm config set fetch-retry-mintimeout 60000 && \ + npm config set fetch-retry-maxtimeout 300000 && \ + npm config set fetch-timeout 600000 && \ + npm ci COPY . . # Build without type checking (vite build only) @@ -18,18 +22,16 @@ ENV SIMPLE_MODE=$SIMPLE_MODE ARG COMPRESSION_MODE=all ENV COMPRESSION_MODE=$COMPRESSION_MODE -# global arg to local arg +# global arg to local arg - BASE_URL is read from env by vite.config.ts ARG BASE_URL ENV BASE_URL=$BASE_URL -RUN if [ -z "$BASE_URL" ]; then \ - npm run build -- --mode production; \ - else \ - npm run build -- --base=${BASE_URL} --mode production; \ - fi +ENV NODE_OPTIONS="--max-old-space-size=3072" + +RUN npm run build:with-docs # Production stage -FROM nginxinc/nginx-unprivileged:stable-alpine-slim +FROM quay.io/nginx/nginx-unprivileged:stable-alpine-slim LABEL org.opencontainers.image.source="https://github.com/alam00000/bentopdf" LABEL org.opencontainers.image.url="https://github.com/alam00000/bentopdf" diff --git a/README.md b/README.md index 379c25f..3b583e2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,54 @@

BentoPDF

+

+ + DigitalOcean Referral Badge + +

**BentoPDF** is a powerful, privacy-first, client-side PDF toolkit that is self hostable and allows you to manipulate, edit, merge, and process PDF files directly in your browser. No server-side processing is required, ensuring your files remain secure and private. -![Docker Pulls](https://img.shields.io/docker/pulls/bentopdf/bentopdf) [![Ko-fi](https://img.shields.io/badge/Buy%20me%20a%20Coffee-yellow?logo=kofi&style=flat-square)](https://ko-fi.com/alio01) ![GitHub Stars](https://img.shields.io/github/stars/alam00000/bentopdf?style=social) +![Docker Pulls](https://img.shields.io/docker/pulls/bentopdfteam/bentopdf) [![Ko-fi](https://img.shields.io/badge/Buy%20me%20a%20Coffee-yellow?logo=kofi&style=flat-square)](https://ko-fi.com/alio01) ![GitHub Stars](https://img.shields.io/github/stars/alam00000/bentopdf?style=social) [![Sponsor me on GitHub](https://img.shields.io/badge/Sponsor-%E2%9D%A4-ff69b4)](https://github.com/sponsors/alam00000) ![BentoPDF Tools](public/images/bentopdf-tools.png) --- +## Table of Contents + +- [Join Us on Discord](#-join-us-on-discord) +- [Documentation](#-documentation) +- [Licensing](#-licensing) +- [Stargazers over time](#-stargazers-over-time) +- [Thank You to Our Sponsors](#-thank-you-to-our-sponsors) +- [Why BentoPDF?](#-why-bentopdf) +- [Features / Tools Supported](#๏ธ-features--tools-supported) + - [Organize & Manage PDFs](#organize--manage-pdfs) + - [Edit & Modify PDFs](#edit--modify-pdfs) + - [Convert to PDF](#convert-to-pdf) + - [Convert from PDF](#convert-from-pdf) + - [Secure & Optimize PDFs](#secure--optimize-pdfs) +- [Translations](#-translations) +- [Getting Started](#-getting-started) + - [Prerequisites](#prerequisites) + - [Quick Start](#-quick-start) + - [Static Hosting](#static-hosting-using-netlify-vercel-and-github-pages) + - [Self-Hosting Locally](#-self-hosting-locally) + - [Docker Compose / Podman Compose](#-run-with-docker-compose--podman-compose-recommended) + - [Podman Quadlet](#-podman-quadlet-systemd-integration) + - [Simple Mode](#-simple-mode-for-internal-use) + - [Security Features](#-security-features) + - [Digital Signature CORS Proxy](#digital-signature-cors-proxy-required) + - [Version Management](#-version-management) + - [Development Setup](#-development-setup) +- [Tech Stack & Background](#๏ธ-tech-stack--background) +- [Roadmap](#๏ธ-roadmap) +- [Contributing](#-contributing) +- [Special Thanks](#special-thanks) + +--- + ## ๐Ÿ“ข Join Us on Discord [![Discord](https://img.shields.io/badge/Discord-Join%20Server-7289da?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/Bgq3Ay3f2w) @@ -23,6 +62,7 @@ Have questions, feature requests, or want to chat with the community? Join our D [![Documentation](https://img.shields.io/badge/Docs-VitePress-646cff?style=for-the-badge&logo=vite&logoColor=white)](https://bentopdf.com/docs/) Visit our [Documentation](https://bentopdf.com/docs/) for: + - **Getting Started** guide - **Tools Reference** (50+ tools) - **Self-Hosting** guides (Docker, Vercel, Netlify, Cloudflare, AWS, Hostinger, Nginx, Apache) @@ -33,12 +73,40 @@ Visit our [Documentation](https://bentopdf.com/docs/) for: ## ๐Ÿ“œ Licensing -BentoPDF is dual-licensed: +BentoPDF is **dual-licensed** to fit your needs: -- **AGPL-3.0** for open-source projects where you share your full source code publicly -- **Commercial License** for proprietary/closed-source applications - **[Get Lifetime License for $49](https://ko-fi.com/s/f32ca4cb75)** (a one-time lifetime purchase, includes all feature updates forever) +| License | Best For | Price | +| -------------- | -------------------------------------------- | ------------------ | +| **AGPL-3.0** | Open-source projects with public source code | **Free** | +| **Commercial** | Proprietary / closed-source applications | **$49** (lifetime) | -For more details, see our [Licensing Page](https://bentopdf.com/licensing.html) +

+ + Get Commercial License + +

+ +> **One-time purchase** ยท **Unlimited devices & users** ยท **Lifetime updates** ยท **No AGPL obligations** + +๐Ÿ“– For more details, see our [Licensing Page](https://bentopdf.com/licensing.html) + +### AGPL Components (Not Bundled) + +BentoPDF does **not** bundle AGPL-licensed processing libraries. The following components must be configured separately via **Advanced Settings** if you wish to use their features: + +| Component | License | Features Enabled | +| ---------------------- | -------- | --------------------------------------------------------------------------------------------------- | +| **PyMuPDF** | AGPL-3.0 | PDF to Text/Markdown/SVG/DOCX, Extract Images/Tables, EPUB/MOBI/XPS conversion, Compression, Deskew | +| **Ghostscript** | AGPL-3.0 | PDF/A Conversion, Font to Outline | +| **CoherentPDF (CPDF)** | AGPL-3.0 | Merge, Split by Bookmarks, Table of Contents, PDF to/from JSON, Attachments | + +> **Why?** This separation ensures clear legal boundaries. Users who need these features can configure their own WASM sources or use our optional [WASM Proxy](cloudflare/WASM-PROXY.md) to load them from external URLs. + +**To enable these features:** + +1. Navigate to **Advanced Settings** in BentoPDF +2. Configure the URL for each WASM module you need +3. The modules will be loaded dynamically when required
@@ -75,68 +143,93 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs. ### Organize & Manage PDFs -| Tool Name | Description | -| :------------------------ | :------------------------------------------------------------------------- | -| **Merge PDFs** | Combine multiple PDF files into one. | -| **Split PDFs** | Extract specific pages or divide a document into smaller files. | -| **Organize Pages** | Reorder, duplicate, or delete pages with a simple drag-and-drop interface. | -| **Extract Pages** | Save a specific range of pages as a new PDF. | -| **Delete Pages** | Remove unwanted pages from your document. | -| **Rotate PDF** | Rotate individual or all pages in a document. | -| **N-Up PDF** | Combine multiple pages onto a single page. | -| **View PDF** | A powerful, integrated PDF viewer. | -| **Alternate & Mix pages** | Merge pages by alternating pages from each PDF. | -| **Posterize PDF** | Split a PDF into multiple smaller pages for print. | -| **PDF Multi Tool** | Merge, Split, Organize, Delete, Rotate, Add Blank Pages, Extract and Duplicate in an unified interface. | -| **Add Attachments** | Embed one or more files into your PDF. | -| **Extract Attachments** | Extract all embedded files from PDF(s) as a ZIP. | -| **Edit Attachments** | View or remove attachments in your PDF. | -| **Divide Pages** | Divide pages horizontally or vertically. | -| **Combine to Single Page**| Stitch all pages into one continuous scroll. | -| **Add Blank Page** | Insert an empty page anywhere in your PDF. | -| **Reverse Pages** | Flip the order of all pages in your document. | -| **View Metadata** | Inspect the hidden properties of your PDF. | -| **PDFs to ZIP** | Package multiple PDF files into a ZIP archive. | -| **Compare PDFs** | Compare two PDFs side by side. | +| Tool Name | Description | +| :--------------------------- | :------------------------------------------------------------------------------------------------------ | +| **Merge PDFs** | Combine multiple PDF files into one. Preserves Bookmarks. | +| **Split PDFs** | Extract specific pages or divide a document into smaller files. | +| **Organize Pages** | Reorder, duplicate, or delete pages with a simple drag-and-drop interface. | +| **Extract Pages** | Save a specific range of pages as a new PDF. | +| **Delete Pages** | Remove unwanted pages from your document. | +| **Rotate PDF** | Rotate individual or all pages in a document. | +| **Rotate by Custom Degrees** | Rotate pages by any custom angle. | +| **N-Up PDF** | Combine multiple pages onto a single page. | +| **View PDF** | A powerful, integrated PDF viewer. | +| **Alternate & Mix Pages** | Merge pages by alternating pages from each PDF. Preserves Bookmarks. | +| **Posterize PDF** | Split a PDF into multiple smaller pages for print. | +| **PDF Multi Tool** | Merge, Split, Organize, Delete, Rotate, Add Blank Pages, Extract and Duplicate in an unified interface. | +| **PDF Booklet** | Rearrange pages for double-sided booklet printing. Fold and staple to create a booklet. | +| **Add Attachments** | Embed one or more files into your PDF. | +| **Extract Attachments** | Extract all embedded files from PDF(s) as a ZIP. | +| **Edit Attachments** | View or remove attachments in your PDF. | +| **Divide Pages** | Divide pages horizontally or vertically. | +| **Combine to Single Page** | Stitch all pages into one continuous scroll. | +| **Add Blank Page** | Insert an empty page anywhere in your PDF. | +| **Reverse Pages** | Flip the order of all pages in your document. | +| **View Metadata** | Inspect the hidden properties of your PDF. | +| **PDFs to ZIP** | Package multiple PDF files into a ZIP archive. | +| **Compare PDFs** | Compare two PDFs side by side. | ### Edit & Modify PDFs -| Tool Name | Description | -| :--------------------- | :---------------------------------------------------------- | -| **PDF Editor** | A comprehensive editor to modify your PDFs. | +| Tool Name | Description | +| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **PDF Editor** | Annotate, highlight, redact, comment, add shapes/images, search, and view PDFs. | | **Create Fillable Forms** | Create professional fillable PDF forms with text fields, checkboxes, dropdowns, radio buttons, signatures, and more. Fully compliant with PDF standards for compatibility with all PDF viewers. | -| **Add Page Numbers** | Easily add page numbers with customizable formatting. | -| **Add Watermark** | Add text or image watermarks to protect your documents. | -| **Header & Footer** | Add customizable headers and footers. | -| **Crop PDF** | Crop specific pages or the entire document. | -| **Invert Colors** | Invert the colors of your PDF pages for better readability. | -| **Change Background** | Modify the background color of your PDF. | -| **Change Text Color** | Change the color of text content within the PDF. | -| **Fill Forms** | Fill out PDF forms directly in your browser. | -| **Flatten PDF** | Flatten form fields and annotations into static content. | -| **Remove Annotations** | Remove comments, highlights, and other annotations. | -| **Remove Blank Pages** | Auto detect and remove blank pages in a PDF. | -| **Edit Bookmarks** | Add, Edit, Create, Import and Export PDF Bookmarks. | -| **Add Stamps** | Add image stamps to your PDF using the annotation toolbar. | -| **Table of Contents** | Generate a table of contents page from PDF bookmarks. | -| **Redact Content** | Permanently remove sensitive content from your PDFs. | +| **PDF Form Filler** | Fill in forms directly in the browser. Also supports XFA forms. | +| **Add Page Numbers** | Easily add page numbers with customizable formatting. | +| **Add Watermark** | Add text or image watermarks to protect your documents. | +| **Header & Footer** | Add customizable headers and footers. | +| **Crop PDF** | Crop specific pages or the entire document. | +| **Deskew PDF** | Automatically straighten tilted scanned pages using OpenCV. | +| **Font to Outline** | Convert all fonts to vector outlines for consistent rendering across all devices. | +| **Invert Colors** | Invert the colors of your PDF pages for better readability. | +| **Change Background** | Modify the background color of your PDF. | +| **Change Text Color** | Change the color of text content within the PDF. | +| **Flatten PDF** | Flatten form fields and annotations into static content. | +| **Remove Annotations** | Remove comments, highlights, and other annotations. | +| **Remove Blank Pages** | Auto detect and remove blank pages in a PDF. | +| **Edit Bookmarks** | Add, Edit, Create, Import and Export PDF Bookmarks. | +| **Add Stamps** | Add image stamps to your PDF using the annotation toolbar. | +| **Table of Contents** | Generate a table of contents page from PDF bookmarks. | +| **Redact Content** | Permanently remove sensitive content from your PDFs. | ### Convert to PDF -| Tool Name | Description | -| :------------------ | :-------------------------------------------------------------- | -| **Image to PDF** | Convert JPG, PNG, WebP, SVG, BMP, HEIC, and TIFF images to PDF. | -| **JPG to PDF** | Convert JPG images to PDF. | -| **PNG to PDF** | Convert PNG images to PDF. | -| **WebP to PDF** | Convert WebP images to PDF. | -| **SVG to PDF** | Convert SVG images to PDF. | -| **BMP to PDF** | Convert BMP images to PDF. | -| **HEIC to PDF** | Convert HEIC images to PDF. | -| **TIFF to PDF** | Convert TIFF images to PDF. | -| **Markdown to PDF** | Convert `.md` files into professional PDF documents. | -| **Text to PDF** | Convert plain text files into a PDF. | -| **EPUB to PDF** | Convert EPUB e-books to PDF format. | -| **JSON to PDF** | Convert JSON to PDF. | +| Tool Name | Description | +| :-------------------- | :----------------------------------------------------------------------------------------------------- | +| **Image to PDF** | Convert JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP to PDF. | +| **JPG to PDF** | Convert JPG, JPEG, and JPEG2000 (JP2/JPX) images to PDF. | +| **PNG to PDF** | Convert PNG images to PDF. | +| **WebP to PDF** | Convert WebP images to PDF. | +| **SVG to PDF** | Convert SVG images to PDF. | +| **BMP to PDF** | Convert BMP images to PDF. | +| **HEIC to PDF** | Convert HEIC images to PDF. | +| **TIFF to PDF** | Convert TIFF images to PDF. | +| **PSD to PDF** | Convert Adobe Photoshop (PSD) files to PDF. | +| **Word to PDF** | Convert Word documents (DOCX, DOC, ODT, RTF) to PDF. | +| **Excel to PDF** | Convert Excel spreadsheets (XLSX, XLS, ODS, CSV) to PDF. | +| **PowerPoint to PDF** | Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF. | +| **ODT to PDF** | Convert OpenDocument Text files to PDF. | +| **ODS to PDF** | Convert OpenDocument Spreadsheet (ODS) files to PDF. | +| **ODP to PDF** | Convert OpenDocument Presentation (ODP) files to PDF. | +| **ODG to PDF** | Convert OpenDocument Graphics (ODG) files to PDF. | +| **RTF to PDF** | Convert Rich Text Format documents to PDF. | +| **CSV to PDF** | Convert CSV spreadsheet files to PDF. | +| **Markdown to PDF** | Write or paste Markdown and export it as a beautifully formatted PDF. | +| **Text to PDF** | Convert plain text files into a PDF. | +| **JSON to PDF** | Convert JSON files to PDF. | +| **XML to PDF** | Convert XML documents to PDF. | +| **EPUB to PDF** | Convert EPUB e-books to PDF. | +| **MOBI to PDF** | Convert MOBI e-books to PDF. | +| **FB2 to PDF** | Convert FictionBook (FB2) e-books to PDF. | +| **CBZ to PDF** | Convert comic book archives (CBZ/CBR) to PDF. | +| **XPS to PDF** | Convert XPS/OXPS documents to PDF. | +| **Email to PDF** | Convert email files (EML, MSG) to PDF. Supports Outlook exports. | +| **Pages to PDF** | Convert Apple Pages documents to PDF. | +| **WPD to PDF** | Convert WordPerfect documents (WPD) to PDF. | +| **WPS to PDF** | Convert WPS Office documents to PDF. | +| **PUB to PDF** | Convert Microsoft Publisher (PUB) files to PDF. | +| **VSD to PDF** | Convert Microsoft Visio (VSD, VSDX) files to PDF. | ### Convert from PDF @@ -148,30 +241,35 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs. | **PDF to WebP** | Convert each PDF page into a WebP image. | | **PDF to BMP** | Convert each PDF page into a BMP image. | | **PDF to TIFF** | Convert each PDF page into a TIFF image. | +| **PDF to SVG** | Convert each page into a scalable vector graphic (SVG) for perfect quality. | | **PDF to Greyscale** | Convert a color PDF into a black-and-white version. | -| **OCR PDF** | Make scanned PDFs searchable and copyable using Optical Character Recognition. | +| **PDF to Text** | Extract text from PDF files and save as plain text (.txt). | | **PDF to JSON** | Convert PDF files to JSON format. | +| **PDF to CSV** | Extract tables from PDF and convert to CSV format. | +| **PDF to Excel** | Extract tables from PDF and convert to Excel (XLSX) format. | +| **Extract Tables** | Extract tables from PDF files and export as CSV, JSON, or Markdown. | +| **OCR PDF** | Make scanned PDFs searchable and copyable using Optical Character Recognition. | ### Secure & Optimize PDFs -| Tool Name | Description | -| :--------------------- | :----------------------------------------------------------------- | -| **Compress PDF** | Reduce file size while maintaining quality. | -| **Repair PDF** | Attempt to repair and recover data from a corrupted PDF. | -| **Encrypt PDF** | Add a password to protect your PDF from unauthorized access. | -| **Decrypt PDF** | Remove password protection from a PDF (password required). | -| **Change Permissions** | Set or modify user permissions for printing, copying, and editing. | -| **Sign PDF** | Add your digital signature to a document. | -| **Digital Signature** | Add cryptographic digital signatures using X.509 certificates (PFX/PEM). | -| **Validate Signature** | Verify digital signatures and view certificate details. | -| **Redact Content** | Permanently remove sensitive content from your PDFs. | -| **Edit Metadata** | View and modify PDF metadata (author, title, keywords, etc.). | -| **Remove Metadata** | Strip all metadata from your PDF for privacy. | -| **Linearize PDF** | Optimize PDF for fast web view. | -| **Sanitize PDF** | Remove potentially unwanted or malicous files from PDF. | -| **Fix Page Size** | Standardize all pages to a uniform size. | -| **Page Dimensions** | Analyze page size, orientation, and units. | -| **Remove Restrictions**| Remove password protection and security restrictions associated with digitally signed PDF files. | +| Tool Name | Description | +| :---------------------- | :--------------------------------------------------------------------------------------------------------- | +| **Compress PDF** | Reduce file size while maintaining quality. | +| **Repair PDF** | Attempt to repair and recover data from a corrupted PDF. | +| **Encrypt PDF** | Add a password to protect your PDF from unauthorized access. | +| **Decrypt PDF** | Remove password protection from a PDF (password required). | +| **Change Permissions** | Set or modify user permissions for printing, copying, and editing. | +| **Sign PDF** | Draw, type, or upload your signature. | +| **Digital Signature** | Add cryptographic digital signatures using X.509 certificates (PFX/PEM). Private key never leaves browser. | +| **Validate Signature** | Verify digital signatures, check certificate validity, and confirm document integrity. | +| **Redact Content** | Permanently remove sensitive content from your PDFs. | +| **Edit Metadata** | View and modify PDF metadata (author, title, keywords, etc.). | +| **Remove Metadata** | Strip all metadata from your PDF for privacy. | +| **Linearize PDF** | Optimize PDF for fast web viewing. | +| **Sanitize PDF** | Remove metadata, annotations, scripts, and more. | +| **Fix Page Size** | Standardize all pages to a uniform size. | +| **Page Dimensions** | Analyze page size, orientation, and units. | +| **Remove Restrictions** | Remove password protection and security restrictions associated with digitally signed PDF files. | --- @@ -179,12 +277,18 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs. BentoPDF is available in multiple languages: -| Language | Status | -|------------|--------| -| English | [![English](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/en/common.json) | -| German | [![German](https://img.shields.io/badge/In_Progress-yellow?style=flat-square)](public/locales/de/common.json) | -| Vietnamese | [![Vietnamese](https://img.shields.io/badge/In_Progress-yellow?style=flat-square)](public/locales/vi/common.json) | -| Chinese | [![Chinese](https://img.shields.io/badge/In_Progress-yellow?style=flat-square)](public/locales/zh/common.json) | +| Language | Status | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| English | [![English](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/en/common.json) | +| Chinese | [![Chinese](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/zh/common.json) | +| Traditional Chinese | [![Traditional Chinese](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/zh-TW/common.json) | +| French | [![French](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/fr/common.json) | +| German | [![German](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/de/common.json) | +| Indonesian | [![Indonesian](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/id/common.json) | +| Italian | [![Italian](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/it/common.json) | +| Portuguese | [![Portuguese](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/pt/common.json) | +| Turkish | [![Turkish](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/tr/common.json) | +| Vietnamese | [![Vietnamese](https://img.shields.io/badge/Complete-green?style=flat-square)](public/locales/vi/common.json) | Want to help translate BentoPDF into your language? Check out our [Translation Guide](TRANSLATION.md)! @@ -200,22 +304,9 @@ You can run BentoPDF locally for development or personal use. - [npm](https://www.npmjs.com/) (or yarn/pnpm) - [Docker](https://www.docker.com/) & [Docker Compose](https://docs.docker.com/compose/install/) (for containerized setup) -### ๐Ÿš€ Quick Start with Docker +### ๐Ÿš€ Quick Start -[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/K4AU2B) - -You can run BentoPDF directly from Docker Hub or GitHub Container Registry without cloning the repository: - -You can also watch the video on how to set it up ๐Ÿ‘‰ -[BentoPDF Docker Setup](https://drive.google.com/file/d/1C4eJ2nqeaH__1Tlad-xuBHaF2Ha4fSBf/view?usp=drive_link) - -**Using Docker Hub:** - -```bash -docker run -p 3000:8080 bentopdf/bentopdf:latest -``` - -**Using GitHub Container Registry:** +Run BentoPDF instantly from GitHub Container Registry (Recommended): ```bash docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest @@ -223,11 +314,34 @@ docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest Open your browser at: http://localhost:3000 -This is the fastest way to try BentoPDF without setting up a development environment. +
+Alternative: Using Docker Hub or Podman + +**Docker Hub:** + +```bash +docker run -p 3000:8080 bentopdfteam/bentopdf:latest +``` + +**Podman (GHCR):** + +```bash +podman run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest +``` + +**Podman (Docker Hub):** + +```bash +podman run -p 3000:8080 docker.io/bentopdfteam/bentopdf:latest +``` + +> **Note:** All `docker` commands in this documentation work with Podman by replacing `docker` with `podman`. + +
### Static Hosting using Netlify, Vercel, and GitHub Pages -It is very straightforward to host your own instance of BentoPDF using a static web page hosting service. Plus, services such as Netlify, Vercel, and GitHub Pages all offer a free tier for getting started. See [Static Hosting](https://github.com/alam00000/bentopdf/blob/main/STATIC-HOSTING.md)) for details. +It is very straightforward to host your own instance of BentoPDF using a static web page hosting service. Plus, services such as Netlify, Vercel, and GitHub Pages all offer a free tier for getting started. See [Static Hosting](https://github.com/alam00000/bentopdf/blob/main/STATIC-HOSTING.md) for details. ### ๐Ÿ  Self-Hosting Locally @@ -241,7 +355,7 @@ The easiest way to self-host is to download the pre-built distribution file from 2. Download the latest `dist-{version}.zip` file 3. Extract the zip file 4. Serve the extracted folder with your preferred web server - + **Serve the extracted folder (requires Node.js):** ```bash @@ -303,12 +417,12 @@ npm run build:all docker build --build-arg COMPRESSION_MODE=all -t bentopdf:all . ``` -| Mode | Files Kept | Use Case | -|------|------------|----------| -| `g` | `.gz` only | Standard nginx or minimal size | -| `b` | `.br` only | Modern CDN with Brotli support | -| `o` | originals | Development or custom compression | -| `all` | all formats | Maximum compatibility (default) | +| Mode | Files Kept | Use Case | +| ----- | ----------- | --------------------------------- | +| `g` | `.gz` only | Standard nginx or minimal size | +| `b` | `.br` only | Modern CDN with Brotli support | +| `o` | originals | Development or custom compression | +| `all` | all formats | Maximum compatibility (default) | **CDN Optimization:** @@ -323,6 +437,7 @@ npm run build ``` **How it works:** + - When `VITE_USE_CDN=true`: Browser loads WASM files from jsDelivr CDN (fast, global delivery) - Local files are **always included** as automatic fallback - If CDN fails then it falls back to local files @@ -348,7 +463,7 @@ cp -r dist/* serve-test/tools/bentopdf/ npx serve serve-test ``` -The website can be accessible at: ```http://localhost:3000/tools/bentopdf/``` +The website can be accessible at: `http://localhost:3000/tools/bentopdf/` The `npm run package` command creates a `dist-{version}.zip` file that you can use for self-hosting. @@ -378,11 +493,12 @@ docker build \ docker run -p 3000:8080 bentopdf-simple ``` -> **Important**: +> **Important**: +> > - Always include trailing slashes in `BASE_URL` (e.g., `/bentopdf/` not `/bentopdf`) > - The default value is `/` for root deployment -### ๐Ÿš€ Run with Docker Compose (Recommended) +### ๐Ÿš€ Run with Docker Compose / Podman Compose (Recommended) For a more robust setup with auto-restart capabilities: @@ -391,7 +507,8 @@ For a more robust setup with auto-restart capabilities: ```yaml services: bentopdf: - image: bentopdf/bentopdf:latest + image: ghcr.io/alam00000/bentopdf:latest # Recommended + # image: bentopdfteam/bentopdf:latest # Alternative: Docker Hub container_name: bentopdf ports: - '3000:8080' @@ -401,11 +518,48 @@ services: 2. **Start the application**: ```bash +# Docker Compose docker-compose up -d + +# Podman Compose +podman-compose up -d ``` The application will be available at `http://localhost:3000`. +### ๐Ÿง Podman Quadlet (Systemd Integration) + +For Linux production deployments, you can run BentoPDF as a systemd service using [Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html). + +Create `~/.config/containers/systemd/bentopdf.container`: + +```ini +[Unit] +Description=BentoPDF - Privacy-first PDF toolkit +After=network-online.target + +[Container] +Image=ghcr.io/alam00000/bentopdf:latest +ContainerName=bentopdf +PublishPort=3000:8080 +AutoUpdate=registry + +[Service] +Restart=always + +[Install] +WantedBy=default.target +``` + +Then enable and start: + +```bash +systemctl --user daemon-reload +systemctl --user enable --now bentopdf +``` + +For detailed Quadlet configuration, see [Self-Hosting Docker Guide](https://bentopdf.com/docs/self-hosting/docker). + ### ๐Ÿข Simple Mode for Internal Use For organizations that want a clean, distraction-free interface focused solely on PDF tools, BentoPDF supports a **Simple Mode** that hides all branding and marketing content. @@ -441,6 +595,7 @@ For detailed security configuration, see [SECURITY.md](SECURITY.md). The **Digital Signature** tool uses a signing library that may need to fetch certificate chain data from certificate authority provider. Since many certificate servers don't include CORS headers, a proxy is required for this feature to work in the browser. **When is the proxy needed?** + - Only when using the Digital Signature tool - Only if your certificate requires fetching issuer certificates from external URLs - Self-signed certificates typically don't need this @@ -448,16 +603,19 @@ The **Digital Signature** tool uses a signing library that may need to fetch cer **Deploying the CORS Proxy (Cloudflare Workers):** 1. **Navigate to the cloudflare directory:** + ```bash cd cloudflare ``` 2. **Login to Cloudflare (if not already):** + ```bash npx wrangler login ``` 3. **Deploy the worker:** + ```bash npx wrangler deploy ``` @@ -473,13 +631,13 @@ The **Digital Signature** tool uses a signing library that may need to fetch cer The CORS proxy includes several security measures: -| Feature | Description | -|---------|-------------| -| **URL Restrictions** | Only allows certificate URLs (`.crt`, `.cer`, `.pem`, `/certs/`, `/ocsp`) | -| **Private IP Blocking** | Blocks requests to localhost, 10.x, 192.168.x, 172.16-31.x | -| **File Size Limit** | Rejects files larger than 10MB | -| **Rate Limiting** | 60 requests per IP per minute (requires KV) | -| **HMAC Signatures** | Optional client-side signing (limited protection) | +| Feature | Description | +| ----------------------- | ------------------------------------------------------------------------- | +| **URL Restrictions** | Only allows certificate URLs (`.crt`, `.cer`, `.pem`, `/certs/`, `/ocsp`) | +| **Private IP Blocking** | Blocks requests to localhost, 10.x, 192.168.x, 172.16-31.x | +| **File Size Limit** | Rejects files larger than 10MB | +| **Rate Limiting** | 60 requests per IP per minute (requires KV) | +| **HMAC Signatures** | Optional client-side signing (limited protection) | #### Enabling Rate Limiting (Recommended) @@ -521,20 +679,20 @@ VITE_CORS_PROXY_SECRET=your-secret npm run build ### ๐Ÿ“ฆ Version Management -BentoPDF supports semantic versioning with multiple Docker tags available on both Docker Hub and GitHub Container Registry: +BentoPDF supports semantic versioning with multiple container tags available: -**Docker Hub:** - -- **Latest**: `bentopdf/bentopdf:latest` -- **Specific Version**: `bentopdf/bentopdf:1.0.0` -- **Version with Prefix**: `bentopdf/bentopdf:v1.0.0` - -**GitHub Container Registry:** +**GitHub Container Registry (Recommended):** - **Latest**: `ghcr.io/alam00000/bentopdf:latest` - **Specific Version**: `ghcr.io/alam00000/bentopdf:1.0.0` - **Version with Prefix**: `ghcr.io/alam00000/bentopdf:v1.0.0` +**Docker Hub:** + +- **Latest**: `bentopdfteam/bentopdf:latest` +- **Specific Version**: `bentopdfteam/bentopdf:1.0.0` +- **Version with Prefix**: `bentopdfteam/bentopdf:v1.0.0` + #### Quick Release ```bash @@ -657,6 +815,7 @@ npm run docs:preview ``` Documentation files are in the `docs/` folder: + - `docs/index.md` - Home page - `docs/getting-started.md` - Getting started guide - `docs/tools/` - Tools reference @@ -670,6 +829,8 @@ Documentation files are in the `docs/` folder: BentoPDF wouldn't be possible without the amazing open-source tools and libraries that power it. We'd like to extend our heartfelt thanks to the creators and maintainers of: +**Bundled Libraries:** + - **[PDFLib.js](https://pdf-lib.js.org/)** โ€“ For enabling powerful client-side PDF manipulation. - **[PDF.js](https://mozilla.github.io/pdf.js/)** โ€“ For the robust PDF rendering engine in the browser. - **[PDFKit](https://pdfkit.org/)** โ€“ For creating and editing PDFs with ease. @@ -677,10 +838,15 @@ BentoPDF wouldn't be possible without the amazing open-source tools and librarie - **[Cropper.js](https://fengyuanchen.github.io/cropperjs/)** โ€“ For intuitive image cropping functionality. - **[Vite](https://vitejs.dev/)** โ€“ For lightning-fast development and build tooling. - **[Tailwind CSS](https://tailwindcss.com/)** โ€“ For rapid, flexible, and beautiful UI styling. -- **[qpdf](https://github.com/qpdf/qpdf)** and **[qpdf-wasm](https://github.com/neslinesli93/qpdf-wasm)**โ€“ A powerful command-line tool and library for inspecting, repairing, and transforming PDF file ported to wasm -- **[cpdf](https://www.coherentpdf.com/)** โ€“ For content preserving pdf operations. +- **[qpdf](https://github.com/qpdf/qpdf)** and **[qpdf-wasm](https://github.com/neslinesli93/qpdf-wasm)** โ€“ For inspecting, repairing, and transforming PDF files. - **[LibreOffice](https://www.libreoffice.org/)** โ€“ For powerful document conversion capabilities. -- **[PyMuPDF](https://github.com/pymupdf/PyMuPDF)** โ€“ For high-performance PDF manipulation and data extraction. -- **[Ghostscript(GhostPDL)](https://github.com/ArtifexSoftware/ghostpdl)** โ€“ Needs no Introduction. + +**AGPL Libraries (Not Bundled - User Configured):** + +- **[CoherentPDF (cpdf)](https://www.coherentpdf.com/)** โ€“ For content-preserving PDF operations. _(AGPL-3.0)_ +- **[PyMuPDF](https://github.com/pymupdf/PyMuPDF)** โ€“ For high-performance PDF manipulation and data extraction. _(AGPL-3.0)_ +- **[Ghostscript (GhostPDL)](https://github.com/ArtifexSoftware/ghostpdl)** โ€“ For PDF/A conversion and font outlining. _(AGPL-3.0)_ + +> **Note:** AGPL-licensed libraries are not bundled with BentoPDF. Users can optionally configure these via Advanced Settings to enable additional features. Your work inspires and empowers developers everywhere. Thank you for making open-source amazing! diff --git a/RELEASE.md b/RELEASE.md index 88d0c78..106165b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -215,16 +215,16 @@ git reset --hard HEAD~1 1. **GitHub Actions Triggered**: Workflow starts building Docker image 2. **Docker Build**: Multi-architecture image created 3. **Docker Push**: Images pushed to Docker Hub with tags: - - `bentopdf/bentopdf:latest` - - `bentopdf/bentopdf:1.0.1` - - `bentopdf/bentopdf:v1.0.1` + - `bentopdfteam/bentopdf:latest` + - `bentopdfteam/bentopdf:1.0.1` + - `bentopdfteam/bentopdf:v1.0.1` ### **End Result:** Users can immediately pull your new version: ```bash -docker pull bentopdf/bentopdf:1.0.1 +docker pull bentopdfteam/bentopdf:1.0.1 ``` --- diff --git a/SIMPLE_MODE.md b/SIMPLE_MODE.md index 996caef..4dd45d6 100644 --- a/SIMPLE_MODE.md +++ b/SIMPLE_MODE.md @@ -23,27 +23,35 @@ When enabled, Simple Mode will: Use the pre-built Simple Mode image directly: +**Using GitHub Container Registry (Recommended):** + +```bash +# Docker +docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest + +# Podman +podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest +``` + **Using Docker Hub:** ```bash -docker run -p 3000:8080 bentopdf/bentopdf-simple:latest +# Docker +docker run -p 3000:8080 bentopdfteam/bentopdf-simple:latest + +# Podman +podman run -p 3000:8080 docker.io/bentopdfteam/bentopdf-simple:latest ``` -**Using GitHub Container Registry:** - -```bash -docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest -``` - -Or with Docker Compose: +Or with Docker Compose / Podman Compose: ```yaml services: bentopdf: - # Using Docker Hub - image: bentopdf/bentopdf-simple:latest - # Or using GitHub Container Registry - # image: ghcr.io/alam00000/bentopdf-simple:latest + # Using GitHub Container Registry (Recommended) + image: ghcr.io/alam00000/bentopdf-simple:latest + # Or using Docker Hub + # image: bentopdfteam/bentopdf-simple:latest container_name: bentopdf restart: unless-stopped ports: @@ -105,9 +113,13 @@ This automatically builds and serves Simple Mode on `http://localhost:3000`. ### Method 2: Using Pre-built Image (Easiest for Production) ```bash -# Pull and run the Simple Mode image -docker pull bentopdf/bentopdf-simple:latest -docker run -p 3000:8080 bentopdf/bentopdf-simple:latest +# Docker - Pull and run the Simple Mode image +docker pull ghcr.io/alam00000/bentopdf-simple:latest +docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest + +# Podman +podman pull ghcr.io/alam00000/bentopdf-simple:latest +podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest ``` Open `http://localhost:3000` in your browser. @@ -127,11 +139,13 @@ Open `http://localhost:3000` in your browser. ### Method 4: Compare Both Modes ```bash -# Test Normal Mode -docker run -p 3000:8080 bentopdf/bentopdf:latest +# Test Normal Mode (Docker) +docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest -# Test Simple Mode -docker run -p 3001:8080 bentopdf/bentopdf-simple:latest +# Test Simple Mode (Docker) +docker run -p 3001:8080 ghcr.io/alam00000/bentopdf-simple:latest + +# Podman users: replace 'docker' with 'podman' ``` - Normal Mode: `http://localhost:3000` @@ -149,52 +163,82 @@ When Simple Mode is working correctly, you should see: - โŒ No hero section with "The PDF Toolkit built for privacy" - โŒ No features, FAQ, testimonials, or footer sections -## ๐Ÿ“ฆ Available Docker Images +## ๐Ÿ“ฆ Available Container Images ### Normal Mode (Full Branding) -**Docker Hub:** - -- `bentopdf/bentopdf:latest` -- `bentopdf/bentopdf:v1.0.0` (versioned) - -**GitHub Container Registry:** +**GitHub Container Registry (Recommended):** - `ghcr.io/alam00000/bentopdf:latest` - `ghcr.io/alam00000/bentopdf:v1.0.0` (versioned) -### Simple Mode (Clean Interface) - **Docker Hub:** -- `bentopdf/bentopdf-simple:latest` -- `bentopdf/bentopdf-simple:v1.0.0` (versioned) +- `bentopdfteam/bentopdf:latest` +- `bentopdfteam/bentopdf:v1.0.0` (versioned) -**GitHub Container Registry:** +### Simple Mode (Clean Interface) + +**GitHub Container Registry (Recommended):** - `ghcr.io/alam00000/bentopdf-simple:latest` - `ghcr.io/alam00000/bentopdf-simple:v1.0.0` (versioned) +**Docker Hub:** + +- `bentopdfteam/bentopdf-simple:latest` +- `bentopdfteam/bentopdf-simple:v1.0.0` (versioned) + ## ๐Ÿš€ Production Deployment Examples -### Internal Company Tool +### Docker Compose / Podman Compose ```yaml services: bentopdf: - image: bentopdf/bentopdf-simple:latest + image: ghcr.io/alam00000/bentopdf-simple:latest # Recommended + # image: bentopdfteam/bentopdf-simple:latest # Alternative: Docker Hub container_name: bentopdf restart: unless-stopped ports: - - '80:80' + - '80:8080' environment: - PUID=1000 - PGID=1000 ``` +### Podman Quadlet (Linux Systemd) + +Create `~/.config/containers/systemd/bentopdf-simple.container`: + +```ini +[Unit] +Description=BentoPDF Simple Mode +After=network-online.target + +[Container] +Image=ghcr.io/alam00000/bentopdf-simple:latest +ContainerName=bentopdf-simple +PublishPort=80:8080 +AutoUpdate=registry + +[Service] +Restart=always + +[Install] +WantedBy=default.target +``` + +Enable and start: + +```bash +systemctl --user daemon-reload +systemctl --user enable --now bentopdf-simple +``` + ## โš ๏ธ Important Notes -- **Pre-built images**: Use `bentopdf/bentopdf-simple:latest` for Simple Mode +- **Pre-built images**: Use `ghcr.io/alam00000/bentopdf-simple:latest` for Simple Mode (recommended) - **Environment variables**: `SIMPLE_MODE=true` only works during build, not runtime - **Build-time optimization**: Simple Mode uses dead code elimination for smaller bundles - **Same functionality**: All PDF tools work identically in both modes diff --git a/TRANSLATION.md b/TRANSLATION.md index 57dc499..d5354bf 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -20,16 +20,32 @@ This guide will help you add new languages or improve existing translations for BentoPDF uses **i18next** for internationalization (i18n). Currently supported languages: - **English** (`en`) - Default +- **Belarusian** (`be`) - **German** (`de`) +- **Spanish** (`es`) +- **French** (`fr`) +- **Italian** (`it`) +- **Portuguese** (`pt`) +- **Turkish** (`tr`) - **Vietnamese** (`vi`) - **Indonesian** (`id`) +- **Chinese** (`zh`) +- **Traditional Chinese (Taiwan)** (`zh-TW`) The app automatically detects the language from the URL path: -- `/en/` โ†’ English +- `/` or `/en/` โ†’ English (default) - `/de/` โ†’ German -- `/vi/` โ†’ Vietnamese -- `/id/` โ†’ Indonesian +- `/fr/` โ†’ French +- etc. + +### Architecture + +BentoPDF uses a **static pre-rendering** approach for SEO-optimized i18n: + +1. **Build time**: `scripts/generate-i18n-pages.mjs` generates localized HTML files in `dist/{lang}/` +2. **Dev/Preview**: `languageRouterPlugin` in `vite.config.ts` handles URL rewriting +3. **Production**: Nginx serves static files directly from language directories --- @@ -37,50 +53,52 @@ The app automatically detects the language from the URL path: **To improve existing translations:** -1. Navigate to `public/locales/{language}/common.json` +1. Navigate to `public/locales/{language}/common.json` and `public/locales/{language}/tools.json` 2. Find the key you want to update 3. Change the translation value 4. Save and test -**To add a new language (e.g., Spanish):** +**To add a new language (e.g., Japanese `ja`):** -1. Copy `public/locales/en/common.json` to `public/locales/es/common.json` -2. Translate all values in `es/common.json` -3. Add Spanish to `supportedLanguages` in `src/js/i18n/i18n.ts` -4. Add Spanish name to `languageNames` in `src/js/i18n/i18n.ts` -5. Test thoroughly +1. Copy `public/locales/en/` to `public/locales/ja/` +2. Translate all values in both `ja/common.json` and `ja/tools.json` +3. Add Japanese to `supportedLanguages` and `languageNames` in `src/js/i18n/i18n.ts` +4. Add `'ja'` to `SUPPORTED_LANGUAGES` in `vite.config.ts` +5. Restart the dev server +6. Run `npm run build` to generate static language pages +7. Test thoroughly --- ## Adding a New Language -Let's add **French** as an example: +Let's add **Spanish** as an example: -### Step 1: Create Translation File +### Step 1: Create Translation Files ```bash # Create the directory -mkdir -p public/locales/fr +mkdir -p public/locales/es # Copy the English template -cp public/locales/en/common.json public/locales/fr/common.json +cp public/locales/en/common.json public/locales/es/common.json ``` -### Step 2: Translate the JSON File +### Step 2: Translate the JSON Files -Open `public/locales/fr/common.json` and translate all the values: +Open `public/locales/es/common.json` and translate all the values: ```json { "nav": { - "home": "Accueil", - "about": "ร€ propos", - "contact": "Contact", - "allTools": "Tous les outils" + "home": "Inicio", + "about": "Acerca de", + "contact": "Contacto", + "allTools": "Todas las herramientas" }, "hero": { - "title": "Votre boรฎte ร  outils PDF gratuite et sรฉcurisรฉe", - "subtitle": "Fusionnez, divisez, compressez et modifiez des PDF directement dans votre navigateur." + "title": "Tu conjunto de herramientas PDF gratuito y seguro", + "subtitle": "Combina, divide, comprime y edita archivos PDF directamente en tu navegador." } // ... continue translating all keys } @@ -91,22 +109,24 @@ Open `public/locales/fr/common.json` and translate all the values: โœ… **Correct:** ```json -"home": "Accueil" +"home": "Inicio" ``` โŒ **Wrong:** ```json -"accueil": "Accueil" +"inicio": "Inicio" ``` +Then do the same for `public/locales/fr/tools.json` to translate all tool names and descriptions. + ### Step 3: Register the Language Edit `src/js/i18n/i18n.ts`: ```typescript // Add 'fr' to supported languages -export const supportedLanguages = ['en', 'de', 'fr'] as const; +export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi'] as const; export type SupportedLanguage = (typeof supportedLanguages)[number]; // Add French display name @@ -119,21 +139,46 @@ export const languageNames: Record = { ### Step 4: Update Vite Configuration -In `vite.config.ts`, ensure the new language is included in the build: +In `vite.config.ts`, add your language to the `SUPPORTED_LANGUAGES` array: ```typescript -// Add 'fr' to the language regex -const langMatch = url.match(/^\/(en|de|zh|vi|it|fr)(\/.*)?$/); +const SUPPORTED_LANGUAGES = [ + 'en', + 'de', + 'es', + 'zh', + 'zh-TW', + 'vi', + 'it', + 'id', + 'tr', + 'fr', + 'pt', + 'ja', +] as const; ``` +> **Important**: This is required for both dev server routing and the build-time i18n generation. + ### Step 5: Test Your Translation ```bash -# Start the dev server +# Restart the dev server npm run dev -# Visit the French version -# http://localhost:5173/fr/ +# Visit the Japanese version +# http://localhost:5173/ja/ +``` + +### Step 6: Build and Verify Static Files + +```bash +# Run build (includes i18n page generation) +npm run build + +# Verify files were created +ls dist/ja/ +# Should show: index.html, merge-pdf.html, etc. ``` --- @@ -283,7 +328,10 @@ In `common.json`: - German: `http://localhost:5173/de/` - Vietnamese: `http://localhost:5173/vi/` - Indonesian: `http://localhost:5173/id/` - - Your new language: `http://localhost:5173/fr/` + - Chinese: `http://localhost:5173/zh/` + - Traditional Chinese (Taiwan): `http://localhost:5173/zh-TW/` + - French: `http://localhost:5173/fr/` + - Your new language: `http://localhost:5173/es/` 3. **Check these pages:** - Homepage (`/`) @@ -445,14 +493,48 @@ SyntaxError: Unexpected token } in JSON at position 1234 Make sure you added the language to both arrays in `i18n.ts`: ```typescript -export const supportedLanguages = ['en', 'de', 'fr']; // โ† Add here +export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi']; // โ† Add here export const languageNames = { en: 'English', de: 'Deutsch', + es: 'Espaรฑol', fr: 'Franรงais', // โ† And here + zh: 'ไธญๆ–‡', + vi: 'Tiแบฟng Viแป‡t', }; ``` +### Issue: 404 Error When Accessing Language Pages + +**Symptoms:** +Visiting `http://localhost:5173/ja/about.html` shows a 404 error page. + +**Solution:** +You need to add your language code to `SUPPORTED_LANGUAGES` in `vite.config.ts`: + +```typescript +const SUPPORTED_LANGUAGES = [ + 'en', + 'de', + 'es', + 'zh', + 'zh-TW', + 'vi', + 'it', + 'id', + 'tr', + 'fr', + 'pt', + 'ja', +] as const; +``` + +After updating, restart the dev server: + +```bash +npm run dev +``` + --- ## File Checklist @@ -462,10 +544,13 @@ When adding a new language, make sure these files are updated: - [ ] `public/locales/{lang}/common.json` - Main translation file - [ ] `public/locales/{lang}/tools.json` - Tools translation file - [ ] `src/js/i18n/i18n.ts` - Add to `supportedLanguages` and `languageNames` +- [ ] `vite.config.ts` - Add to `SUPPORTED_LANGUAGES` array - [ ] Test all pages: homepage, about, contact, FAQ, tool pages - [ ] Test settings modal and shortcuts - [ ] Test language switcher in footer - [ ] Verify URL routing works (`/{lang}/`) +- [ ] Run `npm run build` and verify `dist/{lang}/` folder is created +- [ ] Test that all tools load correctly --- @@ -501,14 +586,21 @@ Thank you for contributing to BentoPDF! ๐ŸŽ‰ Current translation coverage: -| Language | Code | Status | Maintainer | -| ------------- | ---- | -------------- | ---------- | -| English | `en` | โœ… Complete | Core team | -| German | `de` | ๐Ÿšง In Progress | Core team | -| Vietnamese | `vi` | โœ… Complete | Community | -| Indonesian | `id` | โœ… Complete | Community | -| Your Language | `??` | ๐Ÿšง In Progress | You? | +| Language | Code | Status | Maintainer | +| ------------------- | ------- | -------------- | ---------- | +| English | `en` | โœ… Complete | Core team | +| German | `de` | โœ… Complete | Community | +| Spanish | `es` | โœ… Complete | Community | +| French | `fr` | โœ… Complete | Community | +| Italian | `it` | โœ… Complete | Community | +| Portuguese | `pt` | โœ… Complete | Community | +| Turkish | `tr` | โœ… Complete | Community | +| Vietnamese | `vi` | โœ… Complete | Community | +| Indonesian | `id` | โœ… Complete | Community | +| Chinese | `zh` | โœ… Complete | Community | +| Traditional Chinese | `zh-TW` | โœ… Complete | Community | +| Your Language | `??` | ๐Ÿšง In Progress | You? | --- -**Last Updated**: December 2025 +**Last Updated**: January 2026 diff --git a/about.html b/about.html index 5a2ecbe..76dd16b 100644 --- a/about.html +++ b/about.html @@ -78,125 +78,7 @@ - + {{> navbar }}
@@ -412,171 +294,7 @@
- + {{> footer }} diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..812fd93 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: bentopdf +description: BentoPDF static frontend served by NGINX +icon: https://raw.githubusercontent.com/spwoodcock/bentopdf/refs/heads/main/public/favicon.ico +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.2.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.15.4" diff --git a/chart/README.md b/chart/README.md new file mode 100644 index 0000000..5199ab9 --- /dev/null +++ b/chart/README.md @@ -0,0 +1,114 @@ +# BentoPDF Helm Chart + +Deploys **BentoPDF** as a **single NGINX container** serving the static frontend. + +## Prereqs + +- Kubernetes cluster +- Helm v3 with OCI support +- An image that serves BentoPDF via nginx (default chart expects the repo image, which listens on **8080** inside the container) + +## Quickstart (ClusterIP + port-forward) + +```bash +helm install bentopdf ./chart + +kubectl port-forward deploy/bentopdf 8080:8080 +# open http://127.0.0.1:8080 +``` + +## Configuration + +### Image + +- **`image.repository`**: container image repo (default `bentopdf/bentopdf`) +- **`image.tag`**: image tag (default: `Chart.appVersion`) +- **`image.pullPolicy`**: default `IfNotPresent` + +### Ports + +- **`containerPort`**: container listen port (**8080** for the BentoPDF nginx image) +- **`service.port`**: Service port exposed in-cluster (default **80**) + +### Environment variables + +Use **`env`** for the container. + +Example (IPv4-only environments): + +```yaml +env: + - name: DISABLE_IPV6 + value: "true" +``` + +### Ingress (optional) + +Enable the built-in Kubernetes Ingress: + +```yaml +ingress: + enabled: true + className: nginx + hosts: + - host: bentopdf.example.com + paths: + - path: / + pathType: Prefix +``` + +### Gateway API: Gateway + HTTPRoute (optional) + +This chart can optionally: + +- Create a **Gateway** (`gateway.enabled=true`) +- Create an **HTTPRoute** (`httpRoute.enabled=true`) that points at the chart Service + +If your cluster uses a shared Gateway created elsewhere, set `gateway.enabled=false` and point `httpRoute.parentRefs` to that Gateway. + +Example (create both Gateway + HTTPRoute): + +```yaml +gateway: + enabled: true + gatewayClassName: cloudflare # or nginx, istio, etc (controller-specific) + listeners: + - name: http + protocol: HTTP + port: 80 + +httpRoute: + enabled: true + hostnames: + - bentopdf.example.com + parentRefs: + - name: "" # default: release fullname (or gateway.name if set) + sectionName: http + rules: + - matches: + - path: + type: PathPrefix + value: / +``` + +## Publish this chart to GHCR (OCI) for testing/deploying + +### Build And Push OCI + +```bash +echo "$GHCR_TOKEN" | helm registry login ghcr.io -u "$GHCR_USERNAME" --password-stdin + +cd chart +helm package . + +# produces bentopdf-.tgz +helm push bentopdf-*.tgz oci://ghcr.io/$GHCR_USERNAME/charts +``` + +This could be automated as part of a Github workflow. + +### Deploy + +```bash +helm upgrade --install bentopdf oci://ghcr.io/$GHCR_USERNAME/charts/bentopdf --version 0.1.0 +``` diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000..137f4f1 --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1,35 @@ +1. Get the application URL by running these commands: +{{- if .Values.httpRoute.enabled }} +{{- if .Values.httpRoute.hostnames }} + export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} +{{- else }} + export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") + {{- end }} +{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} + echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" + + NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. + The rules can be set for path, method, header and query parameters. + You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' +{{- end }} +{{- else if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "chart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "chart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..52b41f3 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,52 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "chart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "chart.labels" -}} +helm.sh/chart: {{ include "chart.chart" . }} +{{ include "chart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml new file mode 100644 index 0000000..5cde309 --- /dev/null +++ b/chart/templates/deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "chart.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.containerPort }} + protocol: TCP + {{- with .Values.env }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} diff --git a/chart/templates/gateway.yaml b/chart/templates/gateway.yaml new file mode 100644 index 0000000..b43028f --- /dev/null +++ b/chart/templates/gateway.yaml @@ -0,0 +1,17 @@ +{{- if .Values.gateway.enabled -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: {{ default (include "chart.fullname" .) .Values.gateway.name }} + namespace: {{ default .Release.Namespace .Values.gateway.namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.gateway.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + gatewayClassName: {{ required "values.gateway.gatewayClassName is required when gateway.enabled=true" .Values.gateway.gatewayClassName }} + listeners: + {{- toYaml .Values.gateway.listeners | nindent 4 }} +{{- end }} diff --git a/chart/templates/httproute.yaml b/chart/templates/httproute.yaml new file mode 100644 index 0000000..38a527a --- /dev/null +++ b/chart/templates/httproute.yaml @@ -0,0 +1,51 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $fullName := include "chart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- $defaultGatewayName := (default $fullName .Values.gateway.name) -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- range $ref := .Values.httpRoute.parentRefs }} + - name: {{ default $defaultGatewayName $ref.name | quote }} + {{- with $ref.sectionName }} + sectionName: {{ . | quote }} + {{- end }} + {{- with $ref.namespace }} + namespace: {{ . | quote }} + {{- end }} + {{- with $ref.kind }} + kind: {{ . | quote }} + {{- end }} + {{- with $ref.group }} + group: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.httpRoute.rules }} + {{- with .matches }} + - matches: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .filters }} + filters: + {{- toYaml . | nindent 8 }} + {{- end }} + backendRefs: + - name: {{ $fullName }} + port: {{ $svcPort }} + weight: 1 + {{- end }} +{{- end }} diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml new file mode 100644 index 0000000..89ec883 --- /dev/null +++ b/chart/templates/ingress.yaml @@ -0,0 +1,43 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- with .pathType }} + pathType: {{ . }} + {{- end }} + backend: + service: + name: {{ include "chart.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 0000000..dfc5b3a --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "chart.selectorLabels" . | nindent 4 }} diff --git a/chart/templates/serviceaccount.yaml b/chart/templates/serviceaccount.yaml new file mode 100644 index 0000000..ff2b900 --- /dev/null +++ b/chart/templates/serviceaccount.yaml @@ -0,0 +1,4 @@ +# The service account was removed, as it's not necessary for a chart like this. +# +# There are no calls to the Kubernetes API - routing between services. +# It's a simple nginx static website deployment only. diff --git a/chart/templates/tests/test-connection.yaml b/chart/templates/tests/test-connection.yaml new file mode 100644 index 0000000..2a38998 --- /dev/null +++ b/chart/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "chart.fullname" . }}-test-connection" + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['-qO-', 'http://{{ include "chart.fullname" . }}:{{ .Values.service.port }}/'] + restartPolicy: Never diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..6670d22 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,72 @@ +# Default values for the BentoPDF chart (single nginx static frontend). +replicaCount: 1 + +image: + # Image built from this repo's `Dockerfile` (nginx serving static frontend). + repository: alam00000/bentopdf-simple + pullPolicy: IfNotPresent + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} +podLabels: {} + +service: + type: ClusterIP + port: 80 + +# Container listen port (BentoPDF nginx image listens on 8080). +containerPort: 8080 + +env: [] + +ingress: + enabled: false + className: "" + annotations: {} + hosts: + - host: bentopdf.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + +# Gateway API (optional) +gateway: + enabled: false + name: "" # default: release fullname + namespace: "" # default: release namespace + annotations: {} + gatewayClassName: "" # required when enabled=true + listeners: + - name: http + protocol: HTTP + port: 80 + +httpRoute: + enabled: false + annotations: {} + parentRefs: + - name: "" # default: gateway.name (if set) else release fullname + sectionName: http + hostnames: + - bentopdf.local + rules: + - matches: + - path: + type: PathPrefix + value: / + +resources: {} + +livenessProbe: + httpGet: + path: / + port: http +readinessProbe: + httpGet: + path: / + port: http diff --git a/cloudflare/WASM-PROXY.md b/cloudflare/WASM-PROXY.md new file mode 100644 index 0000000..1a762c4 --- /dev/null +++ b/cloudflare/WASM-PROXY.md @@ -0,0 +1,92 @@ +# WASM Proxy Setup Guide + +BentoPDF uses a Cloudflare Worker to proxy WASM library requests, bypassing CORS restrictions when loading AGPL-licensed components (PyMuPDF, Ghostscript, CoherentPDF) from external sources. + +## Quick Start + +### 1. Deploy the Worker + +```bash +cd cloudflare +npx wrangler login +npx wrangler deploy -c wasm-wrangler.toml +``` + +### 2. Configure Source URLs + +Set environment secrets with the base URLs for your WASM files: + +```bash +# Option A: Interactive prompts +npx wrangler secret put PYMUPDF_SOURCE -c wasm-wrangler.toml +npx wrangler secret put GS_SOURCE -c wasm-wrangler.toml +npx wrangler secret put CPDF_SOURCE -c wasm-wrangler.toml + +# Option B: Set via Cloudflare Dashboard +# Go to Workers & Pages > bentopdf-wasm-proxy > Settings > Variables +``` + +**Recommended Source URLs:** + +- PYMUPDF_SOURCE: `https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm@0.11.14/` +- GS_SOURCE: `https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm/assets/` +- CPDF_SOURCE: `https://cdn.jsdelivr.net/npm/coherentpdf/dist/` + +> **Note:** You can use your own hosted WASM files instead of the recommended URLs. Just ensure your files match the expected directory structure and file names that BentoPDF expects for each module. + +### 3. Configure BentoPDF + +In BentoPDF's Advanced Settings (wasm-settings.html), enter: + +| Module | URL | +| ----------- | ------------------------------------------------------------------- | +| PyMuPDF | `https://bentopdf-wasm-proxy..workers.dev/pymupdf/` | +| Ghostscript | `https://bentopdf-wasm-proxy..workers.dev/gs/` | +| CoherentPDF | `https://bentopdf-wasm-proxy..workers.dev/cpdf/` | + +## Custom Domain (Optional) + +To use a custom domain like `wasm.bentopdf.com`: + +1. Add route in `wasm-wrangler.toml`: + +```toml +routes = [ + { pattern = "wasm.bentopdf.com/*", zone_name = "bentopdf.com" } +] +``` + +2. Add DNS record in Cloudflare: + - Type: AAAA + - Name: wasm + - Content: 100:: + - Proxied: Yes + +3. Redeploy: + +```bash +npx wrangler deploy -c wasm-wrangler.toml +``` + +## Security Features + +- **Origin validation**: Only allows requests from configured origins +- **Rate limiting**: 100 requests/minute per IP (requires KV namespace) +- **File type restrictions**: Only WASM-related files (.js, .wasm, .data, etc.) +- **Size limits**: Max 100MB per file +- **Caching**: Reduces origin requests and improves performance + +## Self-Hosting Notes + +1. Update `ALLOWED_ORIGINS` in `wasm-proxy-worker.js` to include your domain +2. Host your WASM files on any origin (R2, S3, or any CDN) +3. Set source URLs as secrets in your worker + +## Endpoints + +| Endpoint | Description | +| ------------ | -------------------------------------- | +| `/` | Health check, shows configured modules | +| `/pymupdf/*` | PyMuPDF WASM files | +| `/gs/*` | Ghostscript WASM files | +| `/cpdf/*` | CoherentPDF files | diff --git a/cloudflare/wasm-proxy-worker.js b/cloudflare/wasm-proxy-worker.js new file mode 100644 index 0000000..a61346e --- /dev/null +++ b/cloudflare/wasm-proxy-worker.js @@ -0,0 +1,356 @@ +/** + * BentoPDF WASM Proxy Worker + * + * This Cloudflare Worker proxies WASM module requests to bypass CORS restrictions. + * It fetches WASM libraries (PyMuPDF, Ghostscript, CoherentPDF) from configured sources + * and serves them with proper CORS headers. + * + * Endpoints: + * - /pymupdf/* - Proxies to PyMuPDF WASM source + * - /gs/* - Proxies to Ghostscript WASM source + * - /cpdf/* - Proxies to CoherentPDF WASM source + * + * Deploy: cd cloudflare && npx wrangler deploy -c wasm-wrangler.toml + * + * Required Environment Variables (set in Cloudflare dashboard): + * - PYMUPDF_SOURCE: Base URL for PyMuPDF WASM files (e.g., https://cdn.example.com/pymupdf) + * - GS_SOURCE: Base URL for Ghostscript WASM files (e.g., https://cdn.example.com/gs) + * - CPDF_SOURCE: Base URL for CoherentPDF files (e.g., https://cdn.example.com/cpdf) + */ + +const ALLOWED_ORIGINS = ['https://www.bentopdf.com', 'https://bentopdf.com']; + +const MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024; + +const RATE_LIMIT_MAX_REQUESTS = 100; +const RATE_LIMIT_WINDOW_MS = 60 * 1000; + +const CACHE_TTL_SECONDS = 604800; + +const ALLOWED_EXTENSIONS = [ + '.js', + '.mjs', + '.wasm', + '.data', + '.py', + '.so', + '.zip', + '.json', + '.mem', + '.asm.js', + '.worker.js', + '.html', +]; + +function isAllowedOrigin(origin) { + if (!origin) return true; // Allow no-origin requests (e.g., direct browser navigation) + return ALLOWED_ORIGINS.some((allowed) => + origin.startsWith(allowed.replace(/\/$/, '')) + ); +} + +function isAllowedFile(pathname) { + const ext = pathname.substring(pathname.lastIndexOf('.')).toLowerCase(); + if (ALLOWED_EXTENSIONS.includes(ext)) return true; + + if (!pathname.includes('.') || pathname.endsWith('/')) return true; + + return false; +} + +function corsHeaders(origin) { + return { + 'Access-Control-Allow-Origin': origin || '*', + 'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Range, Cache-Control', + 'Access-Control-Expose-Headers': + 'Content-Length, Content-Range, Content-Type', + 'Access-Control-Max-Age': '86400', + }; +} + +function handleOptions(request) { + const origin = request.headers.get('Origin'); + return new Response(null, { + status: 204, + headers: corsHeaders(origin), + }); +} + +function getContentType(pathname) { + const ext = pathname.substring(pathname.lastIndexOf('.')).toLowerCase(); + const contentTypes = { + '.js': 'application/javascript', + '.mjs': 'application/javascript', + '.wasm': 'application/wasm', + '.json': 'application/json', + '.data': 'application/octet-stream', + '.py': 'text/x-python', + '.so': 'application/octet-stream', + '.zip': 'application/zip', + '.mem': 'application/octet-stream', + '.html': 'text/html', + }; + return contentTypes[ext] || 'application/octet-stream'; +} + +async function proxyRequest(request, env, sourceBaseUrl, subpath, origin) { + if (!sourceBaseUrl) { + return new Response( + JSON.stringify({ + error: 'Source not configured', + message: 'This WASM module source URL has not been configured.', + }), + { + status: 503, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } + + const normalizedBase = sourceBaseUrl.endsWith('/') + ? sourceBaseUrl.slice(0, -1) + : sourceBaseUrl; + const normalizedPath = subpath.startsWith('/') ? subpath : `/${subpath}`; + const targetUrl = `${normalizedBase}${normalizedPath}`; + + if (!isAllowedFile(normalizedPath)) { + return new Response( + JSON.stringify({ + error: 'Forbidden file type', + message: 'Only WASM-related file types are allowed.', + }), + { + status: 403, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } + + try { + const cacheKey = new Request(targetUrl, request); + const cache = caches.default; + let response = await cache.match(cacheKey); + + if (!response) { + response = await fetch(targetUrl, { + headers: { + 'User-Agent': 'BentoPDF-WASM-Proxy/1.0', + Accept: '*/*', + }, + }); + + if (!response.ok) { + return new Response( + JSON.stringify({ + error: 'Failed to fetch resource', + status: response.status, + statusText: response.statusText, + targetUrl: targetUrl, + }), + { + status: response.status, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } + + const contentLength = parseInt( + response.headers.get('Content-Length') || '0', + 10 + ); + if (contentLength > MAX_FILE_SIZE_BYTES) { + return new Response( + JSON.stringify({ + error: 'File too large', + message: `File exceeds maximum size of ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB`, + }), + { + status: 413, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } + + response = new Response(response.body, response); + response.headers.set( + 'Cache-Control', + `public, max-age=${CACHE_TTL_SECONDS}` + ); + + if (response.status === 200) { + await cache.put(cacheKey, response.clone()); + } + } + + const bodyData = await response.arrayBuffer(); + + return new Response(bodyData, { + status: 200, + headers: { + ...corsHeaders(origin), + 'Content-Type': getContentType(normalizedPath), + 'Content-Length': bodyData.byteLength.toString(), + 'Cache-Control': `public, max-age=${CACHE_TTL_SECONDS}`, + 'X-Proxied-From': new URL(targetUrl).hostname, + }, + }); + } catch (error) { + return new Response( + JSON.stringify({ + error: 'Proxy error', + message: error.message, + }), + { + status: 500, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } +} + +export default { + async fetch(request, env, ctx) { + const url = new URL(request.url); + const pathname = url.pathname; + const origin = request.headers.get('Origin'); + + if (request.method === 'OPTIONS') { + return handleOptions(request); + } + + if (!isAllowedOrigin(origin)) { + return new Response( + JSON.stringify({ + error: 'Forbidden', + message: + 'Origin not allowed. Add your domain to ALLOWED_ORIGINS if self-hosting.', + }), + { + status: 403, + headers: { + 'Content-Type': 'application/json', + ...corsHeaders(origin), + }, + } + ); + } + + if (request.method !== 'GET' && request.method !== 'HEAD') { + return new Response('Method not allowed', { + status: 405, + headers: corsHeaders(origin), + }); + } + + if (env.RATE_LIMIT_KV) { + const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown'; + const rateLimitKey = `wasm-ratelimit:${clientIP}`; + const now = Date.now(); + + const rateLimitData = await env.RATE_LIMIT_KV.get(rateLimitKey, { + type: 'json', + }); + const requests = rateLimitData?.requests || []; + const recentRequests = requests.filter( + (t) => now - t < RATE_LIMIT_WINDOW_MS + ); + + if (recentRequests.length >= RATE_LIMIT_MAX_REQUESTS) { + return new Response( + JSON.stringify({ + error: 'Rate limit exceeded', + message: `Maximum ${RATE_LIMIT_MAX_REQUESTS} requests per minute.`, + }), + { + status: 429, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + 'Retry-After': '60', + }, + } + ); + } + + recentRequests.push(now); + await env.RATE_LIMIT_KV.put( + rateLimitKey, + JSON.stringify({ requests: recentRequests }), + { + expirationTtl: 120, + } + ); + } + + if (pathname.startsWith('/pymupdf/')) { + const subpath = pathname.replace('/pymupdf', ''); + return proxyRequest(request, env, env.PYMUPDF_SOURCE, subpath, origin); + } + + if (pathname.startsWith('/gs/')) { + const subpath = pathname.replace('/gs', ''); + return proxyRequest(request, env, env.GS_SOURCE, subpath, origin); + } + + if (pathname.startsWith('/cpdf/')) { + const subpath = pathname.replace('/cpdf', ''); + return proxyRequest(request, env, env.CPDF_SOURCE, subpath, origin); + } + + if (pathname === '/' || pathname === '/health') { + return new Response( + JSON.stringify({ + service: 'BentoPDF WASM Proxy', + version: '1.0.0', + endpoints: { + pymupdf: '/pymupdf/*', + gs: '/gs/*', + cpdf: '/cpdf/*', + }, + configured: { + pymupdf: !!env.PYMUPDF_SOURCE, + gs: !!env.GS_SOURCE, + cpdf: !!env.CPDF_SOURCE, + }, + }), + { + status: 200, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + } + + return new Response( + JSON.stringify({ + error: 'Not Found', + message: 'Use /pymupdf/*, /gs/*, or /cpdf/* endpoints', + }), + { + status: 404, + headers: { + ...corsHeaders(origin), + 'Content-Type': 'application/json', + }, + } + ); + }, +}; diff --git a/cloudflare/wasm-wrangler.toml b/cloudflare/wasm-wrangler.toml new file mode 100644 index 0000000..c994f32 --- /dev/null +++ b/cloudflare/wasm-wrangler.toml @@ -0,0 +1,69 @@ +name = "bentopdf-wasm-proxy" +main = "wasm-proxy-worker.js" +compatibility_date = "2024-01-01" + +# ============================================================================= +# DEPLOYMENT +# ============================================================================= +# Deploy this worker: +# cd cloudflare +# npx wrangler deploy -c wasm-wrangler.toml +# +# Set environment secrets (one of the following methods): +# Option A: Cloudflare Dashboard +# Go to Workers & Pages > bentopdf-wasm-proxy > Settings > Variables +# Add: PYMUPDF_SOURCE, GS_SOURCE, CPDF_SOURCE +# +# Option B: Wrangler CLI +# npx wrangler secret put PYMUPDF_SOURCE -c wasm-wrangler.toml +# npx wrangler secret put GS_SOURCE -c wasm-wrangler.toml +# npx wrangler secret put CPDF_SOURCE -c wasm-wrangler.toml + +# ============================================================================= +# WASM SOURCE URLS +# ============================================================================= +# Set these as secrets in the Cloudflare dashboard or via wrangler: +# +# PYMUPDF_SOURCE: Base URL to PyMuPDF WASM files +# Example: https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm/assets +# https://your-bucket.r2.cloudflarestorage.com/pymupdf +# +# GS_SOURCE: Base URL to Ghostscript WASM files +# Example: https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm/assets +# https://your-bucket.r2.cloudflarestorage.com/gs +# +# CPDF_SOURCE: Base URL to CoherentPDF files +# Example: https://cdn.jsdelivr.net/npm/coherentpdf/cpdf +# https://your-bucket.r2.cloudflarestorage.com/cpdf + +# ============================================================================= +# USAGE FROM BENTOPDF +# ============================================================================= +# In BentoPDF's WASM Settings page, configure URLs like: +# PyMuPDF: https://wasm.bentopdf.com/pymupdf/ +# Ghostscript: https://wasm.bentopdf.com/gs/ +# CoherentPDF: https://wasm.bentopdf.com/cpdf/ + +# ============================================================================= +# RATE LIMITING (Optional but recommended) +# ============================================================================= +# Create KV namespace: +# npx wrangler kv namespace create "RATE_LIMIT_KV" +# +# Then uncomment and update the ID below: +# [[kv_namespaces]] +# binding = "RATE_LIMIT_KV" +# id = "" + +# Use the same KV namespace as the CORS proxy if you want shared rate limiting +[[kv_namespaces]] +binding = "RATE_LIMIT_KV" +id = "b88e030b308941118cd484e3fcb3ae49" + +# ============================================================================= +# CUSTOM DOMAIN (Optional) +# ============================================================================= +# If you want a custom domain like wasm.bentopdf.com: +# routes = [ +# { pattern = "wasm.bentopdf.com/*", zone_name = "bentopdf.com" } +# ] diff --git a/contact.html b/contact.html index 6de7636..1e9c012 100644 --- a/contact.html +++ b/contact.html @@ -78,125 +78,7 @@ - + {{> navbar }}
@@ -229,171 +111,7 @@
- + {{> footer }} diff --git a/docker-compose.yml b/docker-compose.yml index 4999418..95dbe02 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,12 @@ services: bentopdf: - # simple mode - bentopdf/bentopdf-simple:latest - # default mode - bentopdf/bentopdf:latest - image: bentopdf/bentopdf-simple:latest + # GitHub Container Registry (Recommended) + # simple mode - ghcr.io/alam00000/bentopdf-simple:latest + # default mode - ghcr.io/alam00000/bentopdf:latest + # Docker Hub (Alternative) + # simple mode - bentopdfteam/bentopdf-simple:latest + # default mode - bentopdfteam/bentopdf:latest + image: ghcr.io/alam00000/bentopdf-simple:latest container_name: bentopdf restart: unless-stopped ports: diff --git a/docs/licensing.md b/docs/licensing.md index 7bdde64..b972035 100644 --- a/docs/licensing.md +++ b/docs/licensing.md @@ -12,13 +12,13 @@ For complete licensing information, delivery details, AGPL component notices, an ## When Do You Need a Commercial License? -| Use Case | License Required | -|----------|------------------| -| Open-source project with public source code | AGPL-3.0 (Free) | -| Internal company tool (not distributed) | AGPL-3.0 (Free) | -| Proprietary/closed-source application | **Commercial License** | +| Use Case | License Required | +| ------------------------------------------- | ---------------------- | +| Open-source project with public source code | AGPL-3.0 (Free) | +| Internal company tool (not distributed) | AGPL-3.0 (Free) | +| Proprietary/closed-source application | **Commercial License** | | SaaS product without source code disclosure | **Commercial License** | -| Redistributing without AGPL compliance | **Commercial License** | +| Redistributing without AGPL compliance | **Commercial License** | ## Delivery & Licensing Model @@ -30,12 +30,32 @@ For complete licensing information, delivery details, AGPL component notices, an ## Important Notice on Third-Party Components -::: warning AGPL Components -This software includes components licensed under the **GNU AGPL v3**, such as CPDF. +::: warning AGPL Components - Not Bundled +BentoPDF **does not bundle** AGPL-licensed processing libraries. The following components are loaded separately by users who configure them via **Advanced Settings**: -- This commercial license **does not** grant rights to use AGPL components in a closed-source manner. -- Users must comply with the AGPL v3 terms for these components. -- Source code for all AGPL components is included in the distribution. +| Component | License | Status | +| --------------- | -------- | ----------------------------- | +| **PyMuPDF** | AGPL-3.0 | Not bundled - user configured | +| **Ghostscript** | AGPL-3.0 | Not bundled - user configured | +| **CoherentPDF** | AGPL-3.0 | Not bundled - user configured | + +**Why are AGPL binaries not included?** + +To maintain clear legal separation, BentoPDF does not distribute AGPL-licensed binaries. Users who need features powered by these libraries can: + +1. Configure their own WASM sources in Advanced Settings +2. Host their own WASM proxy to serve these files +3. Use any compatible CDN that hosts these packages + +This approach ensures: + +- BentoPDF's core code remains under its dual-license (AGPL-3.0 / Commercial) +- Users make an informed choice when enabling AGPL features +- Clear compliance boundaries for commercial users + ::: + +::: tip Commercial License & AGPL Features +The commercial license covers BentoPDF's own code. If you configure and use AGPL components (PyMuPDF, Ghostscript, CoherentPDF), you must still comply with their respective AGPL-3.0 license terms, which may require source code disclosure if you distribute modified versions. ::: ## Invoicing @@ -47,15 +67,15 @@ This software includes components licensed under the **GNU AGPL v3**, such as CP ## What's Included -| Feature | Included | -|---------|----------| -| Full source code | โœ… | -| All 50+ PDF tools | โœ… | -| Self-hosting rights | โœ… | -| Lifetime updates | โœ… | -| Remove branding (Simple Mode) | โœ… | -| Commercial support | โœ… (via email) | -| Priority feature requests | โœ… | +| Feature | Included | +| ----------------------------- | -------------- | +| Full source code | โœ… | +| All 50+ PDF tools | โœ… | +| Self-hosting rights | โœ… | +| Lifetime updates | โœ… | +| Remove branding (Simple Mode) | โœ… | +| Commercial support | โœ… (via email) | +| Priority feature requests | โœ… | ## FAQ @@ -69,7 +89,7 @@ Yes, with a commercial license. Without it, you must comply with AGPL-3.0, which ### What about the AGPL components? -Components like CPDF are licensed under AGPL v3 and remain under that license. The commercial license covers BentoPDF's own code but does not override third-party AGPL obligations. +Components like CoherentPDF are licensed under AGPL v3 and remain under that license. The commercial license covers BentoPDF's own code but does not override third-party AGPL obligations. ### How do I get an invoice? diff --git a/docs/self-hosting/apache.md b/docs/self-hosting/apache.md index 0264acf..4b80551 100644 --- a/docs/self-hosting/apache.md +++ b/docs/self-hosting/apache.md @@ -73,22 +73,46 @@ Create `/etc/apache2/sites-available/bentopdf.conf`: ``` -## Step 4: .htaccess for SPA Routing +## Step 4: .htaccess for Routing Create `/var/www/bentopdf/.htaccess`: ```apache - - RewriteEngine On - RewriteBase / - - # Don't rewrite files or directories - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - - # Rewrite everything else to index.html - RewriteRule ^ index.html [L] - +RewriteEngine On +RewriteBase / + +# Existing files/dirs - serve directly +RewriteCond %{REQUEST_FILENAME} -f [OR] +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^ - [L] + +# ============================================ +# LANGUAGE ROUTES +# ============================================ +# Supported languages: de, es, zh, zh-TW, vi, it, id, tr, fr, pt +# English has no prefix - served from root + +# English prefix redirects to root +RewriteRule ^en/?$ / [R=301,L] +RewriteRule ^en/(.+)$ /$1 [R=301,L] + +# Language prefix root (e.g., /de/ -> /de/index.html) +RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L] + +# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html) +RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L] + +# ============================================ +# ADD .HTML EXTENSION (ROOT LEVEL) +# ============================================ +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] + +ErrorDocument 404 /404.html ``` ## Step 5: Enable Required Modules @@ -122,14 +146,31 @@ BASE_URL=/pdf/ npm run build 2. Update `.htaccess`: ```apache - - RewriteEngine On - RewriteBase /pdf/ - - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^ index.html [L] - +RewriteEngine On +RewriteBase /pdf/ + +# Existing files/dirs - serve directly +RewriteCond %{REQUEST_FILENAME} -f [OR] +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^ - [L] + +# Language routes +RewriteRule ^en/?$ /pdf/ [R=301,L] +RewriteRule ^en/(.+)$ /pdf/$1 [R=301,L] + +RewriteCond %{DOCUMENT_ROOT}/pdf/$1/index.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /pdf/$1/index.html [L] + +RewriteCond %{DOCUMENT_ROOT}/pdf/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /pdf/$1/$2.html [L] + +# Root level .html extension +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] + +ErrorDocument 404 /pdf/404.html ``` ## Troubleshooting diff --git a/docs/self-hosting/docker.md b/docs/self-hosting/docker.md index 0130afd..8630da2 100644 --- a/docs/self-hosting/docker.md +++ b/docs/self-hosting/docker.md @@ -1,27 +1,38 @@ -# Deploy with Docker +# Deploy with Docker / Podman The easiest way to self-host BentoPDF in a production environment. > [!IMPORTANT] > **Required Headers for Office File Conversion** -> +> > LibreOffice-based tools (Word, Excel, PowerPoint conversion) require these HTTP headers for `SharedArrayBuffer` support: +> > - `Cross-Origin-Opener-Policy: same-origin` > - `Cross-Origin-Embedder-Policy: require-corp` -> -> The official Docker images include these headers. If using a reverse proxy (Traefik, Caddy, etc.), ensure these headers are preserved or added. +> +> The official container images include these headers. If using a reverse proxy (Traefik, Caddy, etc.), ensure these headers are preserved or added. + +> [!TIP] +> **Podman Users:** All `docker` commands work with Podman by replacing `docker` with `podman` and `docker-compose` with `podman-compose`. ## Quick Start ```bash +# Docker docker run -d \ --name bentopdf \ -p 3000:8080 \ --restart unless-stopped \ ghcr.io/alam00000/bentopdf:latest + +# Podman +podman run -d \ + --name bentopdf \ + -p 3000:8080 \ + ghcr.io/alam00000/bentopdf:latest ``` -## Docker Compose +## Docker Compose / Podman Compose Create `docker-compose.yml`: @@ -31,10 +42,10 @@ services: image: ghcr.io/alam00000/bentopdf:latest container_name: bentopdf ports: - - "3000:8080" + - '3000:8080' restart: unless-stopped healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080"] + test: ['CMD', 'curl', '-f', 'http://localhost:8080'] interval: 30s timeout: 10s retries: 3 @@ -43,7 +54,11 @@ services: Run: ```bash +# Docker Compose docker compose up -d + +# Podman Compose +podman-compose up -d ``` ## Build Your Own Image @@ -73,10 +88,10 @@ docker run -d -p 3000:8080 bentopdf:custom ## Environment Variables -| Variable | Description | Default | -|----------|-------------|---------| +| Variable | Description | Default | +| ------------- | ------------------------------- | ------- | | `SIMPLE_MODE` | Build without LibreOffice tools | `false` | -| `BASE_URL` | Deploy to subdirectory | `/` | +| `BASE_URL` | Deploy to subdirectory | `/` | Example: @@ -94,15 +109,15 @@ services: traefik: image: traefik:v2.10 command: - - "--providers.docker=true" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.letsencrypt.acme.email=you@example.com" - - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" + - '--providers.docker=true' + - '--entrypoints.web.address=:80' + - '--entrypoints.websecure.address=:443' + - '--certificatesresolvers.letsencrypt.acme.email=you@example.com' + - '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json' + - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web' ports: - - "80:80" - - "443:443" + - '80:80' + - '443:443' volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt @@ -110,15 +125,15 @@ services: bentopdf: image: ghcr.io/alam00000/bentopdf:latest labels: - - "traefik.enable=true" - - "traefik.http.routers.bentopdf.rule=Host(`pdf.example.com`)" - - "traefik.http.routers.bentopdf.entrypoints=websecure" - - "traefik.http.routers.bentopdf.tls.certresolver=letsencrypt" - - "traefik.http.services.bentopdf.loadbalancer.server.port=8080" + - 'traefik.enable=true' + - 'traefik.http.routers.bentopdf.rule=Host(`pdf.example.com`)' + - 'traefik.http.routers.bentopdf.entrypoints=websecure' + - 'traefik.http.routers.bentopdf.tls.certresolver=letsencrypt' + - 'traefik.http.services.bentopdf.loadbalancer.server.port=8080' # Required headers for SharedArrayBuffer (LibreOffice WASM) - - "traefik.http.routers.bentopdf.middlewares=bentopdf-headers" - - "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin" - - "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp" + - 'traefik.http.routers.bentopdf.middlewares=bentopdf-headers' + - 'traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin' + - 'traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp' restart: unless-stopped ``` @@ -129,12 +144,12 @@ services: caddy: image: caddy:2 ports: - - "80:80" - - "443:443" + - '80:80' + - '443:443' volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - + bentopdf: image: ghcr.io/alam00000/bentopdf:latest restart: unless-stopped @@ -169,6 +184,141 @@ services: memory: 128M ``` +## Podman Quadlet (Systemd Integration) + +[Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) allows you to run Podman containers as systemd services. This is ideal for production deployments on Linux systems. + +### Basic Quadlet Setup + +Create a container unit file at `~/.config/containers/systemd/bentopdf.container` (user) or `/etc/containers/systemd/bentopdf.container` (system): + +```ini +[Unit] +Description=BentoPDF - Privacy-first PDF toolkit +After=network-online.target +Wants=network-online.target + +[Container] +Image=ghcr.io/alam00000/bentopdf:latest +ContainerName=bentopdf +PublishPort=3000:8080 +AutoUpdate=registry + +[Service] +Restart=always +TimeoutStartSec=300 + +[Install] +WantedBy=default.target +``` + +### Enable and Start + +```bash +# Reload systemd to detect new unit +systemctl --user daemon-reload + +# Start the service +systemctl --user start bentopdf + +# Enable on boot +systemctl --user enable bentopdf + +# Check status +systemctl --user status bentopdf + +# View logs +journalctl --user -u bentopdf -f +``` + +> [!TIP] +> For system-wide deployment, use `systemctl` without `--user` flag and place the file in `/etc/containers/systemd/`. + +### Simple Mode Quadlet + +For Simple Mode deployment, create `bentopdf-simple.container`: + +```ini +[Unit] +Description=BentoPDF Simple Mode - Clean PDF toolkit +After=network-online.target +Wants=network-online.target + +[Container] +Image=ghcr.io/alam00000/bentopdf-simple:latest +ContainerName=bentopdf-simple +PublishPort=3000:8080 +AutoUpdate=registry + +[Service] +Restart=always +TimeoutStartSec=300 + +[Install] +WantedBy=default.target +``` + +### Quadlet with Health Check + +```ini +[Unit] +Description=BentoPDF with health monitoring +After=network-online.target +Wants=network-online.target + +[Container] +Image=ghcr.io/alam00000/bentopdf:latest +ContainerName=bentopdf +PublishPort=3000:8080 +AutoUpdate=registry +HealthCmd=curl -f http://localhost:8080 || exit 1 +HealthInterval=30s +HealthTimeout=10s +HealthRetries=3 + +[Service] +Restart=always +TimeoutStartSec=300 + +[Install] +WantedBy=default.target +``` + +### Auto-Update with Quadlet + +Podman can automatically update containers when new images are available: + +```bash +# Enable auto-update timer +systemctl --user enable --now podman-auto-update.timer + +# Check for updates manually +podman auto-update + +# Dry run (check without updating) +podman auto-update --dry-run +``` + +### Quadlet Network Configuration + +For custom network configuration, create a network file `bentopdf.network`: + +```ini +[Network] +Subnet=10.89.0.0/24 +Gateway=10.89.0.1 +``` + +Then reference it in your container file: + +```ini +[Container] +Image=ghcr.io/alam00000/bentopdf:latest +ContainerName=bentopdf +PublishPort=3000:8080 +Network=bentopdf.network +``` + ## Updating ```bash diff --git a/docs/self-hosting/hostinger.md b/docs/self-hosting/hostinger.md index 8deaf68..ae0ca99 100644 --- a/docs/self-hosting/hostinger.md +++ b/docs/self-hosting/hostinger.md @@ -141,7 +141,7 @@ AddType image/webp .webp # ============================================ # 5. REDIRECTS & ROUTING # ============================================ -# Canonical WWW +# Canonical WWW (update domain as needed) RewriteCond %{HTTP_HOST} ^bentopdf\.com [NC] RewriteRule ^(.*)$ https://www.bentopdf.com/$1 [L,R=301] @@ -149,19 +149,34 @@ RewriteRule ^(.*)$ https://www.bentopdf.com/$1 [L,R=301] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] -# Remove trailing slash +# Remove trailing slash (except for language root directories) RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_URI} !^/(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/$ RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [R=301,L] -# Existing files/dirs +# Existing files/dirs - serve directly RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] -# Language routes -RewriteRule ^(en|de|zh|vi|it|id)/(.*)$ /$2 [L] -RewriteRule ^(en|de|zh|vi|it|id)/?$ / [L] +# ============================================ +# 5.1. LANGUAGE ROUTES +# ============================================ +# Supported languages: de, es, zh, zh-TW, vi, it, id, tr, fr, pt +# English has no prefix - served from root + +# English prefix redirects to root (for SEO consistency) +RewriteRule ^en/?$ / [R=301,L] +RewriteRule ^en/(.+)$ /$1 [R=301,L] + +# Language prefix root (e.g., /de/ -> /de/index.html) +RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L] + +# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html) +RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L] # ============================================ # 5.5. DOCS ROUTING (VitePress) @@ -172,15 +187,17 @@ RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html [L] # ============================================ -# 6. SPA FALLBACK +# 6. ADD .HTML EXTENSION IF FILE EXISTS (ROOT LEVEL ONLY) # ============================================ -# SPA Fallback (exclude /docs) -RewriteCond %{REQUEST_URI} !^/docs RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^ /index.html [L] +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] -ErrorDocument 404 /index.html +# ============================================ +# 7. ERROR PAGES +# ============================================ +ErrorDocument 404 /404.html ``` ## Subdirectory .htaccess Example @@ -190,12 +207,23 @@ For `yourdomain.com/pdf-tools/`, update these lines: ```apache RewriteBase /pdf-tools/ -# ... (same content) ... +# ... (same content as above, but update paths) ... -# SPA Fallback - update path -RewriteRule ^ /pdf-tools/index.html [L] +# Language prefix root +RewriteCond %{DOCUMENT_ROOT}/pdf-tools/$1/index.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /pdf-tools/$1/index.html [L] -ErrorDocument 404 /pdf-tools/index.html +# Language prefix with path +RewriteCond %{DOCUMENT_ROOT}/pdf-tools/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /pdf-tools/$1/$2.html [L] + +# Root level .html extension +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] + +ErrorDocument 404 /pdf-tools/404.html ``` ## Troubleshooting @@ -221,12 +249,16 @@ If headers aren't being applied, contact Hostinger support to enable `mod_header ### 404 Errors on Page Refresh -Make sure the SPA fallback rule is at the end of your `.htaccess`: +Make sure the `.html` extension rule and language routes are correctly configured. BentoPDF uses static HTML files, not SPA routing: ```apache -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^ /index.html [L] +# Language routes serve actual files from language directories +RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f +RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L] + +# Root level pages +RewriteCond %{REQUEST_FILENAME}.html -f +RewriteRule ^([^/]+)$ $1.html [L] ``` ### File Upload Limits diff --git a/docs/self-hosting/index.md b/docs/self-hosting/index.md index a492ec2..10dedf4 100644 --- a/docs/self-hosting/index.md +++ b/docs/self-hosting/index.md @@ -2,15 +2,19 @@ BentoPDF can be self-hosted on your own infrastructure. This guide covers various deployment options. -## Quick Start with Docker +## Quick Start with Docker / Podman The fastest way to self-host BentoPDF: ```bash +# Docker docker run -d -p 3000:8080 ghcr.io/alam00000/bentopdf:latest + +# Podman +podman run -d -p 3000:8080 ghcr.io/alam00000/bentopdf:latest ``` -Or with Docker Compose: +Or with Docker Compose / Podman Compose: ```yaml # docker-compose.yml @@ -18,14 +22,43 @@ services: bentopdf: image: ghcr.io/alam00000/bentopdf:latest ports: - - "3000:8080" + - '3000:8080' restart: unless-stopped ``` ```bash +# Docker Compose docker compose up -d + +# Podman Compose +podman-compose up -d ``` +## Podman Quadlet (Linux Systemd) + +Run BentoPDF as a systemd service. Create `~/.config/containers/systemd/bentopdf.container`: + +```ini +[Container] +Image=ghcr.io/alam00000/bentopdf:latest +ContainerName=bentopdf +PublishPort=3000:8080 +AutoUpdate=registry + +[Service] +Restart=always + +[Install] +WantedBy=default.target +``` + +```bash +systemctl --user daemon-reload +systemctl --user enable --now bentopdf +``` + +See [Docker deployment guide](/self-hosting/docker) for full Quadlet documentation. + ## Building from Source ```bash @@ -45,6 +78,7 @@ npm run build Simple Mode is designed for internal organizational use where you want to hide all branding and marketing content, showing only the essential PDF tools. **What Simple Mode hides:** + - Navigation bar - Hero section with marketing content - Features, FAQ, testimonials sections @@ -56,7 +90,7 @@ Simple Mode is designed for internal organizational use where you want to hide a SIMPLE_MODE=true npm run build # Or use the pre-built Docker image -docker run -p 3000:8080 bentopdf/bentopdf-simple:latest +docker run -p 3000:8080 bentopdfteam/bentopdf-simple:latest ``` See [SIMPLE_MODE.md](https://github.com/alam00000/bentopdf/blob/main/SIMPLE_MODE.md) for full details. @@ -81,15 +115,52 @@ Choose your platform: - [Nginx](/self-hosting/nginx) - [Apache](/self-hosting/apache) - [Docker](/self-hosting/docker) +- [Kubernetes](/self-hosting/kubernetes) - [CORS Proxy](/self-hosting/cors-proxy) - Required for digital signatures +## Configuring AGPL WASM Components + +BentoPDF **does not bundle** AGPL-licensed processing libraries. Some advanced features require you to configure WASM modules separately. + +::: warning AGPL Components Not Included +The following WASM modules are **not bundled** with BentoPDF and must be configured by users who want to use features powered by these libraries: + +| Component | License | Features | +| --------------- | -------- | ---------------------------------------------------------------- | +| **PyMuPDF** | AGPL-3.0 | EPUB/MOBI/FB2/XPS conversion, image extraction, table extraction | +| **Ghostscript** | AGPL-3.0 | PDF/A conversion, compression, deskewing, rasterization | +| **CoherentPDF** | AGPL-3.0 | Table of contents, attachments, PDF merge with bookmarks | + +::: + +### How to Configure WASM Sources + +1. Navigate to **Advanced Settings** in the BentoPDF interface +2. Enter the URLs for the WASM modules you want to use +3. You can use: + - Your own hosted WASM files + - A [WASM proxy](/self-hosting/cors-proxy) you deploy (handles CORS) + - Any compatible CDN hosting these packages + +### Hosting Your Own WASM Proxy + +If you need to serve AGPL WASM files with proper CORS headers, you can deploy a simple proxy. See the [Cloudflare WASM Proxy guide](https://github.com/alam00000/bentopdf/blob/main/cloudflare/WASM-PROXY.md) for an example implementation. + +::: tip Why Separate? +This separation ensures: + +- Clear legal compliance for commercial users +- Users make informed choices when enabling AGPL features +- BentoPDF's core remains under its dual-license (AGPL-3.0 / Commercial) + ::: + ## System Requirements -| Requirement | Minimum | -|-------------|---------| -| Storage | ~500 MB (with all WASM modules) | -| RAM | 512 MB | -| CPU | Any modern processor | +| Requirement | Minimum | +| ----------- | ----------------------------------- | +| Storage | ~100 MB (core without AGPL modules) | +| RAM | 512 MB | +| CPU | Any modern processor | ::: tip BentoPDF is a static siteโ€”there's no database or backend server required! diff --git a/docs/self-hosting/kubernetes.md b/docs/self-hosting/kubernetes.md new file mode 100644 index 0000000..183ad9e --- /dev/null +++ b/docs/self-hosting/kubernetes.md @@ -0,0 +1,157 @@ +# Deploy with Kubernetes + +Kubernetes may be overkill for a static site, but it can be a great fit if you already standardize on Helm + GitOps. + +> [!IMPORTANT] +> **Required Headers for Office File Conversion** +> +> LibreOffice-based tools (Word, Excel, PowerPoint conversion) require these HTTP headers for `SharedArrayBuffer` support: +> - `Cross-Origin-Opener-Policy: same-origin` +> - `Cross-Origin-Embedder-Policy: require-corp` +> +> The official BentoPDF nginx images include these headers. In Kubernetes, **Ingress/Gateway controllers are also reverse proxies**, so ensure these headers are preserved (or add them at the edge). + +## Prereqs + +- Kubernetes cluster +- Helm v3 +- A BentoPDF nginx image (e.g. `ghcr.io/alam00000/bentopdf:`) that serves on **port 8080** + +## Deploy with Helm + +### Install from this repo (local chart) + +```bash +kubectl create namespace bentopdf + +helm upgrade --install bentopdf /path/to/bentopdf/chart \ + --namespace bentopdf \ + --set image.repository=ghcr.io/alam00000/bentopdf \ + --set image.tag=latest +``` + +### Install from GHCR (OCI chart) + +If the chart is published to GHCR as an OCI artifact: + +```bash +export GHCR_USERNAME="" + +helm upgrade --install bentopdf oci://ghcr.io/$GHCR_USERNAME/charts/bentopdf \ + --namespace bentopdf \ + --create-namespace \ + --version 0.1.0 \ + --set image.repository=ghcr.io/alam00000/bentopdf \ + --set image.tag=latest +``` + +## Expose it + +### Port-forward (quick test) + +```bash +kubectl -n bentopdf port-forward deploy/bentopdf 8080:8080 +``` + +### Ingress (optional) + +Enable Ingress (example for nginx-ingress): + +```yaml +ingress: + enabled: true + className: nginx + hosts: + - host: pdf.example.com + paths: + - path: / + pathType: Prefix +``` + +### Gateway API (optional) + +This chart supports Gateway API `Gateway` + `HTTPRoute`. + +Example (Cloudflare Gateway API operator): + +```yaml +gateway: + enabled: true + name: bento-tunnel + namespace: bentopdf + gatewayClassName: cloudflare + +httpRoute: + enabled: true + parentRefs: + - name: bento-tunnel + namespace: bentopdf + sectionName: http + hostnames: + - pdfs.example.com +``` + +## Ensuring the SharedArrayBuffer headers still work (Ingress/Gateway) + +### What "should" happen + +BentoPDFโ€™s nginx config sets the required response headers. Most Ingress/Gateway controllers **pass upstream response headers through unchanged**. + +### What can break it + +- A controller/edge policy that **overrides** or **strips** response headers +- A "security headers" middleware that sets different COOP/COEP values + +### How to verify + +Run this against your public endpoint: + +```bash +curl -I https://pdf.example.com/ | egrep -i 'cross-origin-opener-policy|cross-origin-embedder-policy' +``` + +You should see: + +- `Cross-Origin-Opener-Policy: same-origin` +- `Cross-Origin-Embedder-Policy: require-corp` + +### If your Ingress controller does not preserve them + +Add the headers at the edge (controller-specific). Example for **nginx-ingress**: + +```yaml +ingress: + enabled: true + className: nginx + annotations: + nginx.ingress.kubernetes.io/configuration-snippet: | + add_header Cross-Origin-Opener-Policy "same-origin" always; + add_header Cross-Origin-Embedder-Policy "require-corp" always; +``` + +### If youโ€™re using Gateway API and want to force-add headers + +Gateway API supports a `ResponseHeaderModifier` filter. You can attach it in `httpRoute.rules[*].filters`: + +```yaml +httpRoute: + enabled: true + hostnames: [pdf.example.com] + parentRefs: + - name: bento-tunnel + namespace: misc + sectionName: http + rules: + - matches: + - path: { type: PathPrefix, value: / } + filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + set: + - name: Cross-Origin-Opener-Policy + value: same-origin + - name: Cross-Origin-Embedder-Policy + value: require-corp +``` + +Support for specific filters depends on your Gateway controller; if a filter is ignored, add headers at the edge/controller layer instead. diff --git a/faq.html b/faq.html index 34190bd..770521a 100644 --- a/faq.html +++ b/faq.html @@ -77,97 +77,7 @@ - + {{> navbar }}
@@ -378,142 +288,7 @@
- + {{> footer }} diff --git a/index.html b/index.html index 4e6a244..9da3b4f 100644 --- a/index.html +++ b/index.html @@ -99,167 +99,7 @@ - + {{> navbar }}
+ + + DigitalOcean Referral Badge +
@@ -861,6 +716,28 @@ > + + + +
+ + Advanced Settings + +

+ Configure external processing modules (PyMuPDF, Ghostscript, + CoherentPDF) +

+
+ +
@@ -1434,171 +1311,7 @@ - + {{> footer }} diff --git a/licensing.html b/licensing.html index 5ac6d62..3654199 100644 --- a/licensing.html +++ b/licensing.html @@ -78,125 +78,7 @@ - + {{> navbar }}
@@ -212,6 +94,131 @@

+ +
+
+ + + LIFETIME LICENSE + + + +

+ Commercial License +

+ + +
+ + +
+
+
+ +
+ Proprietary Use +
+
+
+ +
+ Unlimited Devices +
+
+
+ +
+ Enterprise Support +
+
+
+ +
+ Unlimited Users +
+
+
+ +
+ Early Access Features +
+
+
+ +
+ Lifetime Updates +
+
+
+ +
+ No AGPL Obligations +
+
+
+ +
+ Flexible Terms +
+
+ + +
+ + +
+
+ $99 + $49 + one-time +
+ + Get License Now + + + + + +
+
+
+
@@ -360,75 +367,34 @@
- - -

+ Get Commercial License + + + + + +

๐Ÿ’ก Custom requests and development are available for separate charges. - Contact us for details. @@ -586,10 +552,33 @@

+ + Get Commercial License - $49 + + + + +

Still not sure? Contact us @@ -909,13 +898,15 @@ BentoPDF is available under a lifetime, one-time purchase commercial license. You can purchase it directly here: Buy Commercial License.

If you have specific requirements or want a custom licensing arrangement, feel free to - contact us with details about your use case, company size, and deployment @@ -1002,53 +993,22 @@

- - Important Notice on Third-Party Components + + Invoicing

-

- This software includes components licensed under the - GNU AGPL v3, including: -

-
    -
  • - CPDF -
  • -
  • - PyMuPDF -
  • -
  • - Ghostscript -
  • -
  • This commercial license - does not grant rights to - use AGPL components in a closed-source manner. -
  • -
  • - - Users must comply with the AGPL v3 terms for these - components.We use Polar for + payments, which + automatically sends invoices + via email after purchase.
  • @@ -1057,8 +1017,23 @@ class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5" > Source code for all AGPL components is included in the - distribution.Polar handles + VAT invoices for + businesses in applicable regions. +
  • +
  • + + For VAT invoices, select + "I'm purchasing as a business" + during checkout and enter your billing address and Tax/VAT + number.
@@ -1068,36 +1043,76 @@

- - Invoicing + + AGPL Components - Not Bundled

-
    +

    + BentoPDF + does not bundle AGPL-licensed + processing libraries. The following components must be configured + separately via + Advanced Settings if you wish + to use their features: +

    +
      +
    • + PyMuPDF (AGPL-3.0) +
    • +
    • + Ghostscript (AGPL-3.0) +
    • +
    • + CoherentPDF / CPDF (AGPL-3.0) +
    • +
    +

    + To enable features powered by these libraries: +

    +
    • - - Ko-fi does not automatically issue invoices. + 1. + Navigate to + Advanced Settings in + BentoPDF
    • - + 2. + Configure the URL for each WASM module you need +
    • +
    • + 3. An official invoice will be provided immediately upon - request.You can host your own files, use a + WASM proxy, or use any compatible CDN
    -

    - Contact us: - contact@bentopdf.com - with your purchase details. +

    + + The commercial license covers + BentoPDF's own code only. It + does not bypass the AGPL licensing of these components. Users must + comply with the AGPL v3 terms for these components.

@@ -1113,7 +1128,7 @@ We're here to help. Reach out to discuss your licensing needs.

Contact Us @@ -1121,171 +1136,7 @@ - + {{> footer }} diff --git a/nginx.conf b/nginx.conf index a4904f5..ecf93a6 100644 --- a/nginx.conf +++ b/nginx.conf @@ -26,7 +26,6 @@ http { root /usr/share/nginx/html; index index.html; - rewrite ^/(en|de|zh|vi|it|tr|id)/(.*)$ /$2 last; location ~* \.html$ { expires 1h; @@ -84,6 +83,22 @@ http { add_header Cache-Control "public, immutable"; } + location ~ ^/(en|de|es|zh|zh-TW|vi|it|id|tr|fr|pt|be)(/.*)?$ { + try_files $uri $uri/ $uri.html /$1/index.html /index.html; + expires 5m; + add_header Cache-Control "public, must-revalidate"; + add_header Cross-Origin-Embedder-Policy "require-corp" always; + add_header Cross-Origin-Opener-Policy "same-origin" always; + } + + location ~ ^/(.+?)/(en|de|es|zh|zh-TW|vi|it|id|tr|fr|pt|be)(/.*)?$ { + try_files $uri $uri/ $uri.html /$1/$2/index.html /$1/index.html /index.html; + expires 5m; + add_header Cache-Control "public, must-revalidate"; + add_header Cross-Origin-Embedder-Policy "require-corp" always; + add_header Cross-Origin-Opener-Policy "same-origin" always; + } + location / { try_files $uri $uri/ $uri.html /index.html; expires 5m; diff --git a/package-lock.json b/package-lock.json index 276e066..39ca5a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,14 @@ { "name": "bento-pdf", - "version": "1.15.4", + "version": "1.16.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bento-pdf", - "version": "1.15.4", + "version": "1.16.1", "license": "AGPL-3.0-only", "dependencies": { - "@bentopdf/gs-wasm": "^0.1.0", - "@bentopdf/pymupdf-wasm": "^0.1.11", "@fontsource/cedarville-cursive": "^5.2.7", "@fontsource/dancing-script": "^5.2.8", "@fontsource/dm-sans": "^5.2.8", @@ -37,7 +35,7 @@ "i18next": "^25.7.2", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", - "jspdf": "^3.0.3", + "jspdf": "^4.0.0", "jspdf-autotable": "^5.0.2", "jszip": "^3.10.1", "lucide": "^0.546.0", @@ -78,6 +76,7 @@ "@types/pdfkit": "^0.17.3", "@types/sortablejs": "^1.15.8", "@types/utif": "^3.0.6", + "@vitejs/plugin-basic-ssl": "^2.1.4", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "eslint": "^9.39.2", @@ -91,6 +90,7 @@ "typescript-eslint": "^8.51.0", "vite": "^7.1.11", "vite-plugin-compression": "^0.5.1", + "vite-plugin-handlebars": "^2.0.0", "vite-plugin-node-polyfills": "^0.24.0", "vitepress": "^1.6.4", "vitest": "^3.2.4", @@ -504,24 +504,6 @@ "node": ">=18" } }, - "node_modules/@bentopdf/gs-wasm": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@bentopdf/gs-wasm/-/gs-wasm-0.1.0.tgz", - "integrity": "sha512-C71zxZW4R7Oa6fdya5leTh2VOZOxqH8IQlveh13OeuwZ2ulrovSi9629xTzAiIeeVKvDZma1Klxy4MuK65xe9w==", - "license": "AGPL-3.0", - "dependencies": { - "@types/emscripten": "^1.39.10" - } - }, - "node_modules/@bentopdf/pymupdf-wasm": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@bentopdf/pymupdf-wasm/-/pymupdf-wasm-0.1.11.tgz", - "integrity": "sha512-sbDFmvm2KzT3oCmqNqMx7w6TMsKpLXeooVK8EVRjyQIV4hU5Ioq0JxWMr8SX7MESu8Caz1feeELd6zt5K966SA==", - "license": "AGPL-3.0", - "peerDependencies": { - "@bentopdf/gs-wasm": "*" - } - }, "node_modules/@braintree/sanitize-url": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", @@ -3619,12 +3601,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/emscripten": { - "version": "1.41.5", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz", - "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==", - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -4048,6 +4024,19 @@ "dev": true, "license": "ISC" }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.4.tgz", + "integrity": "sha512-HXciTXN/sDBYWgeAD4V4s0DN0g72x5mlxQhHxtYu3Tt8BLa6MzcJZUyDVFCdtjNs3bfENVHVzOsmooTVuNgAAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" + } + }, "node_modules/@vitest/coverage-v8": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", @@ -7351,6 +7340,37 @@ "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", "license": "MIT" }, + "node_modules/hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -8184,9 +8204,9 @@ } }, "node_modules/jspdf": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-3.0.4.tgz", - "integrity": "sha512-dc6oQ8y37rRcHn316s4ngz/nOjayLF/FFxBF4V9zamQKRqXxyiH1zagkCdktdWhtoQId5K20xt1lB90XzkB+hQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-4.0.0.tgz", + "integrity": "sha512-w12U97Z6edKd2tXDn3LzTLg7C7QLJlx0BPfM3ecjK2BckUl9/81vZ+r5gK4/3KQdhAcEZhENUxRhtgYBj75MqQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.4", @@ -8790,9 +8810,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, "node_modules/lodash-es": { @@ -9327,6 +9347,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -9417,6 +9447,13 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -11830,6 +11867,20 @@ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", "license": "MIT" }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -12169,6 +12220,507 @@ "vite": ">=2.0.0" } }, + "node_modules/vite-plugin-handlebars": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vite-plugin-handlebars/-/vite-plugin-handlebars-2.0.0.tgz", + "integrity": "sha512-+J3It0nyhPzx4nT1I+fnWH+jShTEXzm6X0Tgsggdm9IYFD7/eJ6a3ROI13HTe0CVoyaxm/fPxH5HDAKyfz7T0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "handlebars": "^4.7.6", + "vite": "^5.0.0" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite-plugin-handlebars/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/vite-plugin-node-polyfills": { "version": "0.24.0", "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.24.0.tgz", @@ -13066,6 +13618,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", diff --git a/package.json b/package.json index 57a5829..afa3b27 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "bento-pdf", "private": true, - "version": "1.15.4", + "version": "1.16.1", "license": "AGPL-3.0-only", "type": "module", "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": "tsc && vite build && NODE_OPTIONS='--max-old-space-size=3072' node scripts/generate-i18n-pages.mjs && node scripts/generate-sitemap.mjs", "build:with-docs": "npm run build && npm run docs:build && node scripts/include-docs-in-dist.js", "build:gzip": "COMPRESSION_MODE=g npm run build", "build:brotli": "COMPRESSION_MODE=b npm run build", @@ -44,6 +44,7 @@ "@types/pdfkit": "^0.17.3", "@types/sortablejs": "^1.15.8", "@types/utif": "^3.0.6", + "@vitejs/plugin-basic-ssl": "^2.1.4", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "eslint": "^9.39.2", @@ -57,14 +58,13 @@ "typescript-eslint": "^8.51.0", "vite": "^7.1.11", "vite-plugin-compression": "^0.5.1", + "vite-plugin-handlebars": "^2.0.0", "vite-plugin-node-polyfills": "^0.24.0", "vitepress": "^1.6.4", "vitest": "^3.2.4", "vue": "^3.5.26" }, "dependencies": { - "@bentopdf/gs-wasm": "^0.1.0", - "@bentopdf/pymupdf-wasm": "^0.1.11", "@fontsource/cedarville-cursive": "^5.2.7", "@fontsource/dancing-script": "^5.2.8", "@fontsource/dm-sans": "^5.2.8", @@ -91,7 +91,7 @@ "i18next": "^25.7.2", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", - "jspdf": "^3.0.3", + "jspdf": "^4.0.0", "jspdf-autotable": "^5.0.2", "jszip": "^3.10.1", "lucide": "^0.546.0", diff --git a/pdf-converter.html b/pdf-converter.html index e09f671..eb02e3d 100644 --- a/pdf-converter.html +++ b/pdf-converter.html @@ -84,64 +84,7 @@ - + {{> navbar }}
@@ -539,116 +482,7 @@
- + {{> footer }} diff --git a/pdf-editor.html b/pdf-editor.html index 13a9f3c..0e1a0ad 100644 --- a/pdf-editor.html +++ b/pdf-editor.html @@ -84,64 +84,7 @@ - + {{> navbar }}
@@ -408,116 +351,7 @@
- + {{> footer }} diff --git a/pdf-merge-split.html b/pdf-merge-split.html index 6cbeef3..a250c11 100644 --- a/pdf-merge-split.html +++ b/pdf-merge-split.html @@ -95,64 +95,7 @@ - + {{> navbar }}
@@ -366,116 +309,7 @@
- + {{> footer }} diff --git a/pdf-security.html b/pdf-security.html index 6208ef0..58db29a 100644 --- a/pdf-security.html +++ b/pdf-security.html @@ -84,64 +84,7 @@ - + {{> navbar }}
@@ -343,116 +286,7 @@
- + {{> footer }} diff --git a/privacy.html b/privacy.html index 8d1dd2d..78de50c 100644 --- a/privacy.html +++ b/privacy.html @@ -77,97 +77,7 @@ - + {{> navbar }}
@@ -303,142 +213,7 @@
- + {{> footer }} diff --git a/public/ghostscript-wasm/gs.js b/public/ghostscript-wasm/gs.js deleted file mode 100644 index b2541ea..0000000 --- a/public/ghostscript-wasm/gs.js +++ /dev/null @@ -1,113 +0,0 @@ -async function Module(moduleArg={}){var moduleRtn;var f=moduleArg,aa="object"==typeof window,ba="undefined"!=typeof WorkerGlobalScope,k="object"==typeof process&&process.versions?.node&&"renderer"!=process.type,ca=!aa&&!k&&!ba;if(k){const {createRequire:a}=await import("module");var require=a(import.meta.url)}var da="./this.program",ea=(a,b)=>{throw b;},ia=import.meta.url,ja="",ka,la; -if(k){if("object"!=typeof process||!process.versions?.node||"renderer"==process.type)throw Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var ma=process.versions.node,na=ma.split(".").slice(0,3);na=1E4*na[0]+100*na[1]+1*na[2].split("-")[0];if(16E4>na)throw Error("This emscripten-generated code requires node v16.0.0 (detected v"+ma+")");var fs=require("fs"); -ia.startsWith("file:")&&(ja=require("path").dirname(require("url").fileURLToPath(ia))+"/");la=a=>{a=oa(a)?new URL(a):a;a=fs.readFileSync(a);m(Buffer.isBuffer(a));return a};ka=async a=>{a=oa(a)?new URL(a):a;a=fs.readFileSync(a,void 0);m(Buffer.isBuffer(a));return a};1{process.exitCode=a;throw b;}}else if(ca){if("object"==typeof process&&process.versions?.node&&"renderer"!=process.type||"object"==typeof window|| -"undefined"!=typeof WorkerGlobalScope)throw Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");}else if(aa||ba){try{ja=(new URL(".",ia)).href}catch{}if("object"!=typeof window&&"undefined"==typeof WorkerGlobalScope)throw Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)"); -ba&&(la=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)});ka=async a=>{if(oa(a))return new Promise((c,d)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d(e.status)};e.onerror=d;e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url);}}else throw Error("environment detection error"); -var p=console.log.bind(console),t=console.error.bind(console);m(!ca,"shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.");var pa;"object"!=typeof WebAssembly&&t("no native wasm support detected");var qa=!1,ra;function m(a,b){a||v("Assertion failed"+(b?": "+b:""))}var oa=a=>a.startsWith("file://");function sa(){var a=ta();m(0==(a&3));0==a&&(a+=4);x[a>>2]=34821223;x[a+4>>2]=2310721022;x[0]=1668509029} -function ua(){if(!qa){var a=ta();0==a&&(a+=4);var b=x[a>>2],c=x[a+4>>2];34821223==b&&2310721022==c||v(`Stack overflow! Stack cookie has been overwritten at ${va(a)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${va(c)} ${va(b)}`);1668509029!=x[0]&&v("Runtime error: The application has corrupted its heap memory area (address zero)!")}}var wa=new Int16Array(1),xa=new Int8Array(wa.buffer);wa[0]=25459; -if(115!==xa[0]||99!==xa[1])throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)";function ya(a){Object.getOwnPropertyDescriptor(f,a)||Object.defineProperty(f,a,{configurable:!0,set(){v(`Attempt to set \`Module.${a}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`)}})} -function y(a){return()=>m(!1,`call to '${a}' via reference taken before Wasm module initialization`)}function Aa(a){return"FS_createPath"===a||"FS_createDataFile"===a||"FS_createPreloadedFile"===a||"FS_preloadFile"===a||"FS_unlink"===a||"addRunDependency"===a||"FS_createLazyFile"===a||"FS_createDevice"===a||"removeRunDependency"===a}function Ba(a,b){"undefined"==typeof globalThis||Object.getOwnPropertyDescriptor(globalThis,a)||Object.defineProperty(globalThis,a,{configurable:!0,get(){b()}})} -function Ca(a,b){Ba(a,()=>{z(`\`${a}\` is not longer defined by emscripten. ${b}`)})}Ca("buffer","Please use HEAP8.buffer or wasmMemory.buffer");Ca("asm","Please use wasmExports instead");function Da(a){Object.getOwnPropertyDescriptor(f,a)||Object.defineProperty(f,a,{configurable:!0,get(){var b=`'${a}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;Aa(a)&&(b+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you");v(b)}})} -var Ea,Fa,Ga,A,Ha,Ia,B,x,C,Ja=!1;function Ka(){var a=Ga.buffer;A=new Int8Array(a);Ia=new Int16Array(a);Ha=new Uint8Array(a);new Uint16Array(a);B=new Int32Array(a);x=new Uint32Array(a);new Float32Array(a);new Float64Array(a);C=new BigInt64Array(a);new BigUint64Array(a)}m("undefined"!=typeof Int32Array&&"undefined"!==typeof Float64Array&&void 0!=Int32Array.prototype.subarray&&void 0!=Int32Array.prototype.set,"JS engine does not provide full typed array support");var E=0,La=null,Ma={},I=null; -function Na(a){E++;f.monitorRunDependencies?.(E);m(a,"addRunDependency requires an ID");m(!Ma[a]);Ma[a]=1;null===I&&"undefined"!=typeof setInterval&&(I=setInterval(()=>{if(qa)clearInterval(I),I=null;else{var b=!1,c;for(c in Ma)b||(b=!0,t("still waiting on run dependencies:")),t(`dependency: ${c}`);b&&t("(end of list)")}},1E4),I.unref?.())} -function Oa(a){E--;f.monitorRunDependencies?.(E);m(a,"removeRunDependency requires an ID");m(Ma[a]);delete Ma[a];0==E&&(null!==I&&(clearInterval(I),I=null),La&&(a=La,La=null,a()))}function v(a){f.onAbort?.(a);a="Aborted("+a+")";t(a);qa=!0;a=new WebAssembly.RuntimeError(a);Fa?.(a);throw a;} -function K(a,b){return(...c)=>{m(Ja,`native function \`${a}\` called before runtime initialization`);var d=L[a];m(d,`exported native function \`${a}\` not found`);m(c.length<=b,`native function \`${a}\` called with ${c.length} args but expects ${b}`);return d(...c)}}var Pa;async function Qa(a){if(!pa)try{var b=await ka(a);return new Uint8Array(b)}catch{}if(a==Pa&&pa)a=new Uint8Array(pa);else if(la)a=la(a);else throw"both async and sync fetching of the wasm failed";return a} -async function Ra(a,b){try{var c=await Qa(a);return await WebAssembly.instantiate(c,b)}catch(d){t(`failed to asynchronously prepare wasm: ${d}`),oa(Pa)&&t(`warning: Loading from a file URI (${Pa}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`),v(d)}} -async function Sa(a){var b=Pa;if(!pa&&!oa(b)&&!k)try{var c=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(c,a)}catch(d){t(`wasm streaming compile failed: ${d}`),t("falling back to ArrayBuffer instantiation")}return Ra(b,a)}class Ta{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}} -var Ua=a=>{for(;0{var a=f.preRun.shift();Wa.push(a)},Ya=!0,va=a=>{m("number"===typeof a);return"0x"+(a>>>0).toString(16).padStart(8,"0")},z=a=>{z.$||(z.$={});z.$[a]||(z.$[a]=1,k&&(a="warning: "+a),t(a))},Za="undefined"!=typeof TextDecoder?new TextDecoder:void 0,$a=(a,b=0)=>{var c=b;for(var d=c+void 0;a[c]&&!(c>=d);)++c;if(16e?d+=String.fromCharCode(e):(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else d+=String.fromCharCode(e)}return d},M=a=>{m("number"==typeof a,`UTF8ToString expects a number (got ${typeof a})`);return a?$a(Ha,a):""},ab=(a,b)=>{for(var c=0,d=a.length- -1;0<=d;d--){var e=a[d];"."===e?a.splice(d,1):".."===e?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift("..");return a},bb=a=>{var b="/"===a.charAt(0),c="/"===a.slice(-1);(a=ab(a.split("/").filter(d=>!!d),!b).join("/"))||b||(a=".");a&&c&&(a+="/");return(b?"/":"")+a},cb=a=>{var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1);a=b[0];b=b[1];if(!a&&!b)return".";b&&=b.slice(0,-1);return a+b},N=a=>a&&a.match(/([^\/]+|\/)\/*$/)[1],db=(a,b)=>bb(a+"/"+ -b),eb=()=>{if(k){var a=require("crypto");return b=>a.randomFillSync(b)}return b=>crypto.getRandomValues(b)},fb=a=>{(fb=eb())(a)},gb=(...a)=>{for(var b="",c=!1,d=a.length-1;-1<=d&&!c;d--){c=0<=d?a[d]:O.cwd();if("string"!=typeof c)throw new TypeError("Arguments to path.resolve must be strings");if(!c)return"";b=c+"/"+b;c="/"===c.charAt(0)}b=ab(b.split("/").filter(e=>!!e),!c).join("/");return(c?"/":"")+b||"."},hb=(a,b)=>{function c(h){for(var l=0;lr?[]:h.slice(l,r-l+1)}a=gb(a).slice(1);b=gb(b).slice(1);a=c(a.split("/"));b=c(b.split("/"));for(var d=Math.min(a.length,b.length),e=d,g=0;g{for(var b=0,c=0;c=d?b++:2047>=d?b+=2:55296<=d&&57343>=d?(b+=4,++c):b+=3}return b},kb=(a,b,c,d)=>{m("string"===typeof a,`stringToUTF8Array expects a string (got ${typeof a})`); -if(!(0=h){if(c>=d)break;b[c++]=h}else if(2047>=h){if(c+1>=d)break;b[c++]=192|h>>6;b[c++]=128|h&63}else if(65535>=h){if(c+2>=d)break;b[c++]=224|h>>12;b[c++]=128|h>>6&63;b[c++]=128|h&63}else{if(c+3>=d)break;1114111>18;b[c++]= -128|h>>12&63;b[c++]=128|h>>6&63;b[c++]=128|h&63;g++}}b[c]=0;return c-e},lb=a=>{var b=Array(jb(a)+1);a=kb(a,b,0,b.length);b.length=a;return b},mb=[];function nb(a,b){mb[a]={input:[],output:[],H:b};ob(a,pb)} -var pb={open(a){var b=mb[a.node.rdev];if(!b)throw new O.g(43);a.tty=b;a.seekable=!1},close(a){a.tty.H.fsync(a.tty)},fsync(a){a.tty.H.fsync(a.tty)},read(a,b,c,d){if(!a.tty||!a.tty.H.ha)throw new O.g(60);for(var e=0,g=0;g{v("internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported")}, -P={D:null,m(){return P.createNode(null,"/",16895,0)},createNode(a,b,c,d){if(24576===(c&61440)||O.isFIFO(c))throw new O.g(63);P.D||(P.D={dir:{node:{v:P.h.v,B:P.h.B,lookup:P.h.lookup,G:P.h.G,rename:P.h.rename,unlink:P.h.unlink,rmdir:P.h.rmdir,readdir:P.h.readdir,symlink:P.h.symlink},stream:{s:P.i.s}},file:{node:{v:P.h.v,B:P.h.B},stream:{s:P.i.s,read:P.i.read,write:P.i.write,M:P.i.M,P:P.i.P}},link:{node:{v:P.h.v,B:P.h.B,readlink:P.h.readlink},stream:{}},ba:{node:{v:P.h.v,B:P.h.B},stream:O.ta}});c=O.createNode(a, -b,c,d);Q(c.mode)?(c.h=P.D.dir.node,c.i=P.D.dir.stream,c.j={}):O.isFile(c.mode)?(c.h=P.D.file.node,c.i=P.D.file.stream,c.o=0,c.j=null):40960===(c.mode&61440)?(c.h=P.D.link.node,c.i=P.D.link.stream):8192===(c.mode&61440)&&(c.h=P.D.ba.node,c.i=P.D.ba.stream);c.atime=c.mtime=c.ctime=Date.now();a&&(a.j[b]=c,a.atime=a.mtime=a.ctime=c.atime);return c},fb(a){return a.j?a.j.subarray?a.j.subarray(0,a.o):new Uint8Array(a.j):new Uint8Array(0)},h:{v(a){var b={};b.dev=8192===(a.mode&61440)?a.id:1;b.ino=a.id;b.mode= -a.mode;b.nlink=1;b.uid=0;b.gid=0;b.rdev=a.rdev;Q(a.mode)?b.size=4096:O.isFile(a.mode)?b.size=a.o:40960===(a.mode&61440)?b.size=a.link.length:b.size=0;b.atime=new Date(a.atime);b.mtime=new Date(a.mtime);b.ctime=new Date(a.ctime);b.blksize=4096;b.blocks=Math.ceil(b.size/b.blksize);return b},B(a,b){for(var c of["mode","atime","mtime","ctime"])null!=b[c]&&(a[c]=b[c]);void 0!==b.size&&(b=b.size,a.o!=b&&(0==b?(a.j=null,a.o=0):(c=a.j,a.j=new Uint8Array(b),c&&a.j.set(c.subarray(0,Math.min(b,a.o))),a.o=b)))}, -lookup(){throw new O.g(44);},G(a,b,c,d){return P.createNode(a,b,c,d)},rename(a,b,c){try{var d=R(b,c)}catch(g){}if(d){if(Q(a.mode))for(var e in d.j)throw new O.g(55);tb(d)}delete a.parent.j[a.name];b.j[c]=a;a.name=c;b.ctime=b.mtime=a.parent.ctime=a.parent.mtime=Date.now()},unlink(a,b){delete a.j[b];a.ctime=a.mtime=Date.now()},rmdir(a,b){var c=R(a,b),d;for(d in c.j)throw new O.g(55);delete a.j[b];a.ctime=a.mtime=Date.now()},readdir(a){return[".","..",...Object.keys(a.j)]},symlink(a,b,c){a=P.createNode(a, -b,41471,0);a.link=c;return a},readlink(a){if(40960!==(a.mode&61440))throw new O.g(28);return a.link}},i:{read(a,b,c,d,e){var g=a.node.j;if(e>=a.node.o)return 0;a=Math.min(a.node.o-e,d);m(0<=a);if(8=g||(g=Math.max(g,h*(1048576>h?2:1.125)>>>0),0!=h&&(g=Math.max(g,256)),h=a.j,a.j=new Uint8Array(g),0b)throw new O.g(28); -return b},M(a,b,c,d,e){if(!O.isFile(a.node.mode))throw new O.g(43);a=a.node.j;if(e&2||!a||a.buffer!==A.buffer){d=!0;e=sb();if(!e)throw new O.g(48);if(a){if(0{var c=0;a&&(c|=365);b&&(c|=146);return c},vb={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6, -EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118, -ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23, -EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135},wb=async a=>{var b=await ka(a);m(b,`Loading data file "${a}" failed (no arrayBuffer).`);return new Uint8Array(b)},xb=[],zb=async(a,b)=>{"undefined"!=typeof Browser&&yb();for(var c of xb)if(c.canHandle(b))return m("AsyncFunction"=== -c.handle.constructor.name,"Filesystem plugin handlers must be async functions (See #24914)"),c.handle(a,b);return a},Bb=async(a,b,c,d,e,g,h,l)=>{var r=b?gb(bb(a+"/"+b)):a,q;a:for(var u=q=`cp ${r}`;;){if(!Ma[q])break a;q=u+Math.random()}Na(q);try{if(u=c,"string"==typeof c&&(u=await wb(c)),u=await zb(u,r),l?.(),!g){c=u;g=b;a&&(a="string"==typeof a?a:Ab(a),g=b?bb(a+"/"+b):a);var n=ub(d,e),w=O.create(g,n);if(c){if("string"==typeof c){var F=Array(c.length);b=0;for(var G=c.length;bc;c++){a=a.split("/").filter(l=>!!l);for(var d=O.root,e="/",g=0;g>>0)%O.C.length}function Db(a){var b=Cb(a.parent.id,a.name);a.L=O.C[b];O.C[b]=a} -function Eb(a){var b=["r","w","rw"][a&3];a&512&&(b+="w");return b}function S(a,b){if(O.ia)return 0;if(!b.includes("r")||a.mode&292){if(b.includes("w")&&!(a.mode&146)||b.includes("x")&&!(a.mode&73))return 2}else return 2;return 0}function Fb(a,b){if(!Q(a.mode))return 54;try{return R(a,b),20}catch(c){}return S(a,"wx")} -function Gb(a,b,c){try{var d=R(a,b)}catch(e){return e.l}if(a=S(a,"wx"))return a;if(c){if(!Q(d.mode))return 54;if(O.N(d)||Ab(d)===O.cwd())return 10}else if(Q(d.mode))return 31;return 0}function Hb(a,b){if(!a)throw new O.g(b);return a}function U(a){a=O.ga(a);if(!a)throw new O.g(8);return a}function Ib(a,b=-1){m(-1<=b);a=Object.assign(new O.ra,a);if(-1==b)a:{for(b=0;b<=O.aa;b++)if(!O.streams[b])break a;throw new O.g(33);}a.fd=b;return O.streams[b]=a} -function Jb(a,b=-1){a=Ib(a,b);a.i?.Za?.(a);return a}function Kb(a,b,c){var d=a?.i.B;a=d?a:b;d??=b.h.B;Hb(d,63);d(a,c)}function Lb(a){var b=[];for(a=[a];a.length;){var c=a.pop();b.push(c);a.push(...c.O)}return b}function Mb(a){var b={Na:4096,bb:4096,blocks:1E6,Ma:5E5,La:5E5,files:O.Y,$a:O.Y-1,cb:42,flags:2,kb:255};a.h.oa&&Object.assign(b,a.h.oa(a.m.Ea.root));return b}function Nb(a,b,c){"undefined"==typeof c&&(c=b,b=438);return O.G(a,b|8192,c)} -function Ob(a,b,c,d){Kb(a,b,{mode:c&4095|b.mode&-4096,ctime:Date.now(),fa:d})}function Pb(a,b,c){if(Q(b.mode))throw new O.g(31);if(!O.isFile(b.mode))throw new O.g(28);var d=S(b,"w");if(d)throw new O.g(d);Kb(a,b,{size:c,timestamp:Date.now()})} -function Qb(a,b){try{var c=T(a,{u:!b});a=c.path}catch(e){}var d={N:!1,exists:!1,error:0,name:null,path:null,object:null,Fa:!1,Ha:null,Ga:null};try{c=T(a,{parent:!0}),d.Fa=!0,d.Ha=c.path,d.Ga=c.node,d.name=N(a),c=T(a,{u:!b}),d.exists=!0,d.path=c.path,d.object=c.node,d.name=c.node.name,d.N="/"===c.path}catch(e){d.error=e.l}return d}function Rb(a,b,c,d){a="string"==typeof a?a:Ab(a);b=bb(a+"/"+b);return O.create(b,ub(c,d))} -function Sb(a){if(!(a.Aa||a.Ba||a.link||a.j)){if("undefined"!=typeof XMLHttpRequest)throw Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");try{a.j=la(a.url),a.o=a.j.length}catch(b){throw new O.g(29);}}} -var O={root:null,O:[],ea:{},streams:[],Y:1,C:null,da:"/",T:!1,ia:!0,va:null,R:0,na:{},g:class extends Error{name="ErrnoError";constructor(a){super(Ja?M(Tb(a)):"");this.l=a;for(var b in vb)if(vb[b]===a){this.code=b;break}}},ra:class{F={};node=null;get object(){return this.node}set object(a){this.node=a}get flags(){return this.F.flags}set flags(a){this.F.flags=a}get position(){return this.F.position}set position(a){this.F.position=a}},qa:class{h={};i={};A=null;constructor(a,b,c,d){a||=this;this.parent= -a;this.m=a.m;this.id=O.Y++;this.name=b;this.mode=c;this.rdev=d;this.atime=this.mtime=this.ctime=Date.now()}get read(){return 365===(this.mode&365)}set read(a){a?this.mode|=365:this.mode&=-366}get write(){return 146===(this.mode&146)}set write(a){a?this.mode|=146:this.mode&=-147}get Ba(){return Q(this.mode)}get Aa(){return 8192===(this.mode&61440)}},createNode(a,b,c,d){m("object"==typeof a);a=new O.qa(a,b,c,d);Db(a);return a},N(a){return a===a.parent},isFile(a){return 32768===(a&61440)},isFIFO(a){return 4096=== -(a&61440)},isSocket(a){return 49152===(a&49152)},aa:4096,ga:a=>O.streams[a],ta:{open(a){a.i=O.wa(a.node.rdev).i;a.i.open?.(a)},s(){throw new O.g(70);}},X:a=>a>>8,hb:a=>a&255,K:(a,b)=>a<<8|b,wa:a=>O.ea[a],pa(a,b){function c(h){m(0=e.length&&c(null)}"function"==typeof a&&(b=a,a=!1);O.R++;1 -{if(!h.type.pa)return d(null);h.type.pa(h,a,d)})},m(a,b,c){if("string"==typeof a)throw a;var d="/"===c,e=!c;if(d&&O.root)throw new O.g(10);if(!d&&!e){var g=T(c,{S:!1});c=g.path;g=g.node;if(g.A)throw new O.g(10);if(!Q(g.mode))throw new O.g(54);}b={type:a,Ea:b,ma:c,O:[]};a=a.m(b);a.m=b;b.root=a;d?O.root=a:g&&(g.A=b,g.m&&g.m.O.push(b));return a},qb(a){a=T(a,{S:!1});if(!a.node.A)throw new O.g(28);a=a.node;var b=a.A,c=Lb(b);Object.keys(O.C).forEach(d=>{for(d=O.C[d];d;){var e=d.L;c.includes(d.m)&&tb(d); -d=e}});a.A=null;b=a.m.O.indexOf(b);m(-1!==b);a.m.O.splice(b,1)},lookup(a,b){return a.h.lookup(a,b)},G(a,b,c){var d=T(a,{parent:!0}).node;a=N(a);if(!a)throw new O.g(28);if("."===a||".."===a)throw new O.g(20);var e=Fb(d,a);if(e)throw new O.g(e);if(!d.h.G)throw new O.g(63);return d.h.G(d,a,b,c)},oa(a){return Mb(T(a,{u:!0}).node)},ob(a){return Mb(a.node)},create(a,b=438){return O.G(a,b&4095|32768,0)},mkdir(a,b=511){return O.G(a,b&1023|16384,0)},ib(a,b){var c=a.split("/"),d="",e;for(e of c)if(e){if(d|| -"/"===a.charAt(0))d+="/";d+=e;try{O.mkdir(d,b)}catch(g){if(20!=g.l)throw g;}}},symlink(a,b){if(!gb(a))throw new O.g(44);var c=T(b,{parent:!0}).node;if(!c)throw new O.g(44);b=N(b);var d=Fb(c,b);if(d)throw new O.g(d);if(!c.h.symlink)throw new O.g(63);return c.h.symlink(c,b,a)},rename(a,b){var c=cb(a),d=cb(b),e=N(a),g=N(b);var h=T(a,{parent:!0});var l=h.node;h=T(b,{parent:!0});h=h.node;if(!l||!h)throw new O.g(44);if(l.m!==h.m)throw new O.g(75);var r=R(l,e);a=hb(a,d);if("."!==a.charAt(0))throw new O.g(28); -a=hb(b,c);if("."!==a.charAt(0))throw new O.g(55);try{var q=R(h,g)}catch(u){}if(r!==q){b=Q(r.mode);if(e=Gb(l,e,b))throw new O.g(e);if(e=q?Gb(h,g,b):Fb(h,g))throw new O.g(e);if(!l.h.rename)throw new O.g(63);if(r.A||q&&q.A)throw new O.g(10);if(h!==l&&(e=S(l,"w")))throw new O.g(e);tb(r);try{l.h.rename(r,h,g),r.parent=h}catch(u){throw u;}finally{Db(r)}}},rmdir(a){var b=T(a,{parent:!0}).node;a=N(a);var c=R(b,a),d=Gb(b,a,!0);if(d)throw new O.g(d);if(!b.h.rmdir)throw new O.g(63);if(c.A)throw new O.g(10); -b.h.rmdir(b,a);tb(c)},readdir(a){a=T(a,{u:!0}).node;return Hb(a.h.readdir,54)(a)},unlink(a){var b=T(a,{parent:!0}).node;if(!b)throw new O.g(44);a=N(a);var c=R(b,a),d=Gb(b,a,!1);if(d)throw new O.g(d);if(!b.h.unlink)throw new O.g(63);if(c.A)throw new O.g(10);b.h.unlink(b,a);tb(c)},readlink(a){a=T(a).node;if(!a)throw new O.g(44);if(!a.h.readlink)throw new O.g(28);return a.h.readlink(a)},stat(a,b){a=T(a,{u:!b}).node;return Hb(a.h.v,63)(a)},fstat(a){var b=U(a);a=b.node;var c=b.i.v;b=c?b:a;c??=a.h.v;Hb(c, -63);return c(b)},lstat(a){return O.stat(a,!0)},chmod(a,b,c){a="string"==typeof a?T(a,{u:!c}).node:a;Ob(null,a,b,c)},lchmod(a,b){O.chmod(a,b,!0)},fchmod(a,b){a=U(a);Ob(a,a.node,b,!1)},chown(a,b,c,d){a="string"==typeof a?T(a,{u:!d}).node:a;Kb(null,a,{timestamp:Date.now(),fa:d})},lchown(a,b,c){O.chown(a,b,c,!0)},fchown(a){a=U(a);Kb(a,a.node,{timestamp:Date.now(),fa:!1})},truncate(a,b){if(0>b)throw new O.g(28);a="string"==typeof a?T(a,{u:!0}).node:a;Pb(null,a,b)},eb(a,b){a=U(a);if(0>b||0===(a.flags&2097155))throw new O.g(28); -Pb(a,a.node,b)},rb(a,b,c){a=T(a,{u:!0}).node;Hb(a.h.B,63)(a,{atime:b,mtime:c})},open(a,b,c=438){if(""===a)throw new O.g(44);if("string"==typeof b){var d={r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090}[b];if("undefined"==typeof d)throw Error(`Unknown file open mode: ${b}`);b=d}c=b&64?c&4095|32768:0;if("object"==typeof a)d=a;else{var e=a.endsWith("/");a=T(a,{u:!(b&131072),Ca:!0});d=a.node;a=a.path}var g=!1;if(b&64)if(d){if(b&128)throw new O.g(20);}else{if(e)throw new O.g(31);d=O.G(a,c|511,0);g=!0}if(!d)throw new O.g(44); -8192===(d.mode&61440)&&(b&=-513);if(b&65536&&!Q(d.mode))throw new O.g(54);if(!g&&(e=d?40960===(d.mode&61440)?32:Q(d.mode)&&("r"!==Eb(b)||b&576)?31:S(d,Eb(b)):44))throw new O.g(e);b&512&&!g&&O.truncate(d,0);b&=-131713;e=Ib({node:d,path:Ab(d),flags:b,seekable:!0,position:0,i:d.i,Ja:[],error:!1});e.i.open&&e.i.open(e);g&&O.chmod(d,c&511);!f.logReadFiles||b&1||a in O.na||(O.na[a]=1);return e},close(a){if(null===a.fd)throw new O.g(8);a.J&&(a.J=null);try{a.i.close&&a.i.close(a)}catch(b){throw b;}finally{O.streams[a.fd]= -null}a.fd=null},s(a,b,c){if(null===a.fd)throw new O.g(8);if(!a.seekable||!a.i.s)throw new O.g(70);if(0!=c&&1!=c&&2!=c)throw new O.g(28);a.position=a.i.s(a,b,c);a.Ja=[];return a.position},read(a,b,c,d,e){m(0<=c);if(0>d||0>e)throw new O.g(28);if(null===a.fd)throw new O.g(8);if(1===(a.flags&2097155))throw new O.g(8);if(Q(a.node.mode))throw new O.g(31);if(!a.i.read)throw new O.g(28);var g="undefined"!=typeof e;if(!g)e=a.position;else if(!a.seekable)throw new O.g(70);b=a.i.read(a,b,c,d,e);g||(a.position+= -b);return b},write(a,b,c,d,e,g){m(0<=c);if(0>d||0>e)throw new O.g(28);if(null===a.fd)throw new O.g(8);if(0===(a.flags&2097155))throw new O.g(8);if(Q(a.node.mode))throw new O.g(31);if(!a.i.write)throw new O.g(28);a.seekable&&a.flags&1024&&O.s(a,0,2);var h="undefined"!=typeof e;if(!h)e=a.position;else if(!a.seekable)throw new O.g(70);b=a.i.write(a,b,c,d,e,g);h||(a.position+=b);return b},M(a,b,c,d,e){if(0!==(d&2)&&0===(e&2)&&2!==(a.flags&2097155))throw new O.g(2);if(1===(a.flags&2097155))throw new O.g(2); -if(!a.i.M)throw new O.g(43);if(!b)throw new O.g(28);return a.i.M(a,b,c,d,e)},P(a,b,c,d,e){m(0<=c);return a.i.P?a.i.P(a,b,c,d,e):0},W(a,b,c){if(!a.i.W)throw new O.g(59);return a.i.W(a,b,c)},readFile(a,b={}){b.flags=b.flags||0;b.encoding=b.encoding||"binary";if("utf8"!==b.encoding&&"binary"!==b.encoding)throw Error(`Invalid encoding type "${b.encoding}"`);var c=O.open(a,b.flags);a=O.stat(a).size;var d=new Uint8Array(a);O.read(c,d,0,a,0);"utf8"===b.encoding&&(d=$a(d));O.close(c);return d},writeFile(a, -b,c={}){c.flags=c.flags||577;a=O.open(a,c.flags,c.mode);"string"==typeof b&&(b=new Uint8Array(lb(b)));if(ArrayBuffer.isView(b))O.write(a,b,0,b.byteLength,void 0,c.Ta);else throw Error("Unsupported data type");O.close(a)},cwd:()=>O.da,chdir(a){a=T(a,{u:!0});if(null===a.node)throw new O.g(44);if(!Q(a.node.mode))throw new O.g(54);var b=S(a.node,"x");if(b)throw new O.g(b);O.da=a.path},mb(){O.T=!1;Ub(0);for(var a of O.streams)a&&O.close(a)},ab(a,b){a=Qb(a,b);return a.exists?a.object:null},Xa(a,b){a="string"== -typeof a?a:Ab(a);for(b=b.split("/").reverse();b.length;){var c=b.pop();if(c){var d=bb(a+"/"+c);try{O.mkdir(d)}catch(e){if(20!=e.l)throw e;}a=d}}return d},I(a,b,c,d){a=db("string"==typeof a?a:Ab(a),b);b=ub(!!c,!!d);var e;(e=O.I).X??(e.X=64);e=O.K(O.I.X++,0);ob(e,{open(g){g.seekable=!1},close(){d?.buffer?.length&&d(10)},read(g,h,l,r){for(var q=0,u=0;u=n.length)return 0;G=Math.min(n.length-D,G);m(0<=G);if(n.slice)for(var H=0;Hthis.length-1||0>n)){var w=n%this.chunkSize;return this.U(n/this.chunkSize|0)[w]}}Da(n){this.U= -n}la(){var n=new XMLHttpRequest;n.open("HEAD",c,!1);n.send(null);if(!(200<=n.status&&300>n.status||304===n.status))throw Error("Couldn't load "+c+". Status: "+n.status);var w=Number(n.getResponseHeader("Content-length")),F,G=(F=n.getResponseHeader("Accept-Ranges"))&&"bytes"===F;n=(F=n.getResponseHeader("Content-Encoding"))&&"gzip"===F;var D=1048576;G||(D=w);var H=this;H.Da(fa=>{var za=fa*D,ha=(fa+1)*D-1;ha=Math.min(ha,w-1);if("undefined"==typeof H.F[fa]){var Bc=H.F;if(za>ha)throw Error("invalid range ("+ -za+", "+ha+") or no bytes requested!");if(ha>w-1)throw Error("only "+w+" bytes available! programmer error!");var J=new XMLHttpRequest;J.open("GET",c,!1);w!==D&&J.setRequestHeader("Range","bytes="+za+"-"+ha);J.responseType="arraybuffer";J.overrideMimeType&&J.overrideMimeType("text/plain; charset=x-user-defined");J.send(null);if(!(200<=J.status&&300>J.status||304===J.status))throw Error("Couldn't load "+c+". Status: "+J.status);za=void 0!==J.response?new Uint8Array(J.response||[]):lb(J.responseText|| -"");Bc[fa]=za}if("undefined"==typeof H.F[fa])throw Error("doXHR failed!");return H.F[fa]});if(n||!w)D=w=1,D=w=this.U(0).length,p("LazyFiles on gzip forces download of the whole file when length is accessed");this.ka=w;this.ja=D;this.V=!0}get length(){this.V||this.la();return this.ka}get chunkSize(){this.V||this.la();return this.ja}}if("undefined"!=typeof XMLHttpRequest){if(!ba)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; -var l=new h;var r=void 0}else r=c,l=void 0;var q=Rb(a,b,d,e);l?q.j=l:r&&(q.j=null,q.url=r);Object.defineProperties(q,{o:{get:function(){return this.j.length}}});var u={};Object.keys(q.i).forEach(n=>{var w=q.i[n];u[n]=(...F)=>{Sb(q);return w(...F)}});u.read=(n,w,F,G,D)=>{Sb(q);return g(n,w,F,G,D)};u.M=(n,w,F)=>{Sb(q);var G=sb();if(!G)throw new O.g(48);g(n,A,G,w,F);return{Ia:G,sa:!0}};q.i=u;return q},Ka(){v("FS.absolutePath has been removed; use PATH_FS.resolve instead")},Ua(){v("FS.createFolder has been removed; use FS.mkdir instead")}, -Wa(){v("FS.createLink has been removed; use FS.symlink instead")},gb(){v("FS.joinPath has been removed; use PATH.join instead")},jb(){v("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},nb(){v("FS.standardizePath has been removed; use PATH.normalize instead")}};function Vb(a,b,c){if("/"===b.charAt(0))return b;a=-100===a?O.cwd():U(a).path;if(0==b.length){if(!c)throw new O.g(44);return a}return a+"/"+b} -function Wb(a,b){x[a>>2]=b.dev;x[a+4>>2]=b.mode;x[a+8>>2]=b.nlink;x[a+12>>2]=b.uid;x[a+16>>2]=b.gid;x[a+20>>2]=b.rdev;C[a+24>>3]=BigInt(b.size);B[a+32>>2]=4096;B[a+36>>2]=b.blocks;var c=b.atime.getTime(),d=b.mtime.getTime(),e=b.ctime.getTime();C[a+40>>3]=BigInt(Math.floor(c/1E3));x[a+48>>2]=c%1E3*1E6;C[a+56>>3]=BigInt(Math.floor(d/1E3));x[a+64>>2]=d%1E3*1E6;C[a+72>>3]=BigInt(Math.floor(e/1E3));x[a+80>>2]=e%1E3*1E6;C[a+88>>3]=BigInt(b.ino);return 0} -var Xb=void 0,V=()=>{m(void 0!=Xb);var a=B[+Xb>>2];Xb+=4;return a},W=(a,b,c)=>{m("number"==typeof c,"stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return kb(a,Ha,b,c)},Yb=0,Zb=a=>0===a%4&&(0!==a%100||0===a%400),$b=[0,31,60,91,121,152,182,213,244,274,305,335],ac=[0,31,59,90,120,151,181,212,243,273,304,334],bc={},cc=a=>{if(a instanceof Ta||"unwind"==a)return ra;ua();a instanceof WebAssembly.RuntimeError&&0>=X()&&t("Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)"); -ea(1,a)},dc=a=>{ra=a;Ya||0{ra=a;ec();(Ya||0{if(qa)t("user callback triggered after runtime exited or application aborted. Ignoring."); -else try{if(a(),!(Ya||0{if(!ic){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.language||"C").replace("-","_")+".UTF-8",_:da||"./this.program"},b;for(b in hc)void 0===hc[b]?delete a[b]:a[b]=hc[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);ic=c}return ic},ic,kc=(a,b,c,d)=>{for(var e=0,g=0;g>2],l=x[b+4>>2];b+=8;h=O.read(a,A,h,l,d);if(0>h)return-1; -e+=h;if(h{for(var e=0,g=0;g>2],l=x[b+4>>2];b+=8;h=O.write(a,A,h,l,d);if(0>h)return-1;e+=h;if(h{Bb(a,b,c,d,e,l,r,q).then(g).catch(h)};O.lb=Bb;O.C=Array(4096);O.m(P,{},"/");O.mkdir("/tmp");O.mkdir("/home");O.mkdir("/home/web_user"); -(function(){O.mkdir("/dev");ob(O.K(1,3),{read:()=>0,write:(d,e,g,h)=>h,s:()=>0});Nb("/dev/null",O.K(1,3));nb(O.K(5,0),qb);nb(O.K(6,0),rb);Nb("/dev/tty",O.K(5,0));Nb("/dev/tty1",O.K(6,0));var a=new Uint8Array(1024),b=0,c=()=>{0===b&&(fb(a),b=a.byteLength);return a[--b]};O.I("/dev","random",c);O.I("/dev","urandom",c);O.mkdir("/dev/shm");O.mkdir("/dev/shm/tmp")})(); -(function(){O.mkdir("/proc");var a=O.mkdir("/proc/self");O.mkdir("/proc/self/fd");O.m({m(){var b=O.createNode(a,"fd",16895,73);b.i={s:P.i.s};b.h={lookup(c,d){c=+d;var e=U(c);c={parent:null,m:{ma:"fake"},h:{readlink:()=>e.path},id:c+1};return c.parent=c},readdir(){return Array.from(O.streams.entries()).filter(([,c])=>c).map(([c])=>c.toString())}};return b}},{},"/proc/self/fd")})();O.va={MEMFS:P};f.noExitRuntime&&(Ya=f.noExitRuntime);f.preloadPlugins&&(xb=f.preloadPlugins);f.print&&(p=f.print); -f.printErr&&(t=f.printErr);f.wasmBinary&&(pa=f.wasmBinary);Object.getOwnPropertyDescriptor(f,"fetchSettings")&&v("`Module.fetchSettings` was supplied but `fetchSettings` not included in INCOMING_MODULE_JS_API");f.thisProgram&&(da=f.thisProgram);m("undefined"==typeof f.memoryInitializerPrefixURL,"Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");m("undefined"==typeof f.pthreadMainPrefixURL,"Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead"); -m("undefined"==typeof f.cdInitializerPrefixURL,"Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");m("undefined"==typeof f.filePackagePrefixURL,"Module.filePackagePrefixURL option was removed, use Module.locateFile instead");m("undefined"==typeof f.read,"Module.read option was removed");m("undefined"==typeof f.readAsync,"Module.readAsync option was removed (modify readAsync in JS)");m("undefined"==typeof f.readBinary,"Module.readBinary option was removed (modify readBinary in JS)"); -m("undefined"==typeof f.setWindowTitle,"Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)");m("undefined"==typeof f.TOTAL_MEMORY,"Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");m("undefined"==typeof f.ENVIRONMENT,"Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)");m("undefined"==typeof f.STACK_SIZE,"STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time"); -m("undefined"==typeof f.wasmMemory,"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally");m("undefined"==typeof f.INITIAL_MEMORY,"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically");f.callMain=nc;f.FS=O; -"writeI53ToI64 writeI53ToI64Clamped writeI53ToI64Signaling writeI53ToU64Clamped writeI53ToU64Signaling readI53FromI64 readI53FromU64 convertI32PairToI53 convertI32PairToI53Checked convertU32PairToI53 getTempRet0 setTempRet0 zeroMemory withStackSave inetPton4 inetNtop4 inetPton6 inetNtop6 readSockaddr writeSockaddr readEmAsmArgs jstoi_q autoResumeAudioContext dynCallLegacy getDynCaller dynCall runtimeKeepalivePush runtimeKeepalivePop asmjsMangle HandleAllocator getNativeTypeSize addOnInit addOnPostCtor addOnPreMain addOnExit STACK_SIZE STACK_ALIGN POINTER_SIZE ASSERTIONS ccall cwrap convertJsFunctionToWasm getEmptyTableSlot updateTableMap getFunctionAddress addFunction removeFunction intArrayToString AsciiToString stringToAscii UTF16ToString stringToUTF16 lengthBytesUTF16 UTF32ToString stringToUTF32 lengthBytesUTF32 stringToNewUTF8 writeArrayToMemory registerKeyEventCallback maybeCStringToJsString findEventTarget getBoundingClientRect fillMouseEventData registerMouseEventCallback registerWheelEventCallback registerUiEventCallback registerFocusEventCallback fillDeviceOrientationEventData registerDeviceOrientationEventCallback fillDeviceMotionEventData registerDeviceMotionEventCallback screenOrientation fillOrientationChangeEventData registerOrientationChangeEventCallback fillFullscreenChangeEventData registerFullscreenChangeEventCallback JSEvents_requestFullscreen JSEvents_resizeCanvasForFullscreen registerRestoreOldStyle hideEverythingExceptGivenElement restoreHiddenElements setLetterbox softFullscreenResizeWebGLRenderTarget doRequestFullscreen fillPointerlockChangeEventData registerPointerlockChangeEventCallback registerPointerlockErrorEventCallback requestPointerLock fillVisibilityChangeEventData registerVisibilityChangeEventCallback registerTouchEventCallback fillGamepadEventData registerGamepadEventCallback registerBeforeUnloadEventCallback fillBatteryEventData registerBatteryEventCallback setCanvasElementSize getCanvasElementSize jsStackTrace getCallstack convertPCtoSourceLocation wasiRightsToMuslOFlags wasiOFlagsToMuslOFlags safeSetTimeout setImmediateWrapped safeRequestAnimationFrame clearImmediateWrapped registerPostMainLoop registerPreMainLoop getPromise makePromise idsToPromises makePromiseCallback ExceptionInfo findMatchingCatch Browser_asyncPrepareDataCounter arraySum addDays getSocketFromFD getSocketAddress FS_mkdirTree _setNetworkCallback heapObjectForWebGLType toTypedArrayIndex webgl_enable_ANGLE_instanced_arrays webgl_enable_OES_vertex_array_object webgl_enable_WEBGL_draw_buffers webgl_enable_WEBGL_multi_draw webgl_enable_EXT_polygon_offset_clamp webgl_enable_EXT_clip_control webgl_enable_WEBGL_polygon_mode emscriptenWebGLGet computeUnpackAlignedImageSize colorChannelsInGlTextureFormat emscriptenWebGLGetTexPixelData emscriptenWebGLGetUniform webglGetUniformLocation webglPrepareUniformLocationsBeforeFirstUse webglGetLeftBracePos emscriptenWebGLGetVertexAttrib __glGetActiveAttribOrUniform writeGLArray registerWebGlEventCallback runAndAbortIfError ALLOC_NORMAL ALLOC_STACK allocate writeStringToMemory writeAsciiToMemory demangle stackTrace".split(" ").forEach(function(a){Ba(a,()=> -{var b=`\`${a}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`,c=a;c.startsWith("_")||(c="$"+a);b+=` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${c}')`;Aa(a)&&(b+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you");z(b)});Da(a)});"run addRunDependency removeRunDependency out err abort wasmMemory wasmExports HEAPF32 HEAPF64 HEAP8 HEAPU8 HEAP16 HEAPU16 HEAP32 HEAPU32 HEAP64 HEAPU64 writeStackCookie checkStackCookie INT53_MAX INT53_MIN bigintToI53Checked stackSave stackRestore stackAlloc ptrToString exitJS getHeapMax growMemory ENV ERRNO_CODES strError DNS Protocols Sockets timers warnOnce readEmAsmArgsArray getExecutableName handleException keepRuntimeAlive callUserCallback maybeExit asyncLoad alignMemory mmapAlloc wasmTable getUniqueRunDependency noExitRuntime addOnPreRun addOnPostRun freeTableIndexes functionsInTableMap setValue getValue PATH PATH_FS UTF8Decoder UTF8ArrayToString UTF8ToString stringToUTF8Array stringToUTF8 lengthBytesUTF8 intArrayFromString UTF16Decoder stringToUTF8OnStack JSEvents specialHTMLTargets findCanvasEventTarget currentFullscreenStrategy restoreOldWindowedStyle UNWIND_CACHE ExitStatus getEnvStrings checkWasiClock doReadv doWritev initRandomFill randomFill emSetImmediate emClearImmediate_deps emClearImmediate promiseMap uncaughtExceptionCount exceptionLast exceptionCaught Browser requestFullscreen requestFullScreen setCanvasSize getUserMedia createContext getPreloadedImageData__data wget MONTH_DAYS_REGULAR MONTH_DAYS_LEAP MONTH_DAYS_REGULAR_CUMULATIVE MONTH_DAYS_LEAP_CUMULATIVE isLeapYear ydayFromDate SYSCALLS preloadPlugins FS_createPreloadedFile FS_preloadFile FS_modeStringToFlags FS_getMode FS_stdin_getChar_buffer FS_stdin_getChar FS_unlink FS_createPath FS_createDevice FS_readFile FS_root FS_mounts FS_devices FS_streams FS_nextInode FS_nameTable FS_currentPath FS_initialized FS_ignorePermissions FS_filesystems FS_syncFSRequests FS_readFiles FS_lookupPath FS_getPath FS_hashName FS_hashAddNode FS_hashRemoveNode FS_lookupNode FS_createNode FS_destroyNode FS_isRoot FS_isMountpoint FS_isFile FS_isDir FS_isLink FS_isChrdev FS_isBlkdev FS_isFIFO FS_isSocket FS_flagsToPermissionString FS_nodePermissions FS_mayLookup FS_mayCreate FS_mayDelete FS_mayOpen FS_checkOpExists FS_nextfd FS_getStreamChecked FS_getStream FS_createStream FS_closeStream FS_dupStream FS_doSetAttr FS_chrdev_stream_ops FS_major FS_minor FS_makedev FS_registerDevice FS_getDevice FS_getMounts FS_syncfs FS_mount FS_unmount FS_lookup FS_mknod FS_statfs FS_statfsStream FS_statfsNode FS_create FS_mkdir FS_mkdev FS_symlink FS_rename FS_rmdir FS_readdir FS_readlink FS_stat FS_fstat FS_lstat FS_doChmod FS_chmod FS_lchmod FS_fchmod FS_doChown FS_chown FS_lchown FS_fchown FS_doTruncate FS_truncate FS_ftruncate FS_utime FS_open FS_close FS_isClosed FS_llseek FS_read FS_write FS_mmap FS_msync FS_ioctl FS_writeFile FS_cwd FS_chdir FS_createDefaultDirectories FS_createDefaultDevices FS_createSpecialDirectories FS_createStandardStreams FS_staticInit FS_init FS_quit FS_findObject FS_analyzePath FS_createFile FS_createDataFile FS_forceLoadFile FS_createLazyFile FS_absolutePath FS_createFolder FS_createLink FS_joinPath FS_mmapAlloc FS_standardizePath MEMFS TTY PIPEFS SOCKFS tempFixedLengthArray miniTempWebGLFloatBuffers miniTempWebGLIntBuffers GL AL GLUT EGL GLEW IDBStore SDL SDL_gfx allocateUTF8 allocateUTF8OnStack print printErr jstoi_s".split(" ").forEach(Da); -var oc=f._main=y("_main"),Tb=y("_strerror"),Ub=y("_fflush"),ta=y("_emscripten_stack_get_end"),pc=y("__emscripten_timeout"),Y=y("_setThrew"),qc=y("_emscripten_stack_init"),Z=y("__emscripten_stack_restore"),rc=y("__emscripten_stack_alloc"),X=y("_emscripten_stack_get_current"),dynCall_v=y("dynCall_v"),dynCall_iii=y("dynCall_iii"),sc=y("dynCall_viii"),tc=y("dynCall_iiii"),uc=y("dynCall_ii"),dynCall_vi=y("dynCall_vi"),vc=y("dynCall_iiiii"),wc=y("dynCall_iiiiiiiii"),dynCall_vii=y("dynCall_vii"),xc=y("dynCall_iiji"), -yc=y("dynCall_viiii"),zc=y("dynCall_viiiii"),Ac=y("dynCall_viiiiii"),Oc={__assert_fail:(a,b,c,d)=>v(`Assertion failed: ${M(a)}, at: `+[b?M(b):"unknown filename",c,d?M(d):"unknown function"]),__syscall_dup:function(a){try{var b=U(a);return Jb(b).fd}catch(c){if("undefined"==typeof O||"ErrnoError"!==c.name)throw c;return-c.l}},__syscall_dup3:function(a,b,c){try{var d=U(a);m(!c);if(d.fd===b)return-28;if(0>b||b>=O.aa)return-8;var e=O.ga(b);e&&O.close(e);return Jb(d,b).fd}catch(g){if("undefined"==typeof O|| -"ErrnoError"!==g.name)throw g;return-g.l}},__syscall_fcntl64:function(a,b,c){Xb=c;try{var d=U(a);switch(b){case 0:var e=V();if(0>e)break;for(;O.streams[e];)e++;return Jb(d,e).fd;case 1:case 2:return 0;case 3:return d.flags;case 4:return e=V(),d.flags|=e,0;case 12:return e=V(),Ia[e+0>>1]=2,0;case 13:case 14:return 0}return-28}catch(g){if("undefined"==typeof O||"ErrnoError"!==g.name)throw g;return-g.l}},__syscall_fstat64:function(a,b){try{return Wb(b,O.fstat(a))}catch(c){if("undefined"==typeof O||"ErrnoError"!== -c.name)throw c;return-c.l}},__syscall_getdents64:function(a,b,c){try{var d=U(a);d.J||(d.J=O.readdir(d.path));a=0;var e=O.s(d,0,1),g=Math.floor(e/280),h=Math.min(d.J.length,g+Math.floor(c/280));for(c=g;c>3]=BigInt(r);C[b+a+8>>3]=BigInt(280*(c+ -1));Ia[b+a+16>>1]=280;A[b+a+18]=q;W(l,b+a+19,256);a+=280}O.s(d,280*c,0);return a}catch(n){if("undefined"==typeof O||"ErrnoError"!==n.name)throw n;return-n.l}},__syscall_ioctl:function(a,b,c){Xb=c;try{var d=U(a);switch(b){case 21509:return d.tty?0:-59;case 21505:if(!d.tty)return-59;if(d.tty.H.xa){a=[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];var e=V();B[e>>2]=25856;B[e+4>>2]=5;B[e+8>>2]=191;B[e+12>>2]=35387;for(var g=0;32>g;g++)A[e+g+17]=a[g]||0}return 0;case 21510:case 21511:case 21512:return d.tty? -0:-59;case 21506:case 21507:case 21508:if(!d.tty)return-59;if(d.tty.H.ya)for(e=V(),a=[],g=0;32>g;g++)a.push(A[e+g+17]);return 0;case 21519:if(!d.tty)return-59;e=V();return B[e>>2]=0;case 21520:return d.tty?-28:-59;case 21537:case 21531:return e=V(),O.W(d,b,e);case 21523:if(!d.tty)return-59;d.tty.H.za&&(g=[24,80],e=V(),Ia[e>>1]=g[0],Ia[e+2>>1]=g[1]);return 0;case 21524:return d.tty?0:-59;case 21515:return d.tty?0:-59;default:return-28}}catch(h){if("undefined"==typeof O||"ErrnoError"!==h.name)throw h; -return-h.l}},__syscall_lstat64:function(a,b){try{return a=M(a),Wb(b,O.lstat(a))}catch(c){if("undefined"==typeof O||"ErrnoError"!==c.name)throw c;return-c.l}},__syscall_newfstatat:function(a,b,c,d){try{b=M(b);var e=d&256,g=d&4096;d&=-6401;m(!d,`unknown flags in __syscall_newfstatat: ${d}`);b=Vb(a,b,g);return Wb(c,e?O.lstat(b):O.stat(b))}catch(h){if("undefined"==typeof O||"ErrnoError"!==h.name)throw h;return-h.l}},__syscall_openat:function(a,b,c,d){Xb=d;try{b=M(b);b=Vb(a,b);var e=d?V():0;return O.open(b, -c,e).fd}catch(g){if("undefined"==typeof O||"ErrnoError"!==g.name)throw g;return-g.l}},__syscall_renameat:function(a,b,c,d){try{return b=M(b),d=M(d),b=Vb(a,b),d=Vb(c,d),O.rename(b,d),0}catch(e){if("undefined"==typeof O||"ErrnoError"!==e.name)throw e;return-e.l}},__syscall_rmdir:function(a){try{return a=M(a),O.rmdir(a),0}catch(b){if("undefined"==typeof O||"ErrnoError"!==b.name)throw b;return-b.l}},__syscall_stat64:function(a,b){try{return a=M(a),Wb(b,O.stat(a))}catch(c){if("undefined"==typeof O||"ErrnoError"!== -c.name)throw c;return-c.l}},__syscall_unlinkat:function(a,b,c){try{b=M(b);b=Vb(a,b);if(c)if(512===c)O.rmdir(b);else return-28;else O.unlink(b);return 0}catch(d){if("undefined"==typeof O||"ErrnoError"!==d.name)throw d;return-d.l}},_abort_js:()=>v("native code called abort()"),_emscripten_runtime_keepalive_clear:()=>{Ya=!1;Yb=0},_emscripten_throw_longjmp:()=>{throw Infinity;},_gmtime_js:function(a,b){a=-9007199254740992>a||9007199254740992>2]=a.getUTCSeconds(); -B[b+4>>2]=a.getUTCMinutes();B[b+8>>2]=a.getUTCHours();B[b+12>>2]=a.getUTCDate();B[b+16>>2]=a.getUTCMonth();B[b+20>>2]=a.getUTCFullYear()-1900;B[b+24>>2]=a.getUTCDay();B[b+28>>2]=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0},_localtime_js:function(a,b){a=-9007199254740992>a||9007199254740992>2]=a.getSeconds();B[b+4>>2]=a.getMinutes();B[b+8>>2]=a.getHours();B[b+12>>2]=a.getDate();B[b+16>>2]=a.getMonth();B[b+20>>2]=a.getFullYear()-1900;B[b+24>> -2]=a.getDay();B[b+28>>2]=(Zb(a.getFullYear())?$b:ac)[a.getMonth()]+a.getDate()-1|0;B[b+36>>2]=-(60*a.getTimezoneOffset());var c=(new Date(a.getFullYear(),6,1)).getTimezoneOffset(),d=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();B[b+32>>2]=(c!=d&&a.getTimezoneOffset()==Math.min(d,c))|0},_mktime_js:function(a){var b=new Date(B[a+20>>2]+1900,B[a+16>>2],B[a+12>>2],B[a+8>>2],B[a+4>>2],B[a>>2],0),c=B[a+32>>2],d=b.getTimezoneOffset(),e=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),g=(new Date(b.getFullYear(), -0,1)).getTimezoneOffset(),h=Math.min(g,e);0>c?B[a+32>>2]=Number(e!=g&&h==d):0>2]=b.getDay();B[a+28>>2]=(Zb(b.getFullYear())?$b:ac)[b.getMonth()]+b.getDate()-1|0;B[a>>2]=b.getSeconds();B[a+4>>2]=b.getMinutes();B[a+8>>2]=b.getHours();B[a+12>>2]=b.getDate();B[a+16>>2]=b.getMonth();B[a+20>>2]=b.getYear();a=b.getTime();return BigInt(isNaN(a)?-1:a/1E3)},_setitimer_js:(a,b)=>{bc[a]&&(clearTimeout(bc[a].id),delete bc[a]);if(!b)return 0; -var c=setTimeout(()=>{m(a in bc);delete bc[a];gc(()=>pc(a,performance.now()))},b);bc[a]={id:c,pb:b};return 0},_tzset_js:(a,b,c,d)=>{var e=(new Date).getFullYear(),g=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();x[a>>2]=60*Math.max(g,e);B[b>>2]=Number(g!=e);b=h=>{var l=Math.abs(h);return`UTC${0<=h?"-":"+"}${String(Math.floor(l/60)).padStart(2,"0")}${String(l%60).padStart(2,"0")}`};a=b(g);b=b(e);m(a);m(b);m(16>=jb(a),`timezone name truncated to fit in TZNAME_MAX (${a})`); -m(16>=jb(b),`timezone name truncated to fit in TZNAME_MAX (${b})`);e=a))return 28;C[c>>3]=BigInt(Math.round(1E6*(0===a?Date.now():performance.now())));return 0},emscripten_date_now:()=>Date.now(),emscripten_resize_heap:a=>{var b=Ha.length;a>>>=0;m(a>b);if(2147483648=c;c*=2){var d=b*(1+.2/c);d= -Math.min(d,a+100663296);var e=Math,g=e.min;d=Math.max(a,d);m(65536,"alignment argument is required");e=g.call(e,2147483648,65536*Math.ceil(d/65536));a:{g=e;d=Ga.buffer.byteLength;try{Ga.grow((g-d+65535)/65536|0);Ka();var h=1;break a}catch(l){t(`growMemory: Attempted to grow heap from ${d} bytes to ${g} bytes, but got error: ${l}`)}h=void 0}if(h)return!0}t(`Failed to grow the heap from ${b} bytes to ${e} bytes, not enough memory!`);return!1},environ_get:(a,b)=>{var c=0,d=0,e;for(e of jc()){var g=b+ -c;x[a+d>>2]=g;c+=W(e,g,Infinity)+1;d+=4}return 0},environ_sizes_get:(a,b)=>{var c=jc();x[a>>2]=c.length;a=0;for(var d of c)a+=jb(d)+1;x[b>>2]=a;return 0},exit:fc,fd_close:function(a){try{var b=U(a);O.close(b);return 0}catch(c){if("undefined"==typeof O||"ErrnoError"!==c.name)throw c;return c.l}},fd_pread:function(a,b,c,d,e){d=-9007199254740992>d||9007199254740992>2]=h;return 0}catch(l){if("undefined"==typeof O||"ErrnoError"!== -l.name)throw l;return l.l}},fd_pwrite:function(a,b,c,d,e){d=-9007199254740992>d||9007199254740992>2]=h;return 0}catch(l){if("undefined"==typeof O||"ErrnoError"!==l.name)throw l;return l.l}},fd_read:function(a,b,c,d){try{var e=U(a),g=kc(e,b,c);x[d>>2]=g;return 0}catch(h){if("undefined"==typeof O||"ErrnoError"!==h.name)throw h;return h.l}},fd_seek:function(a,b,c,d){b=-9007199254740992>b||9007199254740992>3]=BigInt(e.position);e.J&&0===b&&0===c&&(e.J=null);return 0}catch(g){if("undefined"==typeof O||"ErrnoError"!==g.name)throw g;return g.l}},fd_write:function(a,b,c,d){try{var e=U(a),g=lc(e,b,c);x[d>>2]=g;return 0}catch(h){if("undefined"==typeof O||"ErrnoError"!==h.name)throw h;return h.l}},invoke_ii:Cc,invoke_iii:Dc,invoke_iiii:Ec,invoke_iiiii:Fc,invoke_iiiiiiiii:Gc,invoke_iiji:Hc,invoke_vi:Ic,invoke_vii:Jc,invoke_viii:Kc,invoke_viiii:Lc,invoke_viiiii:Mc,invoke_viiiiii:Nc, -proc_exit:dc},L=await (async function(){function a(d){L=d.exports;Ga=L.memory;m(Ga,"memory not found in wasm exports");Ka();mc=L.__indirect_function_table;m(mc,"table not found in wasm exports");d=L;f._main=oc=K("__main_argc_argv",2);Tb=K("strerror",1);Ub=K("fflush",1);ta=d.emscripten_stack_get_end;pc=K("_emscripten_timeout",2);Y=K("setThrew",2);qc=d.emscripten_stack_init;Z=d._emscripten_stack_restore;rc=d._emscripten_stack_alloc;X=d.emscripten_stack_get_current;dynCall_v=K("dynCall_v", -1);dynCall_iii=K("dynCall_iii",3);sc=K("dynCall_viii",4);tc=K("dynCall_iiii",4);uc=K("dynCall_ii",2);dynCall_vi=K("dynCall_vi",2);vc=K("dynCall_iiiii",5);wc=K("dynCall_iiiiiiiii",9);dynCall_vii=K("dynCall_vii",3);xc=K("dynCall_iiji",4);yc=K("dynCall_viiii",5);zc=K("dynCall_viiiii",6);Ac=K("dynCall_viiiiii",7);Oa("wasm-instantiate");return L}Na("wasm-instantiate");var b=f,c={env:Oc,wasi_snapshot_preview1:Oc};if(f.instantiateWasm)return new Promise((d,e)=>{try{f.instantiateWasm(c,(g,h)=>{d(a(g,h))})}catch(g){t(`Module.instantiateWasm callback failed with error: ${g}`), -e(g)}});Pa??=f.locateFile?f.locateFile?f.locateFile("gs.wasm",ja):ja+"gs.wasm":(new URL("gs.wasm",import.meta.url)).href;return function(d){m(f===b,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");b=null;return a(d.instance)}(await Sa(c))}());function Ic(a,b){var c=X();try{dynCall_vi(a,b)}catch(d){Z(c);if(d!==d+0)throw d;Y(1,0)}} -function Jc(a,b,c){var d=X();try{dynCall_vii(a,b,c)}catch(e){Z(d);if(e!==e+0)throw e;Y(1,0)}}function Cc(a,b){var c=X();try{return uc(a,b)}catch(d){Z(c);if(d!==d+0)throw d;Y(1,0)}}function Ec(a,b,c,d){var e=X();try{return tc(a,b,c,d)}catch(g){Z(e);if(g!==g+0)throw g;Y(1,0)}}function Dc(a,b,c){var d=X();try{return dynCall_iii(a,b,c)}catch(e){Z(d);if(e!==e+0)throw e;Y(1,0)}}function Kc(a,b,c,d){var e=X();try{sc(a,b,c,d)}catch(g){Z(e);if(g!==g+0)throw g;Y(1,0)}} -function Lc(a,b,c,d,e){var g=X();try{yc(a,b,c,d,e)}catch(h){Z(g);if(h!==h+0)throw h;Y(1,0)}}function Hc(a,b,c,d){var e=X();try{return xc(a,b,c,d)}catch(g){Z(e);if(g!==g+0)throw g;Y(1,0)}}function Fc(a,b,c,d,e){var g=X();try{return vc(a,b,c,d,e)}catch(h){Z(g);if(h!==h+0)throw h;Y(1,0)}}function Mc(a,b,c,d,e,g){var h=X();try{zc(a,b,c,d,e,g)}catch(l){Z(h);if(l!==l+0)throw l;Y(1,0)}}function Nc(a,b,c,d,e,g,h){var l=X();try{Ac(a,b,c,d,e,g,h)}catch(r){Z(l);if(r!==r+0)throw r;Y(1,0)}} -function Gc(a,b,c,d,e,g,h,l,r){var q=X();try{return wc(a,b,c,d,e,g,h,l,r)}catch(u){Z(q);if(u!==u+0)throw u;Y(1,0)}}var Pc; -function nc(a=[]){m(0==E,'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');m("undefined"===typeof Wa||0==Wa.length,"cannot call main when preRun functions remain to be called");var b=oc;a.unshift(da);var c=a.length,d=rc(4*(c+1)),e=d;a.forEach(h=>{var l=x,r=e>>2,q=jb(h)+1,u=rc(q);W(h,u,q);l[r]=u;e+=4});x[e>>2]=0;try{var g=b(c,d);fc(g,!0);return g}catch(h){return cc(h)}} -function Qc(){function a(){m(!Pc);Pc=!0;f.calledRun=!0;if(!qa){m(!Ja);Ja=!0;ua();f.noFSInit||O.T||yb();L.__wasm_call_ctors();O.ia=!1;ua();Ea?.(f);f.onRuntimeInitialized?.();ya("onRuntimeInitialized");ua();if(f.postRun)for("function"==typeof f.postRun&&(f.postRun=[f.postRun]);f.postRun.length;){var b=f.postRun.shift();Va.push(b)}ya("postRun");Ua(Va)}}if(0{setTimeout(()=>f.setStatus(""),1);a()},1)):a(),ua())}}function ec(){var a=p,b=t,c=!1;p=t=()=>{c=!0};try{Ub(0),["stdout","stderr"].forEach(d=>{(d=Qb("/dev/"+d))&&mb[d.object.rdev]?.output?.length&&(c=!0)})}catch(d){}p=a;t=b;c&&z("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.")} -if(f.preInit)for("function"==typeof f.preInit&&(f.preInit=[f.preInit]);0{Ea=a;Fa=b});for(const a of Object.keys(f))a in moduleArg||Object.defineProperty(moduleArg,a,{configurable:!0,get(){v(`Access to module property ('${a}') is no longer possible via the module constructor argument; Instead, use the result of the module constructor.`)}}); -;return moduleRtn}export default Module; diff --git a/public/ghostscript-wasm/gs.wasm b/public/ghostscript-wasm/gs.wasm deleted file mode 100755 index 159cc23..0000000 Binary files a/public/ghostscript-wasm/gs.wasm and /dev/null differ diff --git a/public/images/badge.svg b/public/images/badge.svg new file mode 100644 index 0000000..9a87f3f --- /dev/null +++ b/public/images/badge.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/locales/be/common.json b/public/locales/be/common.json new file mode 100644 index 0000000..34507b5 --- /dev/null +++ b/public/locales/be/common.json @@ -0,0 +1,323 @@ +{ + "nav": { + "home": "ะ“ะฐะปะพัžะฝะฐั", + "about": "ะŸั€ะฐ ะฝะฐั", + "contact": "ะšะฐะฝั‚ะฐะบั‚ั‹", + "licensing": "ะ›ั–ั†ัะฝะทั–ั", + "allTools": "ะฃัะต ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹", + "openMainMenu": "ะะดะบั€ั‹ั†ัŒ ะณะฐะปะพัžะฝะฐะต ะผะตะฝัŽ", + "language": "ะœะพะฒะฐ" + }, + "donation": { + "message": "ะŸะฐะดะฐะฑะฐะตั†ั†ะฐ BentoPDF? ะŸะฐะดั‚ั€ั‹ะผะฐะนั†ะต, ะบะฐะฑ ั‘ะฝ ะทะฐัั‚ะฐะฒะฐัžัั ะฑััะฟะปะฐั‚ะฝั‹ะผ ั– ะท ะฐะดะบั€ั‹ั‚ั‹ะผ ะทั‹ั…ะพะดะฝั‹ะผ ะบะพะดะฐะผ!", + "button": "ะั…ะฒัั€ะฐะฒะฐั†ัŒ" + }, + "hero": { + "title": "ะะฐะฑะพั€", + "pdfToolkit": "ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž PDF", + "builtForPrivacy": "ะดะปั ะผะฐะบัั–ะผะฐะปัŒะฝะฐะน ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ั–", + "noSignups": "ะ‘ะตะท ั€ัะณั–ัั‚ั€ะฐั†ั‹ั–", + "unlimitedUse": "ะ‘ะตะท ะฐะฑะผะตะถะฐะฒะฐะฝะฝััž", + "worksOffline": "ะŸั€ะฐั†ัƒะต ะฟะฐ-ะทะฐ ัะตั‚ะบะฐะน", + "startUsing": "ะŸะฐั‡ะฐั†ัŒ" + }, + "usedBy": { + "title": "ะ’ั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตั†ั†ะฐ ะบะฐะผะฟะฐะฝั–ัะผั– ั– ะปัŽะดะทัŒะผั–, ัะบั–ั ะฟั€ะฐั†ัƒัŽั†ัŒ ัƒ" + }, + "features": { + "title": "ะงะฐะผัƒ ะฒั‹ะฑั–ั€ะฐัŽั†ัŒ", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "ะ‘ะตะท ั€ัะณั–ัั‚ั€ะฐั†ั‹ั–", + "description": "ะŸะฐั‡ั‹ะฝะฐะนั†ะต ะฐะดั€ะฐะทัƒ, ะฑะตะท ัƒะปั–ะบะพะฒะฐะณะฐ ะทะฐะฟั–ััƒ ั– ัะปะตะบั‚ั€ะพะฝะฝะฐะน ะฟะพัˆั‚ั‹." + }, + "noUploads": { + "title": "ะ‘ะตะท ะทะฐะฟะฐะผะฟะพัžะฒะฐะฝะฝััž", + "description": "100% ะฝะฐ ะฑะฐะบัƒ ะบะปั–ะตะฝั‚ะฐ, ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะดะฐัŽั†ัŒ ะฟั€ั‹ะปะฐะดัƒ." + }, + "foreverFree": { + "title": "ะ—ะฐัžัั‘ะดั‹ ะฑััะฟะปะฐั‚ะฝะฐ", + "description": "ะฃัะต ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹, ะฝั–ัะบั–ั… ะฟั€ะพะฑะฝั‹ั… ะฟะตั€ั‹ัะดะฐัž ั– ะฟะปะฐั‚ะฝั‹ั… ะฑะฐั€'ะตั€ะฐัž." + }, + "noLimits": { + "title": "ะ‘ะตะท ะปั–ะผั–ั‚ะฐัž", + "description": "ะšะฐั€ั‹ัั‚ะฐะนั†ะตัั ะบะพะปัŒะบั– ะทะฐัžะณะพะดะฝะฐ, ะฑะตะท ัั…ะฐะฒะฐะฝั‹ั… ะฐะฑะผะตะถะฐะฒะฐะฝะฝััž." + }, + "batchProcessing": { + "title": "ะŸะฐะบะตั‚ะฝะฐั ะฐะฟั€ะฐั†ะพัžะบะฐ", + "description": "ะะฟั€ะฐั†ะพัžะฒะฐะนั†ะต ะฝะตะฐะฑะผะตะถะฐะฒะฐะฝัƒัŽ ะบะพะปัŒะบะฐัั†ัŒ PDF ะทะฐ ะฐะดะทั–ะฝ ั€ะฐะท." + }, + "lightningFast": { + "title": "ะ— ั…ัƒั‚ะบะฐัั†ัŽ ะผะฐะปะฐะฝะบั–", + "description": "ะะฟั€ะฐั†ะพัžะฒะฐะนั†ะต PDF ั–ะผะณะฝะตะฝะฝะฐ, ะฑะตะท ั‡ะฐะบะฐะฝะฝั ั– ะทะฐั‚ั€ั‹ะผะฐะบ." + } + }, + "tools": { + "title": "ะŸะฐั‡ะฝั–ั†ะต ะฟั€ะฐั†ัƒ ะท", + "toolsLabel": "ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐะผั–", + "subtitle": "ะะฐั†ั–ัะฝั–ั†ะต ะฝะฐ ั–ะฝัั‚ั€ัƒะผะตะฝั‚, ะบะฐะฑ ะฐะดะบั€ั‹ั†ัŒ ะทะฐะฟะฐะผะฟะพัžัˆั‡ั‹ะบ", + "searchPlaceholder": "ะŸะพัˆัƒะบ (ะฝะฐะฟั€., \"ะฒั‹ะดะฐะปั–ั†ัŒ\", \"ัั†ั–ัะฝัƒั†ัŒ\"...)", + "backToTools": "ะะฐะทะฐะด ะดะฐ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž", + "firstLoadNotice": "ะŸะตั€ัˆะฐะต ะฐะดะบั€ั‹ั†ั†ั‘ ะทะฐะนะผะฐะต ะบั€ั‹ั…ัƒ ั‡ะฐััƒ, ะฟะฐะบัƒะปัŒ ะทะฐะณั€ัƒะถะฐะตั†ั†ะฐ ั€ัƒั…ะฐะฒั–ะบ ะบะฐะฝะฒะตั€ั‚ะฐั†ั‹ั–. ะŸะพั‚ั‹ะผ ัƒัั‘ ะฑัƒะดะทะต ะฐะดะบั€ั‹ะฒะฐั†ั†ะฐ ั–ะผะณะฝะตะฝะฝะฐ." + }, + "upload": { + "clickToSelect": "ะะฐั†ั–ัะฝั–ั†ะต, ะบะฐะฑ ะฒั‹ะฑั€ะฐั†ัŒ ั„ะฐะนะป,", + "orDragAndDrop": "ะฐะฑะพ ะฟะตั€ะฐั†ัะณะฝั–ั†ะต ััŽะดั‹", + "pdfOrImages": "PDF ะฐะฑะพ ะฒั–ะดะฐั€ั‹ัั‹", + "filesNeverLeave": "ะ’ะฐัˆั‹ ั„ะฐะนะปั‹ ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะดะฐัŽั†ัŒ ะฟั€ั‹ะปะฐะดัƒ.", + "addMore": "ะ”ะฐะดะฐั†ัŒ ะฑะพะปัŒัˆ ั„ะฐะนะปะฐัž", + "clearAll": "ะั‡ั‹ัั†ั–ั†ัŒ ัƒัั‘" + }, + "loader": { + "processing": "ะะฟั€ะฐั†ะพัžะบะฐ..." + }, + "alert": { + "title": "ะะฟะฐะฒััˆั‡ัะฝะฝะต", + "ok": "ะžะš" + }, + "preview": { + "title": "ะŸะฐะฟัั€ัะดะฝั– ะฟั€ะฐะณะปัะด ะดะฐะบัƒะผะตะฝั‚ะฐ", + "downloadAsPdf": "ะกะฟะฐะผะฟะฐะฒะฐั†ัŒ ัะบ PDF", + "close": "ะ—ะฐะบั€ั‹ั†ัŒ" + }, + "settings": { + "title": "ะะฐะปะฐะดั‹", + "shortcuts": "ะกะฟะฐะปัƒั‡ัะฝะฝั– ะบะปะฐะฒั–ัˆ", + "preferences": "ะŸะฐั€ะฐะผะตั‚ั€ั‹", + "displayPreferences": "ะŸะฐั€ะฐะผะตั‚ั€ั‹ ะฐะดะปัŽัั‚ั€ะฐะฒะฐะฝะฝั", + "searchShortcuts": "ะŸะพัˆัƒะบ ัะฟะฐะปัƒั‡ัะฝะฝััž...", + "shortcutsInfo": "ะฃั‚ั€ั‹ะผะปั–ะฒะฐะนั†ะต ะบะปะฐะฒั–ัˆั‹, ะบะฐะฑ ะทะฐะดะฐั†ัŒ ัะฟะฐะปัƒั‡ัะฝะฝะต. ะ—ะผะตะฝั‹ ะทะฐั…ะพัžะฒะฐัŽั†ั†ะฐ ะฐัžั‚ะฐะผะฐั‚ั‹ั‡ะฝะฐ.", + "shortcutsWarning": "โš ๏ธ ะŸะฐะทะฑัะณะฐะนั†ะต ัั‚ะฐะฝะดะฐั€ั‚ะฝั‹ั… ัะฟะฐะปัƒั‡ัะฝะฝััž ะฑั€ะฐัžะทะตั€ะฐ (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N ั– ั–ะฝัˆ.), ะฑะพ ัะฝั‹ ะผะพะณัƒั†ัŒ ะฟั€ะฐั†ะฐะฒะฐั†ัŒ ะฝะตะฝะฐะดะทะตะนะฝะฐ.", + "import": "ะ†ะผะฟะฐั€ั‚", + "export": "ะญะบัะฟะฐั€ั‚", + "resetToDefaults": "ะกะบั–ะฝัƒั†ัŒ ะดะฐ ะฟั€ะฐะดะฒั‹ะทะฝะฐั‡ะฐะฝั‹ั…", + "fullWidthMode": "ะะฐ ัžััŽ ัˆั‹ั€ั‹ะฝัŽ", + "fullWidthDescription": "ะ’ั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐั†ัŒ ัƒััŽ ัˆั‹ั€ั‹ะฝัŽ ัะบั€ะฐะฝะฐ ะดะปั ัžัั–ั… ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž ะทะฐะผะตัั‚ ั†ัะฝั‚ั€ะฐะฒะฐะฝะฐะณะฐ ะบะฐะฝั‚ัะนะฝะตั€ะฐ", + "settingsAutoSaved": "ะะฐะปะฐะดั‹ ะทะฐั…ะพัžะฒะฐัŽั†ั†ะฐ ะฐัžั‚ะฐะผะฐั‚ั‹ั‡ะฝะฐ", + "clickToSet": "ะ—ะฐะดะฐั†ัŒ", + "pressKeys": "ะะฐั†ั–ัะฝั–ั†ะต...", + "warnings": { + "alreadyInUse": "ะกะฟะฐะปัƒั‡ัะฝะฝะต ะบะปะฐะฒั–ัˆ ัƒะถะพ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตั†ั†ะฐ", + "assignedTo": "ัƒะถะพ ะฟั€ั‹ะทะฝะฐั‡ะฐะฝะฐ ะดะปั:", + "chooseDifferent": "ะ’ั‹ะฑะตั€ั‹ั†ะต ั–ะฝัˆะฐะต ัะฟะฐะปัƒั‡ัะฝะฝะต.", + "reserved": "ะŸะฐะฟัั€ัะดะถะฐะฝะฝะต ะฐะฑ ะทะฐั€ัะทะตั€ะฒะฐะฒะฐะฝั‹ะผ ัะฟะฐะปัƒั‡ัะฝะฝั– ะบะปะฐะฒั–ัˆ", + "commonlyUsed": "ั‡ะฐัั‚ะฐ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตั†ั†ะฐ ะดะปั:", + "unreliable": "ะ“ัั‚ะฐ ัะฟะฐะปัƒั‡ัะฝะฝะต ะบะปะฐะฒั–ัˆ ะผะพะถะฐ ะฟั€ะฐั†ะฐะฒะฐั†ัŒ ะฝะตะฝะฐะดะทะตะนะฝะฐ ะฐะฑะพ ะบะฐะฝั„ะปั–ะบั‚ะฐะฒะฐั†ัŒ ะท ะฟะฐะฒะพะดะทั–ะฝะฐะผั– ะฑั€ะฐัžะทะตั€ะฐ/ัั–ัั‚ัะผั‹.", + "useAnyway": "ะฃัั‘ ั€ะพัžะฝะฐ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐั†ัŒ?", + "resetTitle": "ะกะบั–ะฝัƒั†ัŒ ัะฟะฐะปัƒั‡ัะฝะฝั–", + "resetMessage": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ัะบั–ะฝัƒั†ัŒ ัƒัะต ัะฟะฐะปัƒั‡ัะฝะฝั– ะดะฐ ะฟั€ะฐะดะฒั‹ะทะฝะฐั‡ะฐะฝั‹ั… ะทะฝะฐั‡ัะฝะฝััž?

ะ“ัั‚ะฐ ะดะทะตัะฝะฝะต ะฝะตะปัŒะณะฐ ะฐะดั€ะฐะฑั–ั†ัŒ.", + "importSuccessTitle": "ะ†ะผะฟะฐั€ั‚ ะฟะฐัะฟัั…ะพะฒั‹", + "importSuccessMessage": "ะกะฟะฐะปัƒั‡ัะฝะฝั– ะบะปะฐะฒั–ัˆ ะฟะฐัะฟัั…ะพะฒะฐ ั–ะผะฟะฐั€ั‚ะฐะฒะฐะฝั‹ั!", + "importFailTitle": "ะะต ัžะดะฐะปะพัั ั–ะผะฟะฐั€ั‚ะฐะฒะฐั†ัŒ", + "importFailMessage": "ะะต ะฐั‚ั€ั‹ะผะฐะปะฐัั ั–ะผะฟะฐั€ั‚ะฐะฒะฐั†ัŒ ัะฟะฐะปัƒั‡ัะฝะฝั– ะบะปะฐะฒั–ัˆ. ะŸะฐะผั‹ะปะบะพะฒั‹ ั„ะฐั€ะผะฐั‚ ั„ะฐะนะปะฐ." + } + }, + "warning": { + "title": "ะŸะฐะฟัั€ัะดะถะฐะฝะฝะต", + "cancel": "ะกะบะฐัะฐะฒะฐั†ัŒ", + "proceed": "ะŸั€ะฐั†ัะณะฝัƒั†ัŒ" + }, + "compliance": { + "title": "ะ’ะฐัˆั‹ ะดะฐะฝั‹ั ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะดะฐัŽั†ัŒ ะฟั€ั‹ะปะฐะดัƒ", + "weKeep": "ะœั‹ ะทะฐั…ะพัžะฒะฐะตะผ", + "yourInfoSafe": "ะฒะฐัˆัƒ ั–ะฝั„ะฐั€ะผะฐั†ั‹ัŽ ัž ะฑััะฟะตั†ั‹", + "byFollowingStandards": "ะฟะฐะฒะพะดะปะต ะณะปะฐะฑะฐะปัŒะฝั‹ั… ัั‚ะฐะฝะดะฐั€ั‚ะฐัž.", + "processingLocal": "ะฃัั ะฐะฟั€ะฐั†ะพัžะบะฐ ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ะปะฐะบะฐะปัŒะฝะฐ ะฝะฐ ะฒะฐัˆะฐะน ะฟั€ั‹ะปะฐะดะทะต.", + "gdpr": { + "title": "ะะดะฟะฐะฒะตะดะฝะฐัั†ัŒ GDPR", + "description": "ะั…ะพัžะฒะฐะต ะฟะตั€ัะฐะฝะฐะปัŒะฝั‹ั ะดะฐะฝั‹ั ั– ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ะปัŽะดะทะตะน ัƒ ะ•ัžั€ะฐะฟะตะนัะบั–ะผ ะกะฐัŽะทะต." + }, + "ccpa": { + "title": "ะะดะฟะฐะฒะตะดะฝะฐัั†ัŒ CCPA", + "description": "ะ”ะฐะต ะถั‹ั…ะฐั€ะฐะผ ะšะฐะปั–ั„ะพั€ะฝั–ั– ะฟั€ะฐะฒั‹ ะฒะตะดะฐั†ัŒ, ัะบ ะทะฑั–ั€ะฐะตั†ั†ะฐ, ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตั†ั†ะฐ ั– ะฟะตั€ะฐะดะฐะตั†ั†ะฐ ั–ั… ะฟะตั€ัะฐะฝะฐะปัŒะฝะฐั ั–ะฝั„ะฐั€ะผะฐั†ั‹ั." + }, + "hipaa": { + "title": "ะะดะฟะฐะฒะตะดะฝะฐัั†ัŒ HIPAA", + "description": "ะฃัั‚ะฐะปั‘ัžะฒะฐะต ะผะตั€ั‹ ะฑััะฟะตะบั– ะดะปั ะฐะฟั€ะฐั†ะพัžะบั– ะบะฐะฝั„ั–ะดัะฝั†ั‹ะนะฝะฐะน ะผะตะดั‹ั†ั‹ะฝัะบะฐะน ั–ะฝั„ะฐั€ะผะฐั†ั‹ั– ัž ัั–ัั‚ัะผะต ะฐั…ะพะฒั‹ ะทะดะฐั€ะพัžั ะ—ะจะ." + } + }, + "faq": { + "title": "ะงะฐัั‚ั‹ั", + "questions": "ะฟั‹ั‚ะฐะฝะฝั–", + "isFree": { + "question": "BentoPDF ัะฐะฟั€ะฐัžะดั‹ ะฑััะฟะปะฐั‚ะฝั‹?", + "answer": "ะขะฐะบ, ะฐะฑัะฐะปัŽั‚ะฝะฐ. ะฃัะต ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ BentoPDF ะฝะฐ 100% ะฑััะฟะปะฐั‚ะฝั‹ั ะดะปั ะฒั‹ะบะฐั€ั‹ัั‚ะฐะฝะฝั, ะฑะตะท ะปั–ะผั–ั‚ะฐัž ั„ะฐะนะปะฐัž, ะฑะตะท ั€ัะณั–ัั‚ั€ะฐั†ั‹ั– ั– ะฑะตะท ะฒะฐะดะทัะฝั‹ั… ะทะฝะฐะบะฐัž. ะœั‹ ะฒะตั€ั‹ะผ, ัˆั‚ะพ ะบะพะถะฝั‹ ะผะฐะต ะฟั€ะฐะฒะฐ ะดะพัั‚ัƒะฟัƒ ะดะฐ ะฟั€ะพัั‚ั‹ั… ั– ะผะฐะณัƒั‚ะฝั‹ั… ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž PDF ะฑะตะท ะฟะปะฐั‚ะฝั‹ั… ะฑะฐั€'ะตั€ะฐัž." + }, + "areFilesSecure": { + "question": "ะฆั– ัž ะฑััะฟะตั†ั‹ ะผะฐะต ั„ะฐะนะปั‹? ะ”ะทะต ัะฝั‹ ะฐะฟั€ะฐั†ะพัžะฒะฐัŽั†ั†ะฐ?", + "answer": "ะ’ะฐัˆั‹ ั„ะฐะนะปั‹ ัž ะฑััะฟะตั†ั‹ ะฝะฐัั‚ะพะปัŒะบั–, ะฝะฐะบะพะปัŒะบั– ะณัั‚ะฐ ะผะฐะณั‡ั‹ะผะฐ, ะฑะพ ัะฝั‹ ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะดะฐัŽั†ัŒ ะฒะฐัˆ ะบะฐะผะฟ'ัŽั‚ะฐั€. ะฃัั ะฐะฟั€ะฐั†ะพัžะบะฐ ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ะฝะตะฟะฐัั€ัะดะฝะฐ ัž ะฒะฐัˆั‹ะผ ะฑั€ะฐัžะทะตั€ั‹ (ะฝะฐ ะฑะฐะบัƒ ะบะปั–ะตะฝั‚ะฐ). ะœั‹ ะฝั–ะบะพะปั– ะฝะต ะทะฐะฟะฐะผะฟะพัžะฒะฐะตะผ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝะฐ ัะตั€ะฒะตั€, ั‚ะฐะผัƒ ะฒั‹ ะทะฐั…ะพัžะฒะฐะตั†ะต ะฟะพัžะฝัƒัŽ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ั– ะบะฐะฝั‚ั€ะพะปัŒ ะฝะฐะด ัะฒะฐั–ะผั– ะดะฐะบัƒะผะตะฝั‚ะฐะผั–." + }, + "platforms": { + "question": "ะฆั– ะฟั€ะฐั†ัƒะต BentoPDF ะฝะฐ Mac, Windows ั– ะผะฐะฑั–ะปัŒะฝั‹ั… ะฟั€ั‹ะปะฐะดะฐั…?", + "answer": "ะขะฐะบ! ะŸะฐะบะพะปัŒะบั– BentoPDF ะฟั€ะฐั†ัƒะต ะฒั‹ะบะปัŽั‡ะฝะฐ ัž ะฑั€ะฐัžะทะตั€ั‹, ั‘ะฝ ะฟั€ะฐั†ัƒะต ะฝะฐ ะปัŽะฑะพะน ะฐะฟะตั€ะฐั†ั‹ะนะฝะฐะน ัั–ัั‚ัะผะต ะท ััƒั‡ะฐัะฝั‹ะผ ะฒัะฑ-ะฑั€ะฐัžะทะตั€ะฐะผ, ัƒะบะปัŽั‡ะฐัŽั‡ั‹ Windows, macOS, Linux, iOS ั– Android." + }, + "gdprCompliant": { + "question": "ะฆั– ะฐะดะฟะฐะฒัะดะฐะต BentoPDF GDPR?", + "answer": "ะขะฐะบ. BentoPDF ั†ะฐะปะบะฐะผ ะฐะดะฟะฐะฒัะดะฐะต GDPR. ะŸะฐะบะพะปัŒะบั– ัžัั ะฐะฟั€ะฐั†ะพัžะบะฐ ั„ะฐะนะปะฐัž ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ะปะฐะบะฐะปัŒะฝะฐ ัž ะฑั€ะฐัžะทะตั€ั‹ ั– ะผั‹ ะฝั–ะบะพะปั– ะฝะต ะทะฑั–ั€ะฐะตะผ ั– ะฝะต ะฟะตั€ะฐะดะฐั‘ะผ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝะฐ ัะตั€ะฒะตั€, ะผั‹ ะฝะต ะผะฐะตะผ ะดะพัั‚ัƒะฟัƒ ะดะฐ ะฒะฐัˆั‹ั… ะดะฐะฝั‹ั…. ะ“ัั‚ะฐ ะณะฐั€ะฐะฝั‚ัƒะต, ัˆั‚ะพ ะฒั‹ ะทะฐัžัั‘ะดั‹ ะบะฐะฝั‚ั€ะฐะปัŽะตั†ะต ัะฒะฐะต ะดะฐะบัƒะผะตะฝั‚ั‹." + }, + "dataStorage": { + "question": "ะ’ั‹ ะทะฐั…ะพัžะฒะฐะตั†ะต ะฐะฑะพ ะฐะดัะพั‡ะฒะฐะตั†ะต ะผะฐะต ั„ะฐะนะปั‹?", + "answer": "ะะต. ะœั‹ ะฝั–ะบะพะปั– ะฝะต ะทะฐั…ะพัžะฒะฐะตะผ, ะฝะต ะฐะดัะพั‡ะฒะฐะตะผ ั– ะฝะต ะทะฐะฟั–ัะฒะฐะตะผ ะทะฒะตัั‚ะบั– ะฟั€ะฐ ะฒะฐัˆั‹ ั„ะฐะนะปั‹. ะฃัั‘, ัˆั‚ะพ ะฒั‹ ั€ะพะฑั–ั†ะต ัž BentoPDF, ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ัž ะฟะฐะผัั†ั– ะฒะฐัˆะฐะณะฐ ะฑั€ะฐัžะทะตั€ะฐ ั– ะทะฝั–ะบะฐะต ะฟะฐัะปั ะทะฐะบั€ั‹ั†ั†ั ัั‚ะฐั€ะพะฝะบั–. ะัะผะฐ ะทะฐะฟะฐะผะฟะพัžะฒะฐะฝะฝััž, ะฝัะผะฐ ะณั–ัั‚ะพั€ั‹ั– ั– ะฝัะผะฐ ัะตั€ะฒะตั€ะฐัž." + }, + "different": { + "question": "ะงั‹ะผ BentoPDF ะฐะดั€ะพะทะฝั–ะฒะฐะตั†ั†ะฐ ะฐะด ั–ะฝัˆั‹ั… ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž PDF?", + "answer": "ะ—ะฒั‹ั‡ะฐะนะฝะฐ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ PDF ะทะฐะฟะฐะผะฟะพัžะฒะฐัŽั†ัŒ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝะฐ ัะตั€ะฒะตั€ ะดะปั ะฐะฟั€ะฐั†ะพัžะบั–. BentoPDF ะฝั–ะบะพะปั– ั‚ะฐะบ ะฝะต ั€ะพะฑั–ั†ัŒ. ะœั‹ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตะผ ะฑััะฟะตั‡ะฝั‹ั ััƒั‡ะฐัะฝั‹ั ะฒัะฑ-ั‚ัั…ะฝะฐะปะพะณั–ั–, ะบะฐะฑ ะฐะฟั€ะฐั†ะพัžะฒะฐั†ัŒ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝะตะฟะฐัั€ัะดะฝะฐ ัž ะฑั€ะฐัžะทะตั€ั‹. ะ“ัั‚ะฐ ะฐะทะฝะฐั‡ะฐะต ะฑะพะปัŒัˆัƒัŽ ั…ัƒั‚ะบะฐัั†ัŒ, ะปะตะฟัˆัƒัŽ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ั– ะฟะพัžะฝั‹ ัะฟะฐะบะพะน." + }, + "browserBased": { + "question": "ะงะฐะผัƒ ะฐะฟั€ะฐั†ะพัžะบะฐ ัž ะฑั€ะฐัžะทะตั€ั‹ - ะณัั‚ะฐ ะฑััะฟะตั‡ะฝะฐ?", + "answer": "ะŸั€ะฐั†ัƒัŽั‡ั‹ ั†ะฐะปะบะฐะผ ัƒ ะฑั€ะฐัžะทะตั€ั‹, BentoPDF ะณะฐั€ะฐะฝั‚ัƒะต, ัˆั‚ะพ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะฝัƒั†ัŒ ะฒะฐัˆัƒ ะฟั€ั‹ะปะฐะดัƒ. ะ“ัั‚ะฐ ะปั–ะบะฒั–ะดัƒะต ั€ั‹ะทั‹ะบั– ัžะทะปะพะผัƒ ัะตั€ะฒะตั€ะฐัž, ัƒั†ะตั‡ะฐะบ ะดะฐะฝั‹ั… ะฐะฑะพ ะฝะตัะฐะฝะบั†ั‹ัะฝะฐะฒะฐะฝะฐะณะฐ ะดะพัั‚ัƒะฟัƒ. ะ’ะฐัˆั‹ ั„ะฐะนะปั‹ ะทะฐัั‚ะฐัŽั†ั†ะฐ ะฒะฐัˆั‹ะผั– โ€” ะทะฐัžัั‘ะดั‹." + }, + "analytics": { + "question": "ะ’ั‹ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตั†ะต cookies ะฐะฑะพ ะฐะฝะฐะปั–ั‚ั‹ะบัƒ, ะบะฐะฑ ัะฐั‡ั‹ั†ัŒ ะทะฐ ะผะฝะพะน?", + "answer": "ะœั‹ ะดะฑะฐะตะผ ะฟั€ะฐ ะฒะฐัˆัƒ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ. BentoPDF ะฝะต ะฐะดัะพั‡ะฒะฐะต ะฟะตั€ัะฐะฝะฐะปัŒะฝัƒัŽ ั–ะฝั„ะฐั€ะผะฐั†ั‹ัŽ. ะœั‹ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตะผ Simple Analytics, ั‚ะพะปัŒะบั– ะบะฐะฑ ะฑะฐั‡ั‹ั†ัŒ ะฐะฝะฐะฝั–ะผะฝัƒัŽ ัั‚ะฐั‚ั‹ัั‚ั‹ะบัƒ ะฝะฐะฒะตะดะฒะฐะฝะฝััž. ะ“ัั‚ะฐ ะทะฝะฐั‡ั‹ั†ัŒ, ะผั‹ ะฒะตะดะฐะตะผ, ะบะพะปัŒะบั– ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบะฐัž ะฝะฐะฒะตะดะฒะฐะต ะฝะฐัˆ ัะฐะนั‚, ะฐะปะต ะฝั–ะบะพะปั– ะฝะต ะฒะตะดะฐะตะผ, ั…ั‚ะพ ะฒั‹. Simple Analytics ั†ะฐะปะบะฐะผ ะฐะดะฟะฐะฒัะดะฐะต GDPR ั– ัˆะฐะฝัƒะต ะฒะฐัˆัƒ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ." + } + }, + "testimonials": { + "title": "ะจั‚ะพ ะบะฐะถัƒั†ัŒ", + "users": "ะฝะฐัˆั‹ ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบั–", + "say": " " + }, + "support": { + "title": "ะกะฟะฐะดะฐะฑะฐะปะฐัั ะผะฐั ะฟั€ะฐั†ะฐ?", + "description": "BentoPDF โ€” ะณัั‚ะฐ ะฟั€ะฐะตะบั‚, ัั‚ะฒะพั€ะฐะฝั‹ ะฝะฐ ัะฝั‚ัƒะทั–ัะทะผะต ะท ะผัั‚ะฐะน, ะบะฐะฑ ะบะพะถะฝั‹ ะผะตัž ะฑััะฟะปะฐั‚ะฝั‹, ะฟั€ั‹ะฒะฐั‚ะฝั‹ ั– ะผะฐะณัƒั‚ะฝั‹ ะฝะฐะฑะพั€ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž PDF. ะšะฐะปั– ั‘ะฝ ะฟั€ั‹ะฝะพัั–ั†ัŒ ะฒะฐะผ ะบะฐั€ั‹ัั†ัŒ, ะฟะฐะดั‚ั€ั‹ะผะฐะนั†ะต ั€ะฐัะฟั€ะฐั†ะพัžะบัƒ. ะ”ะฐะฟะฐะผะฐะณะฐะต ะบะพะถะฝะฐั ะบะฐะฒะฐ!", + "buyMeCoffee": "ะŸะฐั‡ะฐัั‚ัƒะนั†ะต ะผัะฝะต ะบะฐะฒะฐะน" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. ะฃัะต ะฟั€ะฐะฒั‹ ะฐะฑะฐั€ะพะฝะตะฝั‹.", + "version": "ะ’ะตั€ัั–ั", + "company": "ะšะฐะผะฟะฐะฝั–ั", + "aboutUs": "ะŸั€ะฐ ะฝะฐั", + "faqLink": "ะงะฐัั‚ั‹ั ะฟั‹ั‚ะฐะฝะฝั–", + "contactUs": "ะ—ะฒัะทะฐั†ั†ะฐ ะท ะฝะฐะผั–", + "legal": "ะŸั€ะฐะฒะฐะฒะฐั ั–ะฝั„ะฐั€ะผะฐั†ั‹ั", + "termsAndConditions": "ะฃะผะพะฒั‹ ะฒั‹ะบะฐั€ั‹ัั‚ะฐะฝะฝั", + "privacyPolicy": "ะŸะฐะปั–ั‚ั‹ะบะฐ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ั–", + "followUs": "ะกะฐั‡ั‹ั†ะต ะทะฐ ะฝะฐะผั–" + }, + "merge": { + "title": "ะะฑ'ัะดะฝะฐั†ัŒ PDF", + "description": "ะะฑ'ัะดะฝะพัžะฒะฐะนั†ะต ั†ัะปั‹ั ั„ะฐะนะปั‹ ะฐะฑะพ ะฒั‹ะฑั–ั€ะฐะนั†ะต ะฟััžะฝั‹ั ัั‚ะฐั€ะพะฝะบั–, ะท ัะบั–ั… ะฑัƒะดะทะต ัะบะปะฐะดะฐั†ั†ะฐ ะฝะพะฒั‹ ะดะฐะบัƒะผะตะฝั‚.", + "fileMode": "ะ ัะถั‹ะผ ั„ะฐะนะปะฐัž", + "pageMode": "ะ ัะถั‹ะผ ัั‚ะฐั€ะพะฝะฐะบ", + "howItWorks": "ะฏะบ ะณัั‚ะฐ ะฟั€ะฐั†ัƒะต:", + "fileModeInstructions": [ + "ะะฐั†ั–ัะฝั–ั†ะต ั– ะฟะตั€ะฐั†ัะณะฝั–ั†ะต ะทะฝะฐั‡ะพะบ, ะบะฐะฑ ะทะผัะฝั–ั†ัŒ ะฟะฐั€ะฐะดะฐะบ ั„ะฐะนะปะฐัž.", + "ะฃ ะฟะพะปั– \"ะกั‚ะฐั€ะพะฝะบั–\" ะดะปั ะบะพะถะฝะฐะณะฐ ั„ะฐะนะปะฐ ะผะพะถะฝะฐ ะทะฐะดะฐั†ัŒ ะดั‹ัะฟะฐะทะพะฝั‹ (ะฝะฐะฟั€., \"1-3, 5\"), ะบะฐะฑ ะฐะฑ'ัะดะฝะฐั†ัŒ ั‚ะพะปัŒะบั– ะณัั‚ั‹ั ัั‚ะฐั€ะพะฝะบั–.", + "ะŸะฐะบั–ะฝัŒั†ะต ะฟะพะปะต \"ะกั‚ะฐั€ะพะฝะบั–\" ะฟัƒัั‚ั‹ะผ, ะบะฐะฑ ัƒะบะปัŽั‡ั‹ั†ัŒ ัƒัะต ัั‚ะฐั€ะพะฝะบั– ะณัั‚ะฐะณะฐ ั„ะฐะนะปะฐ." + ], + "pageModeInstructions": [ + "ะฃัะต ัั‚ะฐั€ะพะฝะบั– ะท ะทะฐะฟะฐะผะฟะฐะฒะฐะฝั‹ั… PDF ะฟะฐะบะฐะทะฐะฝั‹ ะฝั–ะถัะน.", + "ะŸั€ะพัั‚ะฐ ะฟะตั€ะฐั†ัะณะฝั–ั†ะต ะผั–ะฝั–ัั†ัŽั€ั‹ ัั‚ะฐั€ะพะฝะฐะบ, ะบะฐะฑ ะทะฐะดะฐั†ัŒ ะฟะฐั‚ั€ัะฑะฝั‹ ะฟะฐั€ะฐะดะฐะบ ะดะปั ะฝะพะฒะฐะณะฐ ั„ะฐะนะปะฐ." + ], + "mergePdfs": "ะะฑ'ัะดะฝะฐั†ัŒ PDF" + }, + "common": { + "page": "ะกั‚ะฐั€ะพะฝะบะฐ", + "pages": "ะกั‚ะฐั€ะพะฝะบั–", + "of": "ะท", + "download": "ะกะฟะฐะผะฟะฐะฒะฐั†ัŒ", + "cancel": "ะกะบะฐัะฐะฒะฐั†ัŒ", + "save": "ะ—ะฐั…ะฐะฒะฐั†ัŒ", + "delete": "ะ’ั‹ะดะฐะปั–ั†ัŒ", + "edit": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ", + "add": "ะ”ะฐะดะฐั†ัŒ", + "remove": "ะ’ั‹ะดะฐะปั–ั†ัŒ", + "loading": "ะ—ะฐะณั€ัƒะทะบะฐ...", + "error": "ะŸะฐะผั‹ะปะบะฐ", + "success": "ะŸะพัะฟะตั…", + "file": "ะคะฐะนะป", + "files": "ะคะฐะนะปั‹" + }, + "about": { + "hero": { + "title": "ะœั‹ ะปั–ั‡ั‹ะผ, ัˆั‚ะพ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ PDF ะฟะฐะฒั–ะฝะฝั‹ ะฑั‹ั†ัŒ", + "subtitle": "ั…ัƒั‚ะบั–ะผั–, ะฟั€ั‹ะฒะฐั‚ะฝั‹ะผั– ั– ะฑััะฟะปะฐั‚ะฝั‹ะผั–.", + "noCompromises": "ะ‘ะตะท ะบะฐะผะฟั€ะฐะผั–ัะฐัž." + }, + "mission": { + "title": "ะะฐัˆะฐ ะผั–ัั–ั", + "description": "ะ”ะฐั†ัŒ ะฝะฐะนะฑะพะปัŒัˆ ะฟะพัžะฝั‹ ะฝะฐะฑะพั€ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž PDF, ัะบั– ัˆะฐะฝัƒะต ะฒะฐัˆัƒ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ั– ะฝั–ะบะพะปั– ะฝะต ะฟะฐั‚ั€ะฐะฑัƒะต ะฐะฟะปะฐั‚ั‹. ะœั‹ ะปั–ั‡ั‹ะผ, ัˆั‚ะพ ะฝะตะฐะฑั…ะพะดะฝั‹ั ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ ะดะปั ะดะฐะบัƒะผะตะฝั‚ะฐัž ะฟะฐะฒั–ะฝะฝั‹ ะฑั‹ั†ัŒ ะดะฐัั‚ัƒะฟะฝั‹ะผั– ัžัั–ะผ, ะฟะฐัžััŽะปัŒ, ะฑะตะท ะฑะฐั€'ะตั€ะฐัž." + }, + "philosophy": { + "label": "ะะฐัˆะฐ ะฐัะฝะพัžะฝะฐั ั„ั–ะปะฐัะพั„ั–ั", + "title": "ะŸั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ะฝะฐ ะฟะตั€ัˆั‹ะผ ะผะตัั†ั‹. ะ—ะฐัžัั‘ะดั‹.", + "description": "ะฃ ัะฟะพั…ัƒ, ะบะฐะปั– ะดะฐะฝั‹ั โ€” ะณัั‚ะฐ ั‚ะฐะฒะฐั€, ะผั‹ ะฒั‹ะฑั–ั€ะฐะตะผ ั–ะฝัˆั‹ ัˆะปัั…. ะฃัั ะฐะฟั€ะฐั†ะพัžะบะฐ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž BentoPDF ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ะปะฐะบะฐะปัŒะฝะฐ ัž ะฒะฐัˆั‹ะผ ะฑั€ะฐัžะทะตั€ั‹. ะ“ัั‚ะฐ ะทะฝะฐั‡ั‹ั†ัŒ, ัˆั‚ะพ ะฒะฐัˆั‹ ั„ะฐะนะปั‹ ะฝั–ะบะพะปั– ะฝะต ั‚ั€ะฐะฟะปััŽั†ัŒ ะฝะฐ ะฝะฐัˆั‹ ัะตั€ะฒะตั€ั‹, ะผั‹ ะฝะต ะฑะฐั‡ั‹ะผ ะฒะฐัˆั‹ั… ะดะฐะบัƒะผะตะฝั‚ะฐัž ั– ะฝะต ะฐะดัะพั‡ะฒะฐะตะผ, ัˆั‚ะพ ะฒั‹ ั€ะพะฑั–ั†ะต. ะ’ะฐัˆั‹ ะดะฐะบัƒะผะตะฝั‚ั‹ ะทะฐัั‚ะฐัŽั†ั†ะฐ ั†ะฐะปะบะฐะผ ั– ะฑะตะทัƒะผะพัžะฝะฐ ะฟั€ั‹ะฒะฐั‚ะฝั‹ะผั–. ะ“ัั‚ะฐ ะฝะต ะฟั€ะพัั‚ะฐ ั„ัƒะฝะบั†ั‹ั โ€” ะณัั‚ะฐ ะฝะฐัˆ ะฟะฐะดะผัƒั€ะฐะบ." + }, + "whyBentopdf": { + "title": "ะงะฐะผัƒ", + "speed": { + "title": "ะกั‚ะฒะพั€ะฐะฝั‹ ะดะปั ั…ัƒั‚ะบะฐัั†ั–", + "description": "ะะต ั‚ั€ัะฑะฐ ั‡ะฐะบะฐั†ัŒ ะทะฐะฟะฐะผะฟะพัžะฒะฐะฝะฝั ะฝะฐ ัะตั€ะฒะตั€. ะะฟั€ะฐั†ะพัžะฒะฐัŽั‡ั‹ ั„ะฐะนะปั‹ ะฝะตะฟะฐัั€ัะดะฝะฐ ัž ะฒะฐัˆั‹ะผ ะฑั€ะฐัžะทะตั€ั‹ ะท ะดะฐะฟะฐะผะพะณะฐะน ััƒั‡ะฐัะฝั‹ั… ะฒัะฑ-ั‚ัั…ะฝะฐะปะพะณั–ะน, ั‚ะฐะบั–ั… ัะบ WebAssembly, ะผั‹ ะฟั€ะฐะฟะฐะฝัƒะตะผ ะฝะตะฟะฐั€ะฐัžะฝะฐะปัŒะฝัƒัŽ ั…ัƒั‚ะบะฐัั†ัŒ ะดะปั ัžัั–ั… ะฝะฐัˆั‹ั… ั–ะฝัั‚ั€ัƒะผะตะฝั‚ะฐัž." + }, + "free": { + "title": "ะฆะฐะปะบะฐะผ ะฑััะฟะปะฐั‚ะฝะฐ", + "description": "ะ‘ะตะท ะฟั€ะพะฑะฝั‹ั… ะฒะตั€ัั–ะน, ะฟะฐะดะฟั–ัะฐะบ, ัั…ะฐะฒะฐะฝั‹ั… ะฟะปะฐั†ัะถะพัž ั– ะฑะตะท \"ะฟั€ัะผั–ัƒะผ\" ั„ัƒะฝะบั†ั‹ะน. ะœั‹ ะฒะตั€ั‹ะผ, ัˆั‚ะพ ะผะฐะณัƒั‚ะฝั‹ั ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ PDF ะฟะฐะฒั–ะฝะฝั‹ ะฑั‹ั†ัŒ ะณั€ะฐะผะฐะดัะบะฐะน ะบะฐั€ั‹ัั†ัŽ, ะฐ ะฝะต ั†ัะฝั‚ั€ะฐะผ ะฟั€ั‹ะฑั‹ั‚ะบัƒ." + }, + "noAccount": { + "title": "ะะต ะฟะฐั‚ั€ัะฑะฝั‹ ัžะปั–ะบะพะฒั‹ ะทะฐะฟั–ั", + "description": "ะŸะฐั‡ั‹ะฝะฐะนั†ะต ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐั†ัŒ ะปัŽะฑั‹ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ ะฐะดั€ะฐะทัƒ. ะะฐะผ ะฝะต ะฟะฐั‚ั€ัะฑะฝั‹ั ะฒะฐัˆะฐ ัะปะตะบั‚ั€ะพะฝะฝะฐั ะฟะพัˆั‚ะฐ, ะฟะฐั€ะพะปัŒ ะฐะฑะพ ะฐัะฐะฑั–ัั‚ั‹ั ะดะฐะฝั‹ั. ะŸั€ะฐั†ะพัžะฝั‹ ะฟั€ะฐั†ัั ะฟะฐะฒั–ะฝะตะฝ ะฑั‹ั†ัŒ ะณะปะฐะดะบั–ะผ ั– ะฐะฝะฐะฝั–ะผะฝั‹ะผ." + }, + "openSource": { + "title": "ะ”ัƒั… ะฐะดะบั€ั‹ั‚ะฐะณะฐ ะบะพะดะฐ", + "description": "ะ—ะฐะดัƒะผะฐะฝั‹ ั– ัั‚ะฒะพั€ะฐะฝั‹ ะฟั€ะฐะทั€ั‹ัั‚ั‹ะผ. ะœั‹ ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะตะผ ะฒั‹ะดะฐั‚ะฝั‹ั ะฑั–ะฑะปั–ัั‚ัะบั– ะท ะฐะดะบั€ั‹ั‚ั‹ะผ ะทั‹ั…ะพะดะฝั‹ะผ ะบะพะดะฐะผ, ั‚ะฐะบั–ั ัะบ PDF-lib ั– PDF.js, ั– ะฒะตั€ั‹ะผ ัƒ ะฝะฐะผะฐะณะฐะฝะฝั– ััƒะฟะพะปัŒะฝะฐัั†ั– ะทั€ะฐะฑั–ั†ัŒ ะผะฐะณัƒั‚ะฝั‹ั ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹ ะดะฐัั‚ัƒะฟะฝั‹ะผั– ัžัั–ะผ." + } + }, + "cta": { + "title": "ะ“ะฐั‚ะพะฒั‹ ะฟะฐั‡ะฐั†ัŒ?", + "description": "ะ”ะฐะปัƒั‡ะฐะนั†ะตัั ะดะฐ ั‚ั‹ััั‡ ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบะฐัž, ัะบั–ั ะดะฐะฒัั€ะฐัŽั†ัŒ BentoPDF ัะฒะฐะต ัˆั‚ะพะดะทั‘ะฝะฝั‹ั ะฟะฐั‚ั€ัะฑั‹ ะท ะดะฐะบัƒะผะตะฝั‚ะฐะผั–. ะะดั‡ัƒะนั†ะต ั€ะพะทะฝั–ั†ัƒ, ัะบัƒัŽ ะดะฐัŽั†ัŒ ะฟั€ั‹ะฒะฐั‚ะฝะฐัั†ัŒ ั– ะฟั€ะฐะดัƒะบั†ั‹ะนะฝะฐัั†ัŒ.", + "button": "ะŸะฐะณะปัะดะทะตั†ัŒ ัƒัะต ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹" + } + }, + "contact": { + "title": "ะ—ะฒัะทะฐั†ั†ะฐ ะท ะฝะฐะผั–", + "subtitle": "ะœั‹ ะฑัƒะดะทะตะผ ั€ะฐะดั‹ ะฟะฐั‡ัƒั†ัŒ ะฒะฐัˆะฐ ะผะตั€ะบะฐะฒะฐะฝะฝะต. ะšะฐะปั– ัž ะฒะฐั ั‘ัั†ัŒ ะฟั‹ั‚ะฐะฝะฝะต, ะฒะพะดะณัƒะบ ะฐะฑะพ ะฟั€ะฐะฟะฐะฝะพะฒะฐ ั„ัƒะฝะบั†ั‹ั–, ะฝะต ัะฐั€ะพะผะตะนั†ะตัั ะทะฒัั€ั‚ะฐั†ั†ะฐ.", + "email": "ะ’ั‹ ะผะพะถะฐั†ะต ะฝะฐะฟั–ัะฐั†ัŒ ะฝะฐะผ ะฝะฐ email:" + }, + "licensing": { + "title": "ะ›ั–ั†ัะฝะทั–ั ะฝะฐ", + "subtitle": "ะ’ั‹ะฑะตั€ั‹ั†ะต ะปั–ั†ัะฝะทั–ัŽ, ัะบะฐั ะฟะฐะดั‹ั…ะพะดะทั–ั†ัŒ ะฒะฐะผ." + }, + "multiTool": { + "uploadPdfs": "ะ—ะฐะฟะฐะผะฟะฐะฒะฐั†ัŒ PDF", + "upload": "ะ—ะฐะฟะฐะผะฟะฐะฒะฐั†ัŒ", + "addBlankPage": "ะ”ะฐะดะฐั†ัŒ ะฟัƒัั‚ัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ", + "edit": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ:", + "undo": "ะะดั€ะฐะฑั–ั†ัŒ", + "redo": "ะฃะทะฝะฐะฒั–ั†ัŒ", + "reset": "ะกะบั–ะฝัƒั†ัŒ", + "selection": "ะ’ั‹ะปัƒั‡ัะฝะฝะต:", + "selectAll": "ะ’ั‹ะปัƒั‡ั‹ั†ัŒ ัƒัั‘", + "deselectAll": "ะ—ะฝัั†ัŒ ะฒั‹ะปัƒั‡ัะฝะฝะต", + "rotate": "ะŸะฐะฒะฐั€ะพั‚:", + "rotateLeft": "ะะฐะปะตะฒะฐ", + "rotateRight": "ะะฐะฟั€ะฐะฒะฐ", + "transform": "ะŸะตั€ะฐัžั‚ะฒะฐั€ัะฝะฝะต:", + "duplicate": "ะ”ัƒะฑะปัะฒะฐั†ัŒ", + "split": "ะŸะฐะดะทัะปั–ั†ัŒ", + "clear": "ะั‡ั‹ัั†ั–ั†ัŒ:", + "delete": "ะ’ั‹ะดะฐะปั–ั†ัŒ", + "download": "ะกะฟะฐะผะฟะฐะฒะฐั†ัŒ:", + "downloadSelected": "ะกะฟะฐะผะฟะฐะฒะฐั†ัŒ ะฒั‹ะฑั€ะฐะฝะฐะต", + "exportPdf": "ะญะบัะฟะฐั€ั‚ะฐะฒะฐั†ัŒ PDF", + "uploadPdfFiles": "ะ’ั‹ะฑั€ะฐั†ัŒ PDF ั„ะฐะนะปั‹", + "dragAndDrop": "ะŸะตั€ะฐั†ัะณะฝั–ั†ะต PDF ั„ะฐะนะปั‹ ััŽะดั‹ ะฐะฑะพ ะฝะฐั†ั–ัะฝั–ั†ะต, ะบะฐะฑ ะฒั‹ะฑั€ะฐั†ัŒ", + "selectFiles": "ะ’ั‹ะฑั€ะฐั†ัŒ ั„ะฐะนะปั‹", + "renderingPages": "ะะฟั€ะฐั†ะพัžะบะฐ ัั‚ะฐั€ะพะฝะฐะบ...", + "actions": { + "duplicatePage": "ะ”ัƒะฑะปัะฒะฐั†ัŒ ะณัั‚ัƒ ัั‚ะฐั€ะพะฝะบัƒ", + "deletePage": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะณัั‚ัƒ ัั‚ะฐั€ะพะฝะบัƒ", + "insertPdf": "ะฃัั‚ะฐะฒั–ั†ัŒ PDF ะฟะฐัะปั ะณัั‚ะฐะน ัั‚ะฐั€ะพะฝะบั–", + "toggleSplit": "ะŸะตั€ะฐะบะปัŽั‡ั‹ั†ัŒ ะฟะฐะดะทะตะป ะฟะฐัะปั ะณัั‚ะฐะน ัั‚ะฐั€ะพะฝะบั–" + }, + "pleaseWait": "ะŸะฐั‡ะฐะบะฐะนั†ะต", + "pagesRendering": "ะกั‚ะฐั€ะพะฝะบั– ััˆั‡ั ะฐะฟั€ะฐั†ะพัžะฒะฐัŽั†ั†ะฐ. ะŸะฐั‡ะฐะบะฐะนั†ะต...", + "noPagesSelected": "ะกั‚ะฐั€ะพะฝะบั– ะฝะต ะฒั‹ะฑั€ะฐะฝั‹", + "selectOnePage": "ะ’ั‹ะฑะตั€ั‹ั†ะต ั…ะฐั†ั ะฑ ะฐะดะฝัƒ ัั‚ะฐั€ะพะฝะบัƒ ะดะปั ัะฟะฐะผะฟะพัžะฒะฐะฝะฝั.", + "noPages": "ะัะผะฐ ัั‚ะฐั€ะพะฝะฐะบ", + "noPagesToExport": "ะัะผะฐ ัั‚ะฐั€ะพะฝะฐะบ ะดะปั ัะบัะฟะฐั€ั‚ัƒ.", + "renderingTitle": "ะะฟั€ะฐั†ะพัžะบะฐ ะฟะตั€ะฐะดะฟั€ะฐะณะปัะดะฐัž ัั‚ะฐั€ะพะฝะฐะบ", + "errorRendering": "ะะต ัžะดะฐะปะพัั ะฐะฟั€ะฐั†ะฐะฒะฐั†ัŒ ะผั–ะฝั–ัั†ัŽั€ั‹ ัั‚ะฐั€ะพะฝะฐะบ", + "error": "ะŸะฐะผั‹ะปะบะฐ", + "failedToLoad": "ะะต ัžะดะฐะปะพัั ะทะฐะณั€ัƒะทั–ั†ัŒ" + } +} diff --git a/public/locales/be/tools.json b/public/locales/be/tools.json new file mode 100644 index 0000000..1db6633 --- /dev/null +++ b/public/locales/be/tools.json @@ -0,0 +1,533 @@ +{ + "categories": { + "popularTools": "ะŸะฐะฟัƒะปัั€ะฝั‹ั ั–ะฝัั‚ั€ัƒะผะตะฝั‚ั‹", + "editAnnotate": "ะ ัะดะฐะณะฐะฒะฐะฝะฝะต ั– ะฐะฝะฐั‚ะฐั†ั‹ั–", + "convertToPdf": "ะšะฐะฝะฒะตั€ั‚ะฐั†ั‹ั ัž PDF", + "convertFromPdf": "ะšะฐะฝะฒะตั€ั‚ะฐั†ั‹ั ะท PDF", + "organizeManage": "ะั€ะณะฐะฝั–ะทะฐั†ั‹ั ั– ะบั–ั€ะฐะฒะฐะฝะฝะต", + "optimizeRepair": "ะะฟั‚ั‹ะผั–ะทะฐั†ั‹ั ั– ะฐะดะฝะฐัžะปะตะฝะฝะต", + "securePdf": "ะ‘ััะฟะตะบะฐ PDF" + }, + "pdfMultiTool": { + "name": "ะœัƒะปัŒั‚ั‹ั–ะฝัั‚ั€ัƒะผะตะฝั‚ PDF", + "subtitle": "ะะฑ'ัะดะฝะฐั†ัŒ, ะŸะฐะดะทัะปั–ั†ัŒ, ะั€ะณะฐะฝั–ะทะฐะฒะฐั†ัŒ, ะ’ั‹ะดะฐะปั–ั†ัŒ, ะŸะฐะฒัั€ะฝัƒั†ัŒ, ะ”ะฐะดะฐั†ัŒ ะฟัƒัั‚ั‹ั ัั‚ะฐั€ะพะฝะบั–, ะ’ั‹ะฝัั†ัŒ ั– ะ”ัƒะฑะปัะฒะฐั†ัŒ ัƒ ะฐะดะทั–ะฝั‹ะผ ั–ะฝั‚ัั€ั„ะตะนัะต." + }, + "mergePdf": { + "name": "ะะฑ'ัะดะฝะฐั†ัŒ PDF", + "subtitle": "ะะฑ'ัะดะฝะฐั†ัŒ ะฝะตะบะฐะปัŒะบั– PDF ัƒ ะฐะดะทั–ะฝ ั„ะฐะนะป. ะ—ะฐะบะปะฐะดะบั– ะทะฐั…ะพัžะฒะฐัŽั†ั†ะฐ." + }, + "splitPdf": { + "name": "ะŸะฐะดะทัะปั–ั†ัŒ PDF", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ะดั‹ัะฟะฐะทะพะฝ ัั‚ะฐั€ะพะฝะฐะบ ัƒ ะฝะพะฒั‹ PDF." + }, + "compressPdf": { + "name": "ะกั†ั–ัะฝัƒั†ัŒ PDF", + "subtitle": "ะ—ะผะตะฝัˆั‹ั†ัŒ ะฟะฐะผะตั€ ั„ะฐะนะปะฐ PDF.", + "algorithmLabel": "ะะปะณะฐั€ั‹ั‚ะผ ัั†ั–ัะบะฐะฝะฝั", + "condense": "Condense (ะ ัะบะฐะผะตะฝะดัƒะตั†ั†ะฐ)", + "photon": "Photon (ะ”ะปั PDF ะท ะฒัะปั–ะบะฐะน ะบะพะปัŒะบะฐัั†ัŽ ั„ะพั‚ะฐ)", + "condenseInfo": "Condense ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะต ะฟั€ะฐััƒะฝัƒั‚ะฐะต ัั†ั–ัะบะฐะฝะฝะต: ะฒั‹ะดะฐะปัะต ะปั–ัˆะฝัะต, ะฐะฟั‚ั‹ะผั–ะทัƒะต ะฒั–ะดะฐั€ั‹ัั‹, ะฟะฐะดะฝะฐะฑะพั€ั‹ ัˆั€ั‹ั„ั‚ะพัž. ะะฐะนะปะตะฟัˆ ะฟะฐััƒะต ะดะปั ะฑะพะปัŒัˆะฐัั†ั– PDF.", + "photonInfo": "Photon ะฟะตั€ะฐั‚ะฒะฐั€ะฐะต ัั‚ะฐั€ะพะฝะบั– ัž ะฒั–ะดะฐั€ั‹ัั‹. ะ”ะปั PDF ะท ะฒัะปั–ะบะฐะน ะบะพะปัŒะบะฐัั†ัŽ ั„ะพั‚ะฐ ะฐะฑะพ ัะบะฐะฝั–ั€ะฐะฒะฐะฝั‹ั… PDF.", + "photonWarning": "ะŸะฐะฟัั€ัะดะถะฐะฝะฝะต: ัั‚ะฐะฝะต ะฝะตะผะฐะณั‡ั‹ะผะฐ ะฒั‹ะปัƒั‡ั‹ั†ัŒ ั‚ัะบัั‚, ั– ะฟะตั€ะฐัั‚ะฐะฝัƒั†ัŒ ะฟั€ะฐั†ะฐะฒะฐั†ัŒ ัะฟะฐัั‹ะปะบั–.", + "levelLabel": "ะฃะทั€ะพะฒะตะฝัŒ ัั†ั–ัะบะฐะฝะฝั", + "light": "ะ›ั‘ะณะบั– (ะ—ะฐั…ะฐะฒะฐะฝะฝะต ัะบะฐัั†ั–)", + "balanced": "ะ—ะฑะฐะปะฐะฝัะฐะฒะฐะฝั‹ (ะ ัะบะฐะผะตะฝะดัƒะตั†ั†ะฐ)", + "aggressive": "ะะณั€ััั–ัžะฝั‹ (ะœะตะฝัˆั‹ั ั„ะฐะนะปั‹)", + "extreme": "ะญะบัั‚ั€ัะผะฐะปัŒะฝั‹ (ะœะฐะบัั–ะผะฐะปัŒะฝะฐะต ัั†ั–ัะบะฐะฝะฝะต)", + "grayscale": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ ะณั€ะฐะดะฐั†ั‹ั– ัˆัั€ะฐะณะฐ", + "grayscaleHint": "ะŸะฐะผัะฝัˆะฐะต ะฟะฐะผะตั€ ั„ะฐะนะปะฐ, ะฒั‹ะดะฐะปััŽั‡ั‹ ั–ะฝั„ะฐั€ะผะฐั†ั‹ัŽ ะฟั€ะฐ ะบะพะปะตั€", + "customSettings": "ะšะฐั€ั‹ัั‚ะฐะปัŒะฝั–ั†ะบั–ั ะฝะฐะปะฐะดั‹", + "customSettingsHint": "ะ”ะฐะบะปะฐะดะฝะฐั ะฝะฐัั‚ั€ะพะนะบะฐ ะฟะฐั€ะฐะผะตั‚ั€ะฐัž ัั†ั–ัะบะฐะฝะฝั:", + "outputQuality": "ะฏะบะฐัั†ัŒ ะฒั‹ะฒะฐะดัƒ", + "resizeImagesTo": "ะ—ะผัะฝั–ั†ัŒ ะฟะฐะผะตั€ ะฒั–ะดะฐั€ั‹ัะฐัž ะดะฐ", + "onlyProcessAbove": "ะะฟั€ะฐั†ะพัžะฒะฐั†ัŒ ั‚ะพะปัŒะบั– ะฑะพะปัŒัˆั‹ั ะทะฐ", + "removeMetadata": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะผะตั‚ะฐะดะฐะฝั‹ั", + "subsetFonts": "ะŸะฐะดะฝะฐะฑะพั€ ัˆั€ั‹ั„ั‚ะพัž (ะฒั‹ะดะฐะปั–ั†ัŒ ัั–ะผะฒะฐะปั‹, ัะบั–ั ะฝะต ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐัŽั†ั†ะฐ)", + "removeThumbnails": "ะ’ั‹ะดะฐะปั–ั†ัŒ ัƒะฑัƒะดะฐะฒะฐะฝั‹ั ะผั–ะฝั–ัั†ัŽั€ั‹", + "compressButton": "ะกั†ั–ัะฝัƒั†ัŒ PDF" + }, + "pdfEditor": { + "name": "ะ ัะดะฐะบั‚ะฐั€ PDF", + "subtitle": "ะะฝะฐั‚ะฐะฒะฐั†ัŒ, ะฒั‹ะปัƒั‡ั‹ั†ัŒ, ะทะฐั†ัะผะฝั–ั†ัŒ, ะดะฐะดะฐั†ัŒ ั„ั–ะณัƒั€ั‹/ะฒั–ะดะฐั€ั‹ัั‹, ะบะฐะผะตะฝั‚ะฐั€ั‹ั–, ะฟะพัˆัƒะบ ั– ะฟั€ะฐะณะปัะด PDF." + }, + "jpgToPdf": { + "name": "JPG ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฒั–ะดะฐั€ั‹ัะฐัž JPG, JPEG ั– JPEG2000 (JP2/JPX)." + }, + "signPdf": { + "name": "ะŸะฐะดะฟั–ัะฐั†ัŒ PDF", + "subtitle": "ะะฐั€ั‹ัะฐะฒะฐั†ัŒ, ะฝะฐะฑั€ะฐั†ัŒ ะฐะฑะพ ะทะฐะฟะฐะผะฟะฐะฒะฐั†ัŒ ัะฒะพะน ะฟะพะดะฟั–ั." + }, + "cropPdf": { + "name": "ะะฑั€ัะทะฐั†ัŒ PDF", + "subtitle": "ะะฑั€ัะทะฐั†ัŒ ะฟะฐะปั– ะบะพะถะฝะฐะน ัั‚ะฐั€ะพะฝะบั– PDF." + }, + "extractPages": { + "name": "ะ’ั‹ะฝัั†ัŒ ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะ—ะฐั…ะฐะฒะฐั†ัŒ ะฒั‹ะฑั€ะฐะฝั‹ั ัั‚ะฐั€ะพะฝะบั– ัž ะฝะพะฒั‹ะผ ั„ะฐะนะปะต." + }, + "duplicateOrganize": { + "name": "ะ”ัƒะฑะปัะฒะฐั†ัŒ ั– ะฐั€ะณะฐะฝั–ะทะฐะฒะฐั†ัŒ", + "subtitle": "ะ”ัƒะฑะปัะฒะฐั†ัŒ, ะทะผัะฝั–ั†ัŒ ะฟะฐั€ะฐะดะฐะบ ั– ะฒั‹ะดะฐะปั–ั†ัŒ ัั‚ะฐั€ะพะฝะบั–." + }, + "deletePages": { + "name": "ะ’ั‹ะดะฐะปั–ั†ัŒ ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะท ะดะฐะบัƒะผะตะฝั‚ะฐ ะฟััžะฝั‹ั ัั‚ะฐั€ะพะฝะบั–." + }, + "editBookmarks": { + "name": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ ะทะฐะบะปะฐะดะบั–", + "subtitle": "ะ”ะฐะดะฐั†ัŒ, ั€ัะดะฐะณะฐะฒะฐั†ัŒ, ั–ะผะฟะฐั€ั‚ะฐะฒะฐั†ัŒ, ะฒั‹ะดะฐะปั–ั†ัŒ ั– ะฒั‹ะฝัั†ัŒ ะทะฐะบะปะฐะดะบั– PDF." + }, + "tableOfContents": { + "name": "ะ—ะผะตัั‚", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ะท ะทะฐะบะปะฐะดะฐะบ PDF ัั‚ะฐั€ะพะฝะบัƒ ะทะผะตัั‚ัƒ." + }, + "pageNumbers": { + "name": "ะัƒะผะฐั€ั‹ ัั‚ะฐั€ะพะฝะฐะบ", + "subtitle": "ะฃัั‚ะฐะฒั–ั†ัŒ ัƒ ะดะฐะบัƒะผะตะฝั‚ ะฝัƒะผะฐั€ั‹ ัั‚ะฐั€ะพะฝะฐะบ." + }, + "addWatermark": { + "name": "ะ”ะฐะดะฐั†ัŒ ะฒะฐะดะทัะฝั‹ ะทะฝะฐะบ", + "subtitle": "ะะฐะบะปะฐัั†ั– ะฝะฐ ัั‚ะฐั€ะพะฝะบั– PDF ั‚ัะบัั‚ ะฐะฑะพ ะฒั–ะดะฐั€ั‹ั." + }, + "headerFooter": { + "name": "ะ’ะตั€ั…ะฝั– ั– ะฝั–ะถะฝั– ะบะฐะปะฐะฝั‚ั‹ั‚ัƒะป", + "subtitle": "ะ”ะฐะดะฐั†ัŒ ั‚ัะบัั‚ ัƒะฒะตั€ัะต ั– ัžะฝั–ะทะต ัั‚ะฐั€ะพะฝะฐะบ." + }, + "invertColors": { + "name": "ะ†ะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะปะตั€ั‹", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ะฒะตั€ัั–ัŽ PDF ัƒ \"ั†ั‘ะผะฝะฐะน ั‚ัะผะต\"." + }, + "backgroundColor": { + "name": "ะšะพะปะตั€ ั„ะพะฝัƒ", + "subtitle": "ะ—ะผัะฝั–ั†ัŒ ะบะพะปะตั€ ั„ะพะฝัƒ PDF." + }, + "changeTextColor": { + "name": "ะ—ะผัะฝั–ั†ัŒ ะบะพะปะตั€ ั‚ัะบัั‚ัƒ", + "subtitle": "ะ—ะผัะฝั–ั†ัŒ ะบะพะปะตั€ ั‚ัะบัั‚ัƒ ัž PDF." + }, + "addStamps": { + "name": "ะ”ะฐะดะฐั†ัŒ ัˆั‚ะฐะผะฟั‹", + "subtitle": "ะ”ะฐะดะฐั†ัŒ ัƒ PDF ัˆั‚ะฐะผะฟั‹-ะฒั–ะดะฐั€ั‹ัั‹ ะฟั€ะฐะท ะฟะฐะฝัะปัŒ ะฐะฝะฐั‚ะฐั†ั‹ะน.", + "usernameLabel": "ะ†ะผั ะดะปั ัˆั‚ะฐะผะฟะฐ", + "usernamePlaceholder": "ะฃะฒัะดะทั–ั†ะต ัะฒะฐั‘ ั–ะผั (ะดะปั ัˆั‚ะฐะผะฟะฐัž)", + "usernameHint": "ะ“ัั‚ะฐ ั–ะผั ะท'ัะฒั–ั†ั†ะฐ ะฝะฐ ัั‚ะฒะพั€ะฐะฝั‹ั… ะฒะฐะผั– ัˆั‚ะฐะผะฟะฐั…." + }, + "removeAnnotations": { + "name": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะฐะฝะฐั‚ะฐั†ั‹ั–", + "subtitle": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะบะฐะผะตะฝั‚ะฐั€ั‹ั–, ะฒั‹ะปัƒั‡ัะฝะฝั– ั– ัะฟะฐัั‹ะปะบั–." + }, + "pdfFormFiller": { + "name": "ะ—ะฐะฟะพัžะฝั–ั†ัŒ ั„ะพั€ะผัƒ PDF", + "subtitle": "ะ—ะฐะฟะพัžะฝั–ั†ัŒ ั„ะพั€ะผัƒ ะฝะตะฟะฐัั€ัะดะฝะฐ ัž ะฑั€ะฐัžะทะตั€ั‹. ะขะฐะบัะฐะผะฐ ะฟะฐะดั‚ั€ั‹ะผะปั–ะฒะฐัŽั†ั†ะฐ ั„ะพั€ะผั‹ XFA." + }, + "createPdfForm": { + "name": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ั„ะพั€ะผัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ะทะฐะฟะฐัžะฝัะปัŒะฝั‹ั ั„ะพั€ะผั‹ PDF ะท ั‚ัะบัั‚ะฐะฒั‹ะผั– ะฟะฐะปัะผั–, ัะบั–ั ะผะพะถะฝะฐ ะฟะตั€ะฐั†ัะณะฒะฐั†ัŒ." + }, + "removeBlankPages": { + "name": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะฟัƒัั‚ั‹ั ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะัžั‚ะฐะผะฐั‚ั‹ั‡ะฝะฐ ะฒั‹ัะฒั–ั†ัŒ ั– ะฒั‹ะดะฐะปั–ั†ัŒ ะฟัƒัั‚ั‹ั ัั‚ะฐั€ะพะฝะบั–." + }, + "imageToPdf": { + "name": "ะ’ั–ะดะฐั€ั‹ัั‹ ัž PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP ัƒ PDF." + }, + "pngToPdf": { + "name": "PNG ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž PNG." + }, + "webpToPdf": { + "name": "WebP ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž WebP." + }, + "svgToPdf": { + "name": "SVG ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž SVG." + }, + "bmpToPdf": { + "name": "BMP ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž BMP." + }, + "heicToPdf": { + "name": "HEIC ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž HEIC." + }, + "tiffToPdf": { + "name": "TIFF ัƒ PDF", + "subtitle": "ะกั‚ะฒะฐั€ั‹ั†ัŒ PDF ะท ะฐะดะฝะฐะณะพ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั–ั… ะฒั–ะดะฐั€ั‹ัะฐัž TIFF." + }, + "textToPdf": { + "name": "ะขัะบัั‚ ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะทะฒั‹ั‡ะฐะนะฝั‹ ั‚ัะบัั‚ะฐะฒั‹ ั„ะฐะนะป ัƒ PDF." + }, + "jsonToPdf": { + "name": "JSON ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ JSON ัƒ ั„ะฐั€ะผะฐั‚ PDF." + }, + "pdfToJpg": { + "name": "PDF ัƒ JPG", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะฒั–ะดะฐั€ั‹ั JPG." + }, + "pdfToPng": { + "name": "PDF ัƒ PNG", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะฒั–ะดะฐั€ั‹ั PNG." + }, + "pdfToWebp": { + "name": "PDF ัƒ WebP", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะฒั–ะดะฐั€ั‹ั WebP." + }, + "pdfToBmp": { + "name": "PDF ัƒ BMP", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะฒั–ะดะฐั€ั‹ั BMP." + }, + "pdfToTiff": { + "name": "PDF ัƒ TIFF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะฒั–ะดะฐั€ั‹ั TIFF." + }, + "pdfToGreyscale": { + "name": "PDF ัƒ ะณั€ะฐะดะฐั†ั‹ั– ัˆัั€ะฐะณะฐ", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒัะต ะบะพะปะตั€ั‹ ัž ั‡ะพั€ะฝะฐ-ะฑะตะปั‹ั." + }, + "pdfToJson": { + "name": "PDF ัƒ JSON", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ PDF ัƒ ั„ะฐั€ะผะฐั‚ JSON." + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "ะ”ะฐะดะฐั†ัŒ ัƒ PDF ะผะฐะณั‡ั‹ะผะฐัั†ั– ะฟะพัˆัƒะบัƒ ั– ะบะฐะฟั–ั€ะฐะฒะฐะฝะฝั." + }, + "alternateMix": { + "name": "ะงะฐั€ะณะฐะฒะฐั†ัŒ ั– ะทะผััˆะฐั†ัŒ ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะะฑ'ัะดะฝะฐั†ัŒ PDF, ั‡ะฐั€ะณัƒัŽั‡ั‹ ัั‚ะฐั€ะพะฝะบั– ะท ะฐัะพะฑะฝั‹ั… PDF. ะ—ะฐะบะปะฐะดะบั– ะทะฐั…ะพัžะฒะฐัŽั†ั†ะฐ." + }, + "addAttachments": { + "name": "ะ”ะฐะดะฐั†ัŒ ะดะฐะปัƒั‡ัะฝะฝั–", + "subtitle": "ะฃะฑัƒะดะฐะฒะฐั†ัŒ ะฐะดะทั–ะฝ ะฐะฑะพ ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž ัƒ PDF." + }, + "extractAttachments": { + "name": "ะ’ั‹ะฝัั†ัŒ ะดะฐะปัƒั‡ัะฝะฝั–", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ัƒัะต ัžะฑัƒะดะฐะฒะฐะฝั‹ั ั„ะฐะนะปั‹ ะท PDF ัะบ ZIP." + }, + "editAttachments": { + "name": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ ะดะฐะปัƒั‡ัะฝะฝั–", + "subtitle": "ะŸั€ะฐะณะปะตะดะทะตั†ัŒ ะฐะฑะพ ะฒั‹ะดะฐะปั–ั†ัŒ ะดะฐะปัƒั‡ัะฝะฝั– ัž PDF." + }, + "dividePages": { + "name": "ะŸะฐะดะทัะปั–ั†ัŒ ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะŸะฐะดะทัะปั–ั†ัŒ ัั‚ะฐั€ะพะฝะบั– ะณะฐั€ั‹ะทะฐะฝั‚ะฐะปัŒะฝะฐ ะฐะฑะพ ะฒะตั€ั‚ั‹ะบะฐะปัŒะฝะฐ." + }, + "addBlankPage": { + "name": "ะ”ะฐะดะฐั†ัŒ ะฟัƒัั‚ัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ", + "subtitle": "ะฃัั‚ะฐะฒั–ั†ัŒ ะฟัƒัั‚ัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ ัž ะปัŽะฑั‹ะผ ะผะตัั†ั‹ PDF." + }, + "reversePages": { + "name": "ะะดะฒะฐั€ะพั‚ะฝั‹ ะฟะฐั€ะฐะดะฐะบ ัั‚ะฐั€ะพะฝะฐะบ", + "subtitle": "ะ—ะผัะฝั–ั†ัŒ ะฟะฐั€ะฐะดะฐะบ ัƒัั–ั… ัั‚ะฐั€ะพะฝะฐะบ ัƒ ะดะฐะบัƒะผะตะฝั†ะต ะฝะฐ ะฐะดะฒะฐั€ะพั‚ะฝั‹." + }, + "rotatePdf": { + "name": "ะŸะฐะฒัั€ะฝัƒั†ัŒ PDF", + "subtitle": "ะŸะฐะฒัั€ะฝัƒั†ัŒ ัั‚ะฐั€ะพะฝะบั– ะฝะฐ 90 ะณั€ะฐะดัƒัะฐัž." + }, + "rotateCustom": { + "name": "ะŸะฐะฒัั€ะฝัƒั†ัŒ ะฝะฐ ะทะฐะดะฐะดะทะตะฝั‹ ะฒัƒะณะฐะป", + "subtitle": "ะŸะฐะฒัั€ะฝัƒั†ัŒ ัั‚ะฐั€ะพะฝะบั– ะฝะฐ ะปัŽะฑั‹ ะฒัƒะณะฐะป." + }, + "nUpPdf": { + "name": "N-Up PDF", + "subtitle": "ะ ะฐะทะผััั†ั–ั†ัŒ ะฝะตะบะฐะปัŒะบั– ัั‚ะฐั€ะพะฝะฐะบ ะฝะฐ ะฐะดะฝั‹ะผ ะฐั€ะบัƒัˆั‹." + }, + "combineToSinglePage": { + "name": "ะะฑ'ัะดะฝะฐั†ัŒ ัƒ ะฐะดะฝัƒ ัั‚ะฐั€ะพะฝะบัƒ", + "subtitle": "ะกัˆั‹ั†ัŒ ัƒัะต ัั‚ะฐั€ะพะฝะบั– ัž ะฐะดะฝัƒ ะฑะตัะฟะตั€ะฐะฟั‹ะฝะฝัƒัŽ ะฟั€ะฐะณะพั€ั‚ะบัƒ." + }, + "viewMetadata": { + "name": "ะŸั€ะฐะณะปัะดะทะตั†ัŒ ะผะตั‚ะฐะดะฐะฝั‹ั", + "subtitle": "ะŸั€ะฐะณะปัะดะทะตั†ัŒ ัั…ะฐะฒะฐะฝั‹ั ัžะปะฐัั†ั–ะฒะฐัั†ั– PDF." + }, + "editMetadata": { + "name": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ ะผะตั‚ะฐะดะฐะฝั‹ั", + "subtitle": "ะ—ะผัะฝั–ั†ัŒ ะฐัžั‚ะฐั€ะฐ, ะฝะฐะทะฒัƒ ั– ั–ะฝัˆั‹ั ัžะปะฐัั†ั–ะฒะฐัั†ั–." + }, + "pdfsToZip": { + "name": "PDF ัƒ ZIP", + "subtitle": "ะ—ะฐะฟะฐะบะฐะฒะฐั†ัŒ ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž PDF ัƒ ZIP-ะฐั€ั…ั–ัž." + }, + "comparePdfs": { + "name": "ะŸะฐั€ะฐัžะฝะฐั†ัŒ PDF", + "subtitle": "ะŸะฐั€ะฐัžะฝะฐั†ัŒ ะดะฒะฐ PDF ะฟะพะฑะฐั‡." + }, + "posterizePdf": { + "name": "ะŸะตั€ะฐัžั‚ะฒะฐั€ั‹ั†ัŒ ัƒ ะฟะพัั‚ัั€", + "subtitle": "ะ ะฐะทะฑั–ั†ัŒ ะฒัะปั–ะบัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ ะฝะฐ ะฝะตะบะฐะปัŒะบั– ะผะตะฝัˆั‹ั…." + }, + "fixPageSize": { + "name": "ะฃะฝั–ั„ั–ะบะฐะฒะฐั†ัŒ ะฟะฐะผะตั€ ัั‚ะฐั€ะพะฝะฐะบ", + "subtitle": "ะฃะฝั–ั„ั–ะบะฐะฒะฐั†ัŒ ะฟะฐะผะตั€ ัƒัั–ั… ัั‚ะฐั€ะพะฝะฐะบ." + }, + "linearizePdf": { + "name": "ะ—ั€ะฐะฑั–ั†ัŒ ะปั–ะฝะตะนะฝั‹ PDF", + "subtitle": "ะะฟั‚ั‹ะผั–ะทะฐะฒะฐั†ัŒ PDF ะดะปั ั…ัƒั‚ะบะฐะณะฐ ะฟั€ะฐะณะปัะดัƒ ัž ั–ะฝั‚ัั€ะฝัั†ะต." + }, + "pageDimensions": { + "name": "ะŸะฐะผะตั€ั‹ ัั‚ะฐั€ะพะฝะบั–", + "subtitle": "ะะฝะฐะปั–ะทะฐะฒะฐั†ัŒ ะฟะฐะผะตั€ ัั‚ะฐั€ะพะฝะบั–, ะฐั€ั‹ะตะฝั‚ะฐั†ั‹ัŽ ั– ะฐะดะทั–ะฝะบั–." + }, + "removeRestrictions": { + "name": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะฐะฑะผะตะถะฐะฒะฐะฝะฝั–", + "subtitle": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะฐั…ะพะฒัƒ ะฟะฐั€ะพะปะตะผ ั– ะฐะฑะผะตะถะฐะฒะฐะฝะฝั– ะฑััะฟะตะบั–, ะทะฒัะทะฐะฝั‹ั ะท ะปั–ั‡ะฑะฐะฒั‹ะผั– ะฟะพะดะฟั–ัะฐะผั– PDF." + }, + "repairPdf": { + "name": "ะะดะฝะฐะฒั–ั†ัŒ PDF", + "subtitle": "ะะดะฝะฐะฒั–ั†ัŒ ะดะฐะฝั‹ั ะท ะฟะฐัˆะบะพะดะถะฐะฝั‹ั… ั„ะฐะนะปะฐัž PDF." + }, + "encryptPdf": { + "name": "ะ—ะฐัˆั‹ั„ั€ะฐะฒะฐั†ัŒ PDF", + "subtitle": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ PDF, ะดะฐะดะฐัžัˆั‹ ะฟะฐั€ะพะปัŒ." + }, + "sanitizePdf": { + "name": "ะั‡ั‹ัั†ั–ั†ัŒ PDF", + "subtitle": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะผะตั‚ะฐะดะฐะฝั‹ั, ะฐะฝะฐั‚ะฐั†ั‹ั–, ัะบั€ั‹ะฟั‚ั‹ ั– ั–ะฝัˆะฐะต." + }, + "decryptPdf": { + "name": "ะ ะฐััˆั‹ั„ั€ะฐะฒะฐั†ัŒ PDF", + "subtitle": "ะ ะฐะทะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ PDF, ะฒั‹ะดะฐะปั–ัžัˆั‹ ะฟะฐั€ะพะปัŒ." + }, + "flattenPdf": { + "name": "ะ—ะฒะตัั†ั– PDF", + "subtitle": "ะ—ั€ะฐะฑั–ั†ัŒ ะฟะฐะปั– ั„ะพั€ะผั‹ ั– ะฐะฝะฐั‚ะฐั†ั‹ั– ั‚ะพะปัŒะบั– ะดะปั ั‡ั‹ั‚ะฐะฝะฝั." + }, + "removeMetadata": { + "name": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะผะตั‚ะฐะดะฐะฝั‹ั", + "subtitle": "ะ’ั‹ะดะฐะปั–ั†ัŒ ัั…ะฐะฒะฐะฝั‹ั ะดะฐะฝั‹ั ะท PDF." + }, + "changePermissions": { + "name": "ะ—ะผัะฝั–ั†ัŒ ะดะฐะทะฒะพะปั‹", + "subtitle": "ะ—ะฐะดะฐั†ัŒ ะฐะฑะพ ะทะผัะฝั–ั†ัŒ ะฟั€ะฐะฒั‹ ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบะฐัž ะดะปั PDF." + }, + "odtToPdf": { + "name": "ODT ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ OpenDocument Text ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ ODT", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "csvToPdf": { + "name": "CSV ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ CSV ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ CSV", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "rtfToPdf": { + "name": "RTF ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ Rich Text Format ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ RTF", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "wordToPdf": { + "name": "Word ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ Word (DOCX, DOC, ODT, RTF) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ DOCX, DOC, ODT, RTF", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "excelToPdf": { + "name": "Excel ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ Excel (XLSX, XLS, ODS, CSV) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ XLSX, XLS, ODS, CSV", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะฟั€ัะทะตะฝั‚ะฐั†ั‹ั– PowerPoint (PPTX, PPT, ODP) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ PPTX, PPT, ODP", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "markdownToPdf": { + "name": "Markdown ัƒ PDF", + "subtitle": "ะะฐะฟั–ัะฐั†ัŒ ะฐะฑะพ ัžัั‚ะฐะฒั–ั†ัŒ Markdown ั– ัะบัะฟะฐั€ั‚ะฐะฒะฐั†ัŒ ัะณะพ ัž ะฟั€ั‹ะณะพะถะฐ ะฐั„ะพั€ะผะปะตะฝั‹ PDF.", + "paneMarkdown": "Markdown", + "panePreview": "ะŸะฐะฟัั€ัะดะฝั– ะฟั€ะฐะณะปัะด", + "btnUpload": "ะ—ะฐะฟะฐะผะฟะฐะฒะฐั†ัŒ", + "btnSyncScroll": "ะกั–ะฝั…ั€ะฐะฝั–ะทะฐั†ั‹ั ะฟั€ะฐะบั€ัƒั‚ะบั–", + "btnSettings": "ะะฐะปะฐะดั‹", + "btnExportPdf": "ะญะบัะฟะฐั€ั‚ะฐะฒะฐั†ัŒ PDF", + "settingsTitle": "ะะฐะปะฐะดั‹ Markdown", + "settingsPreset": "ะะฐะฑะพั€ ะฝะฐะปะฐะด", + "presetDefault": "ะŸั€ะฐะดะฒั‹ะทะฝะฐั‡ะฐะฝั‹ (ัะบ GFM)", + "presetCommonmark": "CommonMark (ัั‚ั€ะพะณั–)", + "presetZero": "ะœั–ะฝั–ะผะฐะปัŒะฝั‹ (ะฑะตะท ั„ัƒะฝะบั†ั‹ะน)", + "settingsOptions": "ะŸะฐั€ะฐะผะตั‚ั€ั‹ Markdown", + "optAllowHtml": "ะ”ะฐะทะฒะพะปั–ั†ัŒ HTML-ั‚ัะณั–", + "optBreaks": "ะŸะตั€ะฐัžั‚ะฒะฐั€ะฐั†ัŒ ะฟะตั€ะฐะฝะพัั‹ ั€ะฐะดะบะพัž ัƒ
", + "optLinkify": "ะัžั‚ะฐะผะฐั‚ั‹ั‡ะฝะฐ ะฟะตั€ะฐัžั‚ะฒะฐั€ะฐั†ัŒ URL-ะฐะดั€ะฐัั‹ ัž ัะฟะฐัั‹ะปะบั–", + "optTypographer": "ะขั‹ะฟะพะณั€ะฐั„ (ั€ะฐะทัƒะผะฝั‹ั ะดะฒัƒะบะพััั– ั– ั–ะฝัˆ.)" + }, + "pdfBooklet": { + "name": "ะ‘ัƒะบะปะตั‚ PDF", + "subtitle": "ะ—ะผัะฝั–ั†ัŒ ะฟะฐั€ะฐะดะฐะบ ัั‚ะฐั€ะพะฝะฐะบ ะดะปั ะดั€ัƒะบัƒ ะดะฒัƒั…ะฑะฐะบะพะฒะฐะณะฐ ะฑัƒะบะปะตั‚ะฐ. ะกะบะปะฐะดะทั–ั†ะต ั– ัั‡ะฐะฟั–ั†ะต ะฐั€ะบัƒัˆั‹, ะบะฐะฑ ะฐั‚ั€ั‹ะผะฐัžัั ะฑัƒะบะปะตั‚.", + "howItWorks": "ะฏะบ ะณัั‚ะฐ ะฟั€ะฐั†ัƒะต:", + "step1": "ะ—ะฐะฟะฐะผะฟัƒะนั†ะต ั„ะฐะนะป PDF.", + "step2": "ะŸะฐั€ะฐะดะฐะบ ัั‚ะฐั€ะพะฝะฐะบ ะฑัƒะดะทะต ะทะผะตะฝะตะฝั‹ ะดะปั ะฑัƒะบะปะตั‚ะฐ.", + "step3": "ะะฐะดั€ัƒะบัƒะนั†ะต ะท ะดะฒัƒั… ะฑะฐะบะพัž, ะฟะตั€ะฐะฒัั€ะฝั–ั†ะต ะฟะฐ ะบะฐั€ะพั‚ะบั–ะผ ะบั€ะฐั–, ัะบะปะฐะดะทั–ั†ะต ั– ััˆั‹ะนั†ะต.", + "paperSize": "ะŸะฐะผะตั€ ะฟะฐะฟะตั€ั‹", + "orientation": "ะั€ั‹ะตะฝั‚ะฐั†ั‹ั", + "portrait": "ะšะฝั–ะถะฝะฐั", + "landscape": "ะะปัŒะฑะพะผะฝะฐั", + "pagesPerSheet": "ะกั‚ะฐั€ะพะฝะฐะบ ะฝะฐ ะฐั€ะบัƒัˆ", + "createBooklet": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ะฑัƒะบะปะตั‚", + "processing": "ะะฟั€ะฐั†ะพัžะบะฐ...", + "pageCount": "ะšะพะปัŒะบะฐัั†ัŒ ัั‚ะฐั€ะพะฝะฐะบ ะฑัƒะดะทะต ะดะฐะฟะพัžะฝะตะฝะฐ ะดะฐ ะบั€ะฐั‚ะฝะฐะน 4 ะฟั€ั‹ ะฝะตะฐะฑั…ะพะดะฝะฐัั†ั–." + }, + "xpsToPdf": { + "name": "XPS ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ XPS/OXPS ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ XPS, OXPS", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "mobiToPdf": { + "name": "MOBI ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัะปะตะบั‚ั€ะพะฝะฝั‹ั ะบะฝั–ะณั– MOBI ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ MOBI", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "epubToPdf": { + "name": "EPUB ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัะปะตะบั‚ั€ะพะฝะฝั‹ั ะบะฝั–ะณั– EPUB ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ EPUB", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "fb2ToPdf": { + "name": "FB2 ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัะปะตะบั‚ั€ะพะฝะฝั‹ั ะบะฝั–ะณั– FictionBook (FB2) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ FB2", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "cbzToPdf": { + "name": "CBZ ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะฐั€ั…ั–ะฒั‹ ะบะพะผั–ะบัะฐัž (CBZ/CBR) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ CBZ, CBR", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "wpdToPdf": { + "name": "WPD ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ WordPerfect (WPD) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ WPD", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "wpsToPdf": { + "name": "WPS ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ WPS Office ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ WPS", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "xmlToPdf": { + "name": "XML ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ XML ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ XML", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "pagesToPdf": { + "name": "Pages ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะดะฐะบัƒะผะตะฝั‚ั‹ Apple Pages ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ Pages", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "odgToPdf": { + "name": "ODG ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ OpenDocument Graphics (ODG) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ ODG", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "odsToPdf": { + "name": "ODS ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ OpenDocument Spreadsheet (ODS) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ ODS", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "odpToPdf": { + "name": "ODP ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ OpenDocument Presentation (ODP) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ ODP", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "pubToPdf": { + "name": "PUB ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ Microsoft Publisher (PUB) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ PUB", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "vsdToPdf": { + "name": "VSD ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ Microsoft Visio (VSD, VSDX) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ VSD, VSDX", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "psdToPdf": { + "name": "PSD ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ Adobe Photoshop (PSD) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "acceptedFormats": "ั„ะฐะนะปั‹ PSD", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "pdfToSvg": { + "name": "PDF ัƒ SVG", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ะบะพะถะฝัƒัŽ ัั‚ะฐั€ะพะฝะบัƒ PDF ัƒ ะผะฐัˆั‚ะฐะฑะฐะฒะฐะฝัƒัŽ ะฒะตะบั‚ะฐั€ะฝัƒัŽ ะณั€ะฐั„ั–ะบัƒ (SVG) ะดะปั ั–ะดัะฐะปัŒะฝะฐะน ัะบะฐัั†ั– ะฝะฐ ะปัŽะฑั‹ะผ ะฟะฐะผะตั€ั‹." + }, + "extractTables": { + "name": "ะ’ั‹ะฝัั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ ะท PDF", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ ะท PDF ั– ัะบัะฟะฐั€ั‚ะฐะฒะฐั†ัŒ ัƒ CSV, JSON ะฐะฑะพ Markdown." + }, + "pdfToCsv": { + "name": "PDF ัƒ CSV", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ ะท PDF ั– ะบะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ CSV." + }, + "pdfToExcel": { + "name": "PDF ัƒ Excel", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ั‚ะฐะฑะปั–ั†ั‹ ะท PDF ั– ะบะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ Excel (XLSX)." + }, + "pdfToText": { + "name": "PDF ัƒ ั‚ัะบัั‚", + "subtitle": "ะ’ั‹ะฝัั†ัŒ ั‚ัะบัั‚ ะท ั„ะฐะนะปะฐัž PDF ั– ะทะฐั…ะฐะฒะฐั†ัŒ ัะบ ั‚ัะบัั‚ะฐะฒั‹ ั„ะฐะนะป (.txt). ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ะฝะตะบะฐะปัŒะบั– ั„ะฐะนะปะฐัž.", + "note": "ะ“ัั‚ั‹ ั–ะฝัั‚ั€ัƒะผะตะฝั‚ ะฟั€ะฐั†ัƒะต ะขะžะ›ะฌะšะ† ะท PDF, ัั‚ะฒะพั€ะฐะฝั‹ะผั– ะปั–ั‡ะฑะฐะฒั‹ะผ ัะฟะพัะฐะฑะฐะผ. ะ”ะปั ัะบะฐะฝั–ั€ะฐะฒะฐะฝั‹ั… ะดะฐะบัƒะผะตะฝั‚ะฐัž ะฐะฑะพ PDF ะฝะฐ ะฐัะฝะพะฒะต ะฒั–ะดะฐั€ั‹ัะฐัž ะฒั‹ะบะฐั€ั‹ัั‚ะพัžะฒะฐะนั†ะต ั–ะฝัั‚ั€ัƒะผะตะฝั‚ OCR PDF.", + "convertButton": "ะ’ั‹ะฝัั†ัŒ ั‚ัะบัั‚" + }, + "digitalSignPdf": { + "name": "ะ›ั–ั‡ะฑะฐะฒั‹ ะฟะพะดะฟั–ั PDF", + "pageTitle": "ะ›ั–ั‡ะฑะฐะฒั‹ ะฟะพะดะฟั–ั PDF - ะ”ะฐะดะฐั†ัŒ ะบั€ั‹ะฟั‚ะฐะณั€ะฐั„ั–ั‡ะฝั‹ ะฟะพะดะฟั–ั | BentoPDF", + "subtitle": "ะ”ะฐะดะฐั†ัŒ ะบั€ั‹ะฟั‚ะฐะณั€ะฐั„ั–ั‡ะฝั‹ ะปั–ั‡ะฑะฐะฒั‹ ะฟะพะดะฟั–ั ะดะฐ PDF ะท ะฒั‹ะบะฐั€ั‹ัั‚ะฐะฝะฝะตะผ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚ะฐัž X.509. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ั„ะฐั€ะผะฐั‚ั‹ PKCS#12 (.pfx, .p12) ั– PEM. ะ’ะฐัˆ ะฟั€ั‹ะฒะฐั‚ะฝั‹ ะบะปัŽั‡ ะฝั–ะบะพะปั– ะฝะต ะฟะฐะบั–ะดะฐะต ะฒะฐัˆ ะฑั€ะฐัžะทะตั€.", + "certificateSection": "ะกะตั€ั‚ั‹ั„ั–ะบะฐั‚", + "uploadCert": "ะ—ะฐะฟะฐะผะฟะฐะฒะฐั†ัŒ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚ (.pfx, .p12)", + "certPassword": "ะŸะฐั€ะพะปัŒ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚ะฐ", + "certPasswordPlaceholder": "ะฃะฒัะดะทั–ั†ะต ะฟะฐั€ะพะปัŒ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚ะฐ", + "certInfo": "ะ†ะฝั„ะฐั€ะผะฐั†ั‹ั ะฟั€ะฐ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚", + "certSubject": "ะกัƒะฑ'ะตะบั‚", + "certIssuer": "ะ’ั‹ะดะฐะฒะตั†", + "certValidity": "ะ”ะทะตะนัะฝั‹", + "signatureDetails": "ะ”ัั‚ะฐะปั– ะฟะพะดะฟั–ััƒ (ะฝะตะฐะฑะฐะฒัะทะบะพะฒะฐ)", + "reason": "ะŸั€ั‹ั‡ั‹ะฝะฐ", + "reasonPlaceholder": "ะฝะฐะฟั€ั‹ะบะปะฐะด, ั ัžั…ะฒะฐะปััŽ ะณัั‚ั‹ ะดะฐะบัƒะผะตะฝั‚", + "location": "ะœะตัั†ะฐะทะฝะฐั…ะพะดะถะฐะฝะฝะต", + "locationPlaceholder": "ะฝะฐะฟั€ั‹ะบะปะฐะด, ะœั–ะฝัะบ, ะ‘ะตะปะฐั€ัƒััŒ", + "contactInfo": "ะšะฐะฝั‚ะฐะบั‚ะฝะฐั ั–ะฝั„ะฐั€ะผะฐั†ั‹ั", + "contactPlaceholder": "ะฝะฐะฟั€ั‹ะบะปะฐะด, email@example.com", + "applySignature": "ะฃะถั‹ั†ัŒ ะปั–ั‡ะฑะฐะฒั‹ ะฟะพะดะฟั–ั", + "successMessage": "PDF ะฟะฐัะฟัั…ะพะฒะฐ ะฟะฐะดะฟั–ัะฐะฝั‹! ะŸะพะดะฟั–ั ะผะพะถะฝะฐ ะฟั€ะฐะฒะตั€ั‹ั†ัŒ ัƒ ะปัŽะฑั‹ะผ PDF-ั‡ั‹ั‚ะฐะปัŒะฝั–ะบัƒ." + }, + "validateSignaturePdf": { + "name": "ะŸั€ะฐะฒะตั€ั‹ั†ัŒ ะฟะพะดะฟั–ั PDF", + "pageTitle": "ะŸั€ะฐะฒะตั€ั‹ั†ัŒ ะฟะพะดะฟั–ั PDF - ะ’ะตั€ั‹ั„ั–ะบะฐั†ั‹ั ะปั–ั‡ะฑะฐะฒั‹ั… ะฟะพะดะฟั–ัะฐัž | BentoPDF", + "subtitle": "ะŸั€ะฐะฒะตั€ั‹ั†ัŒ ะปั–ั‡ะฑะฐะฒั‹ั ะฟะพะดะฟั–ัั‹ ัž PDF. ะŸั€ะฐะฒะตั€ั‹ั†ัŒ ัะฐะฟั€ะฐัžะดะฝะฐัั†ัŒ ัะตั€ั‚ั‹ั„ั–ะบะฐั‚ะฐ, ะฟะฐะณะปัะดะทะตั†ัŒ ะดัั‚ะฐะปั– ะฟะฐะดะฟั–ัะฐะฝั‚ะฐ ั– ะฟะฐั†ะฒะตั€ะดะทั–ั†ัŒ ะฝะฐะดะทะตะนะฝะฐัั†ัŒ ะดะฐะบัƒะผะตะฝั‚ะฐ. ะฃัั ะฐะฟั€ะฐั†ะพัžะบะฐ ะฐะดะฑั‹ะฒะฐะตั†ั†ะฐ ัž ะฒะฐัˆั‹ะผ ะฑั€ะฐัžะทะตั€ั‹." + }, + "emailToPdf": { + "name": "Email ัƒ PDF", + "subtitle": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ั„ะฐะนะปั‹ email (EML, MSG) ัƒ PDF. ะŸะฐะดั‚ั€ั‹ะผะปั–ะฒะฐะต ัะบัะฟะฐั€ั‚ั‹ Outlook ั– ัั‚ะฐะฝะดะฐั€ั‚ะฝั‹ั email-ั„ะฐั€ะผะฐั‚ั‹.", + "acceptedFormats": "ั„ะฐะนะปั‹ EML, MSG", + "convertButton": "ะšะฐะฝะฒะตั€ั‚ะฐะฒะฐั†ัŒ ัƒ PDF" + }, + "fontToOutline": { + "name": "ะจั€ั‹ั„ั‚ ัƒ ะบะพะฝั‚ัƒั€ั‹", + "subtitle": "ะŸะตั€ะฐั‚ะฒะฐั€ั‹ั†ัŒ ัƒัะต ัˆั€ั‹ั„ั‚ั‹ ัž ะฒะตะบั‚ะฐั€ะฝั‹ั ะบะพะฝั‚ัƒั€ั‹ ะดะปั ัั‚ะฐะฑั–ะปัŒะฝะฐะณะฐ ะฐะดะปัŽัั‚ั€ะฐะฒะฐะฝะฝั ะฝะฐ ัžัั–ั… ะฟั€ั‹ะปะฐะดะฐั…." + }, + "deskewPdf": { + "name": "ะ’ั‹ะฟั€ะฐัั‚ะฐั†ัŒ PDF", + "subtitle": "ะัžั‚ะฐะผะฐั‚ั‹ั‡ะฝะฐ ะฒั‹ั€ะฐัžะฝัั†ัŒ ะฝะฐั…ั–ะปะตะฝั‹ั ะฐะดัะบะฐะฝั–ั€ะฐะฒะฐะฝั‹ั ัั‚ะฐั€ะพะฝะบั– ะท ะดะฐะฟะฐะผะพะณะฐะน OpenCV." + } +} diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 750777d..bb23416 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -1,319 +1,325 @@ { - "nav": { - "home": "Startseite", - "about": "รœber uns", - "contact": "Kontakt", - "licensing": "Lizenzierung", - "allTools": "Alle Werkzeuge", - "openMainMenu": "Hauptmenรผ รถffnen", - "language": "Sprache" + "nav": { + "home": "Startseite", + "about": "รœber uns", + "contact": "Kontakt", + "licensing": "Lizenzierung", + "allTools": "Alle Werkzeuge", + "openMainMenu": "Hauptmenรผ รถffnen", + "language": "Sprache" + }, + "donation": { + "message": "Lieben Sie BentoPDF? Helfen Sie uns, es kostenlos und Open Source zu halten!", + "button": "Spenden" + }, + "hero": { + "title": "Das", + "pdfToolkit": "PDF-Toolkit", + "builtForPrivacy": "fรผr maximale Privatsphรคre", + "noSignups": "Keine Anmeldung", + "unlimitedUse": "Unbegrenzte Nutzung", + "worksOffline": "Funktioniert offline", + "startUsing": "Jetzt starten" + }, + "usedBy": { + "title": "Verwendet von Unternehmen und Mitarbeitern bei" + }, + "features": { + "title": "Warum", + "bentoPdf": "BentoPDF wรคhlen?", + "noSignup": { + "title": "Keine Anmeldung", + "description": "Sofort starten, keine Konten oder E-Mails erforderlich." }, - "hero": { - "title": "Das", - "pdfToolkit": "PDF-Toolkit", - "builtForPrivacy": "fรผr maximale Privatsphรคre", - "noSignups": "Keine Anmeldung", - "unlimitedUse": "Unbegrenzte Nutzung", - "worksOffline": "Funktioniert offline", - "startUsing": "Jetzt starten" + "noUploads": { + "title": "Kein Upload", + "description": "100% clientseitig, Ihre Dateien verlassen nie Ihr Gerรคt." }, - "usedBy": { - "title": "Verwendet von Unternehmen und Mitarbeitern bei" + "foreverFree": { + "title": "Fรผr immer kostenlos", + "description": "Alle Werkzeuge, keine Testversionen, keine Bezahlschranken." }, - "features": { - "title": "Warum", - "bentoPdf": "BentoPDF wรคhlen?", - "noSignup": { - "title": "Keine Anmeldung", - "description": "Sofort starten, keine Konten oder E-Mails erforderlich." - }, - "noUploads": { - "title": "Kein Upload", - "description": "100% clientseitig, Ihre Dateien verlassen nie Ihr Gerรคt." - }, - "foreverFree": { - "title": "Fรผr immer kostenlos", - "description": "Alle Werkzeuge, keine Testversionen, keine Bezahlschranken." - }, - "noLimits": { - "title": "Keine Limits", - "description": "Nutzen Sie so viel Sie wollen, ohne versteckte Grenzen." - }, - "batchProcessing": { - "title": "Stapelverarbeitung", - "description": "Verarbeiten Sie unbegrenzt viele PDFs auf einmal." - }, - "lightningFast": { - "title": "Blitzschnell", - "description": "PDFs sofort verarbeiten, ohne Wartezeiten." - } + "noLimits": { + "title": "Keine Limits", + "description": "Nutzen Sie so viel Sie wollen, ohne versteckte Grenzen." }, - "tools": { - "title": "Starten Sie mit", - "toolsLabel": "Werkzeugen", - "subtitle": "Klicken Sie auf ein Werkzeug, um den Datei-Uploader zu รถffnen", - "searchPlaceholder": "Werkzeug suchen (z.B. 'teilen', 'organisieren'...)", - "backToTools": "Zurรผck zu den Werkzeugen", - "firstLoadNotice": "Der erste Ladevorgang dauert einen Moment, da wir unsere Konvertierungs-Engine herunterladen. Danach erfolgt jedes Laden sofort." + "batchProcessing": { + "title": "Stapelverarbeitung", + "description": "Verarbeiten Sie unbegrenzt viele PDFs auf einmal." }, - "upload": { - "clickToSelect": "Klicken Sie, um eine Datei auszuwรคhlen", - "orDragAndDrop": "oder per Drag & Drop", - "pdfOrImages": "PDFs oder Bilder", - "filesNeverLeave": "Ihre Dateien verlassen nie Ihr Gerรคt.", - "addMore": "Weitere Dateien hinzufรผgen", - "clearAll": "Alle lรถschen" - }, - "loader": { - "processing": "Verarbeitung..." - }, - "alert": { - "title": "Hinweis", - "ok": "OK" - }, - "preview": { - "title": "Dokumentvorschau", - "downloadAsPdf": "Als PDF herunterladen", - "close": "SchlieรŸen" - }, - "settings": { - "title": "Einstellungen", - "shortcuts": "Tastenkรผrzel", - "preferences": "Voreinstellungen", - "displayPreferences": "Anzeige-Einstellungen", - "searchShortcuts": "Tastenkรผrzel suchen...", - "shortcutsInfo": "Halten Sie Tasten gedrรผckt, um ein Kรผrzel festzulegen. ร„nderungen werden automatisch gespeichert.", - "shortcutsWarning": "โš ๏ธ Vermeiden Sie gรคngige Browser-Tastenkรผrzel (Strg+W, Strg+T, Strg+N usw.), da diese mรถglicherweise nicht zuverlรคssig funktionieren.", - "import": "Importieren", - "export": "Exportieren", - "resetToDefaults": "Auf Standard zurรผcksetzen", - "fullWidthMode": "Vollbreite-Modus", - "fullWidthDescription": "Verwenden Sie die volle Bildschirmbreite fรผr alle Werkzeuge anstelle eines zentrierten Containers", - "settingsAutoSaved": "Einstellungen werden automatisch gespeichert", - "clickToSet": "Klicken zum Festlegen", - "pressKeys": "Tasten drรผcken...", - "warnings": { - "alreadyInUse": "Tastenkombination bereits vergeben", - "assignedTo": "ist bereits zugewiesen an:", - "chooseDifferent": "Bitte wรคhlen Sie eine andere Tastenkombination.", - "reserved": "Warnung: Reservierte Tastenkombination", - "commonlyUsed": "wird hรคufig verwendet fรผr:", - "unreliable": "Diese Tastenkombination funktioniert mรถglicherweise nicht zuverlรคssig oder kรถnnte mit Browser-/Systemfunktionen in Konflikt geraten.", - "useAnyway": "Mรถchten Sie sie trotzdem verwenden?", - "resetTitle": "Tastenkombinationen zurรผcksetzen", - "resetMessage": "Sind Sie sicher, dass Sie alle Tastenkombinationen auf die Standardwerte zurรผcksetzen mรถchten?

Diese Aktion kann nicht rรผckgรคngig gemacht werden.", - "importSuccessTitle": "Import erfolgreich", - "importSuccessMessage": "Tastenkombinationen erfolgreich importiert!", - "importFailTitle": "Import fehlgeschlagen", - "importFailMessage": "Fehler beim Importieren der Tastenkombinationen. Ungรผltiges Dateiformat." - } - }, - "warning": { - "title": "Warnung", - "cancel": "Abbrechen", - "proceed": "Fortfahren" - }, - "compliance": { - "title": "Ihre Daten verlassen nie Ihr Gerรคt", - "weKeep": "Wir schรผtzen", - "yourInfoSafe": "Ihre Informationen", - "byFollowingStandards": "nach globalen Sicherheitsstandards.", - "processingLocal": "Die gesamte Verarbeitung erfolgt lokal auf Ihrem Gerรคt.", - "gdpr": { - "title": "DSGVO-konform", - "description": "Schรผtzt die personenbezogenen Daten und die Privatsphรคre von Personen innerhalb der Europรคischen Union." - }, - "ccpa": { - "title": "CCPA-konform", - "description": "Gibt Einwohnern Kaliforniens Rechte darรผber, wie ihre persรถnlichen Daten gesammelt, verwendet und weitergegeben werden." - }, - "hipaa": { - "title": "HIPAA-konform", - "description": "Legt SchutzmaรŸnahmen fรผr den Umgang mit sensiblen Gesundheitsinformationen im US-Gesundheitssystem fest." - } - }, - "faq": { - "title": "Hรคufig gestellte", - "questions": "Fragen", - "isFree": { - "question": "Ist BentoPDF wirklich kostenlos?", - "answer": "Ja, absolut. Alle Werkzeuge auf BentoPDF sind zu 100% kostenlos nutzbar, ohne Dateilimits, ohne Anmeldung und ohne Wasserzeichen. Wir glauben, dass jeder Zugang zu einfachen, leistungsstarken PDF-Werkzeugen verdient, ohne Bezahlschranke." - }, - "areFilesSecure": { - "question": "Sind meine Dateien sicher? Wo werden sie verarbeitet?", - "answer": "Ihre Dateien sind so sicher wie mรถglich, da sie nie Ihren Computer verlassen. Die gesamte Verarbeitung erfolgt direkt in Ihrem Webbrowser (clientseitig). Wir laden Ihre Dateien nie auf einen Server hoch, sodass Sie die vollstรคndige Privatsphรคre und Kontrolle รผber Ihre Dokumente behalten." - }, - "platforms": { - "question": "Funktioniert es auf Mac, Windows und Mobilgerรคten?", - "answer": "Ja! Da BentoPDF vollstรคndig in Ihrem Browser lรคuft, funktioniert es auf jedem Betriebssystem mit einem modernen Webbrowser, einschlieรŸlich Windows, macOS, Linux, iOS und Android." - }, - "gdprCompliant": { - "question": "Ist BentoPDF DSGVO-konform?", - "answer": "Ja. BentoPDF ist vollstรคndig DSGVO-konform. Da die gesamte Dateiverarbeitung lokal in Ihrem Browser erfolgt und wir Ihre Dateien nie sammeln oder รผbertragen, haben wir keinen Zugang zu Ihren Daten. Dies stellt sicher, dass Sie immer die Kontrolle รผber Ihre Dokumente haben." - }, - "dataStorage": { - "question": "Speichern oder verfolgen Sie meine Dateien?", - "answer": "Nein. Wir speichern, verfolgen oder protokollieren Ihre Dateien niemals. Alles, was Sie auf BentoPDF tun, geschieht im Speicher Ihres Browsers und verschwindet, sobald Sie die Seite schlieรŸen. Es gibt keine Uploads, keine Verlaufsprotokolle und keine Server." - }, - "different": { - "question": "Was unterscheidet BentoPDF von anderen PDF-Werkzeugen?", - "answer": "Die meisten PDF-Werkzeuge laden Ihre Dateien zur Verarbeitung auf einen Server hoch. BentoPDF tut das nie. Wir verwenden sichere, moderne Webtechnologie, um Ihre Dateien direkt in Ihrem Browser zu verarbeiten. Das bedeutet schnellere Leistung, stรคrkere Privatsphรคre und vollstรคndige Sicherheit." - }, - "browserBased": { - "question": "Wie schรผtzt mich die browserbasierte Verarbeitung?", - "answer": "Durch die vollstรคndige Ausfรผhrung in Ihrem Browser stellt BentoPDF sicher, dass Ihre Dateien nie Ihr Gerรคt verlassen. Dies eliminiert die Risiken von Server-Hacks, Datenschutzverletzungen oder unbefugtem Zugriff. Ihre Dateien bleiben Ihre โ€” immer." - }, - "analytics": { - "question": "Verwenden Sie Cookies oder Analysen, um mich zu verfolgen?", - "answer": "Uns liegt Ihre Privatsphรคre am Herzen. BentoPDF verfolgt keine persรถnlichen Informationen. Wir verwenden Simple Analytics ausschlieรŸlich, um anonyme Besucherzahlen zu sehen. Das bedeutet, wir kรถnnen wissen, wie viele Benutzer unsere Seite besuchen, aber wir wissen nie, wer Sie sind. Simple Analytics ist vollstรคndig DSGVO-konform und respektiert Ihre Privatsphรคre." - } - }, - "testimonials": { - "title": "Was unsere", - "users": "Nutzer", - "say": "sagen" - }, - "support": { - "title": "Gefรคllt Ihnen meine Arbeit?", - "description": "BentoPDF ist ein Leidenschaftsprojekt, entwickelt um ein kostenloses, privates und leistungsstarkes PDF-Toolkit fรผr alle bereitzustellen. Wenn Sie es nรผtzlich finden, erwรคgen Sie, die Entwicklung zu unterstรผtzen. Jeder Kaffee hilft!", - "buyMeCoffee": "Kauf mir einen Kaffee" - }, - "footer": { - "copyright": "ยฉ 2025 BentoPDF. Alle Rechte vorbehalten.", - "version": "Version", - "company": "Unternehmen", - "aboutUs": "รœber uns", - "faqLink": "FAQ", - "contactUs": "Kontakt", - "legal": "Rechtliches", - "termsAndConditions": "Nutzungsbedingungen", - "privacyPolicy": "Datenschutzrichtlinie", - "followUs": "Folgen Sie uns" - }, - "merge": { - "title": "PDFs zusammenfรผhren", - "description": "Kombinieren Sie ganze Dateien oder wรคhlen Sie bestimmte Seiten zum Zusammenfรผhren in ein neues Dokument.", - "fileMode": "Datei-Modus", - "pageMode": "Seiten-Modus", - "howItWorks": "So funktioniert es:", - "fileModeInstructions": [ - "Klicken und ziehen Sie das Symbol, um die Reihenfolge der Dateien zu รคndern.", - "Im Feld \"Seiten\" fรผr jede Datei kรถnnen Sie Bereiche angeben (z.B. \"1-3, 5\"), um nur diese Seiten zusammenzufรผhren.", - "Lassen Sie das Feld \"Seiten\" leer, um alle Seiten dieser Datei einzuschlieรŸen." - ], - "pageModeInstructions": [ - "Alle Seiten Ihrer hochgeladenen PDFs werden unten angezeigt.", - "Ziehen Sie einfach die einzelnen Seitenvorschauen per Drag & Drop, um die gewรผnschte Reihenfolge fรผr Ihre neue Datei zu erstellen." - ], - "mergePdfs": "PDFs zusammenfรผhren" - }, - "common": { - "page": "Seite", - "pages": "Seiten", - "of": "von", - "download": "Herunterladen", - "cancel": "Abbrechen", - "save": "Speichern", - "delete": "Lรถschen", - "edit": "Bearbeiten", - "add": "Hinzufรผgen", - "remove": "Entfernen", - "loading": "Laden...", - "error": "Fehler", - "success": "Erfolg", - "file": "Datei", - "files": "Dateien" - }, - "about": { - "hero": { - "title": "Wir glauben PDF-Werkzeuge sollten", - "subtitle": "schnell, privat und kostenlos sein.", - "noCompromises": "Ohne Kompromisse." - }, - "mission": { - "title": "Unsere Mission", - "description": "Die umfassendste PDF-Toolbox bereitzustellen, die Ihre Privatsphรคre respektiert und niemals eine Bezahlung verlangt. Wir glauben, dass wichtige Dokumentenwerkzeuge fรผr jeden, รผberall und ohne Barrieren zugรคnglich sein sollten." - }, - "philosophy": { - "label": "Unsere Kernphilosophie", - "title": "Privatsphรคre zuerst. Immer.", - "description": "In einer Zeit, in der Daten eine Ware sind, gehen wir einen anderen Weg. Die gesamte Verarbeitung fรผr Bentopdf-Werkzeuge erfolgt lokal in Ihrem Browser. Das bedeutet, Ihre Dateien berรผhren niemals unsere Server, wir sehen Ihre Dokumente nie und verfolgen nicht, was Sie tun. Ihre Dokumente bleiben vollstรคndig und unmissverstรคndlich privat. Es ist nicht nur eine Funktion; es ist unser Fundament." - }, - "whyBentopdf": { - "title": "Warum", - "speed": { - "title": "Fรผr Geschwindigkeit gebaut", - "description": "Kein Warten auf Uploads oder Downloads zu einem Server. Durch die Verarbeitung von Dateien direkt in Ihrem Browser mit modernen Webtechnologien wie WebAssembly bieten wir unvergleichliche Geschwindigkeit fรผr alle unsere Werkzeuge." - }, - "free": { - "title": "Komplett kostenlos", - "description": "Keine Testversionen, keine Abonnements, keine versteckten Gebรผhren und keine \"Premium\"-Funktionen als Geiseln. Wir glauben, leistungsstarke PDF-Werkzeuge sollten ein รถffentliches Gut sein, kein Profitcenter." - }, - "noAccount": { - "title": "Kein Konto erforderlich", - "description": "Beginnen Sie sofort mit der Nutzung eines beliebigen Werkzeugs. Wir brauchen weder Ihre E-Mail noch ein Passwort oder persรถnliche Informationen. Ihr Workflow sollte reibungslos und anonym sein." - }, - "openSource": { - "title": "Open-Source-Geist", - "description": "Mit Transparenz im Blick entwickelt. Wir nutzen groรŸartige Open-Source-Bibliotheken wie PDF-lib und PDF.js und glauben an die gemeinschaftsgetriebene Bemรผhung, leistungsstarke Werkzeuge fรผr alle zugรคnglich zu machen." - } - }, - "cta": { - "title": "Bereit loszulegen?", - "description": "SchlieรŸen Sie sich Tausenden von Benutzern an, die Bentopdf fรผr ihre tรคglichen Dokumentenbedรผrfnisse vertrauen. Erleben Sie den Unterschied, den Privatsphรคre und Leistung machen kรถnnen.", - "button": "Alle Werkzeuge erkunden" - } - }, - "contact": { - "title": "Kontakt aufnehmen", - "subtitle": "Wir freuen uns, von Ihnen zu hรถren. Ob Sie eine Frage, Feedback oder eine Funktionsanfrage haben, zรถgern Sie nicht, uns zu kontaktieren.", - "email": "Sie kรถnnen uns direkt per E-Mail erreichen unter:" - }, - "licensing": { - "title": "Lizenzierung fรผr", - "subtitle": "Wรคhlen Sie die Lizenz, die Ihren Anforderungen entspricht." - }, - "multiTool": { - "uploadPdfs": "PDFs hochladen", - "upload": "Hochladen", - "addBlankPage": "Leere Seite hinzufรผgen", - "edit": "Bearbeiten:", - "undo": "Rรผckgรคngig", - "redo": "Wiederholen", - "reset": "Zurรผcksetzen", - "selection": "Auswahl:", - "selectAll": "Alles auswรคhlen", - "deselectAll": "Auswahl aufheben", - "rotate": "Drehen:", - "rotateLeft": "Links", - "rotateRight": "Rechts", - "transform": "Transformieren:", - "duplicate": "Duplizieren", - "split": "Teilen", - "clear": "Lรถschen:", - "delete": "Entfernen", - "download": "Download:", - "downloadSelected": "Auswahl herunterladen", - "exportPdf": "PDF exportieren", - "uploadPdfFiles": "PDF-Dateien auswรคhlen", - "dragAndDrop": "PDF-Dateien hierhin ziehen oder klicken zum Auswรคhlen", - "selectFiles": "Dateien auswรคhlen", - "renderingPages": "Seiten werden gerendert...", - "actions": { - "duplicatePage": "Diese Seite duplizieren", - "deletePage": "Diese Seite lรถschen", - "insertPdf": "PDF nach dieser Seite einfรผgen", - "toggleSplit": "Trennung nach dieser Seite umschalten" - }, - "pleaseWait": "Bitte warten", - "pagesRendering": "Seiten werden noch gerendert. Bitte warten...", - "noPagesSelected": "Keine Seiten ausgewรคhlt", - "selectOnePage": "Bitte wรคhlen Sie mindestens eine Seite zum Herunterladen aus.", - "noPages": "Keine Seiten", - "noPagesToExport": "Keine Seiten zum Exportieren vorhanden.", - "renderingTitle": "Seiten-Vorschau wird gerendert", - "errorRendering": "Fehler beim Rendern der Seitenvorschau", - "error": "Fehler", - "failedToLoad": "Laden fehlgeschlagen" + "lightningFast": { + "title": "Blitzschnell", + "description": "PDFs sofort verarbeiten, ohne Wartezeiten." } -} \ No newline at end of file + }, + "tools": { + "title": "Starten Sie mit", + "toolsLabel": "Werkzeugen", + "subtitle": "Klicken Sie auf ein Werkzeug, um den Datei-Uploader zu รถffnen", + "searchPlaceholder": "Werkzeug suchen (z.B. 'teilen', 'organisieren'...)", + "backToTools": "Zurรผck zu den Werkzeugen", + "firstLoadNotice": "Der erste Ladevorgang dauert einen Moment, da wir unsere Konvertierungs-Engine herunterladen. Danach erfolgt jedes Laden sofort." + }, + "upload": { + "clickToSelect": "Klicken Sie, um eine Datei auszuwรคhlen", + "orDragAndDrop": "oder per Drag & Drop", + "pdfOrImages": "PDFs oder Bilder", + "filesNeverLeave": "Ihre Dateien verlassen nie Ihr Gerรคt.", + "addMore": "Weitere Dateien hinzufรผgen", + "clearAll": "Alle lรถschen", + "clearFiles": "Dateien lรถschen" + }, + "loader": { + "processing": "Verarbeitung..." + }, + "alert": { + "title": "Hinweis", + "ok": "OK" + }, + "preview": { + "title": "Dokumentvorschau", + "downloadAsPdf": "Als PDF herunterladen", + "close": "SchlieรŸen" + }, + "settings": { + "title": "Einstellungen", + "shortcuts": "Tastenkรผrzel", + "preferences": "Voreinstellungen", + "displayPreferences": "Anzeige-Einstellungen", + "searchShortcuts": "Tastenkรผrzel suchen...", + "shortcutsInfo": "Halten Sie Tasten gedrรผckt, um ein Kรผrzel festzulegen. ร„nderungen werden automatisch gespeichert.", + "shortcutsWarning": "โš ๏ธ Vermeiden Sie gรคngige Browser-Tastenkรผrzel (Strg+W, Strg+T, Strg+N usw.), da diese mรถglicherweise nicht zuverlรคssig funktionieren.", + "import": "Importieren", + "export": "Exportieren", + "resetToDefaults": "Auf Standard zurรผcksetzen", + "fullWidthMode": "Vollbreite-Modus", + "fullWidthDescription": "Verwenden Sie die volle Bildschirmbreite fรผr alle Werkzeuge anstelle eines zentrierten Containers", + "settingsAutoSaved": "Einstellungen werden automatisch gespeichert", + "clickToSet": "Klicken zum Festlegen", + "pressKeys": "Tasten drรผcken...", + "warnings": { + "alreadyInUse": "Tastenkombination bereits vergeben", + "assignedTo": "ist bereits zugewiesen an:", + "chooseDifferent": "Bitte wรคhlen Sie eine andere Tastenkombination.", + "reserved": "Warnung: Reservierte Tastenkombination", + "commonlyUsed": "wird hรคufig verwendet fรผr:", + "unreliable": "Diese Tastenkombination funktioniert mรถglicherweise nicht zuverlรคssig oder kรถnnte mit Browser-/Systemfunktionen in Konflikt geraten.", + "useAnyway": "Mรถchten Sie sie trotzdem verwenden?", + "resetTitle": "Tastenkombinationen zurรผcksetzen", + "resetMessage": "Sind Sie sicher, dass Sie alle Tastenkombinationen auf die Standardwerte zurรผcksetzen mรถchten?

Diese Aktion kann nicht rรผckgรคngig gemacht werden.", + "importSuccessTitle": "Import erfolgreich", + "importSuccessMessage": "Tastenkombinationen erfolgreich importiert!", + "importFailTitle": "Import fehlgeschlagen", + "importFailMessage": "Fehler beim Importieren der Tastenkombinationen. Ungรผltiges Dateiformat." + } + }, + "warning": { + "title": "Warnung", + "cancel": "Abbrechen", + "proceed": "Fortfahren" + }, + "compliance": { + "title": "Ihre Daten verlassen nie Ihr Gerรคt", + "weKeep": "Wir schรผtzen", + "yourInfoSafe": "Ihre Informationen", + "byFollowingStandards": "nach globalen Sicherheitsstandards.", + "processingLocal": "Die gesamte Verarbeitung erfolgt lokal auf Ihrem Gerรคt.", + "gdpr": { + "title": "DSGVO-konform", + "description": "Schรผtzt die personenbezogenen Daten und die Privatsphรคre von Personen innerhalb der Europรคischen Union." + }, + "ccpa": { + "title": "CCPA-konform", + "description": "Gibt Einwohnern Kaliforniens Rechte darรผber, wie ihre persรถnlichen Daten gesammelt, verwendet und weitergegeben werden." + }, + "hipaa": { + "title": "HIPAA-konform", + "description": "Legt SchutzmaรŸnahmen fรผr den Umgang mit sensiblen Gesundheitsinformationen im US-Gesundheitssystem fest." + } + }, + "faq": { + "title": "Hรคufig gestellte", + "questions": "Fragen", + "isFree": { + "question": "Ist BentoPDF wirklich kostenlos?", + "answer": "Ja, absolut. Alle Werkzeuge auf BentoPDF sind zu 100% kostenlos nutzbar, ohne Dateilimits, ohne Anmeldung und ohne Wasserzeichen. Wir glauben, dass jeder Zugang zu einfachen, leistungsstarken PDF-Werkzeugen verdient, ohne Bezahlschranke." + }, + "areFilesSecure": { + "question": "Sind meine Dateien sicher? Wo werden sie verarbeitet?", + "answer": "Ihre Dateien sind so sicher wie mรถglich, da sie nie Ihren Computer verlassen. Die gesamte Verarbeitung erfolgt direkt in Ihrem Webbrowser (clientseitig). Wir laden Ihre Dateien nie auf einen Server hoch, sodass Sie die vollstรคndige Privatsphรคre und Kontrolle รผber Ihre Dokumente behalten." + }, + "platforms": { + "question": "Funktioniert es auf Mac, Windows und Mobilgerรคten?", + "answer": "Ja! Da BentoPDF vollstรคndig in Ihrem Browser lรคuft, funktioniert es auf jedem Betriebssystem mit einem modernen Webbrowser, einschlieรŸlich Windows, macOS, Linux, iOS und Android." + }, + "gdprCompliant": { + "question": "Ist BentoPDF DSGVO-konform?", + "answer": "Ja. BentoPDF ist vollstรคndig DSGVO-konform. Da die gesamte Dateiverarbeitung lokal in Ihrem Browser erfolgt und wir Ihre Dateien nie sammeln oder รผbertragen, haben wir keinen Zugang zu Ihren Daten. Dies stellt sicher, dass Sie immer die Kontrolle รผber Ihre Dokumente haben." + }, + "dataStorage": { + "question": "Speichern oder verfolgen Sie meine Dateien?", + "answer": "Nein. Wir speichern, verfolgen oder protokollieren Ihre Dateien niemals. Alles, was Sie auf BentoPDF tun, geschieht im Speicher Ihres Browsers und verschwindet, sobald Sie die Seite schlieรŸen. Es gibt keine Uploads, keine Verlaufsprotokolle und keine Server." + }, + "different": { + "question": "Was unterscheidet BentoPDF von anderen PDF-Werkzeugen?", + "answer": "Die meisten PDF-Werkzeuge laden Ihre Dateien zur Verarbeitung auf einen Server hoch. BentoPDF tut das nie. Wir verwenden sichere, moderne Webtechnologie, um Ihre Dateien direkt in Ihrem Browser zu verarbeiten. Das bedeutet schnellere Leistung, stรคrkere Privatsphรคre und vollstรคndige Sicherheit." + }, + "browserBased": { + "question": "Wie schรผtzt mich die browserbasierte Verarbeitung?", + "answer": "Durch die vollstรคndige Ausfรผhrung in Ihrem Browser stellt BentoPDF sicher, dass Ihre Dateien nie Ihr Gerรคt verlassen. Dies eliminiert die Risiken von Server-Hacks, Datenschutzverletzungen oder unbefugtem Zugriff. Ihre Dateien bleiben Ihre โ€” immer." + }, + "analytics": { + "question": "Verwenden Sie Cookies oder Analysen, um mich zu verfolgen?", + "answer": "Uns liegt Ihre Privatsphรคre am Herzen. BentoPDF verfolgt keine persรถnlichen Informationen. Wir verwenden Simple Analytics ausschlieรŸlich, um anonyme Besucherzahlen zu sehen. Das bedeutet, wir kรถnnen wissen, wie viele Benutzer unsere Seite besuchen, aber wir wissen nie, wer Sie sind. Simple Analytics ist vollstรคndig DSGVO-konform und respektiert Ihre Privatsphรคre." + } + }, + "testimonials": { + "title": "Was unsere", + "users": "Nutzer", + "say": "sagen" + }, + "support": { + "title": "Gefรคllt Ihnen meine Arbeit?", + "description": "BentoPDF ist ein Leidenschaftsprojekt, entwickelt um ein kostenloses, privates und leistungsstarkes PDF-Toolkit fรผr alle bereitzustellen. Wenn Sie es nรผtzlich finden, erwรคgen Sie, die Entwicklung zu unterstรผtzen. Jeder Kaffee hilft!", + "buyMeCoffee": "Kauf mir einen Kaffee" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. Alle Rechte vorbehalten.", + "version": "Version", + "company": "Unternehmen", + "aboutUs": "รœber uns", + "faqLink": "FAQ", + "contactUs": "Kontakt", + "legal": "Rechtliches", + "termsAndConditions": "Nutzungsbedingungen", + "privacyPolicy": "Datenschutzrichtlinie", + "followUs": "Folgen Sie uns" + }, + "merge": { + "title": "PDFs zusammenfรผhren", + "description": "Kombinieren Sie ganze Dateien oder wรคhlen Sie bestimmte Seiten zum Zusammenfรผhren in ein neues Dokument.", + "fileMode": "Datei-Modus", + "pageMode": "Seiten-Modus", + "howItWorks": "So funktioniert es:", + "fileModeInstructions": [ + "Klicken und ziehen Sie das Symbol, um die Reihenfolge der Dateien zu รคndern.", + "Im Feld \"Seiten\" fรผr jede Datei kรถnnen Sie Bereiche angeben (z.B. \"1-3, 5\"), um nur diese Seiten zusammenzufรผhren.", + "Lassen Sie das Feld \"Seiten\" leer, um alle Seiten dieser Datei einzuschlieรŸen." + ], + "pageModeInstructions": [ + "Alle Seiten Ihrer hochgeladenen PDFs werden unten angezeigt.", + "Ziehen Sie einfach die einzelnen Seitenvorschauen per Drag & Drop, um die gewรผnschte Reihenfolge fรผr Ihre neue Datei zu erstellen." + ], + "mergePdfs": "PDFs zusammenfรผhren" + }, + "common": { + "page": "Seite", + "pages": "Seiten", + "of": "von", + "download": "Herunterladen", + "cancel": "Abbrechen", + "save": "Speichern", + "delete": "Lรถschen", + "edit": "Bearbeiten", + "add": "Hinzufรผgen", + "remove": "Entfernen", + "loading": "Laden...", + "error": "Fehler", + "success": "Erfolg", + "file": "Datei", + "files": "Dateien", + "close": "SchlieรŸen" + }, + "about": { + "hero": { + "title": "Wir glauben PDF-Werkzeuge sollten", + "subtitle": "schnell, privat und kostenlos sein.", + "noCompromises": "Ohne Kompromisse." + }, + "mission": { + "title": "Unsere Mission", + "description": "Die umfassendste PDF-Toolbox bereitzustellen, die Ihre Privatsphรคre respektiert und niemals eine Bezahlung verlangt. Wir glauben, dass wichtige Dokumentenwerkzeuge fรผr jeden, รผberall und ohne Barrieren zugรคnglich sein sollten." + }, + "philosophy": { + "label": "Unsere Kernphilosophie", + "title": "Privatsphรคre zuerst. Immer.", + "description": "In einer Zeit, in der Daten eine Ware sind, gehen wir einen anderen Weg. Die gesamte Verarbeitung fรผr Bentopdf-Werkzeuge erfolgt lokal in Ihrem Browser. Das bedeutet, Ihre Dateien berรผhren niemals unsere Server, wir sehen Ihre Dokumente nie und verfolgen nicht, was Sie tun. Ihre Dokumente bleiben vollstรคndig und unmissverstรคndlich privat. Es ist nicht nur eine Funktion; es ist unser Fundament." + }, + "whyBentopdf": { + "title": "Warum", + "speed": { + "title": "Fรผr Geschwindigkeit gebaut", + "description": "Kein Warten auf Uploads oder Downloads zu einem Server. Durch die Verarbeitung von Dateien direkt in Ihrem Browser mit modernen Webtechnologien wie WebAssembly bieten wir unvergleichliche Geschwindigkeit fรผr alle unsere Werkzeuge." + }, + "free": { + "title": "Komplett kostenlos", + "description": "Keine Testversionen, keine Abonnements, keine versteckten Gebรผhren und keine \"Premium\"-Funktionen als Geiseln. Wir glauben, leistungsstarke PDF-Werkzeuge sollten ein รถffentliches Gut sein, kein Profitcenter." + }, + "noAccount": { + "title": "Kein Konto erforderlich", + "description": "Beginnen Sie sofort mit der Nutzung eines beliebigen Werkzeugs. Wir brauchen weder Ihre E-Mail noch ein Passwort oder persรถnliche Informationen. Ihr Workflow sollte reibungslos und anonym sein." + }, + "openSource": { + "title": "Open-Source-Geist", + "description": "Mit Transparenz im Blick entwickelt. Wir nutzen groรŸartige Open-Source-Bibliotheken wie PDF-lib und PDF.js und glauben an die gemeinschaftsgetriebene Bemรผhung, leistungsstarke Werkzeuge fรผr alle zugรคnglich zu machen." + } + }, + "cta": { + "title": "Bereit loszulegen?", + "description": "SchlieรŸen Sie sich Tausenden von Benutzern an, die Bentopdf fรผr ihre tรคglichen Dokumentenbedรผrfnisse vertrauen. Erleben Sie den Unterschied, den Privatsphรคre und Leistung machen kรถnnen.", + "button": "Alle Werkzeuge erkunden" + } + }, + "contact": { + "title": "Kontakt aufnehmen", + "subtitle": "Wir freuen uns, von Ihnen zu hรถren. Ob Sie eine Frage, Feedback oder eine Funktionsanfrage haben, zรถgern Sie nicht, uns zu kontaktieren.", + "email": "Sie kรถnnen uns direkt per E-Mail erreichen unter:" + }, + "licensing": { + "title": "Lizenzierung fรผr", + "subtitle": "Wรคhlen Sie die Lizenz, die Ihren Anforderungen entspricht." + }, + "multiTool": { + "uploadPdfs": "PDFs hochladen", + "upload": "Hochladen", + "addBlankPage": "Leere Seite hinzufรผgen", + "edit": "Bearbeiten:", + "undo": "Rรผckgรคngig", + "redo": "Wiederholen", + "reset": "Zurรผcksetzen", + "selection": "Auswahl:", + "selectAll": "Alles auswรคhlen", + "deselectAll": "Auswahl aufheben", + "rotate": "Drehen:", + "rotateLeft": "Links", + "rotateRight": "Rechts", + "transform": "Transformieren:", + "duplicate": "Duplizieren", + "split": "Teilen", + "clear": "Lรถschen:", + "delete": "Entfernen", + "download": "Download:", + "downloadSelected": "Auswahl herunterladen", + "exportPdf": "PDF exportieren", + "uploadPdfFiles": "PDF-Dateien auswรคhlen", + "dragAndDrop": "PDF-Dateien hierhin ziehen oder klicken zum Auswรคhlen", + "selectFiles": "Dateien auswรคhlen", + "renderingPages": "Seiten werden gerendert...", + "actions": { + "duplicatePage": "Diese Seite duplizieren", + "deletePage": "Diese Seite lรถschen", + "insertPdf": "PDF nach dieser Seite einfรผgen", + "toggleSplit": "Trennung nach dieser Seite umschalten" + }, + "pleaseWait": "Bitte warten", + "pagesRendering": "Seiten werden noch gerendert. Bitte warten...", + "noPagesSelected": "Keine Seiten ausgewรคhlt", + "selectOnePage": "Bitte wรคhlen Sie mindestens eine Seite zum Herunterladen aus.", + "noPages": "Keine Seiten", + "noPagesToExport": "Keine Seiten zum Exportieren vorhanden.", + "renderingTitle": "Seiten-Vorschau wird gerendert", + "errorRendering": "Fehler beim Rendern der Seitenvorschau", + "error": "Fehler", + "failedToLoad": "Laden fehlgeschlagen" + } +} diff --git a/public/locales/de/tools.json b/public/locales/de/tools.json index d91af6e..769e591 100644 --- a/public/locales/de/tools.json +++ b/public/locales/de/tools.json @@ -521,5 +521,13 @@ "subtitle": "E-Mail-Dateien (EML, MSG) in PDF-Format konvertieren. Unterstรผtzt Outlook-Exporte und Standard-E-Mail-Formate.", "acceptedFormats": "EML, MSG-Dateien", "convertButton": "In PDF konvertieren" + }, + "fontToOutline": { + "name": "Schriftart zu Umriss", + "subtitle": "Alle Schriftarten in Vektorumrisse fรผr konsistente Darstellung auf allen Gerรคten konvertieren." + }, + "deskewPdf": { + "name": "PDF entzerren", + "subtitle": "Automatisch schiefe gescannte Seiten mit OpenCV begradigen." } } diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 754ae64..6550530 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -1,323 +1,325 @@ { - "nav": { - "home": "Home", - "about": "About", - "contact": "Contact", - "licensing": "Licensing", - "allTools": "All Tools", - "openMainMenu": "Open main menu", - "language": "Language" + "nav": { + "home": "Home", + "about": "About", + "contact": "Contact", + "licensing": "Licensing", + "allTools": "All Tools", + "openMainMenu": "Open main menu", + "language": "Language" + }, + "donation": { + "message": "Love BentoPDF? Help us keep it free and open source!", + "button": "Donate" + }, + "hero": { + "title": "The", + "pdfToolkit": "PDF Toolkit", + "builtForPrivacy": "built for privacy", + "noSignups": "No Signups", + "unlimitedUse": "Unlimited Use", + "worksOffline": "Works Offline", + "startUsing": "Start Using Now" + }, + "usedBy": { + "title": "Used by companies and people working at" + }, + "features": { + "title": "Why choose", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "No Signup", + "description": "Start instantly, no accounts or emails." }, - "donation": { - "message": "Love BentoPDF? Help us keep it free and open source!", - "button": "Donate" + "noUploads": { + "title": "No Uploads", + "description": "100% client-side, your files never leave your device." }, - "hero": { - "title": "The", - "pdfToolkit": "PDF Toolkit", - "builtForPrivacy": "built for privacy", - "noSignups": "No Signups", - "unlimitedUse": "Unlimited Use", - "worksOffline": "Works Offline", - "startUsing": "Start Using Now" + "foreverFree": { + "title": "Forever Free", + "description": "All tools, no trials, no paywalls." }, - "usedBy": { - "title": "Used by companies and people working at" + "noLimits": { + "title": "No Limits", + "description": "Use as much as you want, no hidden caps." }, - "features": { - "title": "Why choose", - "bentoPdf": "BentoPDF?", - "noSignup": { - "title": "No Signup", - "description": "Start instantly, no accounts or emails." - }, - "noUploads": { - "title": "No Uploads", - "description": "100% client-side, your files never leave your device." - }, - "foreverFree": { - "title": "Forever Free", - "description": "All tools, no trials, no paywalls." - }, - "noLimits": { - "title": "No Limits", - "description": "Use as much as you want, no hidden caps." - }, - "batchProcessing": { - "title": "Batch Processing", - "description": "Handle unlimited PDFs in one go." - }, - "lightningFast": { - "title": "Lightning Fast", - "description": "Process PDFs instantly, without waiting or delays." - } + "batchProcessing": { + "title": "Batch Processing", + "description": "Handle unlimited PDFs in one go." }, - "tools": { - "title": "Get Started with", - "toolsLabel": "Tools", - "subtitle": "Click a tool to open the file uploader", - "searchPlaceholder": "Search for a tool (e.g., 'split', 'organize'...)", - "backToTools": "Back to Tools", - "firstLoadNotice": "First load takes a moment as we download our conversion engine. After that, all loads will be instant." - }, - "upload": { - "clickToSelect": "Click to select a file", - "orDragAndDrop": "or drag and drop", - "pdfOrImages": "PDFs or Images", - "filesNeverLeave": "Your files never leave your device.", - "addMore": "Add More Files", - "clearAll": "Clear All" - }, - "loader": { - "processing": "Processing..." - }, - "alert": { - "title": "Alert", - "ok": "OK" - }, - "preview": { - "title": "Document Preview", - "downloadAsPdf": "Download as PDF", - "close": "Close" - }, - "settings": { - "title": "Settings", - "shortcuts": "Shortcuts", - "preferences": "Preferences", - "displayPreferences": "Display Preferences", - "searchShortcuts": "Search shortcuts...", - "shortcutsInfo": "Press and hold keys to set a shortcut. Changes are auto-saved.", - "shortcutsWarning": "โš ๏ธ Avoid common browser shortcuts (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N etc.) as they may not work reliably.", - "import": "Import", - "export": "Export", - "resetToDefaults": "Reset to Defaults", - "fullWidthMode": "Full Width Mode", - "fullWidthDescription": "Use the full screen width for all tools instead of a centered container", - "settingsAutoSaved": "Settings are automatically saved", - "clickToSet": "Click to set", - "pressKeys": "Press keys...", - "warnings": { - "alreadyInUse": "Shortcut Already in Use", - "assignedTo": "is already assigned to:", - "chooseDifferent": "Please choose a different shortcut.", - "reserved": "Reserved Shortcut Warning", - "commonlyUsed": "is commonly used for:", - "unreliable": "This shortcut may not work reliably or might conflict with browser/system behavior.", - "useAnyway": "Do you want to use it anyway?", - "resetTitle": "Reset Shortcuts", - "resetMessage": "Are you sure you want to reset all shortcuts to default?

This action cannot be undone.", - "importSuccessTitle": "Import Successful", - "importSuccessMessage": "Shortcuts imported successfully!", - "importFailTitle": "Import Failed", - "importFailMessage": "Failed to import shortcuts. Invalid file format." - } - }, - "warning": { - "title": "Warning", - "cancel": "Cancel", - "proceed": "Proceed" - }, - "compliance": { - "title": "Your data never leaves your device", - "weKeep": "We keep", - "yourInfoSafe": "your information safe", - "byFollowingStandards": "by following global security standards.", - "processingLocal": "All the processing happens locally on your device.", - "gdpr": { - "title": "GDPR compliance", - "description": "Protects the personal data and privacy of individuals within the European Union." - }, - "ccpa": { - "title": "CCPA compliance", - "description": "Gives California residents rights over how their personal information is collected, used, and shared." - }, - "hipaa": { - "title": "HIPAA compliance", - "description": "Sets safeguards for handling sensitive health information in the United States healthcare system." - } - }, - "faq": { - "title": "Frequently Asked", - "questions": "Questions", - "isFree": { - "question": "Is BentoPDF really free?", - "answer": "Yes, absolutely. All tools on BentoPDF are 100% free to use, with no file limits, no sign-ups, and no watermarks. We believe everyone deserves access to simple, powerful PDF tools without a paywall." - }, - "areFilesSecure": { - "question": "Are my files secure? Where are they processed?", - "answer": "Your files are as secure as possible because they never leave your computer. All processing happens directly in your web browser (client-side). We never upload your files to a server, so you maintain complete privacy and control over your documents." - }, - "platforms": { - "question": "Does it work on Mac, Windows, and Mobile?", - "answer": "Yes! Since BentoPDF runs entirely in your browser, it works on any operating system with a modern web browser, including Windows, macOS, Linux, iOS, and Android." - }, - "gdprCompliant": { - "question": "Is BentoPDF GDPR compliant?", - "answer": "Yes. BentoPDF is fully GDPR compliant. Since all file processing happens locally in your browser and we never collect or transmit your files to any server, we have no access to your data. This ensures you are always in control of your documents." - }, - "dataStorage": { - "question": "Do you store or track any of my files?", - "answer": "No. We never store, track, or log your files. Everything you do on BentoPDF happens in your browser memory and disappears once you close the page. There are no uploads, no history logs, and no servers involved." - }, - "different": { - "question": "What makes BentoPDF different from other PDF tools?", - "answer": "Most PDF tools upload your files to a server for processing. BentoPDF never does that. We use secure, modern web technology to process your files directly in your browser. This means faster performance, stronger privacy, and complete peace of mind." - }, - "browserBased": { - "question": "How does browser-based processing keep me safe?", - "answer": "By running entirely inside your browser, BentoPDF ensures that your files never leave your device. This eliminates the risks of server hacks, data breaches, or unauthorized access. Your files remain yoursโ€”always." - }, - "analytics": { - "question": "Do you use cookies or analytics to track me?", - "answer": "We care about your privacy. BentoPDF does not track personal information. We use Simple Analytics solely to see anonymous visit counts. This means we can know how many users visit our site, but we never know who you are. Simple Analytics is fully GDPR-compliant and respects your privacy." - } - }, - "testimonials": { - "title": "What Our", - "users": "Users", - "say": "Say" - }, - "support": { - "title": "Like My Work?", - "description": "BentoPDF is a passion project, built to provide a free, private, and powerful PDF toolkit for everyone. If you find it useful, consider supporting its development. Every coffee helps!", - "buyMeCoffee": "Buy Me a Coffee" - }, - "footer": { - "copyright": "ยฉ 2025 BentoPDF. All rights reserved.", - "version": "Version", - "company": "Company", - "aboutUs": "About Us", - "faqLink": "FAQ", - "contactUs": "Contact Us", - "legal": "Legal", - "termsAndConditions": "Terms and Conditions", - "privacyPolicy": "Privacy Policy", - "followUs": "Follow Us" - }, - "merge": { - "title": "Merge PDFs", - "description": "Combine whole files, or select specific pages to merge into a new document.", - "fileMode": "File Mode", - "pageMode": "Page Mode", - "howItWorks": "How it works:", - "fileModeInstructions": [ - "Click and drag the icon to change the order of the files.", - "In the \"Pages\" box for each file, you can specify ranges (e.g., \"1-3, 5\") to merge only those pages.", - "Leave the \"Pages\" box blank to include all pages from that file." - ], - "pageModeInstructions": [ - "All pages from your uploaded PDFs are shown below.", - "Simply drag and drop the individual page thumbnails to create the exact order you want for your new file." - ], - "mergePdfs": "Merge PDFs" - }, - "common": { - "page": "Page", - "pages": "Pages", - "of": "of", - "download": "Download", - "cancel": "Cancel", - "save": "Save", - "delete": "Delete", - "edit": "Edit", - "add": "Add", - "remove": "Remove", - "loading": "Loading...", - "error": "Error", - "success": "Success", - "file": "File", - "files": "Files" - }, - "about": { - "hero": { - "title": "We believe PDF tools should be", - "subtitle": "fast, private, and free.", - "noCompromises": "No compromises." - }, - "mission": { - "title": "Our Mission", - "description": "To provide the most comprehensive PDF toolbox that respects your privacy and never asks for payment. We believe essential document tools should be accessible to everyone, everywhere, without barriers." - }, - "philosophy": { - "label": "Our Core Philosophy", - "title": "Privacy First. Always.", - "description": "In an era where data is a commodity, we take a different approach. All processing for Bentopdf tools happens locally in your browser. This means your files never touch our servers, we never see your documents, and we don't track what you do. Your documents remain completely and unequivocally private. It's not just a feature; it's our foundation." - }, - "whyBentopdf": { - "title": "Why", - "speed": { - "title": "Built for Speed", - "description": "No waiting for uploads or downloads to a server. By processing files directly in your browser using modern web technologies like WebAssembly, we offer unparalleled speed for all our tools." - }, - "free": { - "title": "Completely Free", - "description": "No trials, no subscriptions, no hidden fees, and no \"premium\" features held hostage. We believe powerful PDF tools should be a public utility, not a profit center." - }, - "noAccount": { - "title": "No Account Required", - "description": "Start using any tool immediately. We don't need your email, a password, or any personal information. Your workflow should be frictionless and anonymous." - }, - "openSource": { - "title": "Open Source Spirit", - "description": "Built with transparency in mind. We leverage incredible open-source libraries like PDF-lib and PDF.js, and believe in the community-driven effort to make powerful tools accessible to everyone." - } - }, - "cta": { - "title": "Ready to get started?", - "description": "Join thousands of users who trust Bentopdf for their daily document needs. Experience the difference that privacy and performance can make.", - "button": "Explore All Tools" - } - }, - "contact": { - "title": "Get in Touch", - "subtitle": "We'd love to hear from you. Whether you have a question, feedback, or a feature request, please don't hesitate to reach out.", - "email": "You can reach us directly by email at:" - }, - "licensing": { - "title": "Licensing for", - "subtitle": "Choose the license that fits your needs." - }, - "multiTool": { - "uploadPdfs": "Upload PDFs", - "upload": "Upload", - "addBlankPage": "Add Blank Page", - "edit": "Edit:", - "undo": "Undo", - "redo": "Redo", - "reset": "Reset", - "selection": "Selection:", - "selectAll": "Select All", - "deselectAll": "Deselect All", - "rotate": "Rotate:", - "rotateLeft": "Left", - "rotateRight": "Right", - "transform": "Transform:", - "duplicate": "Duplicate", - "split": "Split", - "clear": "Clear:", - "delete": "Delete", - "download": "Download:", - "downloadSelected": "Download Selected", - "exportPdf": "Export PDF", - "uploadPdfFiles": "Select PDF Files", - "dragAndDrop": "Drag and drop PDF files here, or click to select", - "selectFiles": "Select Files", - "renderingPages": "Rendering pages...", - "actions": { - "duplicatePage": "Duplicate this page", - "deletePage": "Delete this page", - "insertPdf": "Insert PDF after this page", - "toggleSplit": "Toggle split after this page" - }, - "pleaseWait": "Please Wait", - "pagesRendering": "Pages are still being rendered. Please wait...", - "noPagesSelected": "No Pages Selected", - "selectOnePage": "Please select at least one page to download.", - "noPages": "No Pages", - "noPagesToExport": "There are no pages to export.", - "renderingTitle": "Rendering page previews", - "errorRendering": "Failed to render page thumbnails", - "error": "Error", - "failedToLoad": "Failed to load" + "lightningFast": { + "title": "Lightning Fast", + "description": "Process PDFs instantly, without waiting or delays." } -} \ No newline at end of file + }, + "tools": { + "title": "Get Started with", + "toolsLabel": "Tools", + "subtitle": "Click a tool to open the file uploader", + "searchPlaceholder": "Search for a tool (e.g., 'split', 'organize'...)", + "backToTools": "Back to Tools", + "firstLoadNotice": "First load takes a moment as we download our conversion engine. After that, all loads will be instant." + }, + "upload": { + "clickToSelect": "Click to select a file", + "orDragAndDrop": "or drag and drop", + "pdfOrImages": "PDFs or Images", + "filesNeverLeave": "Your files never leave your device.", + "addMore": "Add More Files", + "clearAll": "Clear All", + "clearFiles": "Clear Files" + }, + "loader": { + "processing": "Processing..." + }, + "alert": { + "title": "Alert", + "ok": "OK" + }, + "preview": { + "title": "Document Preview", + "downloadAsPdf": "Download as PDF", + "close": "Close" + }, + "settings": { + "title": "Settings", + "shortcuts": "Shortcuts", + "preferences": "Preferences", + "displayPreferences": "Display Preferences", + "searchShortcuts": "Search shortcuts...", + "shortcutsInfo": "Press and hold keys to set a shortcut. Changes are auto-saved.", + "shortcutsWarning": "โš ๏ธ Avoid common browser shortcuts (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N etc.) as they may not work reliably.", + "import": "Import", + "export": "Export", + "resetToDefaults": "Reset to Defaults", + "fullWidthMode": "Full Width Mode", + "fullWidthDescription": "Use the full screen width for all tools instead of a centered container", + "settingsAutoSaved": "Settings are automatically saved", + "clickToSet": "Click to set", + "pressKeys": "Press keys...", + "warnings": { + "alreadyInUse": "Shortcut Already in Use", + "assignedTo": "is already assigned to:", + "chooseDifferent": "Please choose a different shortcut.", + "reserved": "Reserved Shortcut Warning", + "commonlyUsed": "is commonly used for:", + "unreliable": "This shortcut may not work reliably or might conflict with browser/system behavior.", + "useAnyway": "Do you want to use it anyway?", + "resetTitle": "Reset Shortcuts", + "resetMessage": "Are you sure you want to reset all shortcuts to default?

This action cannot be undone.", + "importSuccessTitle": "Import Successful", + "importSuccessMessage": "Shortcuts imported successfully!", + "importFailTitle": "Import Failed", + "importFailMessage": "Failed to import shortcuts. Invalid file format." + } + }, + "warning": { + "title": "Warning", + "cancel": "Cancel", + "proceed": "Proceed" + }, + "compliance": { + "title": "Your data never leaves your device", + "weKeep": "We keep", + "yourInfoSafe": "your information safe", + "byFollowingStandards": "by following global security standards.", + "processingLocal": "All the processing happens locally on your device.", + "gdpr": { + "title": "GDPR compliance", + "description": "Protects the personal data and privacy of individuals within the European Union." + }, + "ccpa": { + "title": "CCPA compliance", + "description": "Gives California residents rights over how their personal information is collected, used, and shared." + }, + "hipaa": { + "title": "HIPAA compliance", + "description": "Sets safeguards for handling sensitive health information in the United States healthcare system." + } + }, + "faq": { + "title": "Frequently Asked", + "questions": "Questions", + "isFree": { + "question": "Is BentoPDF really free?", + "answer": "Yes, absolutely. All tools on BentoPDF are 100% free to use, with no file limits, no sign-ups, and no watermarks. We believe everyone deserves access to simple, powerful PDF tools without a paywall." + }, + "areFilesSecure": { + "question": "Are my files secure? Where are they processed?", + "answer": "Your files are as secure as possible because they never leave your computer. All processing happens directly in your web browser (client-side). We never upload your files to a server, so you maintain complete privacy and control over your documents." + }, + "platforms": { + "question": "Does it work on Mac, Windows, and Mobile?", + "answer": "Yes! Since BentoPDF runs entirely in your browser, it works on any operating system with a modern web browser, including Windows, macOS, Linux, iOS, and Android." + }, + "gdprCompliant": { + "question": "Is BentoPDF GDPR compliant?", + "answer": "Yes. BentoPDF is fully GDPR compliant. Since all file processing happens locally in your browser and we never collect or transmit your files to any server, we have no access to your data. This ensures you are always in control of your documents." + }, + "dataStorage": { + "question": "Do you store or track any of my files?", + "answer": "No. We never store, track, or log your files. Everything you do on BentoPDF happens in your browser memory and disappears once you close the page. There are no uploads, no history logs, and no servers involved." + }, + "different": { + "question": "What makes BentoPDF different from other PDF tools?", + "answer": "Most PDF tools upload your files to a server for processing. BentoPDF never does that. We use secure, modern web technology to process your files directly in your browser. This means faster performance, stronger privacy, and complete peace of mind." + }, + "browserBased": { + "question": "How does browser-based processing keep me safe?", + "answer": "By running entirely inside your browser, BentoPDF ensures that your files never leave your device. This eliminates the risks of server hacks, data breaches, or unauthorized access. Your files remain yoursโ€”always." + }, + "analytics": { + "question": "Do you use cookies or analytics to track me?", + "answer": "We care about your privacy. BentoPDF does not track personal information. We use Simple Analytics solely to see anonymous visit counts. This means we can know how many users visit our site, but we never know who you are. Simple Analytics is fully GDPR-compliant and respects your privacy." + } + }, + "testimonials": { + "title": "What Our", + "users": "Users", + "say": "Say" + }, + "support": { + "title": "Like My Work?", + "description": "BentoPDF is a passion project, built to provide a free, private, and powerful PDF toolkit for everyone. If you find it useful, consider supporting its development. Every coffee helps!", + "buyMeCoffee": "Buy Me a Coffee" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. All rights reserved.", + "version": "Version", + "company": "Company", + "aboutUs": "About Us", + "faqLink": "FAQ", + "contactUs": "Contact Us", + "legal": "Legal", + "termsAndConditions": "Terms and Conditions", + "privacyPolicy": "Privacy Policy", + "followUs": "Follow Us" + }, + "merge": { + "title": "Merge PDFs", + "description": "Combine whole files, or select specific pages to merge into a new document.", + "fileMode": "File Mode", + "pageMode": "Page Mode", + "howItWorks": "How it works:", + "fileModeInstructions": [ + "Click and drag the icon to change the order of the files.", + "In the \"Pages\" box for each file, you can specify ranges (e.g., \"1-3, 5\") to merge only those pages.", + "Leave the \"Pages\" box blank to include all pages from that file." + ], + "pageModeInstructions": [ + "All pages from your uploaded PDFs are shown below.", + "Simply drag and drop the individual page thumbnails to create the exact order you want for your new file." + ], + "mergePdfs": "Merge PDFs" + }, + "common": { + "page": "Page", + "pages": "Pages", + "of": "of", + "download": "Download", + "cancel": "Cancel", + "save": "Save", + "delete": "Delete", + "edit": "Edit", + "add": "Add", + "remove": "Remove", + "loading": "Loading...", + "error": "Error", + "success": "Success", + "file": "File", + "files": "Files", + "close": "Close" + }, + "about": { + "hero": { + "title": "We believe PDF tools should be", + "subtitle": "fast, private, and free.", + "noCompromises": "No compromises." + }, + "mission": { + "title": "Our Mission", + "description": "To provide the most comprehensive PDF toolbox that respects your privacy and never asks for payment. We believe essential document tools should be accessible to everyone, everywhere, without barriers." + }, + "philosophy": { + "label": "Our Core Philosophy", + "title": "Privacy First. Always.", + "description": "In an era where data is a commodity, we take a different approach. All processing for Bentopdf tools happens locally in your browser. This means your files never touch our servers, we never see your documents, and we don't track what you do. Your documents remain completely and unequivocally private. It's not just a feature; it's our foundation." + }, + "whyBentopdf": { + "title": "Why", + "speed": { + "title": "Built for Speed", + "description": "No waiting for uploads or downloads to a server. By processing files directly in your browser using modern web technologies like WebAssembly, we offer unparalleled speed for all our tools." + }, + "free": { + "title": "Completely Free", + "description": "No trials, no subscriptions, no hidden fees, and no \"premium\" features held hostage. We believe powerful PDF tools should be a public utility, not a profit center." + }, + "noAccount": { + "title": "No Account Required", + "description": "Start using any tool immediately. We don't need your email, a password, or any personal information. Your workflow should be frictionless and anonymous." + }, + "openSource": { + "title": "Open Source Spirit", + "description": "Built with transparency in mind. We leverage incredible open-source libraries like PDF-lib and PDF.js, and believe in the community-driven effort to make powerful tools accessible to everyone." + } + }, + "cta": { + "title": "Ready to get started?", + "description": "Join thousands of users who trust Bentopdf for their daily document needs. Experience the difference that privacy and performance can make.", + "button": "Explore All Tools" + } + }, + "contact": { + "title": "Get in Touch", + "subtitle": "We'd love to hear from you. Whether you have a question, feedback, or a feature request, please don't hesitate to reach out.", + "email": "You can reach us directly by email at:" + }, + "licensing": { + "title": "Licensing for", + "subtitle": "Choose the license that fits your needs." + }, + "multiTool": { + "uploadPdfs": "Upload PDFs", + "upload": "Upload", + "addBlankPage": "Add Blank Page", + "edit": "Edit:", + "undo": "Undo", + "redo": "Redo", + "reset": "Reset", + "selection": "Selection:", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "rotate": "Rotate:", + "rotateLeft": "Left", + "rotateRight": "Right", + "transform": "Transform:", + "duplicate": "Duplicate", + "split": "Split", + "clear": "Clear:", + "delete": "Delete", + "download": "Download:", + "downloadSelected": "Download Selected", + "exportPdf": "Export PDF", + "uploadPdfFiles": "Select PDF Files", + "dragAndDrop": "Drag and drop PDF files here, or click to select", + "selectFiles": "Select Files", + "renderingPages": "Rendering pages...", + "actions": { + "duplicatePage": "Duplicate this page", + "deletePage": "Delete this page", + "insertPdf": "Insert PDF after this page", + "toggleSplit": "Toggle split after this page" + }, + "pleaseWait": "Please Wait", + "pagesRendering": "Pages are still being rendered. Please wait...", + "noPagesSelected": "No Pages Selected", + "selectOnePage": "Please select at least one page to download.", + "noPages": "No Pages", + "noPagesToExport": "There are no pages to export.", + "renderingTitle": "Rendering page previews", + "errorRendering": "Failed to render page thumbnails", + "error": "Error", + "failedToLoad": "Failed to load" + } +} diff --git a/public/locales/en/tools.json b/public/locales/en/tools.json index a85839c..e093480 100644 --- a/public/locales/en/tools.json +++ b/public/locales/en/tools.json @@ -521,5 +521,13 @@ "subtitle": "Convert email files (EML, MSG) to PDF format. Supports Outlook exports and standard email formats.", "acceptedFormats": "EML, MSG files", "convertButton": "Convert to PDF" + }, + "fontToOutline": { + "name": "Font to Outline", + "subtitle": "Convert all fonts to vector outlines for consistent rendering across all devices." + }, + "deskewPdf": { + "name": "Deskew PDF", + "subtitle": "Automatically straighten tilted scanned pages using OpenCV." } } diff --git a/public/locales/es/common.json b/public/locales/es/common.json new file mode 100644 index 0000000..274f081 --- /dev/null +++ b/public/locales/es/common.json @@ -0,0 +1,325 @@ +{ + "nav": { + "home": "Inicio", + "about": "Acerca de", + "contact": "Contacto", + "licensing": "Licencias", + "allTools": "Todas las Herramientas", + "openMainMenu": "Abrir menรบ principal", + "language": "Idioma" + }, + "donation": { + "message": "ยฟTe encanta BentoPDF? ยกAyรบdanos a mantenerlo gratis y de cรณdigo abierto!", + "button": "Donar" + }, + "hero": { + "title": "El", + "pdfToolkit": "Kit de Herramientas PDF", + "builtForPrivacy": "diseรฑado para la privacidad", + "noSignups": "Sin Registro", + "unlimitedUse": "Uso Ilimitado", + "worksOffline": "Funciona Sin Conexiรณn", + "startUsing": "Comenzar a Usar Ahora" + }, + "usedBy": { + "title": "Usado por empresas y personas que trabajan en" + }, + "features": { + "title": "ยฟPor quรฉ elegir", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "Sin Registro", + "description": "Comienza al instante, sin cuentas ni correos electrรณnicos." + }, + "noUploads": { + "title": "Sin Cargas", + "description": "100% del lado del cliente, tus archivos nunca salen de tu dispositivo." + }, + "foreverFree": { + "title": "Gratis para Siempre", + "description": "Todas las herramientas, sin pruebas, sin restricciones de pago." + }, + "noLimits": { + "title": "Sin Lรญmites", + "description": "Usa tanto como quieras, sin lรญmites ocultos." + }, + "batchProcessing": { + "title": "Procesamiento por Lotes", + "description": "Maneja PDFs ilimitados de una sola vez." + }, + "lightningFast": { + "title": "Ultrarrรกpido", + "description": "Procesa PDFs al instante, sin esperas ni retrasos." + } + }, + "tools": { + "title": "Comienza con", + "toolsLabel": "Herramientas", + "subtitle": "Haz clic en una herramienta para abrir el cargador de archivos", + "searchPlaceholder": "Buscar una herramienta (ej., 'dividir', 'organizar'...)", + "backToTools": "Volver a Herramientas", + "firstLoadNotice": "La primera carga toma un momento mientras descargamos nuestro motor de conversiรณn. Despuรฉs de eso, todas las cargas serรกn instantรกneas." + }, + "upload": { + "clickToSelect": "Haz clic para seleccionar un archivo", + "orDragAndDrop": "o arrastra y suelta", + "pdfOrImages": "PDFs o Imรกgenes", + "filesNeverLeave": "Tus archivos nunca salen de tu dispositivo.", + "addMore": "Agregar Mรกs Archivos", + "clearAll": "Limpiar Todo", + "clearFiles": "Borrar archivos" + }, + "loader": { + "processing": "Procesando..." + }, + "alert": { + "title": "Alerta", + "ok": "OK" + }, + "preview": { + "title": "Vista Previa del Documento", + "downloadAsPdf": "Descargar como PDF", + "close": "Cerrar" + }, + "settings": { + "title": "Configuraciรณn", + "shortcuts": "Atajos", + "preferences": "Preferencias", + "displayPreferences": "Preferencias de Visualizaciรณn", + "searchShortcuts": "Buscar atajos...", + "shortcutsInfo": "Mantรฉn presionadas las teclas para establecer un atajo. Los cambios se guardan automรกticamente.", + "shortcutsWarning": "โš ๏ธ Evita los atajos comunes del navegador (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N, etc.) ya que pueden no funcionar de manera confiable.", + "import": "Importar", + "export": "Exportar", + "resetToDefaults": "Restaurar Valores Predeterminados", + "fullWidthMode": "Modo de Ancho Completo", + "fullWidthDescription": "Usa el ancho completo de la pantalla para todas las herramientas en lugar de un contenedor centrado", + "settingsAutoSaved": "La configuraciรณn se guarda automรกticamente", + "clickToSet": "Haz clic para establecer", + "pressKeys": "Presiona teclas...", + "warnings": { + "alreadyInUse": "Atajo Ya en Uso", + "assignedTo": "ya estรก asignado a:", + "chooseDifferent": "Por favor elige un atajo diferente.", + "reserved": "Advertencia de Atajo Reservado", + "commonlyUsed": "se usa comรบnmente para:", + "unreliable": "Este atajo puede no funcionar de manera confiable o puede entrar en conflicto con el comportamiento del navegador/sistema.", + "useAnyway": "ยฟQuieres usarlo de todos modos?", + "resetTitle": "Restablecer Atajos", + "resetMessage": "ยฟEstรกs seguro de que quieres restablecer todos los atajos a los valores predeterminados?

Esta acciรณn no se puede deshacer.", + "importSuccessTitle": "Importaciรณn Exitosa", + "importSuccessMessage": "ยกAtajos importados exitosamente!", + "importFailTitle": "Importaciรณn Fallida", + "importFailMessage": "Error al importar atajos. Formato de archivo invรกlido." + } + }, + "warning": { + "title": "Advertencia", + "cancel": "Cancelar", + "proceed": "Continuar" + }, + "compliance": { + "title": "Tus datos nunca salen de tu dispositivo", + "weKeep": "Mantenemos", + "yourInfoSafe": "tu informaciรณn segura", + "byFollowingStandards": "siguiendo estรกndares de seguridad globales.", + "processingLocal": "Todo el procesamiento ocurre localmente en tu dispositivo.", + "gdpr": { + "title": "Cumplimiento GDPR", + "description": "Protege los datos personales y la privacidad de las personas dentro de la Uniรณn Europea." + }, + "ccpa": { + "title": "Cumplimiento CCPA", + "description": "Otorga a los residentes de California derechos sobre cรณmo se recopila, usa y comparte su informaciรณn personal." + }, + "hipaa": { + "title": "Cumplimiento HIPAA", + "description": "Establece salvaguardas para el manejo de informaciรณn de salud sensible en el sistema de atenciรณn mรฉdica de Estados Unidos." + } + }, + "faq": { + "title": "Preguntas", + "questions": "Frecuentes", + "isFree": { + "question": "ยฟBentoPDF es realmente gratis?", + "answer": "Sรญ, absolutamente. Todas las herramientas en BentoPDF son 100% gratuitas, sin lรญmites de archivos, sin registro y sin marcas de agua. Creemos que todos merecen acceso a herramientas PDF simples y potentes sin un muro de pago." + }, + "areFilesSecure": { + "question": "ยฟMis archivos estรกn seguros? ยฟDรณnde se procesan?", + "answer": "Tus archivos estรกn lo mรกs seguros posible porque nunca salen de tu computadora. Todo el procesamiento ocurre directamente en tu navegador web (del lado del cliente). Nunca cargamos tus archivos a un servidor, por lo que mantienes total privacidad y control sobre tus documentos." + }, + "platforms": { + "question": "ยฟFunciona en Mac, Windows y Mรณvil?", + "answer": "ยกSรญ! Dado que BentoPDF se ejecuta completamente en tu navegador, funciona en cualquier sistema operativo con un navegador web moderno, incluyendo Windows, macOS, Linux, iOS y Android." + }, + "gdprCompliant": { + "question": "ยฟBentoPDF cumple con GDPR?", + "answer": "Sรญ. BentoPDF cumple completamente con GDPR. Dado que todo el procesamiento de archivos ocurre localmente en tu navegador y nunca recopilamos ni transmitimos tus archivos a ningรบn servidor, no tenemos acceso a tus datos. Esto garantiza que siempre tengas el control de tus documentos." + }, + "dataStorage": { + "question": "ยฟAlmacenan o rastrean alguno de mis archivos?", + "answer": "No. Nunca almacenamos, rastreamos ni registramos tus archivos. Todo lo que haces en BentoPDF ocurre en la memoria de tu navegador y desaparece una vez que cierras la pรกgina. No hay cargas, no hay registros de historial y no hay servidores involucrados." + }, + "different": { + "question": "ยฟQuรฉ hace que BentoPDF sea diferente de otras herramientas PDF?", + "answer": "La mayorรญa de las herramientas PDF cargan tus archivos a un servidor para procesarlos. BentoPDF nunca hace eso. Utilizamos tecnologรญa web moderna y segura para procesar tus archivos directamente en tu navegador. Esto significa un rendimiento mรกs rรกpido, mayor privacidad y total tranquilidad." + }, + "browserBased": { + "question": "ยฟCรณmo me mantiene seguro el procesamiento basado en navegador?", + "answer": "Al ejecutarse completamente dentro de tu navegador, BentoPDF garantiza que tus archivos nunca salgan de tu dispositivo. Esto elimina los riesgos de hackeos de servidores, violaciones de datos o accesos no autorizados. Tus archivos siguen siendo tuyos, siempre." + }, + "analytics": { + "question": "ยฟUsan cookies o anรกlisis para rastrearme?", + "answer": "Nos preocupamos por tu privacidad. BentoPDF no rastrea informaciรณn personal. Usamos Simple Analytics รบnicamente para ver recuentos de visitas anรณnimas. Esto significa que podemos saber cuรกntos usuarios visitan nuestro sitio, pero nunca sabemos quiรฉn eres. Simple Analytics cumple completamente con GDPR y respeta tu privacidad." + } + }, + "testimonials": { + "title": "Lo que Nuestros", + "users": "Usuarios", + "say": "Dicen" + }, + "support": { + "title": "ยฟTe Gusta Mi Trabajo?", + "description": "BentoPDF es un proyecto de pasiรณn, creado para proporcionar un kit de herramientas PDF gratuito, privado y potente para todos. Si te resulta รบtil, considera apoyar su desarrollo. ยกCada cafรฉ ayuda!", + "buyMeCoffee": "Cรณmprame un Cafรฉ" + }, + "footer": { + "copyright": "ยฉ 2025 BentoPDF. Todos los derechos reservados.", + "version": "Versiรณn", + "company": "Empresa", + "aboutUs": "Acerca de Nosotros", + "faqLink": "Preguntas Frecuentes", + "contactUs": "Contรกctanos", + "legal": "Legal", + "termsAndConditions": "Tรฉrminos y Condiciones", + "privacyPolicy": "Polรญtica de Privacidad", + "followUs": "Sรญguenos" + }, + "merge": { + "title": "Fusionar PDFs", + "description": "Combina archivos completos o selecciona pรกginas especรญficas para fusionar en un nuevo documento.", + "fileMode": "Modo Archivo", + "pageMode": "Modo Pรกgina", + "howItWorks": "Cรณmo funciona:", + "fileModeInstructions": [ + "Haz clic y arrastra el รญcono para cambiar el orden de los archivos.", + "En el cuadro \"Pรกginas\" para cada archivo, puedes especificar rangos (ej., \"1-3, 5\") para fusionar solo esas pรกginas.", + "Deja el cuadro \"Pรกginas\" en blanco para incluir todas las pรกginas de ese archivo." + ], + "pageModeInstructions": [ + "Todas las pรกginas de tus PDFs cargados se muestran a continuaciรณn.", + "Simplemente arrastra y suelta las miniaturas de pรกginas individuales para crear el orden exacto que deseas para tu nuevo archivo." + ], + "mergePdfs": "Fusionar PDFs" + }, + "common": { + "page": "Pรกgina", + "pages": "Pรกginas", + "of": "de", + "download": "Descargar", + "cancel": "Cancelar", + "save": "Guardar", + "delete": "Eliminar", + "edit": "Editar", + "add": "Agregar", + "remove": "Remover", + "loading": "Cargando...", + "error": "Error", + "success": "ร‰xito", + "file": "Archivo", + "files": "Archivos", + "close": "Cerrar" + }, + "about": { + "hero": { + "title": "Creemos que las herramientas PDF deben ser", + "subtitle": "rรกpidas, privadas y gratuitas.", + "noCompromises": "Sin compromisos." + }, + "mission": { + "title": "Nuestra Misiรณn", + "description": "Proporcionar la caja de herramientas PDF mรกs completa que respete tu privacidad y nunca pida pago. Creemos que las herramientas de documentos esenciales deben ser accesibles para todos, en todas partes, sin barreras." + }, + "philosophy": { + "label": "Nuestra Filosofรญa Central", + "title": "Privacidad Primero. Siempre.", + "description": "En una era donde los datos son una mercancรญa, adoptamos un enfoque diferente. Todo el procesamiento de las herramientas de Bentopdf ocurre localmente en tu navegador. Esto significa que tus archivos nunca tocan nuestros servidores, nunca vemos tus documentos y no rastreamos lo que haces. Tus documentos permanecen completa e inequรญvocamente privados. No es solo una caracterรญstica; es nuestra base." + }, + "whyBentopdf": { + "title": "Por quรฉ", + "speed": { + "title": "Diseรฑado para la Velocidad", + "description": "Sin esperar cargas o descargas a un servidor. Al procesar archivos directamente en tu navegador usando tecnologรญas web modernas como WebAssembly, ofrecemos una velocidad incomparable para todas nuestras herramientas." + }, + "free": { + "title": "Completamente Gratis", + "description": "Sin pruebas, sin suscripciones, sin tarifas ocultas y sin funciones \"premium\" retenidas como rehenes. Creemos que las herramientas PDF potentes deben ser una utilidad pรบblica, no un centro de ganancias." + }, + "noAccount": { + "title": "No Requiere Cuenta", + "description": "Comienza a usar cualquier herramienta de inmediato. No necesitamos tu correo electrรณnico, una contraseรฑa o cualquier informaciรณn personal. Tu flujo de trabajo debe ser sin fricciones y anรณnimo." + }, + "openSource": { + "title": "Espรญritu de Cรณdigo Abierto", + "description": "Construido con transparencia en mente. Aprovechamos increรญbles bibliotecas de cรณdigo abierto como PDF-lib y PDF.js, y creemos en el esfuerzo impulsado por la comunidad para hacer que las herramientas potentes sean accesibles para todos." + } + }, + "cta": { + "title": "ยฟListo para comenzar?", + "description": "รšnete a miles de usuarios que confรญan en Bentopdf para sus necesidades diarias de documentos. Experimenta la diferencia que la privacidad y el rendimiento pueden hacer.", + "button": "Explorar Todas las Herramientas" + } + }, + "contact": { + "title": "Ponte en Contacto", + "subtitle": "Nos encantarรญa saber de ti. Ya sea que tengas una pregunta, comentario o solicitud de funciรณn, no dudes en comunicarte.", + "email": "Puedes contactarnos directamente por correo electrรณnico en:" + }, + "licensing": { + "title": "Licencias para", + "subtitle": "Elige la licencia que se ajuste a tus necesidades." + }, + "multiTool": { + "uploadPdfs": "Cargar PDFs", + "upload": "Cargar", + "addBlankPage": "Agregar Pรกgina en Blanco", + "edit": "Editar:", + "undo": "Deshacer", + "redo": "Rehacer", + "reset": "Restablecer", + "selection": "Selecciรณn:", + "selectAll": "Seleccionar Todo", + "deselectAll": "Deseleccionar Todo", + "rotate": "Rotar:", + "rotateLeft": "Izquierda", + "rotateRight": "Derecha", + "transform": "Transformar:", + "duplicate": "Duplicar", + "split": "Dividir", + "clear": "Limpiar:", + "delete": "Eliminar", + "download": "Descargar:", + "downloadSelected": "Descargar Seleccionados", + "exportPdf": "Exportar PDF", + "uploadPdfFiles": "Seleccionar Archivos PDF", + "dragAndDrop": "Arrastra y suelta archivos PDF aquรญ, o haz clic para seleccionar", + "selectFiles": "Seleccionar Archivos", + "renderingPages": "Renderizando pรกginas...", + "actions": { + "duplicatePage": "Duplicar esta pรกgina", + "deletePage": "Eliminar esta pรกgina", + "insertPdf": "Insertar PDF despuรฉs de esta pรกgina", + "toggleSplit": "Alternar divisiรณn despuรฉs de esta pรกgina" + }, + "pleaseWait": "Por Favor Espera", + "pagesRendering": "Las pรกginas aรบn se estรกn renderizando. Por favor espera...", + "noPagesSelected": "No Se Seleccionaron Pรกginas", + "selectOnePage": "Por favor selecciona al menos una pรกgina para descargar.", + "noPages": "Sin Pรกginas", + "noPagesToExport": "No hay pรกginas para exportar.", + "renderingTitle": "Renderizando vistas previas de pรกginas", + "errorRendering": "Error al renderizar miniaturas de pรกginas", + "error": "Error", + "failedToLoad": "Error al cargar" + } +} diff --git a/public/locales/es/tools.json b/public/locales/es/tools.json new file mode 100644 index 0000000..920aa57 --- /dev/null +++ b/public/locales/es/tools.json @@ -0,0 +1,533 @@ +{ + "categories": { + "popularTools": "Herramientas Populares", + "editAnnotate": "Editar y Anotar", + "convertToPdf": "Convertir a PDF", + "convertFromPdf": "Convertir desde PDF", + "organizeManage": "Organizar y Gestionar", + "optimizeRepair": "Optimizar y Reparar", + "securePdf": "Asegurar PDF" + }, + "pdfMultiTool": { + "name": "Multiherramienta PDF", + "subtitle": "Fusionar, Dividir, Organizar, Eliminar, Rotar, Agregar Pรกginas en Blanco, Extraer y Duplicar en una interfaz unificada." + }, + "mergePdf": { + "name": "Fusionar PDF", + "subtitle": "Combina mรบltiples PDFs en un solo archivo. Preserva Marcadores." + }, + "splitPdf": { + "name": "Dividir PDF", + "subtitle": "Extrae un rango de pรกginas en un nuevo PDF." + }, + "compressPdf": { + "name": "Comprimir PDF", + "subtitle": "Reduce el tamaรฑo de archivo de tu PDF.", + "algorithmLabel": "Algoritmo de Compresiรณn", + "condense": "Condensar (Recomendado)", + "photon": "Photon (Para PDFs con Muchas Fotos)", + "condenseInfo": "Condensar usa compresiรณn avanzada: elimina peso muerto, optimiza imรกgenes, reduce fuentes. Mejor para la mayorรญa de PDFs.", + "photonInfo": "Photon convierte pรกginas en imรกgenes. รšsalo para PDFs con muchas fotos/escaneados.", + "photonWarning": "Advertencia: El texto dejarรก de ser seleccionable y los enlaces dejarรกn de funcionar.", + "levelLabel": "Nivel de Compresiรณn", + "light": "Ligero (Preservar Calidad)", + "balanced": "Equilibrado (Recomendado)", + "aggressive": "Agresivo (Archivos Mรกs Pequeรฑos)", + "extreme": "Extremo (Compresiรณn Mรกxima)", + "grayscale": "Convertir a Escala de Grises", + "grayscaleHint": "Reduce el tamaรฑo del archivo eliminando informaciรณn de color", + "customSettings": "Configuraciรณn Personalizada", + "customSettingsHint": "Ajusta los parรกmetros de compresiรณn:", + "outputQuality": "Calidad de Salida", + "resizeImagesTo": "Redimensionar Imรกgenes a", + "onlyProcessAbove": "Solo Procesar Arriba de", + "removeMetadata": "Eliminar metadatos", + "subsetFonts": "Reducir fuentes (eliminar glifos no usados)", + "removeThumbnails": "Eliminar miniaturas incrustadas", + "compressButton": "Comprimir PDF" + }, + "pdfEditor": { + "name": "Editor PDF", + "subtitle": "Anotar, resaltar, redactar, comentar, agregar formas/imรกgenes, buscar y ver PDFs." + }, + "jpgToPdf": { + "name": "JPG a PDF", + "subtitle": "Crea un PDF desde imรกgenes JPG, JPEG y JPEG2000 (JP2/JPX)." + }, + "signPdf": { + "name": "Firmar PDF", + "subtitle": "Dibuja, escribe o carga tu firma." + }, + "cropPdf": { + "name": "Recortar PDF", + "subtitle": "Recorta los mรกrgenes de cada pรกgina en tu PDF." + }, + "extractPages": { + "name": "Extraer Pรกginas", + "subtitle": "Guarda una selecciรณn de pรกginas como nuevos archivos." + }, + "duplicateOrganize": { + "name": "Duplicar y Organizar", + "subtitle": "Duplica, reordena y elimina pรกginas." + }, + "deletePages": { + "name": "Eliminar Pรกginas", + "subtitle": "Elimina pรกginas especรญficas de tu documento." + }, + "editBookmarks": { + "name": "Editar Marcadores", + "subtitle": "Agrega, edita, importa, elimina y extrae marcadores PDF." + }, + "tableOfContents": { + "name": "Tabla de Contenidos", + "subtitle": "Genera una pรกgina de tabla de contenidos desde los marcadores PDF." + }, + "pageNumbers": { + "name": "Nรบmeros de Pรกgina", + "subtitle": "Inserta nรบmeros de pรกgina en tu documento." + }, + "addWatermark": { + "name": "Agregar Marca de Agua", + "subtitle": "Estampa texto o una imagen sobre tus pรกginas PDF." + }, + "headerFooter": { + "name": "Encabezado y Pie de Pรกgina", + "subtitle": "Agrega texto en la parte superior e inferior de las pรกginas." + }, + "invertColors": { + "name": "Invertir Colores", + "subtitle": "Crea una versiรณn en \"modo oscuro\" de tu PDF." + }, + "backgroundColor": { + "name": "Color de Fondo", + "subtitle": "Cambia el color de fondo de tu PDF." + }, + "changeTextColor": { + "name": "Cambiar Color de Texto", + "subtitle": "Cambia el color del texto en tu PDF." + }, + "addStamps": { + "name": "Agregar Sellos", + "subtitle": "Agrega sellos de imagen a tu PDF usando la barra de herramientas de anotaciรณn.", + "usernameLabel": "Nombre de Usuario del Sello", + "usernamePlaceholder": "Ingresa tu nombre (para sellos)", + "usernameHint": "Este nombre aparecerรก en los sellos que crees." + }, + "removeAnnotations": { + "name": "Eliminar Anotaciones", + "subtitle": "Elimina comentarios, resaltados y enlaces." + }, + "pdfFormFiller": { + "name": "Rellenar Formularios PDF", + "subtitle": "Rellena formularios directamente en el navegador. Tambiรฉn soporta formularios XFA." + }, + "createPdfForm": { + "name": "Crear Formulario PDF", + "subtitle": "Crea formularios PDF rellenables con campos de texto arrastrables." + }, + "removeBlankPages": { + "name": "Eliminar Pรกginas en Blanco", + "subtitle": "Detecta y elimina automรกticamente pรกginas en blanco." + }, + "imageToPdf": { + "name": "Imรกgenes a PDF", + "subtitle": "Convierte JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP a PDF." + }, + "pngToPdf": { + "name": "PNG a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes PNG." + }, + "webpToPdf": { + "name": "WebP a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes WebP." + }, + "svgToPdf": { + "name": "SVG a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes SVG." + }, + "bmpToPdf": { + "name": "BMP a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes BMP." + }, + "heicToPdf": { + "name": "HEIC a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes HEIC." + }, + "tiffToPdf": { + "name": "TIFF a PDF", + "subtitle": "Crea un PDF desde una o mรกs imรกgenes TIFF." + }, + "textToPdf": { + "name": "Texto a PDF", + "subtitle": "Convierte un archivo de texto plano en un PDF." + }, + "jsonToPdf": { + "name": "JSON a PDF", + "subtitle": "Convierte archivos JSON a formato PDF." + }, + "pdfToJpg": { + "name": "PDF a JPG", + "subtitle": "Convierte cada pรกgina PDF en una imagen JPG." + }, + "pdfToPng": { + "name": "PDF a PNG", + "subtitle": "Convierte cada pรกgina PDF en una imagen PNG." + }, + "pdfToWebp": { + "name": "PDF a WebP", + "subtitle": "Convierte cada pรกgina PDF en una imagen WebP." + }, + "pdfToBmp": { + "name": "PDF a BMP", + "subtitle": "Convierte cada pรกgina PDF en una imagen BMP." + }, + "pdfToTiff": { + "name": "PDF a TIFF", + "subtitle": "Convierte cada pรกgina PDF en una imagen TIFF." + }, + "pdfToGreyscale": { + "name": "PDF a Escala de Grises", + "subtitle": "Convierte todos los colores a blanco y negro." + }, + "pdfToJson": { + "name": "PDF a JSON", + "subtitle": "Convierte archivos PDF a formato JSON." + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "Hace que un PDF sea buscable y copiable." + }, + "alternateMix": { + "name": "Alternar y Mezclar Pรกginas", + "subtitle": "Fusiona PDFs alternando pรกginas de cada PDF. Preserva Marcadores." + }, + "addAttachments": { + "name": "Agregar Adjuntos", + "subtitle": "Incrusta uno o mรกs archivos en tu PDF." + }, + "extractAttachments": { + "name": "Extraer Adjuntos", + "subtitle": "Extrae todos los archivos incrustados de PDF(s) como un ZIP." + }, + "editAttachments": { + "name": "Editar Adjuntos", + "subtitle": "Ve o elimina adjuntos en tu PDF." + }, + "dividePages": { + "name": "Dividir Pรกginas", + "subtitle": "Divide pรกginas horizontal o verticalmente." + }, + "addBlankPage": { + "name": "Agregar Pรกgina en Blanco", + "subtitle": "Inserta una pรกgina vacรญa en cualquier lugar de tu PDF." + }, + "reversePages": { + "name": "Invertir Pรกginas", + "subtitle": "Invierte el orden de todas las pรกginas en tu documento." + }, + "rotatePdf": { + "name": "Rotar PDF", + "subtitle": "Gira pรกginas en incrementos de 90 grados." + }, + "rotateCustom": { + "name": "Rotar por Grados Personalizados", + "subtitle": "Rota pรกginas por cualquier รกngulo personalizado." + }, + "nUpPdf": { + "name": "N-Up PDF", + "subtitle": "Organiza mรบltiples pรกginas en una sola hoja." + }, + "combineToSinglePage": { + "name": "Combinar en Una Sola Pรกgina", + "subtitle": "Une todas las pรกginas en un desplazamiento continuo." + }, + "viewMetadata": { + "name": "Ver Metadatos", + "subtitle": "Inspecciona las propiedades ocultas de tu PDF." + }, + "editMetadata": { + "name": "Editar Metadatos", + "subtitle": "Cambia el autor, tรญtulo y otras propiedades." + }, + "pdfsToZip": { + "name": "PDFs a ZIP", + "subtitle": "Empaqueta mรบltiples archivos PDF en un archivo ZIP." + }, + "comparePdfs": { + "name": "Comparar PDFs", + "subtitle": "Compara dos PDFs lado a lado." + }, + "posterizePdf": { + "name": "Posterizar PDF", + "subtitle": "Divide una pรกgina grande en mรบltiples pรกginas mรกs pequeรฑas." + }, + "fixPageSize": { + "name": "Fijar Tamaรฑo de Pรกgina", + "subtitle": "Estandariza todas las pรกginas a un tamaรฑo uniforme." + }, + "linearizePdf": { + "name": "Linealizar PDF", + "subtitle": "Optimiza el PDF para visualizaciรณn web rรกpida." + }, + "pageDimensions": { + "name": "Dimensiones de Pรกgina", + "subtitle": "Analiza el tamaรฑo, orientaciรณn y unidades de pรกgina." + }, + "removeRestrictions": { + "name": "Eliminar Restricciones", + "subtitle": "Elimina la protecciรณn por contraseรฑa y las restricciones de seguridad asociadas con archivos PDF firmados digitalmente." + }, + "repairPdf": { + "name": "Reparar PDF", + "subtitle": "Recupera datos de archivos PDF corruptos o daรฑados." + }, + "encryptPdf": { + "name": "Cifrar PDF", + "subtitle": "Bloquea tu PDF agregando una contraseรฑa." + }, + "sanitizePdf": { + "name": "Sanear PDF", + "subtitle": "Elimina metadatos, anotaciones, scripts y mรกs." + }, + "decryptPdf": { + "name": "Descifrar PDF", + "subtitle": "Desbloquea PDF eliminando la protecciรณn por contraseรฑa." + }, + "flattenPdf": { + "name": "Aplanar PDF", + "subtitle": "Hace que los campos de formulario y las anotaciones no sean editables." + }, + "removeMetadata": { + "name": "Eliminar Metadatos", + "subtitle": "Elimina datos ocultos de tu PDF." + }, + "changePermissions": { + "name": "Cambiar Permisos", + "subtitle": "Establece o cambia los permisos de usuario en un PDF." + }, + "odtToPdf": { + "name": "ODT a PDF", + "subtitle": "Convierte archivos OpenDocument Text a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos ODT", + "convertButton": "Convertir a PDF" + }, + "csvToPdf": { + "name": "CSV a PDF", + "subtitle": "Convierte archivos de hoja de cรกlculo CSV a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos CSV", + "convertButton": "Convertir a PDF" + }, + "rtfToPdf": { + "name": "RTF a PDF", + "subtitle": "Convierte documentos Rich Text Format a PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos RTF", + "convertButton": "Convertir a PDF" + }, + "wordToPdf": { + "name": "Word a PDF", + "subtitle": "Convierte documentos Word (DOCX, DOC, ODT, RTF) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos DOCX, DOC, ODT, RTF", + "convertButton": "Convertir a PDF" + }, + "excelToPdf": { + "name": "Excel a PDF", + "subtitle": "Convierte hojas de cรกlculo Excel (XLSX, XLS, ODS, CSV) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos XLSX, XLS, ODS, CSV", + "convertButton": "Convertir a PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint a PDF", + "subtitle": "Convierte presentaciones PowerPoint (PPTX, PPT, ODP) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos PPTX, PPT, ODP", + "convertButton": "Convertir a PDF" + }, + "markdownToPdf": { + "name": "Markdown a PDF", + "subtitle": "Escribe o pega Markdown y expรณrtalo como un PDF bellamente formateado.", + "paneMarkdown": "Markdown", + "panePreview": "Vista Previa", + "btnUpload": "Cargar", + "btnSyncScroll": "Sincronizar Desplazamiento", + "btnSettings": "Configuraciรณn", + "btnExportPdf": "Exportar PDF", + "settingsTitle": "Configuraciรณn de Markdown", + "settingsPreset": "Predefinido", + "presetDefault": "Predeterminado (similar a GFM)", + "presetCommonmark": "CommonMark (estricto)", + "presetZero": "Mรญnimo (sin funciones)", + "settingsOptions": "Opciones de Markdown", + "optAllowHtml": "Permitir etiquetas HTML", + "optBreaks": "Convertir saltos de lรญnea a
", + "optLinkify": "Auto-convertir URLs a enlaces", + "optTypographer": "Tipรณgrafo (comillas inteligentes, etc.)" + }, + "pdfBooklet": { + "name": "Folleto PDF", + "subtitle": "Reorganiza pรกginas para impresiรณn de folleto a doble cara. Dobla y engrapa para crear un folleto.", + "howItWorks": "Cรณmo funciona:", + "step1": "Carga un archivo PDF.", + "step2": "Las pรกginas se reorganizarรกn en orden de folleto.", + "step3": "Imprime a doble cara, voltea por el borde corto, dobla y engrapa.", + "paperSize": "Tamaรฑo de Papel", + "orientation": "Orientaciรณn", + "portrait": "Vertical", + "landscape": "Horizontal", + "pagesPerSheet": "Pรกginas por Hoja", + "createBooklet": "Crear Folleto", + "processing": "Procesando...", + "pageCount": "El recuento de pรกginas se rellenarรก a mรบltiplo de 4 si es necesario." + }, + "xpsToPdf": { + "name": "XPS a PDF", + "subtitle": "Convierte documentos XPS/OXPS a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos XPS, OXPS", + "convertButton": "Convertir a PDF" + }, + "mobiToPdf": { + "name": "MOBI a PDF", + "subtitle": "Convierte e-books MOBI a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos MOBI", + "convertButton": "Convertir a PDF" + }, + "epubToPdf": { + "name": "EPUB a PDF", + "subtitle": "Convierte e-books EPUB a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos EPUB", + "convertButton": "Convertir a PDF" + }, + "fb2ToPdf": { + "name": "FB2 a PDF", + "subtitle": "Convierte e-books FictionBook (FB2) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos FB2", + "convertButton": "Convertir a PDF" + }, + "cbzToPdf": { + "name": "CBZ a PDF", + "subtitle": "Convierte archivos de cรณmics (CBZ/CBR) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos CBZ, CBR", + "convertButton": "Convertir a PDF" + }, + "wpdToPdf": { + "name": "WPD a PDF", + "subtitle": "Convierte documentos WordPerfect (WPD) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos WPD", + "convertButton": "Convertir a PDF" + }, + "wpsToPdf": { + "name": "WPS a PDF", + "subtitle": "Convierte documentos WPS Office a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos WPS", + "convertButton": "Convertir a PDF" + }, + "xmlToPdf": { + "name": "XML a PDF", + "subtitle": "Convierte documentos XML a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos XML", + "convertButton": "Convertir a PDF" + }, + "pagesToPdf": { + "name": "Pages a PDF", + "subtitle": "Convierte documentos Apple Pages a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos Pages", + "convertButton": "Convertir a PDF" + }, + "odgToPdf": { + "name": "ODG a PDF", + "subtitle": "Convierte archivos OpenDocument Graphics (ODG) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos ODG", + "convertButton": "Convertir a PDF" + }, + "odsToPdf": { + "name": "ODS a PDF", + "subtitle": "Convierte archivos OpenDocument Spreadsheet (ODS) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos ODS", + "convertButton": "Convertir a PDF" + }, + "odpToPdf": { + "name": "ODP a PDF", + "subtitle": "Convierte archivos OpenDocument Presentation (ODP) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos ODP", + "convertButton": "Convertir a PDF" + }, + "pubToPdf": { + "name": "PUB a PDF", + "subtitle": "Convierte archivos Microsoft Publisher (PUB) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos PUB", + "convertButton": "Convertir a PDF" + }, + "vsdToPdf": { + "name": "VSD a PDF", + "subtitle": "Convierte archivos Microsoft Visio (VSD, VSDX) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos VSD, VSDX", + "convertButton": "Convertir a PDF" + }, + "psdToPdf": { + "name": "PSD a PDF", + "subtitle": "Convierte archivos Adobe Photoshop (PSD) a formato PDF. Soporta mรบltiples archivos.", + "acceptedFormats": "Archivos PSD", + "convertButton": "Convertir a PDF" + }, + "pdfToSvg": { + "name": "PDF a SVG", + "subtitle": "Convierte cada pรกgina de un archivo PDF en un grรกfico vectorial escalable (SVG) para calidad perfecta a cualquier tamaรฑo." + }, + "extractTables": { + "name": "Extraer Tablas de PDF", + "subtitle": "Extrae tablas de archivos PDF y exporta como CSV, JSON o Markdown." + }, + "pdfToCsv": { + "name": "PDF a CSV", + "subtitle": "Extrae tablas de PDF y convierte a formato CSV." + }, + "pdfToExcel": { + "name": "PDF a Excel", + "subtitle": "Extrae tablas de PDF y convierte a formato Excel (XLSX)." + }, + "pdfToText": { + "name": "PDF a Texto", + "subtitle": "Extrae texto de archivos PDF y guarda como texto plano (.txt). Soporta mรบltiples archivos.", + "note": "Esta herramienta funciona SOLO con PDFs creados digitalmente. Para documentos escaneados o PDFs basados en imรกgenes, usa nuestra herramienta OCR PDF en su lugar.", + "convertButton": "Extraer Texto" + }, + "digitalSignPdf": { + "name": "Firma Digital PDF", + "pageTitle": "Firma Digital PDF - Agregar Firma Criptogrรกfica | BentoPDF", + "subtitle": "Agrega una firma digital criptogrรกfica a tu PDF usando certificados X.509. Soporta formatos PKCS#12 (.pfx, .p12) y PEM. Tu clave privada nunca sale de tu navegador.", + "certificateSection": "Certificado", + "uploadCert": "Cargar certificado (.pfx, .p12)", + "certPassword": "Contraseรฑa del Certificado", + "certPasswordPlaceholder": "Ingresa la contraseรฑa del certificado", + "certInfo": "Informaciรณn del Certificado", + "certSubject": "Sujeto", + "certIssuer": "Emisor", + "certValidity": "Vรกlido", + "signatureDetails": "Detalles de la Firma (Opcional)", + "reason": "Razรณn", + "reasonPlaceholder": "ej., Apruebo este documento", + "location": "Ubicaciรณn", + "locationPlaceholder": "ej., Madrid, Espaรฑa", + "contactInfo": "Informaciรณn de Contacto", + "contactPlaceholder": "ej., email@ejemplo.com", + "applySignature": "Aplicar Firma Digital", + "successMessage": "ยกPDF firmado exitosamente! La firma se puede verificar en cualquier lector de PDF." + }, + "validateSignaturePdf": { + "name": "Validar Firma PDF", + "pageTitle": "Validar Firma PDF - Verificar Firmas Digitales | BentoPDF", + "subtitle": "Verifica firmas digitales en tus archivos PDF. Comprueba la validez del certificado, ve los detalles del firmante y confirma la integridad del documento." + }, + "emailToPdf": { + "name": "Email a PDF", + "subtitle": "Convierte archivos de correo (EML, MSG) a formato PDF. Soporta exportaciones de Outlook y formatos de correo estรกndar.", + "acceptedFormats": "Archivos EML, MSG", + "convertButton": "Convertir a PDF" + }, + "fontToOutline": { + "name": "Fuente a Contorno", + "subtitle": "Convierte todas las fuentes a contornos vectoriales para una renderizaciรณn consistente en todos los dispositivos." + }, + "deskewPdf": { + "name": "Enderezar PDF", + "subtitle": "Endereza automรกticamente pรกginas escaneadas inclinadas usando OpenCV." + } +} diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json new file mode 100644 index 0000000..a4a2366 --- /dev/null +++ b/public/locales/fr/common.json @@ -0,0 +1,325 @@ +{ + "nav": { + "home": "Accueil", + "about": "ร€ propos", + "contact": "Contact", + "licensing": "Licence", + "allTools": "Tous les outils", + "openMainMenu": "Ouvrir le menu principal", + "language": "Langue" + }, + "donation": { + "message": "Vous aimez BentoPDF ? Aidez-nous ร  le garder open source !", + "button": "Soutenir" + }, + "hero": { + "title": "La", + "pdfToolkit": "palette dโ€™outils PDF", + "builtForPrivacy": "conรงue pour la confidentialitรฉ", + "noSignups": "Sans inscription", + "unlimitedUse": "Utilisation illimitรฉe", + "worksOffline": "Fonctionne hors ligne", + "startUsing": "Commencer maintenant" + }, + "usedBy": { + "title": "Utilisรฉ par des entreprises et des professionnels de" + }, + "features": { + "title": "Pourquoi choisir", + "bentoPdf": "BentoPDF ?", + "noSignup": { + "title": "Sans inscription", + "description": "Utilisation immรฉdiate, sans compte ni email." + }, + "noUploads": { + "title": "Aucun envoi de fichiers", + "description": "100 % cรดtรฉ navigateur, vos fichiers ne quittent jamais votre appareil." + }, + "foreverFree": { + "title": "Gratuit pour toujours", + "description": "Tous les outils, sans essai, sans paiement, sans restrictions." + }, + "noLimits": { + "title": "Sans limites", + "description": "Utilisez autant que vous voulez, sans plafonds cachรฉs." + }, + "batchProcessing": { + "title": "Traitement par lots", + "description": "Gรฉrez un nombre illimitรฉ de PDF en une seule fois." + }, + "lightningFast": { + "title": "Ultra rapide", + "description": "Traitez vos PDF instantanรฉment, sans attente." + } + }, + "tools": { + "title": "Commencer avec", + "toolsLabel": "Les outils", + "subtitle": "Cliquez sur un outil pour importer vos fichiers", + "searchPlaceholder": "Rechercher un outil (ex. ยซ scinder ยป, ยซ organiser ยป...)", + "backToTools": "Retour aux outils", + "firstLoadNotice": "Le premier chargement peut prendre quelques instants, le temps de charger notre moteur de conversion. Les prochaines fois, tout se chargera instantanรฉment." + }, + "upload": { + "clickToSelect": "Cliquez pour sรฉlectionner un fichier", + "orDragAndDrop": "ou glissez-dรฉposez", + "pdfOrImages": "PDF ou images", + "filesNeverLeave": "Vos fichiers restent sur votre appareil.", + "addMore": "Ajouter dโ€™autres fichiers", + "clearAll": "Tout effacer", + "clearFiles": "Effacer les fichiers" + }, + "loader": { + "processing": "Traitement en cours..." + }, + "alert": { + "title": "Alerte", + "ok": "OK" + }, + "preview": { + "title": "Aperรงu du document", + "downloadAsPdf": "Tรฉlรฉcharger en PDF", + "close": "Fermer" + }, + "settings": { + "title": "Paramรจtres", + "shortcuts": "Raccourcis", + "preferences": "Prรฉfรฉrences", + "displayPreferences": "Prรฉfรฉrences dโ€™affichage", + "searchShortcuts": "Rechercher un raccourci...", + "shortcutsInfo": "Maintenez les touches pour dรฉfinir un raccourci. Les changements sont enregistrรฉs automatiquement.", + "shortcutsWarning": "โš ๏ธ ร‰vitez les raccourcis courants du navigateur (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N, etc.), ils peuvent ne pas fonctionner correctement.", + "import": "Importer", + "export": "Exporter", + "resetToDefaults": "Rรฉtablir les paramรจtres par dรฉfaut", + "fullWidthMode": "Mode pleine largeur", + "fullWidthDescription": "Utiliser toute la largeur de lโ€™รฉcran au lieu dโ€™un affichage centrรฉ", + "settingsAutoSaved": "Les paramรจtres sont enregistrรฉs automatiquement", + "clickToSet": "Cliquez pour dรฉfinir", + "pressKeys": "Appuyez sur les touches...", + "warnings": { + "alreadyInUse": "Raccourci dรฉjร  utilisรฉ", + "assignedTo": "est dรฉjร  attribuรฉ ร  :", + "chooseDifferent": "Veuillez choisir un autre raccourci.", + "reserved": "Avertissement de raccourci rรฉservรฉ", + "commonlyUsed": "est couramment utilisรฉ pour :", + "unreliable": "Ce raccourci peut ne pas fonctionner correctement ou entrer en conflit avec le navigateur ou le systรจme.", + "useAnyway": "Souhaitez-vous lโ€™utiliser quand mรชme ?", + "resetTitle": "Rรฉinitialiser les raccourcis", + "resetMessage": "รŠtes-vous sรปr de vouloir rรฉinitialiser tous les raccourcis par dรฉfaut ?

Cette action est irrรฉversible.", + "importSuccessTitle": "Importation rรฉussie", + "importSuccessMessage": "Les raccourcis ont รฉtรฉ importรฉs avec succรจs !", + "importFailTitle": "ร‰chec de lโ€™importation", + "importFailMessage": "Impossible dโ€™importer les raccourcis. Format de fichier invalide." + } + }, + "warning": { + "title": "Attention", + "cancel": "Annuler", + "proceed": "Continuer" + }, + "compliance": { + "title": "Vos donnรฉes ne quittent jamais votre appareil", + "weKeep": "Nous protรฉgeons", + "yourInfoSafe": "vos informations", + "byFollowingStandards": "en respectant les normes de sรฉcuritรฉ internationales.", + "processingLocal": "Tous les traitements sont effectuรฉs localement sur votre appareil.", + "gdpr": { + "title": "Conformitรฉ RGPD", + "description": "Protรจge les donnรฉes personnelles et la vie privรฉe des citoyens de lโ€™Union europรฉenne." + }, + "ccpa": { + "title": "Conformitรฉ CCPA", + "description": "Accorde aux rรฉsidents de Californie des droits sur lโ€™utilisation de leurs donnรฉes personnelles." + }, + "hipaa": { + "title": "Conformitรฉ HIPAA", + "description": "Dรฉfinit des rรจgles strictes pour la gestion des donnรฉes de santรฉ aux ร‰tats-Unis." + } + }, + "faq": { + "title": "Questions", + "questions": "frรฉquentes", + "isFree": { + "question": "BentoPDF est-il vraiment gratuit ?", + "answer": "Oui, totalement. Tous les outils BentoPDF sont 100 % gratuits, sans limite de fichiers, sans inscription et sans filigrane. Nous pensons que chacun doit avoir accรจs ร  des outils PDF simples et puissants, sans barriรจre payante." + }, + "areFilesSecure": { + "question": "Mes fichiers sont-ils en sรฉcuritรฉ ? Oรน sont-ils traitรฉs ?", + "answer": "Vos fichiers sont parfaitement sรฉcurisรฉs car ils ne quittent jamais votre ordinateur. Tous les traitements se font directement dans votre navigateur. Aucun fichier nโ€™est envoyรฉ sur un serveur." + }, + "platforms": { + "question": "Est-ce compatible avec Mac, Windows et mobile ?", + "answer": "Oui ! BentoPDF fonctionne entiรจrement dans le navigateur et est compatible avec Windows, macOS, Linux, iOS et Android." + }, + "gdprCompliant": { + "question": "BentoPDF est-il conforme au RGPD ?", + "answer": "Oui. Comme tous les traitements sont locaux et quโ€™aucune donnรฉe nโ€™est collectรฉe ou transmise, vous restez entiรจrement maรฎtre de vos documents." + }, + "dataStorage": { + "question": "Stockez-vous ou suivez-vous mes fichiers ?", + "answer": "Non. Aucun stockage, aucun suivi, aucun historique. Tout disparaรฎt dรจs que vous fermez la page." + }, + "different": { + "question": "Quโ€™est-ce qui diffรฉrencie BentoPDF des autres outils PDF ?", + "answer": "La plupart des outils envoient vos fichiers sur un serveur. BentoPDF traite tout localement dans votre navigateur, pour plus de rapiditรฉ, de confidentialitรฉ et de tranquillitรฉ dโ€™esprit." + }, + "browserBased": { + "question": "Pourquoi le traitement dans le navigateur est-il plus sรปr ?", + "answer": "Parce que vos fichiers restent sur votre appareil. Aucun risque de fuite, de piratage ou dโ€™accรจs non autorisรฉ." + }, + "analytics": { + "question": "Utilisez-vous des cookies ou des outils de suivi ?", + "answer": "Nous respectons votre vie privรฉe. BentoPDF utilise uniquement des statistiques anonymes pour connaรฎtre le nombre de visites, sans jamais identifier les utilisateurs." + } + }, + "testimonials": { + "title": "Ce que disent", + "users": "nos utilisateurs", + "say": "" + }, + "support": { + "title": "Vous aimez ce projet ?", + "description": "BentoPDF est un projet passion, crรฉรฉ pour offrir une palette dโ€™outils PDF gratuite, privรฉe et puissante. Si cela vous aide, vous pouvez soutenir son dรฉveloppement. Chaque cafรฉ compte !", + "buyMeCoffee": "Mโ€™offrir un cafรฉ" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. Tous droits rรฉservรฉs.", + "version": "Version", + "company": "Entreprise", + "aboutUs": "ร€ propos", + "faqLink": "FAQ", + "contactUs": "Nous contacter", + "legal": "Mentions lรฉgales", + "termsAndConditions": "Conditions gรฉnรฉrales", + "privacyPolicy": "Politique de confidentialitรฉ", + "followUs": "Nous suivre" + }, + "merge": { + "title": "Fusionner des PDF", + "description": "Combinez des fichiers entiers ou sรฉlectionnez des pages spรฉcifiques pour crรฉer un nouveau document.", + "fileMode": "Mode fichiers", + "pageMode": "Mode pages", + "howItWorks": "Fonctionnement :", + "fileModeInstructions": [ + "Cliquez-glissez lโ€™icรดne pour modifier lโ€™ordre des fichiers.", + "Dans le champ ยซ Pages ยป de chaque fichier, vous pouvez dรฉfinir des plages (ex. ยซ 1-3, 5 ยป) pour ne fusionner que certaines pages.", + "Laissez le champ ยซ Pages ยป vide pour inclure toutes les pages du fichier." + ], + "pageModeInstructions": [ + "Toutes les pages de vos PDF importรฉs sโ€™affichent ci-dessous.", + "Glissez-dรฉposez simplement les miniatures pour dรฉfinir lโ€™ordre exact de votre nouveau document." + ], + "mergePdfs": "Fusionner les PDF" + }, + "common": { + "page": "Page", + "pages": "Pages", + "of": "sur", + "download": "Tรฉlรฉcharger", + "cancel": "Annuler", + "save": "Enregistrer", + "delete": "Supprimer", + "edit": "Modifier", + "add": "Ajouter", + "remove": "Retirer", + "loading": "Chargement...", + "error": "Erreur", + "success": "Succรจs", + "file": "Fichier", + "files": "Fichiers", + "close": "Fermer" + }, + "about": { + "hero": { + "title": "Nous pensons que les outils PDF doivent รชtre", + "subtitle": "rapides, privรฉs et gratuits.", + "noCompromises": "Sans compromis." + }, + "mission": { + "title": "Notre mission", + "description": "Proposer la palette dโ€™outils PDF la plus complรจte, tout en respectant votre vie privรฉe et sans jamais demander de paiement. Les outils essentiels doivent รชtre accessibles ร  tous, partout, sans barriรจres." + }, + "philosophy": { + "label": "Notre philosophie", + "title": "La confidentialitรฉ avant tout. Toujours.", + "description": "ร€ une รฉpoque oรน les donnรฉes sont devenues une monnaie, nous faisons un choix diffรฉrent. Tous les traitements des outils BentoPDF sont effectuรฉs localement dans votre navigateur. Vos fichiers ne passent jamais par nos serveurs, nous ne voyons jamais vos documents et nous ne suivons pas votre activitรฉ. Ce nโ€™est pas une option, cโ€™est notre fondation." + }, + "whyBentopdf": { + "title": "Pourquoi", + "speed": { + "title": "Pensรฉ pour la vitesse", + "description": "Aucune attente liรฉe aux envois ou tรฉlรฉchargements serveur. Grรขce au traitement local et aux technologies web modernes comme WebAssembly, nos outils sont extrรชmement rapides." + }, + "free": { + "title": "Entiรจrement gratuit", + "description": "Aucun essai, aucun abonnement, aucun coรปt cachรฉ, aucune fonctionnalitรฉ ยซ premium ยป bloquรฉe. Les outils PDF doivent รชtre un service public, pas un produit de luxe." + }, + "noAccount": { + "title": "Aucun compte requis", + "description": "Utilisez nโ€™importe quel outil immรฉdiatement. Pas dโ€™email, pas de mot de passe, aucune donnรฉe personnelle. Votre flux de travail reste fluide et anonyme." + }, + "openSource": { + "title": "Esprit open source", + "description": "Conรงu dans un esprit de transparence. Nous utilisons des bibliothรจques open source reconnues comme PDF-lib et PDF.js, et croyons en la force de la communautรฉ." + } + }, + "cta": { + "title": "Prรชt ร  commencer ?", + "description": "Rejoignez des milliers dโ€™utilisateurs qui font confiance ร  BentoPDF au quotidien. Dรฉcouvrez la diffรฉrence quโ€™apportent la confidentialitรฉ et la performance.", + "button": "Explorer tous les outils" + } + }, + "contact": { + "title": "Nous contacter", + "subtitle": "Nous serions ravis dโ€™รฉchanger avec vous. Question, retour ou suggestion de fonctionnalitรฉ, nโ€™hรฉsitez pas ร  nous รฉcrire.", + "email": "Vous pouvez nous contacter directement par email ร  :" + }, + "licensing": { + "title": "Licences pour", + "subtitle": "Choisissez la licence adaptรฉe ร  vos besoins." + }, + "multiTool": { + "uploadPdfs": "Importer des PDF", + "upload": "Importer", + "addBlankPage": "Ajouter une page vierge", + "edit": "Modifier :", + "undo": "Annuler", + "redo": "Rรฉtablir", + "reset": "Rรฉinitialiser", + "selection": "Sรฉlection :", + "selectAll": "Tout sรฉlectionner", + "deselectAll": "Tout dรฉsรฉlectionner", + "rotate": "Rotation :", + "rotateLeft": "Gauche", + "rotateRight": "Droite", + "transform": "Transformer :", + "duplicate": "Dupliquer", + "split": "Scinder", + "clear": "Effacer :", + "delete": "Supprimer", + "download": "Tรฉlรฉchargement :", + "downloadSelected": "Tรฉlรฉcharger la sรฉlection", + "exportPdf": "Exporter en PDF", + "uploadPdfFiles": "Sรฉlectionner des fichiers PDF", + "dragAndDrop": "Glissez-dรฉposez vos fichiers PDF ici ou cliquez pour sรฉlectionner", + "selectFiles": "Sรฉlectionner des fichiers", + "renderingPages": "Rendu des pages...", + "actions": { + "duplicatePage": "Dupliquer cette page", + "deletePage": "Supprimer cette page", + "insertPdf": "Insรฉrer un PDF aprรจs cette page", + "toggleSplit": "Activer/dรฉsactiver la sรฉparation aprรจs cette page" + }, + "pleaseWait": "Veuillez patienter", + "pagesRendering": "Les pages sont en cours de rendu. Veuillez patienter...", + "noPagesSelected": "Aucune page sรฉlectionnรฉe", + "selectOnePage": "Veuillez sรฉlectionner au moins une page ร  tรฉlรฉcharger.", + "noPages": "Aucune page", + "noPagesToExport": "Aucune page ร  exporter.", + "renderingTitle": "Gรฉnรฉration des aperรงus", + "errorRendering": "ร‰chec du rendu des miniatures", + "error": "Erreur", + "failedToLoad": "ร‰chec du chargement" + } +} diff --git a/public/locales/fr/tools.json b/public/locales/fr/tools.json new file mode 100644 index 0000000..8f36e7c --- /dev/null +++ b/public/locales/fr/tools.json @@ -0,0 +1,533 @@ +{ + "categories": { + "popularTools": "Outils populaires", + "editAnnotate": "ร‰diter et annoter", + "convertToPdf": "Convertir en PDF", + "convertFromPdf": "Convertir depuis le PDF", + "organizeManage": "Organiser et gรฉrer", + "optimizeRepair": "Optimiser et rรฉparer", + "securePdf": "Sรฉcuriser les PDF" + }, + "pdfMultiTool": { + "name": "Outil PDF tout-en-un", + "subtitle": "Fusionner, scinder, organiser, supprimer, faire pivoter, ajouter des pages vierges, extraire et dupliquer dans une interface unifiรฉe." + }, + "mergePdf": { + "name": "Fusionner des PDF", + "subtitle": "Assembler plusieurs PDF en un seul fichier, tout en conservant les signets." + }, + "splitPdf": { + "name": "Scinder un PDF", + "subtitle": "Extraire une plage de pages dans un nouveau PDF." + }, + "compressPdf": { + "name": "Compresser un PDF", + "subtitle": "Rรฉduire la taille du fichier PDF.", + "algorithmLabel": "Algorithme de compression", + "condense": "Condensรฉ (recommandรฉ)", + "photon": "Photon (pour les PDF riches en photos)", + "condenseInfo": "Condensรฉ utilise une compression avancรฉe : suppression du superflu, optimisation des images, sous-ensemble des polices. Idรฉal pour la plupart des PDF.", + "photonInfo": "Photon convertit les pages en images. ร€ utiliser pour les PDF contenant beaucoup de photos ou scannรฉs.", + "photonWarning": "Attention : le texte ne sera plus sรฉlectionnable et les liens ne fonctionneront plus.", + "levelLabel": "Niveau de compression", + "light": "Lรฉger (prรฉserver la qualitรฉ)", + "balanced": "ร‰quilibrรฉ (recommandรฉ)", + "aggressive": "Agressif (fichiers plus petits)", + "extreme": "Extrรชme (compression maximale)", + "grayscale": "Convertir en niveaux de gris", + "grayscaleHint": "Rรฉduit la taille du fichier en supprimant les informations de couleur", + "customSettings": "Paramรจtres personnalisรฉs", + "customSettingsHint": "Affiner les paramรจtres de compression :", + "outputQuality": "Qualitรฉ de sortie", + "resizeImagesTo": "Redimensionner les images ร ", + "onlyProcessAbove": "Traiter uniquement au-dessus de", + "removeMetadata": "Supprimer les mรฉtadonnรฉes", + "subsetFonts": "Sous-ensemble des polices (supprimer les glyphes inutilisรฉs)", + "removeThumbnails": "Supprimer les vignettes intรฉgrรฉes", + "compressButton": "Compresser le PDF" + }, + "pdfEditor": { + "name": "ร‰diteur PDF", + "subtitle": "Annoter, surligner, masquer, commenter, ajouter des formes ou images, rechercher et afficher des PDF." + }, + "jpgToPdf": { + "name": "JPG vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images JPG." + }, + "signPdf": { + "name": "Signer un PDF", + "subtitle": "Dessiner, saisir ou importer votre signature." + }, + "cropPdf": { + "name": "Rogner un PDF", + "subtitle": "Ajuster les marges de chaque page du PDF." + }, + "extractPages": { + "name": "Extraire des pages", + "subtitle": "Enregistrer une sรฉlection de pages dans de nouveaux fichiers." + }, + "duplicateOrganize": { + "name": "Dupliquer et organiser", + "subtitle": "Dupliquer, rรฉorganiser et supprimer des pages." + }, + "deletePages": { + "name": "Supprimer des pages", + "subtitle": "Retirer des pages spรฉcifiques du document." + }, + "editBookmarks": { + "name": "Modifier les signets", + "subtitle": "Ajouter, modifier, importer, supprimer et extraire des signets PDF." + }, + "tableOfContents": { + "name": "Table des matiรจres", + "subtitle": "Gรฉnรฉrer une table des matiรจres ร  partir des signets du PDF." + }, + "pageNumbers": { + "name": "Numรฉros de page", + "subtitle": "Insรฉrer une numรฉrotation dans le document." + }, + "addWatermark": { + "name": "Ajouter un filigrane", + "subtitle": "Apposer un texte ou une image sur les pages du PDF." + }, + "headerFooter": { + "name": "En-tรชte et pied de page", + "subtitle": "Ajouter du texte en haut et en bas des pages." + }, + "invertColors": { + "name": "Inverser les couleurs", + "subtitle": "Crรฉer une version ยซ mode sombre ยป du PDF." + }, + "backgroundColor": { + "name": "Couleur de fond", + "subtitle": "Modifier la couleur de fond du PDF." + }, + "changeTextColor": { + "name": "Changer la couleur du texte", + "subtitle": "Modifier la couleur du texte dans le PDF." + }, + "addStamps": { + "name": "Ajouter des tampons", + "subtitle": "Ajouter des tampons image via la barre dโ€™annotations.", + "usernameLabel": "Nom du tampon", + "usernamePlaceholder": "Entrez votre nom (pour les tampons)", + "usernameHint": "Ce nom apparaรฎtra sur les tampons que vous crรฉez." + }, + "removeAnnotations": { + "name": "Supprimer les annotations", + "subtitle": "Retirer les commentaires, surlignages et liens." + }, + "pdfFormFiller": { + "name": "Remplir un formulaire PDF", + "subtitle": "Remplir des formulaires directement dans le navigateur, y compris les formulaires XFA." + }, + "createPdfForm": { + "name": "Crรฉer un formulaire PDF", + "subtitle": "Crรฉer des formulaires PDF interactifs avec des champs glisser-dรฉposer." + }, + "removeBlankPages": { + "name": "Supprimer les pages blanches", + "subtitle": "Dรฉtecter et supprimer automatiquement les pages vides." + }, + "imageToPdf": { + "name": "Images vers PDF", + "subtitle": "Convertir un JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP en PDF." + }, + "pngToPdf": { + "name": "PNG vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images PNG." + }, + "webpToPdf": { + "name": "WebP vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images WebP." + }, + "svgToPdf": { + "name": "SVG vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images SVG." + }, + "bmpToPdf": { + "name": "BMP vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images BMP." + }, + "heicToPdf": { + "name": "HEIC vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images HEIC." + }, + "tiffToPdf": { + "name": "TIFF vers PDF", + "subtitle": "Crรฉer un PDF ร  partir dโ€™une ou plusieurs images TIFF." + }, + "textToPdf": { + "name": "Texte vers PDF", + "subtitle": "Convertir un fichier texte en PDF." + }, + "jsonToPdf": { + "name": "JSON vers PDF", + "subtitle": "Convertir des fichiers JSON en PDF." + }, + "pdfToJpg": { + "name": "PDF vers JPG", + "subtitle": "Convertir chaque page du PDF en image JPG." + }, + "pdfToPng": { + "name": "PDF vers PNG", + "subtitle": "Convertir chaque page du PDF en image PNG." + }, + "pdfToWebp": { + "name": "PDF vers WebP", + "subtitle": "Convertir chaque page du PDF en image WebP." + }, + "pdfToBmp": { + "name": "PDF vers BMP", + "subtitle": "Convertir chaque page du PDF en image BMP." + }, + "pdfToTiff": { + "name": "PDF vers TIFF", + "subtitle": "Convertir chaque page du PDF en image TIFF." + }, + "pdfToGreyscale": { + "name": "PDF en niveaux de gris", + "subtitle": "Convertir toutes les couleurs en noir et blanc." + }, + "pdfToJson": { + "name": "PDF vers JSON", + "subtitle": "Convertir des fichiers PDF en JSON." + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "Rendre un PDF consultable et copiable." + }, + "alternateMix": { + "name": "Alterner et mรฉlanger les pages", + "subtitle": "Fusionner des PDF en alternant les pages de chaque fichier, tout en conservant les signets." + }, + "addAttachments": { + "name": "Ajouter des piรจces jointes", + "subtitle": "Intรฉgrer un ou plusieurs fichiers dans le PDF." + }, + "extractAttachments": { + "name": "Extraire les piรจces jointes", + "subtitle": "Extraire tous les fichiers intรฉgrรฉs des PDF dans une archive ZIP." + }, + "editAttachments": { + "name": "Gรฉrer les piรจces jointes", + "subtitle": "Afficher ou supprimer les piรจces jointes du PDF." + }, + "dividePages": { + "name": "Diviser les pages", + "subtitle": "Diviser les pages horizontalement ou verticalement." + }, + "addBlankPage": { + "name": "Ajouter une page vierge", + "subtitle": "Insรฉrer une page vide ร  nโ€™importe quel endroit du PDF." + }, + "reversePages": { + "name": "Inverser lโ€™ordre des pages", + "subtitle": "Renverser lโ€™ordre de toutes les pages du document." + }, + "rotatePdf": { + "name": "Faire pivoter un PDF", + "subtitle": "Tourner les pages par incrรฉments de 90ยฐ." + }, + "rotateCustom": { + "name": "Rotation par angle personnalisรฉ", + "subtitle": "Faire pivoter les pages selon un angle personnalisรฉ." + }, + "nUpPdf": { + "name": "PDF N-up", + "subtitle": "Afficher plusieurs pages sur une seule feuille." + }, + "combineToSinglePage": { + "name": "Combiner en une seule page", + "subtitle": "Assembler toutes les pages en un dรฉfilement continu." + }, + "viewMetadata": { + "name": "Afficher les mรฉtadonnรฉes", + "subtitle": "Consulter les propriรฉtรฉs internes du PDF." + }, + "editMetadata": { + "name": "Modifier les mรฉtadonnรฉes", + "subtitle": "Changer lโ€™auteur, le titre et autres propriรฉtรฉs." + }, + "pdfsToZip": { + "name": "PDF vers ZIP", + "subtitle": "Regrouper plusieurs fichiers PDF dans une archive ZIP." + }, + "comparePdfs": { + "name": "Comparer des PDF", + "subtitle": "Comparer deux PDF cรดte ร  cรดte." + }, + "posterizePdf": { + "name": "Posteriser un PDF", + "subtitle": "Dรฉcouper une grande page en plusieurs pages plus petites." + }, + "fixPageSize": { + "name": "Uniformiser la taille des pages", + "subtitle": "Standardiser toutes les pages ร  un format identique." + }, + "linearizePdf": { + "name": "Optimiser pour le web", + "subtitle": "Optimiser le PDF pour un affichage rapide en ligne." + }, + "pageDimensions": { + "name": "Dimensions des pages", + "subtitle": "Analyser la taille, lโ€™orientation et les unitรฉs des pages." + }, + "removeRestrictions": { + "name": "Supprimer les restrictions", + "subtitle": "Supprimer les protections par mot de passe et restrictions de sรฉcuritรฉ des PDF signรฉs." + }, + "repairPdf": { + "name": "Rรฉparer un PDF", + "subtitle": "Rรฉcupรฉrer les donnรฉes de fichiers PDF corrompus ou endommagรฉs." + }, + "encryptPdf": { + "name": "Chiffrer un PDF", + "subtitle": "Protรฉger le PDF en ajoutant un mot de passe." + }, + "sanitizePdf": { + "name": "Nettoyer un PDF", + "subtitle": "Supprimer les mรฉtadonnรฉes, annotations, scripts et autres รฉlรฉments sensibles." + }, + "decryptPdf": { + "name": "Dรฉverrouiller un PDF", + "subtitle": "Supprimer la protection par mot de passe." + }, + "flattenPdf": { + "name": "Aplatir le PDF", + "subtitle": "Rendre les champs de formulaire et annotations non modifiables." + }, + "removeMetadata": { + "name": "Supprimer les mรฉtadonnรฉes", + "subtitle": "Effacer les donnรฉes cachรฉes du PDF." + }, + "changePermissions": { + "name": "Modifier les autorisations", + "subtitle": "Dรฉfinir ou modifier les permissions utilisateur du PDF." + }, + "odtToPdf": { + "name": "ODT vers PDF", + "subtitle": "Convertir des fichiers OpenDocument Text au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers ODT", + "convertButton": "Convertir en PDF" + }, + "csvToPdf": { + "name": "CSV vers PDF", + "subtitle": "Convertir des fichiers tableur CSV au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers CSV", + "convertButton": "Convertir en PDF" + }, + "rtfToPdf": { + "name": "RTF vers PDF", + "subtitle": "Convertir des documents Rich Text Format en PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers RTF", + "convertButton": "Convertir en PDF" + }, + "wordToPdf": { + "name": "Word vers PDF", + "subtitle": "Convertir des documents Word (DOCX, DOC, ODT, RTF) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers DOCX, DOC, ODT, RTF", + "convertButton": "Convertir en PDF" + }, + "excelToPdf": { + "name": "Excel vers PDF", + "subtitle": "Convertir des feuilles de calcul Excel (XLSX, XLS, ODS, CSV) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers XLSX, XLS, ODS, CSV", + "convertButton": "Convertir en PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint vers PDF", + "subtitle": "Convertir des prรฉsentations PowerPoint (PPTX, PPT, ODP) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers PPTX, PPT, ODP", + "convertButton": "Convertir en PDF" + }, + "markdownToPdf": { + "name": "Markdown vers PDF", + "subtitle": "ร‰crire ou coller du Markdown et lโ€™exporter en PDF avec une mise en forme soignรฉe.", + "paneMarkdown": "Markdown", + "panePreview": "Aperรงu", + "btnUpload": "Tรฉlรฉverser", + "btnSyncScroll": "Synchroniser le dรฉfilement", + "btnSettings": "Paramรจtres", + "btnExportPdf": "Exporter en PDF", + "settingsTitle": "Paramรจtres Markdown", + "settingsPreset": "Prรฉrรฉglage", + "presetDefault": "Par dรฉfaut (type GFM)", + "presetCommonmark": "CommonMark (strict)", + "presetZero": "Minimal (aucune fonctionnalitรฉ)", + "settingsOptions": "Options Markdown", + "optAllowHtml": "Autoriser les balises HTML", + "optBreaks": "Convertir les retours ร  la ligne en
", + "optLinkify": "Convertir automatiquement les URL en liens", + "optTypographer": "Typographie (guillemets intelligents, etc.)" + }, + "pdfBooklet": { + "name": "Livret PDF", + "subtitle": "Rรฉorganiser les pages pour lโ€™impression recto verso en livret. Pliez et agrafez pour crรฉer un livret.", + "howItWorks": "Fonctionnement :", + "step1": "Tรฉlรฉversez un fichier PDF.", + "step2": "Les pages seront rรฉorganisรฉes dans lโ€™ordre du livret.", + "step3": "Imprimez en recto verso, retournement sur le bord court, pliez et agrafez.", + "paperSize": "Format du papier", + "orientation": "Orientation", + "portrait": "Portrait", + "landscape": "Paysage", + "pagesPerSheet": "Pages par feuille", + "createBooklet": "Crรฉer le livret", + "processing": "Traitement...", + "pageCount": "Le nombre de pages sera complรฉtรฉ au multiple de 4 si nรฉcessaire." + }, + "xpsToPdf": { + "name": "XPS vers PDF", + "subtitle": "Convertir des documents XPS/OXPS au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers XPS, OXPS", + "convertButton": "Convertir en PDF" + }, + "mobiToPdf": { + "name": "MOBI vers PDF", + "subtitle": "Convertir des livres numรฉriques MOBI au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers MOBI", + "convertButton": "Convertir en PDF" + }, + "epubToPdf": { + "name": "EPUB vers PDF", + "subtitle": "Convertir des livres numรฉriques EPUB au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers EPUB", + "convertButton": "Convertir en PDF" + }, + "fb2ToPdf": { + "name": "FB2 vers PDF", + "subtitle": "Convertir des livres numรฉriques FictionBook (FB2) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers FB2", + "convertButton": "Convertir en PDF" + }, + "cbzToPdf": { + "name": "CBZ vers PDF", + "subtitle": "Convertir des archives de bandes dessinรฉes (CBZ/CBR) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers CBZ, CBR", + "convertButton": "Convertir en PDF" + }, + "wpdToPdf": { + "name": "WPD vers PDF", + "subtitle": "Convertir des documents WordPerfect (WPD) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers WPD", + "convertButton": "Convertir en PDF" + }, + "wpsToPdf": { + "name": "WPS vers PDF", + "subtitle": "Convertir des documents WPS Office au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers WPS", + "convertButton": "Convertir en PDF" + }, + "xmlToPdf": { + "name": "XML vers PDF", + "subtitle": "Convertir des documents XML au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers XML", + "convertButton": "Convertir en PDF" + }, + "pagesToPdf": { + "name": "Pages vers PDF", + "subtitle": "Convertir des documents Apple Pages au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers Pages", + "convertButton": "Convertir en PDF" + }, + "odgToPdf": { + "name": "ODG vers PDF", + "subtitle": "Convertir des fichiers OpenDocument Graphics (ODG) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers ODG", + "convertButton": "Convertir en PDF" + }, + "odsToPdf": { + "name": "ODS vers PDF", + "subtitle": "Convertir des fichiers OpenDocument Spreadsheet (ODS) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers ODS", + "convertButton": "Convertir en PDF" + }, + "odpToPdf": { + "name": "ODP vers PDF", + "subtitle": "Convertir des fichiers OpenDocument Presentation (ODP) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers ODP", + "convertButton": "Convertir en PDF" + }, + "pubToPdf": { + "name": "PUB vers PDF", + "subtitle": "Convertir des fichiers Microsoft Publisher (PUB) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers PUB", + "convertButton": "Convertir en PDF" + }, + "vsdToPdf": { + "name": "VSD vers PDF", + "subtitle": "Convertir des fichiers Microsoft Visio (VSD, VSDX) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers VSD, VSDX", + "convertButton": "Convertir en PDF" + }, + "psdToPdf": { + "name": "PSD vers PDF", + "subtitle": "Convertir des fichiers Adobe Photoshop (PSD) au format PDF. Prend en charge plusieurs fichiers.", + "acceptedFormats": "Fichiers PSD", + "convertButton": "Convertir en PDF" + }, + "pdfToSvg": { + "name": "PDF vers SVG", + "subtitle": "Convertir chaque page dโ€™un fichier PDF en graphique vectoriel รฉvolutif (SVG) pour une qualitรฉ parfaite ร  toutes les tailles." + }, + "extractTables": { + "name": "Extraire les tableaux PDF", + "subtitle": "Extraire les tableaux des fichiers PDF et les exporter en CSV, JSON ou Markdown." + }, + "pdfToCsv": { + "name": "PDF vers CSV", + "subtitle": "Extraire les tableaux dโ€™un PDF et les convertir au format CSV." + }, + "pdfToExcel": { + "name": "PDF vers Excel", + "subtitle": "Extraire les tableaux dโ€™un PDF et les convertir au format Excel (XLSX)." + }, + "pdfToText": { + "name": "PDF vers texte", + "subtitle": "Extraire le texte des fichiers PDF et lโ€™enregistrer en texte brut (.txt). Prend en charge plusieurs fichiers.", + "note": "Cet outil fonctionne UNIQUEMENT avec des PDF crรฉรฉs numรฉriquement. Pour les documents scannรฉs ou les PDF basรฉs sur des images, utilisez plutรดt notre outil OCR PDF.", + "convertButton": "Extraire le texte" + }, + "digitalSignPdf": { + "name": "Signature numรฉrique PDF", + "pageTitle": "Signature numรฉrique PDF - Ajouter une signature cryptographique | BentoPDF", + "subtitle": "Ajouter une signature numรฉrique cryptographique ร  votre PDF ร  lโ€™aide de certificats X.509. Prend en charge les formats PKCS#12 (.pfx, .p12) et PEM. Votre clรฉ privรฉe ne quitte jamais votre navigateur.", + "certificateSection": "Certificat", + "uploadCert": "Tรฉlรฉverser un certificat (.pfx, .p12)", + "certPassword": "Mot de passe du certificat", + "certPasswordPlaceholder": "Saisissez le mot de passe du certificat", + "certInfo": "Informations du certificat", + "certSubject": "Sujet", + "certIssuer": "ร‰metteur", + "certValidity": "Validitรฉ", + "signatureDetails": "Dรฉtails de la signature (facultatif)", + "reason": "Motif", + "reasonPlaceholder": "ex. : Jโ€™approuve ce document", + "location": "Lieu", + "locationPlaceholder": "ex. : Paris, France", + "contactInfo": "Coordonnรฉes", + "contactPlaceholder": "ex. : email@exemple.com", + "applySignature": "Appliquer la signature numรฉrique", + "successMessage": "PDF signรฉ avec succรจs ! La signature peut รชtre vรฉrifiรฉe dans nโ€™importe quel lecteur PDF." + }, + "validateSignaturePdf": { + "name": "Valider la signature PDF", + "pageTitle": "Valider la signature PDF - Vรฉrifier les signatures numรฉriques | BentoPDF", + "subtitle": "Vรฉrifier les signatures numรฉriques de vos fichiers PDF. Contrรดlez la validitรฉ du certificat, consultez les informations du signataire et confirmez lโ€™intรฉgritรฉ du document. Tout le traitement sโ€™effectue dans votre navigateur." + }, + "emailToPdf": { + "name": "Email vers PDF", + "subtitle": "Convertir des fichiers email (EML, MSG) au format PDF. Prend en charge les exports Outlook et les formats email standards.", + "acceptedFormats": "Fichiers EML, MSG", + "convertButton": "Convertir en PDF" + }, + "fontToOutline": { + "name": "Polices en contours", + "subtitle": "Convertir toutes les polices en contours vectoriels pour un rendu cohรฉrent sur tous les appareils." + }, + "deskewPdf": { + "name": "Redresser un PDF", + "subtitle": "Redresser automatiquement les pages scannรฉes inclinรฉes ร  lโ€™aide dโ€™OpenCV." + } +} diff --git a/public/locales/id/common.json b/public/locales/id/common.json index 3dd49f5..cd52487 100644 --- a/public/locales/id/common.json +++ b/public/locales/id/common.json @@ -66,7 +66,8 @@ "pdfOrImages": "PDF atau Gambar", "filesNeverLeave": "File Anda tidak pernah meninggalkan perangkat Anda.", "addMore": "Tambah Lebih Banyak File", - "clearAll": "Hapus Semua" + "clearAll": "Hapus Semua", + "clearFiles": "Hapus file" }, "loader": { "processing": "Memproses..." @@ -183,7 +184,7 @@ "buyMeCoffee": "Beli Kopi untuk Saya" }, "footer": { - "copyright": "ยฉ 2025 BentoPDF. Hak cipta dilindungi.", + "copyright": "ยฉ 2026 BentoPDF. Hak cipta dilindungi.", "version": "Versi", "company": "Perusahaan", "aboutUs": "Tentang Kami", @@ -226,7 +227,8 @@ "error": "Kesalahan", "success": "Berhasil", "file": "File", - "files": "File" + "files": "File", + "close": "Tutup" }, "about": { "hero": { diff --git a/public/locales/id/tools.json b/public/locales/id/tools.json index 497ccdc..95e9bb6 100644 --- a/public/locales/id/tools.json +++ b/public/locales/id/tools.json @@ -521,5 +521,13 @@ "subtitle": "Konversi file email (EML, MSG) ke format PDF. Mendukung ekspor Outlook dan format email standar.", "acceptedFormats": "File EML, MSG", "convertButton": "Konversi ke PDF" + }, + "fontToOutline": { + "name": "Font ke Garis Tepi", + "subtitle": "Konversi semua font ke garis tepi vektor untuk tampilan konsisten di semua perangkat." + }, + "deskewPdf": { + "name": "Luruskan PDF", + "subtitle": "Otomatis meluruskan halaman hasil pindai yang miring menggunakan OpenCV." } } diff --git a/public/locales/it/common.json b/public/locales/it/common.json index c620102..c71f284 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -1,50 +1,50 @@ { "nav": { "home": "Home", - "about": "Chi Siamo", + "about": "Chi siamo", "contact": "Contatti", "licensing": "Licenze", - "allTools": "Tutti gli Strumenti", - "openMainMenu": "Apri il Menu Principale", + "allTools": "Tutti gli strumenti", + "openMainMenu": "Apri il menu principale", "language": "Lingua" }, "donation": { - "message": "Love BentoPDF? Help us keep it free and open source!", - "button": "Donate" + "message": "Ti piace BentoPDF? Aiutaci a mantenerlo gratuito e open source!", + "button": "Dona" }, "hero": { - "title": "I", - "pdfToolkit": "tuoi attrezzi per i PDF", - "builtForPrivacy": "creati per la privacy", - "noSignups": "Nessun iscrizione", + "title": "Il", + "pdfToolkit": "kit di strumenti PDF", + "builtForPrivacy": "pensato per la privacy", + "noSignups": "Nessuna registrazione", "unlimitedUse": "Uso illimitato", "worksOffline": "Funziona offline", - "startUsing": "Inizia ad usarlo ora" + "startUsing": "Inizia a usarlo ora" }, "usedBy": { "title": "Usato da aziende e persone che lavorano in" }, "features": { - "title": "Perchรจ scegliere", + "title": "Perchรฉ scegliere", "bentoPdf": "BentoPDF?", "noSignup": { - "title": "Nessuna Registrazione", - "description": "Usa subito, senza account o email." + "title": "Nessuna registrazione", + "description": "Inizia subito, senza account nรฉ email." }, "noUploads": { "title": "Nessun caricamento", "description": "100% client-side, i tuoi file non lasciano mai il dispositivo." }, "foreverFree": { - "title": "Sempre Gratis", + "title": "Sempre gratis", "description": "Tutti gli strumenti, nessuna prova, nessun paywall." }, "noLimits": { - "title": "Senza Limiti", + "title": "Senza limiti", "description": "Usalo quanto vuoi, senza limiti nascosti." }, "batchProcessing": { - "title": "Elaborazione in Batch", + "title": "Elaborazione in batch", "description": "Gestisci un numero illimitato di PDF in un'unica operazione." }, "lightningFast": { @@ -55,18 +55,19 @@ "tools": { "title": "Inizia con", "toolsLabel": "Strumenti", - "subtitle": "Clicca uno strumento per aprire il caricatore di file", - "searchPlaceholder": "Cerca uno strumento (es. 'split', 'organize'...)", - "backToTools": "Torna agli Strumenti", - "firstLoadNotice": "Il primo caricamento richiede un momento mentre scarichiamo il nostro motore di conversione. Dopo di ciรฒ, tutti i caricamenti saranno immediati." + "subtitle": "Clicca su uno strumento per aprire il caricatore di file", + "searchPlaceholder": "Cerca uno strumento (es. \"split\", \"organizza\"...)", + "backToTools": "Torna agli strumenti", + "firstLoadNotice": "Il primo caricamento richiede qualche istante mentre scarichiamo il motore di conversione. Dopo di ciรฒ, tutti i caricamenti saranno immediati." }, "upload": { "clickToSelect": "Clicca per selezionare un file", - "orDragAndDrop": "o trascina e rilascia", - "pdfOrImages": "PDF o Immagini", + "orDragAndDrop": "oppure trascina e rilascia", + "pdfOrImages": "PDF o immagini", "filesNeverLeave": "I tuoi file non lasciano mai il tuo dispositivo.", "addMore": "Aggiungi altri file", - "clearAll": "Svuota tutto" + "clearAll": "Svuota tutto", + "clearFiles": "Cancella file" }, "loader": { "processing": "Elaborazione..." @@ -76,7 +77,7 @@ "ok": "OK" }, "preview": { - "title": "Anteprima Documento", + "title": "Anteprima documento", "downloadAsPdf": "Scarica come PDF", "close": "Chiudi" }, @@ -87,7 +88,7 @@ "displayPreferences": "Preferenze di visualizzazione", "searchShortcuts": "Cerca scorciatoie...", "shortcutsInfo": "Premi e tieni premuti i tasti per impostare una scorciatoia. Le modifiche vengono salvate automaticamente.", - "shortcutsWarning": "โš ๏ธ Evita scorciatoie comuni del browser (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N ecc.) poichรฉ potrebbero non funzionare in modo affidabile.", + "shortcutsWarning": "โš ๏ธ Evita le scorciatoie comuni del browser (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N ecc.) perchรฉ potrebbero non funzionare in modo affidabile.", "import": "Importa", "export": "Esporta", "resetToDefaults": "Reimposta ai valori predefiniti", @@ -95,7 +96,7 @@ "fullWidthDescription": "Usa l'intera larghezza dello schermo per tutti gli strumenti invece di un contenitore centrato", "settingsAutoSaved": "Le impostazioni vengono salvate automaticamente", "clickToSet": "Clicca per impostare", - "pressKeys": "Premi tasti...", + "pressKeys": "Premi i tasti...", "warnings": { "alreadyInUse": "Scorciatoia giร  in uso", "assignedTo": "รจ giร  assegnata a:", @@ -104,11 +105,11 @@ "commonlyUsed": "รจ comunemente usata per:", "unreliable": "Questa scorciatoia potrebbe non funzionare in modo affidabile o potrebbe avere conflitti con il comportamento del browser/sistema.", "useAnyway": "Vuoi usarla comunque?", - "resetTitle": "Reimposta Scorciatoie", + "resetTitle": "Reimposta scorciatoie", "resetMessage": "Sei sicuro di voler reimpostare tutte le scorciatoie ai valori predefiniti?

Questa azione non puรฒ essere annullata.", - "importSuccessTitle": "Importazione Riuscita", + "importSuccessTitle": "Importazione riuscita", "importSuccessMessage": "Scorciatoie importate con successo!", - "importFailTitle": "Importazione Fallita", + "importFailTitle": "Importazione fallita", "importFailMessage": "Impossibile importare le scorciatoie. Formato file non valido." } }, @@ -137,8 +138,8 @@ } }, "faq": { - "title": "Domande Frequenti", - "questions": "Domande", + "title": "Domande", + "questions": "Frequenti", "isFree": { "question": "BentoPDF รจ davvero gratuito?", "answer": "Sรฌ, assolutamente. Tutti gli strumenti su BentoPDF sono gratuiti al 100%, senza limiti di file, senza registrazioni e senza filigrane. Crediamo che tutti debbano poter accedere a strumenti PDF semplici e potenti senza barriere a pagamento." @@ -174,8 +175,8 @@ }, "testimonials": { "title": "Cosa", - "users": "i Nostri Utenti", - "say": "Dicono" + "users": "dicono i nostri", + "say": "utenti" }, "support": { "title": "Ti piace il mio lavoro?", @@ -183,22 +184,22 @@ "buyMeCoffee": "Offrimi un caffรจ" }, "footer": { - "copyright": "ยฉ 2025 BentoPDF. Tutti i diritti riservati.", + "copyright": "ยฉ 2026 BentoPDF. Tutti i diritti riservati.", "version": "Versione", "company": "Azienda", - "aboutUs": "Chi Siamo", + "aboutUs": "Chi siamo", "faqLink": "FAQ", "contactUs": "Contattaci", "legal": "Legale", - "termsAndConditions": "Termini e Condizioni", - "privacyPolicy": "Informativa sulla Privacy", + "termsAndConditions": "Termini e condizioni", + "privacyPolicy": "Informativa sulla privacy", "followUs": "Seguici" }, "merge": { "title": "Unisci PDF", "description": "Combina file interi, oppure seleziona pagine specifiche da unire in un nuovo documento.", - "fileMode": "Modalitร  File", - "pageMode": "Modalitร  Pagina", + "fileMode": "Modalitร  file", + "pageMode": "Modalitร  pagina", "howItWorks": "Come funziona:", "fileModeInstructions": [ "Clicca e trascina l'icona per cambiare l'ordine dei file.", @@ -226,7 +227,8 @@ "error": "Errore", "success": "Successo", "file": "File", - "files": "File" + "files": "File", + "close": "Chiudi" }, "about": { "hero": { @@ -247,7 +249,7 @@ "title": "Perchรฉ BentoPDF", "speed": { "title": "Progettato per la velocitร ", - "description": "Nessuna attesa per upload o download verso un server. Elaborando i file direttamente nel browser con tecnologie web moderne come WebAssembly, offriamo velocitร  impareggiabile per tutti i nostri strumenti." + "description": "Nessuna attesa per upload o download verso un server. Elaborando i file direttamente nel browser con tecnologie web moderne come WebAssembly, offriamo una velocitร  impareggiabile per tutti i nostri strumenti." }, "free": { "title": "Completamente gratuito", @@ -266,58 +268,58 @@ "title": "Pronto per iniziare?", "description": "Unisciti a migliaia di utenti che si affidano a BentoPDF per le loro esigenze quotidiane sui documenti. Sperimenta la differenza che privacy e prestazioni possono offrire.", "button": "Esplora tutti gli strumenti" - }, - "contact": { - "title": "Contattaci", - "subtitle": "Ci farebbe piacere sentirti. Che tu abbia una domanda, un feedback o una richiesta di funzionalitร , non esitare a contattarci.", - "email": "Puoi contattarci direttamente via email a:" - }, - "licensing": { - "title": "Licenze per", - "subtitle": "Scegli la licenza che si adatta alle tue esigenze." - }, - "multiTool": { - "uploadPdfs": "Carica PDF", - "upload": "Carica", - "addBlankPage": "Aggiungi pagina vuota", - "edit": "Modifica:", - "undo": "Annulla", - "redo": "Ripeti", - "reset": "Reimposta", - "selection": "Selezione:", - "selectAll": "Seleziona tutto", - "deselectAll": "Deseleziona tutto", - "rotate": "Ruota:", - "rotateLeft": "Sinistra", - "rotateRight": "Destra", - "transform": "Trasforma:", - "duplicate": "Duplica", - "split": "Dividi", - "clear": "Svuota:", - "delete": "Elimina", - "download": "Scarica:", - "downloadSelected": "Scarica selezionati", - "exportPdf": "Esporta PDF", - "uploadPdfFiles": "Seleziona file PDF", - "dragAndDrop": "Trascina e rilascia i file PDF qui, oppure clicca per selezionare", - "selectFiles": "Seleziona file", - "renderingPages": "Generazione anteprime pagine...", - "actions": { - "duplicatePage": "Duplica questa pagina", - "deletePage": "Elimina questa pagina", - "insertPdf": "Inserisci PDF dopo questa pagina", - "toggleSplit": "Attiva la divisione dopo questa pagina" - }, - "pleaseWait": "Attendere...", - "pagesRendering": "Le pagine sono ancora in fase di generazione. Attendere...", - "noPagesSelected": "Nessuna pagina selezionata", - "selectOnePage": "Seleziona almeno una pagina da scaricare.", - "noPages": "Nessuna pagina", - "noPagesToExport": "Non ci sono pagine da esportare.", - "renderingTitle": "Generazione anteprime delle pagine", - "errorRendering": "Impossibile generare le miniature delle pagine", - "error": "Errore", - "failedToLoad": "Caricamento fallito" } + }, + "contact": { + "title": "Contattaci", + "subtitle": "Ci farebbe piacere sentirti. Che tu abbia una domanda, un feedback o una richiesta di funzionalitร , non esitare a contattarci.", + "email": "Puoi contattarci direttamente via email a:" + }, + "licensing": { + "title": "Licenze per", + "subtitle": "Scegli la licenza che si adatta alle tue esigenze." + }, + "multiTool": { + "uploadPdfs": "Carica PDF", + "upload": "Carica", + "addBlankPage": "Aggiungi pagina vuota", + "edit": "Modifica:", + "undo": "Annulla", + "redo": "Ripeti", + "reset": "Reimposta", + "selection": "Selezione:", + "selectAll": "Seleziona tutto", + "deselectAll": "Deseleziona tutto", + "rotate": "Ruota:", + "rotateLeft": "Sinistra", + "rotateRight": "Destra", + "transform": "Trasforma:", + "duplicate": "Duplica", + "split": "Dividi", + "clear": "Svuota:", + "delete": "Elimina", + "download": "Scarica:", + "downloadSelected": "Scarica selezionati", + "exportPdf": "Esporta PDF", + "uploadPdfFiles": "Seleziona file PDF", + "dragAndDrop": "Trascina e rilascia i file PDF qui, oppure clicca per selezionare", + "selectFiles": "Seleziona file", + "renderingPages": "Generazione anteprime pagine...", + "actions": { + "duplicatePage": "Duplica questa pagina", + "deletePage": "Elimina questa pagina", + "insertPdf": "Inserisci PDF dopo questa pagina", + "toggleSplit": "Attiva la divisione dopo questa pagina" + }, + "pleaseWait": "Attendere...", + "pagesRendering": "Le pagine sono ancora in fase di generazione. Attendere...", + "noPagesSelected": "Nessuna pagina selezionata", + "selectOnePage": "Seleziona almeno una pagina da scaricare.", + "noPages": "Nessuna pagina", + "noPagesToExport": "Non ci sono pagine da esportare.", + "renderingTitle": "Generazione anteprime delle pagine", + "errorRendering": "Impossibile generare le miniature delle pagine", + "error": "Errore", + "failedToLoad": "Caricamento fallito" } } diff --git a/public/locales/it/tools.json b/public/locales/it/tools.json index 1a9960b..0caf98e 100644 --- a/public/locales/it/tools.json +++ b/public/locales/it/tools.json @@ -3,18 +3,18 @@ "popularTools": "Strumenti popolari", "editAnnotate": "Modifica e Annota", "convertToPdf": "Converti in PDF", - "convertFromPdf": "Convert da PDF", + "convertFromPdf": "Converti da PDF", "organizeManage": "Organizza e Gestisci", "optimizeRepair": "Ottimizza e Ripara", "securePdf": "Proteggi PDF" }, "pdfMultiTool": { - "name": "PDF Multi Tool", - "subtitle": "Unisci, Dividi, Organizza, Elimina, Ruota, Aggiungi Pagine Vuote, Estrai e Duplica in un'interfaccia unificata." + "name": "Strumento PDF multifunzione", + "subtitle": "Unisci, dividi, organizza, elimina, ruota, aggiungi pagine vuote, estrai e duplica in un'interfaccia unificata." }, "mergePdf": { "name": "Unisci PDF", - "subtitle": "Unisci piรน PDF in un unico file. Conserva i Segnalibri." + "subtitle": "Unisci piรน PDF in un unico file. Conserva i segnalibri." }, "splitPdf": { "name": "Dividi PDF", @@ -68,7 +68,7 @@ }, "duplicateOrganize": { "name": "Duplica e Organizza", - "subtitle": "Duplica, riordina e elimina pagine." + "subtitle": "Duplica, riordina ed elimina pagine." }, "deletePages": { "name": "Elimina Pagine", @@ -199,7 +199,7 @@ }, "alternateMix": { "name": "Alterna e Riordina Pagine", - "subtitle": "Unisci PDF sostituendo le pagine di ogni file. Conserva i segnalibri." + "subtitle": "Unisci i PDF alternando le pagine di ogni file. Conserva i segnalibri." }, "addAttachments": { "name": "Aggiungi Allegati", @@ -489,10 +489,45 @@ "note": "Questo strumento funziona SOLO con PDF creati digitalmente. Per documenti scansionati o basati su immagini, usa invece il nostro strumento OCR PDF.", "convertButton": "Estrai testo" }, + "digitalSignPdf": { + "name": "Firma digitale PDF", + "pageTitle": "Firma digitale PDF - Aggiungi firma crittografica | BentoPDF", + "subtitle": "Aggiungi una firma digitale crittografica al tuo PDF usando certificati X.509. Supporta i formati PKCS#12 (.pfx, .p12) e PEM. La tua chiave privata non lascia mai il browser.", + "certificateSection": "Certificato", + "uploadCert": "Carica certificato (.pfx, .p12)", + "certPassword": "Password del certificato", + "certPasswordPlaceholder": "Inserisci la password del certificato", + "certInfo": "Informazioni sul certificato", + "certSubject": "Soggetto", + "certIssuer": "Emittente", + "certValidity": "Valido", + "signatureDetails": "Dettagli della firma (opzionale)", + "reason": "Motivo", + "reasonPlaceholder": "es. Approvo questo documento", + "location": "Luogo", + "locationPlaceholder": "es. Roma, Italia", + "contactInfo": "Contatto", + "contactPlaceholder": "es. email@example.com", + "applySignature": "Applica firma digitale", + "successMessage": "PDF firmato con successo! La firma puรฒ essere verificata in qualsiasi lettore PDF." + }, + "validateSignaturePdf": { + "name": "Verifica firma PDF", + "pageTitle": "Verifica firma PDF - Controlla firme digitali | BentoPDF", + "subtitle": "Verifica le firme digitali nei tuoi PDF. Controlla la validitร  del certificato, visualizza i dati del firmatario e conferma l'integritร  del documento. Tutto avviene nel tuo browser." + }, "emailToPdf": { "name": "Email in PDF", "subtitle": "Converti file email (EML, MSG) in formato PDF. Supporta esportazioni Outlook e formati email standard.", "acceptedFormats": "File EML, MSG", "convertButton": "Converti in PDF" + }, + "fontToOutline": { + "name": "Font in Contorni", + "subtitle": "Converti tutti i font in contorni vettoriali per una visualizzazione coerente su tutti i dispositivi." + }, + "deskewPdf": { + "name": "Raddrizza PDF", + "subtitle": "Raddrizza automaticamente le pagine scansionate inclinate usando OpenCV." } } diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json new file mode 100644 index 0000000..2e2963e --- /dev/null +++ b/public/locales/nl/common.json @@ -0,0 +1,325 @@ +{ + "nav": { + "home": "Thuis", + "about": "Over", + "contact": "Contact", + "licensing": "Licentie", + "allTools": "Alle Tools", + "openMainMenu": "Hoofdmenu openen", + "language": "Taal" + }, + "donation": { + "message": "Vind je BentoPDF geweldig? Help ons het gratis en open source te houden!", + "button": "Doneren" + }, + "hero": { + "title": "De", + "pdfToolkit": "PDF Toolkit", + "builtForPrivacy": "gemaakt voor privacy", + "noSignups": "Geen aanmelding", + "unlimitedUse": "Onbegrenst gebruik", + "worksOffline": "Werkt Offline", + "startUsing": "Direct aan de slag" + }, + "usedBy": { + "title": "Gebruikt door bedrijven en personen werkzaam bij" + }, + "features": { + "title": "Waarom", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "Geen aanmelding", + "description": "Direct aan de slag, zonder account of e-mails." + }, + "noUploads": { + "title": "Geen uploads", + "description": "100% client-side, je bestanden blijven op jouw apparaat." + }, + "foreverFree": { + "title": "Voor altijd gratis", + "description": "Alle tools, geen proef, geen betaalmuur." + }, + "noLimits": { + "title": "Geen beperkingen", + "description": "Gebruik het zoveel je wilt, geen verborgen limiet." + }, + "batchProcessing": { + "title": "Reeksen verwerken", + "description": "Verwerk in een keer een onbeperkt aantal PDF's." + }, + "lightningFast": { + "title": "Bliksemsnel", + "description": "Verwerk PDF's direct, zonder wachten of vertraging." + } + }, + "tools": { + "title": "Aan de slag met", + "toolsLabel": "Tools", + "subtitle": "Klik een tool om de bestandslader te openen", + "searchPlaceholder": "Zoek een tool (bijv., 'splitsen', 'organiseren'...)", + "backToTools": "Terug naar Tools", + "firstLoadNotice": "De eerste keer duurt het even om onze conversiemachine te laden. Daarna gaat alles meteen." + }, + "upload": { + "clickToSelect": "Klik om een bestand te selecteren", + "orDragAndDrop": "of sleep er een hierheen", + "pdfOrImages": "PDF's of Afbeeldingen", + "filesNeverLeave": "Je bestanden blijven op jouw apparaat.", + "addMore": "Meer bestanden toevoegen", + "clearAll": "Alles wissen", + "clearFiles": "Bestanden wissen" + }, + "loader": { + "processing": "Verwerken..." + }, + "alert": { + "title": "Let op", + "ok": "OK" + }, + "preview": { + "title": "Document Weergeven", + "downloadAsPdf": "Downloaden als PDF", + "close": "Sluiten" + }, + "settings": { + "title": "Instellingen", + "shortcuts": "Sneltoetsen", + "preferences": "Voorkeuren", + "displayPreferences": "Voorkeuren weergeven", + "searchShortcuts": "Sneltoetsen zoeken...", + "shortcutsInfo": "Houd toetsen ingedrukt om deze in te stellen als sneltoets. Aanpassingen worden automatisch opgeslagen.", + "shortcutsWarning": "โš ๏ธ Voorkom algemene sneltoetsen voor browsers (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N etc.) aangezien deze niet betrouwbaar kunnen functioneren.", + "import": "Importeren", + "export": "Exporteren", + "resetToDefaults": "Terugzetten naar standaard", + "fullWidthMode": "Volledige breedte", + "fullWidthDescription": "Gebruik de volledige breedte van het scherm in plaats van een gecentreerde kolom", + "settingsAutoSaved": "Instellingen worden automatisch opgeslagen", + "clickToSet": "Klik om in te stellen", + "pressKeys": "Druk toetsen...", + "warnings": { + "alreadyInUse": "Sneltoets al in gebruik", + "assignedTo": "is al toegewezen aan:", + "chooseDifferent": "Kies een andere sneltoets.", + "reserved": "Waarschuwing voor gereserveerde sneltoets", + "commonlyUsed": "wordt algemeen gebruikt voor:", + "unreliable": "Deze sneltoets werkt mogelijk niet goed of is in conflict met gedrag van browser of systeem.", + "useAnyway": "Wil je het toch gebruiken?", + "resetTitle": "Sneltoetsen terugzetten", + "resetMessage": "Weet je zeker dat je alle sneltoetsen wilt terugzetten naar standaard?

Deze actie kan niet ongedaan worden gemaakt.", + "importSuccessTitle": "Import succesvoll", + "importSuccessMessage": "Sneltoetsen zijn met succes geรฏmporteerd!", + "importFailTitle": "Import mislukt", + "importFailMessage": "Het importeren van sneltoetsen is mislukt. Ongeldig bestandsformaat." + } + }, + "warning": { + "title": "Waarschuwing", + "cancel": "Annuleren", + "proceed": "Verder" + }, + "compliance": { + "title": "Jouw gegevens blijven op jouw appraat", + "weKeep": "Wij houden", + "yourInfoSafe": "jouw informatie veilig", + "byFollowingStandards": "volgens de volgende algemene veiligheidsstandaarden.", + "processingLocal": "Alle verwerking vindt lokaal plaats op jouw apparaat.", + "gdpr": { + "title": "AVG-naleving", + "description": "Beschermt persoonlijke gegevens en privacy van individuรซn binnen de Europese Unie." + }, + "ccpa": { + "title": "CCPA-naleving", + "description": "Geeft inwoners van Californiรซ rechten over hoe hun persoonlijke gegevens worden verzameld, gebruikt en gedeeld." + }, + "hipaa": { + "title": "HIPAA-naleving", + "description": "Stelt waarborgen in voor het omgaan met gevoelige gezondheidsinformatie in het gezondheidszorgsysteem van de Verenigde Staten." + } + }, + "faq": { + "title": "Vaak gestelde vragen", + "questions": "Vragen", + "isFree": { + "question": "Is BentoPDF echt gratis?", + "answer": "Ja, absoluut. Alle tools op BentoPDF zijn 100% gratis te gebruiken, zonder bestandslimieten, zonder aanmeldingen en zonder watermerken. Wij vinden dat iedereen toegang verdient tot eenvoudige, krachtige PDF-tools zonder betaalmuur." + }, + "areFilesSecure": { + "question": "Zijn mijn bestanden veilig? Waar worden ze verwerkt?", + "answer": "Je bestanden zijn zo veilig mogelijk omdat ze je computer nooit verlaten. Alle verwerking gebeurt direct in je webbrowser (client-side). Je bestanden worden nooit naar een server ge-upload, zodat je volledige privacy en controle over je documenten behoudt." + }, + "platforms": { + "question": "Werkt het op Mac, Windows en mobiel?", + "answer": "Ja! Omdat BentoPDF volledig in je browser werkt, werkt het op elk besturingssysteem met een moderne webbrowser, inclusief Windows, macOS, Linux, iOS en Android." + }, + "gdprCompliant": { + "question": "Is BentoPDF AVG-conform?", + "answer": "Ja. BentoPDF voldoet volledig aan de AVG. Omdat alle bestandsverwerking lokaal in je browser gebeurt en we nooit je bestanden naar een server sturen of verzamelen, hebben wij geen toegang tot je gegevens. Zo houd jij altijd de controle over je documenten." + }, + "dataStorage": { + "question": "Slaan jullie mijn bestanden op of volgen jullie die?", + "answer": "Nee. We slaan je bestanden nooit op, volgen ze niet en houden er geen logboek van bij. Alles wat je op BentoPDF doet, gebeurt in het geheugen van je browser en verdwijnt zodra je de pagina sluit. Er is geen upload, geen geschiedenislogboek en geen servers bij betrokken." + }, + "different": { + "question": "Wat maakt BentoPDF anders dan andere PDF-tools?", + "answer": "De meeste PDF-tools verlangen dat je je bestanden voor verwerking naar een server uploadt. BentoPDF doet dat nooit. Wij gebruiken veilige, moderne webtechnologie om je bestanden direct in je browser te verwerken. Dit betekent snellere prestaties, betere privacy en totale gemoedsrust." + }, + "browserBased": { + "question": "Hoe zorgt browsergebaseerde verwerking ervoor dat ik veilig blijf?", + "answer": "Omdat BentoPDF helemaal in je browser draait, blijven je bestanden altijd op je apparaat. Daardoor hoef je je geen zorgen te maken over hacks, datalekken of ongeoorloofde toegang. Je bestanden zijn altijd van jou." + }, + "analytics": { + "question": "Gebruikt BentoPDF cookies of analytics om mij te volgen?", + "answer": "We geven om je privacy. BentoPDF houdt geen persoonlijke gegevens bij. We gebruiken Simple Analytics alleen om anonieme bezoekersaantallen te zien. Dit betekent dat we kunnen weten hoeveel mensen onze site bezoeken, maar we weten nooit wie jij bent. Simple Analytics is volledig AVG-conform en respecteert je privacy." + } + }, + "testimonials": { + "title": "Wat Onze", + "users": "Gebruikers", + "say": "Zeggen" + }, + "support": { + "title": "Vind je mijn werk leuk?", + "description": "BentoPDF is een project van passie, gemaakt om iedereen een gratis, privรฉ en krachtig PDF-gereedschap te bieden. Als je het handig vindt, overweeg dan om de ontwikkeling te steunen. Elke koffie helpt!", + "buyMeCoffee": "Koop een kopje koffie voor me" + }, + "footer": { + "copyright": "ยฉ 2025 BentoPDF. Alle rechten voorbehouden.", + "version": "Versie", + "company": "Bedrijf", + "aboutUs": "Over ons", + "faqLink": "FAQ", + "contactUs": "Contact", + "legal": "Juridisch", + "termsAndConditions": "Algemene voorwaarden", + "privacyPolicy": "Privacybeleid", + "followUs": "Volgen" + }, + "merge": { + "title": "PDF's Samenvoegen", + "description": "Combineer hele bestanden, of selecteer specifieke pagina's om te samen te voegen tot een nieuw document.", + "fileMode": "Bestandsmodus", + "pageMode": "Paginamodus", + "howItWorks": "Hoe het werkt:", + "fileModeInstructions": [ + "Klik en sleep het pictogram om de volgorde van de bestanden te wijzigen.", + "In het vak \"Pagina's\" voor elk bestand kan je reeksen opgeven (bijv. \"1-3, 5\") om alleen die pagina's samen te voegen.", + "Laat het vak \"Pagina's\" leeg om alle pagina's in het bestand op te nemen." + ], + "pageModeInstructions": [ + "Alle pagina's van je PDF's worden hieronder weergegeven.", + "Sleep afzonderlijke pagina-miniaturen in de gewenste volgorde voor je nieuwe bestand." + ], + "mergePdfs": "PDF's Samenvoegen" + }, + "common": { + "page": "Pagina", + "pages": "Pagina's", + "of": "van", + "download": "Download", + "cancel": "Annuleren", + "save": "Opslaan", + "delete": "Verwijderen", + "edit": "Bewerken", + "add": "Toevoegen", + "remove": "Verwijderen", + "loading": "Laden...", + "error": "Fout", + "success": "Success", + "file": "Bestand", + "files": "Bestanden", + "close": "Sluiten" + }, + "about": { + "hero": { + "title": "Wij vinden dat PDF-tools", + "subtitle": "snel, privรฉ, en gratis moeten zijn.", + "noCompromises": "Geen compromissen." + }, + "mission": { + "title": "Onze Missie", + "description": "Ons doel is om de meest complete PDF-toolbox te bieden die je privacy respecteert en nooit om betaling vraagt. Wij geloven dat essentiรซle documententools voor iedereen, overal en zonder obstakels toegankelijk moeten zijn." + }, + "philosophy": { + "label": "Onze kernfilosofie", + "title": "Privacy First. Always.", + "description": "In een tijdperk waarin data een handelswaar is, doen wij het net even anders. Alle verwerking voor BentoPDF-tools gebeurt lokaal in je browser. Dat betekent dat je bestanden nooit oop onze servers terechtkomen, dat wij je documenten nooit zien en niets volgen van wat je doet. Je documenten blijven volledig privรฉ, punt. Het is niet zomaar een functie; het is onze basis." + }, + "whyBentopdf": { + "title": "Waarom", + "speed": { + "title": "Gemaakt voor snelheid", + "description": "Geen wachttijd voor uploads of downloads naar een server. Door bestanden direct in je browser te verwerken met moderne webtechnologieรซn zoals WebAssembly, bieden we ongeรซvenaarde snelheid voor al onze tools." + }, + "free": { + "title": "Volledig gratis", + "description": "Geen proefversies, geen abonnementen, geen verborgen kosten en geen \"premium\" functies die vworden achtergehouden. Wij vinden dat krachtige PDF-tools een openbare dienst moeten zijn, geen winstmachine." + }, + "noAccount": { + "title": "Geen account vereist", + "description": "Begin meteen met het gebruiken van een tool. Je e-mail, wachtwoord of persoonlijke gegevens hebben we niet nodig. Je workflow kan soepel en anoniem zijn." + }, + "openSource": { + "title": "De geest van Open Source", + "description": "Gebouwd met transparantie in gedachten. We maken gebruik van geweldige open-source bibliotheken zoals PDF-lib en PDF.js en geloven in de communitygedreven inspanning om krachtige tools voor iedereen toegankelijk te maken." + } + }, + "cta": { + "title": "Klaar om te beginnen?", + "description": "Sluit je aan bij duizenden gebruikers die BentoPDF vertrouwen voor hun dagelijkse documentbehoeften. Ervaar zelf het verschil dat privacy en prestaties kunnen maken.", + "button": "Ontdek alle tools" + } + }, + "contact": { + "title": "Neem contact op", + "subtitle": "We horen graag van je. Of je nu een vraag, feedback of een verzoek voor een functie hebt, aarzel dan niet om contact met ons op te nemen.", + "email": "Je kunt ons rechtstreeks bereiken via e-mail op:" + }, + "licensing": { + "title": "Licentie voor", + "subtitle": "Kies de licentie die bij je past." + }, + "multiTool": { + "uploadPdfs": "PDF's laden", + "upload": "Laden", + "addBlankPage": "Blanco pagina toevoegen", + "edit": "Bewerken:", + "undo": "Ongedaan maken", + "redo": "Opnieuw", + "reset": "Terugzetten", + "selection": "Selectie:", + "selectAll": "Alles selecteren", + "deselectAll": "Selectie opheffen", + "rotate": "Roteren:", + "rotateLeft": "Linksom", + "rotateRight": "Rechtsom", + "transform": "Transformeren:", + "duplicate": "Dupliceren", + "split": "Splitsen", + "clear": "Wissen:", + "delete": "Verwijderen", + "download": "Laden:", + "downloadSelected": "Selectie laden", + "exportPdf": "PDF Exporteren", + "uploadPdfFiles": "PDF-bestanden selecteren", + "dragAndDrop": "Klik om een bestand te selecteren, of sleep er een hierheen", + "selectFiles": "Bestanden selecteren", + "renderingPages": "Pagina's vewerken...", + "actions": { + "duplicatePage": "Deze pagina dupliceren", + "deletePage": "Deze pagina verwijderen", + "insertPdf": "PDF achter deze pagina invoegen", + "toggleSplit": "Splitsing maken na deze pagina" + }, + "pleaseWait": "Even geduld", + "pagesRendering": "Pagina's worden nog verwerkt. Even geduld...", + "noPagesSelected": "Geen pagina's geselecteerd", + "selectOnePage": "Kies tenminste een pagina om te laden.", + "noPages": "Geen pagina's", + "noPagesToExport": "Er zijn geen pagina's om te exporteren.", + "renderingTitle": "Paginavoorbeeld verwerken", + "errorRendering": "Generatie van pagina-miniaturen is mislukt", + "error": "Fout", + "failedToLoad": "Laden is mislukt" + } +} diff --git a/public/locales/nl/tools.json b/public/locales/nl/tools.json new file mode 100644 index 0000000..067f719 --- /dev/null +++ b/public/locales/nl/tools.json @@ -0,0 +1,533 @@ +{ + "categories": { + "popularTools": "Populaire Tools", + "editAnnotate": "Bewerken & Annoteren", + "convertToPdf": "Converteren naar PDF", + "convertFromPdf": "Converteren van PDF", + "organizeManage": "Organiseren & Beheren", + "optimizeRepair": "Optimaliseren & Repareren", + "securePdf": "PDF beveiligen" + }, + "pdfMultiTool": { + "name": "PDF Multi-tool", + "subtitle": "Samenvoegen, Splitsen, Organiseren, Verwijderen, Roteren, Blanco pagina's toevoegen, Extraheren and Dupliceren in een enkele werkomgeving." + }, + "mergePdf": { + "name": "PDF Samenvoegen", + "subtitle": "Meerdere PDFs combineren tot een enkel bestand. Bladwijzers behouden." + }, + "splitPdf": { + "name": "PDF Splitsen", + "subtitle": "Een reeks pagina's opslaan in een nieuwe PDF." + }, + "compressPdf": { + "name": "PDF Comprimeren", + "subtitle": "De bestandsgrootte van je PDF verkleinen.", + "algorithmLabel": "Compressie-algoritme", + "condense": "Condense (Aanbevolen)", + "photon": "Photon (Voor PDF's met veel foto's)", + "condenseInfo": "Condense gebruikt geavanceerde compressie: verwijdert overbodige onderdelen, optimaliseert afbeeldingen en kiest alleen de benodigde letters uit fonts. Ideaal voor de meeste PDF's.", + "photonInfo": "Photon zet pagina's om in afbeeldingen. Handig voor PDF's met veel foto's of gescande documenten.", + "photonWarning": "Let op: De tekst kan dan niet meer geselecteerd worden en links werken niet meer.", + "levelLabel": "Compressieniveau", + "light": "Licht (Kwaliteit behouden)", + "balanced": "Gebalanceerd (Aanbevolen)", + "aggressive": "Agressief (Kleinere bestanden)", + "extreme": "Extreem (Maximale compressie)", + "grayscale": "Converteren naar grijswaarden", + "grayscaleHint": "Vermindert de bestandsgrootte door kleurinformatie te verwijderen", + "customSettings": "Aangepaste instellingen", + "customSettingsHint": "Compressie-instellingen verfijnen:", + "outputQuality": "Uitvoerkwaliteit", + "resizeImagesTo": "Formaat van afbeeldingen aanpassen naar", + "onlyProcessAbove": "Alleen verwerken boven", + "removeMetadata": "Metagegevens wissen", + "subsetFonts": "Subset-lettertypen (ongebruikte tekens verwijderen)", + "removeThumbnails": "Ingesloten miniaturen verwijderen", + "compressButton": "PDF Comprimeren" + }, + "pdfEditor": { + "name": "PDF Editor", + "subtitle": "PDFs annoteren, markeren, redigeren, commentaar toevoegen, vormen/afbeelding toevoegen, doorzoeken and weergeven." + }, + "jpgToPdf": { + "name": "JPG naar PDF", + "subtitle": "Een of meer JPG-afbeeldingen opslaan als PDF." + }, + "signPdf": { + "name": "PDF Ondertekenen", + "subtitle": "Je handtekening tekenen, typen, of invoegen." + }, + "cropPdf": { + "name": "PDF Bijsnijden", + "subtitle": "De marges aanpassen van alle pagina's in je PDF." + }, + "extractPages": { + "name": "Pagina's Extraheren", + "subtitle": "Een selectie van pagina's opslaan als nieuw bestand." + }, + "duplicateOrganize": { + "name": "Dupliceren & Organiseren", + "subtitle": "Pagina's dupliceren, ordenen en verwijderen." + }, + "deletePages": { + "name": "Pagina's Verwijderen", + "subtitle": "Specifieke pagina's uit een dodocument verwijderen." + }, + "editBookmarks": { + "name": "Bladwijzers Bewerken", + "subtitle": "PDF-bladwijzers toevoegen, bewerken, importeren, verwijderen and extraheren." + }, + "tableOfContents": { + "name": "Inhoudsopgave", + "subtitle": "Een inhoudsopgave genereren van PDF-bladwijzers." + }, + "pageNumbers": { + "name": "Paginanummers", + "subtitle": "Paginanummers aan je document toevoegen." + }, + "addWatermark": { + "name": "Watermerk toevoegen", + "subtitle": "Tekst of een afbeelding over de pagina's van je PDF stempelen." + }, + "headerFooter": { + "name": "Koptekst & Voettekst", + "subtitle": "Tekst boven- of onderaan de pagina's toevoegen." + }, + "invertColors": { + "name": "Kleuren Omkeren", + "subtitle": "Maak een \"donkere modus\"-versie van je PDF." + }, + "backgroundColor": { + "name": "Achtergrondkleur", + "subtitle": "Wijzig de achtergrondkleur van je PDF." + }, + "changeTextColor": { + "name": "Tekstkleur", + "subtitle": "Wijzig de tekstkleur van je PDF." + }, + "addStamps": { + "name": "Stempels Toevoegen", + "subtitle": "Voeg afbeeldingsstempels toe aan je PDF met de werkbalk Annotatie.", + "usernameLabel": "Gebruikersnaam stempelen", + "usernamePlaceholder": "Voer je naam in (voor stempels)", + "usernameHint": "Deze naam verschijnt op stempels die jij aanmaakt." + }, + "removeAnnotations": { + "name": "Annotaties Verwijderen", + "subtitle": "Commentaar, markeringen en links verwijderen." + }, + "pdfFormFiller": { + "name": "PDF-formulier Vullen", + "subtitle": "Vul formulieren in vanuit de browser, incl. ondersteuning voor XFA-formulieren." + }, + "createPdfForm": { + "name": "PDF-formulier Aanmaken", + "subtitle": "Maak invulbare PDF-formulieren aan met drag-and-drop tekstvelden." + }, + "removeBlankPages": { + "name": "Blanco pagina's Verwijderen", + "subtitle": "Automatisch blanco pagina's detecteren en verwijderen." + }, + "imageToPdf": { + "name": "Afbeelding naar PDF", + "subtitle": "Converteer JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP naar PDF." + }, + "pngToPdf": { + "name": "PNG naar PDF", + "subtitle": "Maak een PDF van een of meer PNG-afbeeldingen." + }, + "webpToPdf": { + "name": "WebP naar PDF", + "subtitle": "Maak een PDF van een of meer WebP-afbeeldingen." + }, + "svgToPdf": { + "name": "SVG naar PDF", + "subtitle": "Maak een PDF van een of meer SVG-afbeeldingen." + }, + "bmpToPdf": { + "name": "BMP naar PDF", + "subtitle": "Maak een PDF van een of meer BMP-afbeeldingen." + }, + "heicToPdf": { + "name": "HEIC naar PDF", + "subtitle": "Maak een PDF van een of meer HEIC-afbeeldingen." + }, + "tiffToPdf": { + "name": "TIFF naar PDF", + "subtitle": "Maak een PDF van een of meer TIFF-afbeeldingen." + }, + "textToPdf": { + "name": "Tekst naar PDF", + "subtitle": "Converteer een bestand met platte tekst naar een PDF." + }, + "jsonToPdf": { + "name": "JSON naar PDF", + "subtitle": "Converteer JSON-bestanden naar PDF-formaat." + }, + "pdfToJpg": { + "name": "PDF naar JPG", + "subtitle": "Converteer elke PDF-pagina naar een JPG-afbeelding." + }, + "pdfToPng": { + "name": "PDF naar PNG", + "subtitle": "Converteer elke PDF-pagina naar een PNG-afbeelding." + }, + "pdfToWebp": { + "name": "PDF naar WebP", + "subtitle": "Converteer elke PDF-pagina naar een WebP-afbeelding." + }, + "pdfToBmp": { + "name": "PDF naar BMP", + "subtitle": "Converteer elke PDF-pagina naar een BMP-afbeelding." + }, + "pdfToTiff": { + "name": "PDF naar TIFF", + "subtitle": "Converteer elke PDF-pagina naar een TIFF-afbeelding." + }, + "pdfToGreyscale": { + "name": "PDF naar Grijswaarden", + "subtitle": "Converteer alle kleuren naar zwart-wit." + }, + "pdfToJson": { + "name": "PDF naar JSON", + "subtitle": "Converteer PDF-bestanden naar JSON-formaat." + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "Maak een PDF doorzoekbaar en kopieerbaar." + }, + "alternateMix": { + "name": "Pagina's Afwisselen & Mixen", + "subtitle": "Voeg PDF's samen met afwisselende pagina's vanuit elke PDF. Bladwijzers behouden." + }, + "addAttachments": { + "name": "Bijlagen Toevoegen", + "subtitle": "Voeg een of meerbestanden in je PDF." + }, + "extractAttachments": { + "name": "Bijlagen Extraheren", + "subtitle": "Extraheer alle ingevoegde bestanden als ZIP uit PDF(-en)." + }, + "editAttachments": { + "name": "Bijlagen Bewerken", + "subtitle": "Bijlagen in je PDF weergeven of verwijderen." + }, + "dividePages": { + "name": "Paginas Opdelen", + "subtitle": "Pagina's horizontaal of verticaal opdelen." + }, + "addBlankPage": { + "name": "Blanco pagina Toevoegen", + "subtitle": "Een blanco pagina ergens in je PDF invoegen." + }, + "reversePages": { + "name": "Paginavolgorde Omkeren", + "subtitle": "Keer de volgorde om van alle pagina's in je document." + }, + "rotatePdf": { + "name": "PDF Roteren", + "subtitle": "Roteer pagina's in stappen van 90 gradden." + }, + "rotateCustom": { + "name": "Roteren met aangepaste hoek", + "subtitle": "Roteer pagina's met elke gewenste hoek." + }, + "nUpPdf": { + "name": "N+ PDF", + "subtitle": "Arrangeer meerdere pagina's op een enkel blad." + }, + "combineToSinglePage": { + "name": "Combineren tot Enkele pagina", + "subtitle": "Plak alle pagina's aan elkaar tot een doorlopende rol." + }, + "viewMetadata": { + "name": "Metadata Weergeven", + "subtitle": "Bekijk de verborgen eigenschappen van je PDF." + }, + "editMetadata": { + "name": "Metadata Bewerken", + "subtitle": "Auteur, titel en andere eigenschappen aanpassen." + }, + "pdfsToZip": { + "name": "PDF naar ZIP", + "subtitle": "Archiveer meerdere PDF's in een ZIP-bestand." + }, + "comparePdfs": { + "name": "PDF's Vergelijken", + "subtitle": "Twee PDF's zij-aan-zij vergelijken." + }, + "posterizePdf": { + "name": "PDF-Poster", + "subtitle": "Deel een grote pagina op in meerdere kleinere pagina's." + }, + "fixPageSize": { + "name": "Paginagrootte Fiksen", + "subtitle": "Alle pagina's aanpassen tot een uniform formaat." + }, + "linearizePdf": { + "name": "PDF Lineariseren", + "subtitle": "Optimaliseer een PDF voor snelle webweergave." + }, + "pageDimensions": { + "name": "Pagina Afmetingen", + "subtitle": "Maak een analyse van paginagrootte, oriรซntatie en eenheden." + }, + "removeRestrictions": { + "name": "Beperkingen Verwijderen", + "subtitle": "Beveiligingswachtwoord en -beperkingen verwijderen van digitaal ondertekende PDF-bestanden." + }, + "repairPdf": { + "name": "PDF Repareren", + "subtitle": "Gegevens herstellen van beschadigde PDF-bestanden." + }, + "encryptPdf": { + "name": "PDF Versleutelen", + "subtitle": "Vegrendel je PDF door toevoeging van een toegangswachtwoord." + }, + "sanitizePdf": { + "name": "PDF Opschonen", + "subtitle": "Metadata, annotaties, scripts en meer verwijderen." + }, + "decryptPdf": { + "name": "PDF Ontgrendelen", + "subtitle": "PDF ontgrendelen door het verwijderen van de wachtwoordbeveiliging." + }, + "flattenPdf": { + "name": "PDF Platmaken", + "subtitle": "Maak formuliervelden en annotaties onbewerkbaar." + }, + "removeMetadata": { + "name": "Metadata Verwijderen", + "subtitle": "Verwijder verborgen gegevens uit je PDF." + }, + "changePermissions": { + "name": "Rechten Aanpassen", + "subtitle": "Gebruikersrechten van een PDF instellen of aanpasssen." + }, + "odtToPdf": { + "name": "ODT naar PDF", + "subtitle": "Converteer OpenDocument-tekstbestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "ODT-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "csvToPdf": { + "name": "CSV naar PDF", + "subtitle": "Converteer CSV-spreadsheetbestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "CSV-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "rtfToPdf": { + "name": "RTF naar PDF", + "subtitle": "Converteer Rich Text Format-documenten naar PDF. Ondersteunt meerdere bestanden.", + "acceptedFormats": "RTF-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "wordToPdf": { + "name": "Word naar PDF", + "subtitle": "Converteer Word-documenten (DOCX, DOC, ODT, RTF) naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "DOCX-, DOC-, ODT-, RTF-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "excelToPdf": { + "name": "Excel naar PDF", + "subtitle": "Converteer Excel-spreadsheets (XLSX, XLS, ODS, CSV) naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "XLSX-, XLS-, ODS-, CSV-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint naar PDF", + "subtitle": "Converteer PowerPoint-presentaties (PPTX, PPT, ODP) naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "PPTX-, PPT-, ODP-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "markdownToPdf": { + "name": "Markdown naar PDF", + "subtitle": "Schrijf of plak Markdown en zet het om in een opgemaakte PDF.", + "paneMarkdown": "Markdown", + "panePreview": "Voorbeeld", + "btnUpload": "Laden", + "btnSyncScroll": "Synchroon bladeren", + "btnSettings": "Instellingen", + "btnExportPdf": "PDF exporteren", + "settingsTitle": "Markdown-instellingen", + "settingsPreset": "Voorinstelling", + "presetDefault": "Standaard (als GFM)", + "presetCommonmark": "CommonMark (strict)", + "presetZero": "Minimaal (geen functies)", + "settingsOptions": "Markdown-opties", + "optAllowHtml": "HTML-tags toestaan", + "optBreaks": "Newlines omzetten naar
", + "optLinkify": "URL's autom. omzetten naar links", + "optTypographer": "Typograaf (slimme aanhalingstekens, etc.)" + }, + "pdfBooklet": { + "name": "PDF Boekje", + "subtitle": "Herschik de pagina's voor dubbelzijdig boekjeprinten. Vouw en niet ze om een boekje te maken.", + "howItWorks": "Het werkt zo:", + "step1": "Laad een PDF-bestand.", + "step2": "Pagina's worden in brochurevolgorde gerangschikt.", + "step3": "Dubbelzijdig afdrukken, omdraaien langs de korte kant, vouwen en nieten.", + "paperSize": "Paperformaat", + "orientation": "Ori๏ฟฝntatie", + "portrait": "Staand", + "landscape": "Liggend", + "pagesPerSheet": "Pagina's per vel", + "createBooklet": "Boekje aanmaken", + "processing": "Verwerken...", + "pageCount": "Het aantal pagina's wordt indien nodig op een meervoud van 4 afgerond." + }, + "xpsToPdf": { + "name": "XPS naar PDF", + "subtitle": "Converteer XPS/OXPS-documenten naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "XPS-, OXPS-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "mobiToPdf": { + "name": "MOBI naar PDF", + "subtitle": "Converteer MOBI e-books naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "MOBI-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "epubToPdf": { + "name": "EPUB naar PDF", + "subtitle": "Zet EPUB-e-books om naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "EPUB-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "fb2ToPdf": { + "name": "FB2 naar PDF", + "subtitle": "Converteer FictionBook (FB2) e-boeken naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "FB2-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "cbzToPdf": { + "name": "CBZ naar PDF", + "subtitle": "Converteer stripboekenarchieven (CBZ/CBR) naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "CBZ-, CBR-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "wpdToPdf": { + "name": "WPD naar PDF", + "subtitle": "Converteer WordPerfect-documenten (WPD) naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "WPD-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "wpsToPdf": { + "name": "WPS naar PDF", + "subtitle": "Converteer WPS Office-documenten naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "WPS-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "xmlToPdf": { + "name": "XML naar PDF", + "subtitle": "Converteer XML-documenten naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "XML-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "pagesToPdf": { + "name": "Pages naar PDF", + "subtitle": "Zet Apple Pages-documenten om naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "Pages-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "odgToPdf": { + "name": "ODG naar PDF", + "subtitle": "Converteer OpenDocument Graphics (ODG)-bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "ODG-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "odsToPdf": { + "name": "ODS naar PDF", + "subtitle": "Converteer OpenDocument Spreadsheet (ODS)-bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "ODS-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "odpToPdf": { + "name": "ODP naar PDF", + "subtitle": "Converteer OpenDocument-presentatie (ODP) bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "ODP-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "pubToPdf": { + "name": "PUB naar PDF", + "subtitle": "Converteer Microsoft Publisher (PUB) bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "PUB-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "vsdToPdf": { + "name": "VSD naar PDF", + "subtitle": "Converteer Microsoft Visio (VSD, VSDX) bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "VSD-, VSDX-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "psdToPdf": { + "name": "PSD naar PDF", + "subtitle": "Converteer Adobe Photoshop (PSD) bestanden naar PDF-formaat. Ondersteunt meerdere bestanden.", + "acceptedFormats": "PSD-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "pdfToSvg": { + "name": "PDF naar SVG", + "subtitle": "Converteer elke pagina van een PDF-bestand naar een schaalbare vectorafbeelding (SVG) voor perfecte kwaliteit op elke grootte." + }, + "extractTables": { + "name": "PDF-tabellen extraheren", + "subtitle": "Haal tabellen uit PDF-bestanden en exporteer ze als CSV, JSON of Markdown." + }, + "pdfToCsv": { + "name": "PDF naar CSV", + "subtitle": "Haal tabellen uit een PDF en zet ze om naar CSV-formaat." + }, + "pdfToExcel": { + "name": "PDF naar Excel", + "subtitle": "Haal tabellen uit PDF en converteer ze naar Excel (XLSX) formaat." + }, + "pdfToText": { + "name": "PDF naar Text", + "subtitle": "Haal tekst uit PDF-bestanden en sla op als gewone tekst (.txt). Ondersteunt meerdere bestanden.", + "note": "Dit hulpmiddel werkt ALLEEN met digitaal gemaakte PDF's. Gebruik voor gescande documenten of op afbeeldingen gebaseerde PDF's in plaats hiervan de OCR PDF-tool.", + "convertButton": "Tekst extraheren" + }, + "digitalSignPdf": { + "name": "Digitale handtekening PDF", + "pageTitle": "Digitale handtekening PDF - Cryptografische handtekening toevoegen | BentoPDF", + "subtitle": "Voeg een cryptografische digitale handtekening toe aan je PDF met behulp van X.509-certificaten. Ondersteunt PKCS#12 (.pfx, .p12) en PEM-formaten. Je priv๏ฟฝsleutel verlaat jouw browser nooit.", + "certificateSection": "Certificaat", + "uploadCert": "Certificaat laden (.pfx, .p12)", + "certPassword": "Certificaatwachtwoord", + "certPasswordPlaceholder": "Voer het wachtwoord van het certificaat in", + "certInfo": "Certificaatinformatie", + "certSubject": "Onderwerp", + "certIssuer": "Uitgever", + "certValidity": "Geldigheid", + "signatureDetails": "Signature Details (Optioneel)", + "reason": "Reden", + "reasonPlaceholder": "bijv., Ik keur dit document goed", + "location": "Plaats", + "locationPlaceholder": "bijv., New York, USA", + "contactInfo": "Contactinformatie", + "contactPlaceholder": "bijv., email@example.com", + "applySignature": "Digitale handtekening toepassen", + "successMessage": "PDF succesvol ondertekend! De handtekening kan in elke PDF-lezer worden geverifieerd." + }, + "validateSignaturePdf": { + "name": "PDF-handtekening valideren", + "pageTitle": "PDF-handtekening valideren - Digitale handtekeningen verifi๏ฟฝren | BentoPDF", + "subtitle": "Digitale handtekeningen in je PDF-bestanden verifi๏ฟฝren. Controleer de geldigheid van het certificaat, bekijk de gegevens van de ondertekenaar en bevestig de integriteit van het document. Alle verwerking gebeurt binnen jouw browser." + }, + "emailToPdf": { + "name": "E-mail naar PDF", + "subtitle": "Converteer e-mailbestanden (EML, MSG) naar PDF-formaat. Ondersteunt Outlook-exports en standaard e-mailformaten.", + "acceptedFormats": "EML-, MSG-bestanden", + "convertButton": "Omzetten naar PDF" + }, + "fontToOutline": { + "name": "Lettertype naar Contour", + "subtitle": "Converteer alle lettertypen naar vector-contouren voor consistente weergave over alle apparaten." + }, + "deskewPdf": { + "name": "PDF rechttrekken", + "subtitle": "Automatisch rechttrekken van scheef gescande pagina's met OpenCV." + } +} diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json new file mode 100644 index 0000000..f19e3bf --- /dev/null +++ b/public/locales/pt/common.json @@ -0,0 +1,325 @@ +{ + "nav": { + "home": "Inรญcio", + "about": "Sobre", + "contact": "Contato", + "licensing": "Licenciamento", + "allTools": "Todas as Ferramentas", + "openMainMenu": "Abrir menu principal", + "language": "Idioma" + }, + "donation": { + "message": "Adora o BentoPDF? Ajude-nos a mantรช-lo gratuito e de cรณdigo aberto!", + "button": "Doar" + }, + "hero": { + "title": "O", + "pdfToolkit": "Kit de Ferramentas PDF", + "builtForPrivacy": "feito para sua privacidade", + "noSignups": "Sem Cadastros", + "unlimitedUse": "Uso Ilimitado", + "worksOffline": "Funciona Offline", + "startUsing": "Comece a Usar Agora" + }, + "usedBy": { + "title": "Usado por empresas e pessoas que trabalham em" + }, + "features": { + "title": "Por que escolher o", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "Sem Cadastro", + "description": "Comece instantaneamente, sem contas ou e-mails." + }, + "noUploads": { + "title": "Sem Uploads", + "description": "100% no navegador, seus arquivos nunca saem do seu dispositivo." + }, + "foreverFree": { + "title": "Sempre Grรกtis", + "description": "Todas as ferramentas, sem testes ou assinaturas." + }, + "noLimits": { + "title": "Sem Limites", + "description": "Use o quanto quiser, sem taxas escondidas." + }, + "batchProcessing": { + "title": "Processamento em Lote", + "description": "Gerencie vรกrios PDFs de uma sรณ vez." + }, + "lightningFast": { + "title": "Super Rรกpido", + "description": "Processe PDFs instantaneamente, sem esperas ou atrasos." + } + }, + "tools": { + "title": "Comece com as", + "toolsLabel": "Ferramentas", + "subtitle": "Clique em uma ferramenta para abrir o seletor de arquivos", + "searchPlaceholder": "Buscar ferramenta (ex: 'dividir', 'organizar'...)", + "backToTools": "Voltar para Ferramentas", + "firstLoadNotice": "O primeiro carregamento demora um momento enquanto baixamos nosso mecanismo de conversรฃo. Depois disso, todos os carregamentos serรฃo instantรขneos." + }, + "upload": { + "clickToSelect": "Clique para selecionar um arquivo", + "orDragAndDrop": "ou arraste e solte", + "pdfOrImages": "PDFs ou Imagens", + "filesNeverLeave": "Seus arquivos nunca saem do seu dispositivo.", + "addMore": "Adicionar Mais Arquivos", + "clearAll": "Limpar Tudo", + "clearFiles": "Limpar arquivos" + }, + "loader": { + "processing": "Processando..." + }, + "alert": { + "title": "Alerta", + "ok": "OK" + }, + "preview": { + "title": "Visualizaรงรฃo do Documento", + "downloadAsPdf": "Baixar como PDF", + "close": "Fechar" + }, + "settings": { + "title": "Configuraรงรตes", + "shortcuts": "Atalhos", + "preferences": "Preferรชncias", + "displayPreferences": "Preferรชncias de Exibiรงรฃo", + "searchShortcuts": "Buscar atalhos...", + "shortcutsInfo": "Mantenha as teclas pressionadas para definir um atalho. As alteraรงรตes sรฃo salvas automaticamente.", + "shortcutsWarning": "โš ๏ธ Evite atalhos comuns do navegador (Cmd/Ctrl+W, T, N etc.), pois podem nรฃo funcionar corretamente.", + "import": "Importar", + "export": "Exportar", + "resetToDefaults": "Restaurar Padrรตes", + "fullWidthMode": "Modo Largura Total", + "fullWidthDescription": "Usa toda a largura da tela para as ferramentas em vez de um container centralizado", + "settingsAutoSaved": "As configuraรงรตes sรฃo salvas automaticamente", + "clickToSet": "Clique para definir", + "pressKeys": "Pressione as teclas...", + "warnings": { + "alreadyInUse": "Atalho Jรก em Uso", + "assignedTo": "jรก estรก atribuรญdo a:", + "chooseDifferent": "Por favor, escolha um atalho diferente.", + "reserved": "Aviso de Atalho Reservado", + "commonlyUsed": "รฉ comumente usado para:", + "unreliable": "Este atalho pode nรฃo funcionar bem ou conflitar com o navegador/sistema.", + "useAnyway": "Deseja usar mesmo assim?", + "resetTitle": "Redefinir Atalhos", + "resetMessage": "Tem certeza que deseja redefinir todos os atalhos?

Esta aรงรฃo nรฃo pode ser desfeita.", + "importSuccessTitle": "Importaรงรฃo Concluรญda", + "importSuccessMessage": "Atalhos importados com sucesso!", + "importFailTitle": "Falha na Importaรงรฃo", + "importFailMessage": "Falha ao importar atalhos. Formato de arquivo invรกlido." + } + }, + "warning": { + "title": "Aviso", + "cancel": "Cancelar", + "proceed": "Prosseguir" + }, + "compliance": { + "title": "Seus dados nunca saem do seu dispositivo", + "weKeep": "Mantemos", + "yourInfoSafe": "suas informaรงรตes seguras", + "byFollowingStandards": "seguindo padrรตes globais de seguranรงa.", + "processingLocal": "Todo o processamento acontece localmente no seu dispositivo.", + "gdpr": { + "title": "Conformidade GDPR", + "description": "Protege os dados pessoais e a privacidade de indivรญduos na Uniรฃo Europeia." + }, + "ccpa": { + "title": "Conformidade CCPA", + "description": "Dรก aos residentes da Califรณrnia direitos sobre como suas informaรงรตes pessoais sรฃo coletadas e usadas." + }, + "hipaa": { + "title": "Conformidade HIPAA", + "description": "Estabelece salvaguardas para o tratamento de informaรงรตes de saรบde sensรญveis nos Estados Unidos." + } + }, + "faq": { + "title": "Perguntas", + "questions": "Frequentes", + "isFree": { + "question": "O BentoPDF รฉ realmente grรกtis?", + "answer": "Sim, com certeza. Todas as ferramentas do BentoPDF sรฃo 100% gratuitas, sem limites de arquivos, sem cadastros e sem marcas d'รกgua. Acreditamos que todos merecem acesso a ferramentas PDF poderosas sem barreiras financeiras." + }, + "areFilesSecure": { + "question": "Meus arquivos estรฃo seguros? Onde sรฃo processados?", + "answer": "Seus arquivos estรฃo o mais seguros possรญvel porque nunca saem do seu computador. Todo o processamento ocorre diretamente no seu navegador (client-side). Nunca fazemos upload para um servidor, garantindo privacidade total." + }, + "platforms": { + "question": "Funciona no Mac, Windows e Celular?", + "answer": "Sim! Como o BentoPDF roda inteiramente no navegador, funciona em qualquer sistema operacional moderno, incluindo Windows, macOS, Linux, iOS e Android." + }, + "gdprCompliant": { + "question": "O BentoPDF estรก em conformidade com a GDPR?", + "answer": "Sim. Como o processamento รฉ local e nรฃo coletamos seus arquivos, nรฃo temos acesso aos seus dados. Isso garante total conformidade e controle por parte do usuรกrio." + }, + "dataStorage": { + "question": "Vocรชs armazenam ou rastreiam meus arquivos?", + "answer": "Nรฃo. Nunca armazenamos, rastreamos ou registramos seus arquivos. Tudo acontece na memรณria do navegador e desaparece ao fechar a pรกgina. Nรฃo hรก logs nem servidores envolvidos." + }, + "different": { + "question": "O que torna o BentoPDF diferente de outras ferramentas?", + "answer": "A maioria das ferramentas faz upload dos arquivos para um servidor. O BentoPDF usa tecnologia web moderna para processar tudo localmente no seu navegador, garantindo mais velocidade e privacidade." + }, + "browserBased": { + "question": "Como o processamento no navegador me mantรฉm seguro?", + "answer": "Ao rodar no seu dispositivo, eliminamos riscos de ataques a servidores ou vazamentos de dados de terceiros. Seus arquivos permanecem seus โ€” sempre." + }, + "analytics": { + "question": "Vocรชs usam cookies ou rastreamento?", + "answer": "Usamos apenas o Simple Analytics para contar visitas de forma anรดnima. Sabemos quantos usuรกrios nos visitam, mas nunca quem vocรช รฉ. O sistema respeita totalmente a GDPR." + } + }, + "testimonials": { + "title": "O que nossos", + "users": "Usuรกrios", + "say": "Dizem" + }, + "support": { + "title": "Gostou do Trabalho?", + "description": "O BentoPDF รฉ um projeto pessoal feito para fornecer ferramentas poderosas e privadas para todos. Se for รบtil para vocรช, considere apoiar o desenvolvimento!", + "buyMeCoffee": "Pague um Cafรฉ" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. Todos os direitos reservados.", + "version": "Versรฃo", + "company": "Empresa", + "aboutUs": "Sobre Nรณs", + "faqLink": "FAQ", + "contactUs": "Contato", + "legal": "Jurรญdico", + "termsAndConditions": "Termos e Condiรงรตes", + "privacyPolicy": "Polรญtica de Privacidade", + "followUs": "Siga-nos" + }, + "merge": { + "title": "Mesclar PDFs", + "description": "Combine arquivos inteiros ou selecione pรกginas especรญficas para criar um novo documento.", + "fileMode": "Modo Arquivo", + "pageMode": "Modo Pรกgina", + "howItWorks": "Como funciona:", + "fileModeInstructions": [ + "Clique e arraste o รญcone para alterar a ordem dos arquivos.", + "No campo \"Pรกginas\", vocรช pode definir intervalos (ex: \"1-3, 5\") para mesclar apenas essas pรกginas.", + "Deixe o campo em branco para incluir todas as pรกginas do arquivo." + ], + "pageModeInstructions": [ + "Todas as pรกginas dos PDFs enviados aparecem abaixo.", + "Arraste as miniaturas para criar a ordem exata que deseja no novo arquivo." + ], + "mergePdfs": "Mesclar PDFs" + }, + "common": { + "page": "Pรกgina", + "pages": "Pรกginas", + "of": "de", + "download": "Baixar", + "cancel": "Cancelar", + "save": "Salvar", + "delete": "Excluir", + "edit": "Editar", + "add": "Adicionar", + "remove": "Remover", + "loading": "Carregando...", + "error": "Erro", + "success": "Sucesso", + "file": "Arquivo", + "files": "Arquivos", + "close": "Fechar" + }, + "about": { + "hero": { + "title": "Acreditamos que ferramentas PDF devem ser", + "subtitle": "rรกpidas, privadas e gratuitas.", + "noCompromises": "Sem concessรตes." + }, + "mission": { + "title": "Nossa Missรฃo", + "description": "Fornecer o kit de ferramentas PDF mais completo, respeitando sua privacidade e sem cobrar por isso. Ferramentas essenciais devem ser acessรญveis a todos, sem barreiras." + }, + "philosophy": { + "label": "Nossa Filosofia", + "title": "Privacidade Primeiro. Sempre.", + "description": "Em uma era onde dados sรฃo mercadoria, seguimos outro caminho. Todo o processamento ocorre no seu navegador. Arquivos nรฃo tocam nossos servidores e nรฃo rastreamos vocรช. Privacidade nรฃo รฉ apenas um recurso; รฉ nossa base." + }, + "whyBentopdf": { + "title": "Por que o BentoPDF?", + "speed": { + "title": "Feito para Velocidade", + "description": "Sem esperas de upload. Usando tecnologias como WebAssembly, processamos tudo diretamente no navegador com velocidade inigualรกvel." + }, + "free": { + "title": "Totalmente Grรกtis", + "description": "Sem perรญodos de teste, assinaturas ou funรงรตes \"premium\" bloqueadas. Acreditamos em ferramentas como um serviรงo pรบblico." + }, + "noAccount": { + "title": "Sem Necessidade de Conta", + "description": "Use qualquer ferramenta imediatamente. Nรฃo pedimos e-mail, senha ou qualquer dado pessoal. Seu fluxo de trabalho deve ser anรดnimo." + }, + "openSource": { + "title": "Espรญrito Open Source", + "description": "Construรญdo com transparรชncia. Utilizamos bibliotecas incrรญveis como PDF-lib e PDF.js para democratizar o acesso a ferramentas poderosas." + } + }, + "cta": { + "title": "Pronto para comeรงar?", + "description": "Junte-se a milhares de usuรกrios que confiam no BentoPDF. Sinta a diferenรงa da privacidade e do desempenho.", + "button": "Explorar Ferramentas" + } + }, + "contact": { + "title": "Entre em Contato", + "subtitle": "Adorarรญamos ouvir vocรช. Se tiver dรบvidas, feedback ou sugestรตes de recursos, nรฃo hesite em nos contatar.", + "email": "Vocรช pode nos contatar diretamente por e-mail em:" + }, + "licensing": { + "title": "Licenciamento de", + "subtitle": "Escolha a licenรงa que melhor atende ร s suas necessidades." + }, + "multiTool": { + "uploadPdfs": "Enviar PDFs", + "upload": "Enviar", + "addBlankPage": "Adicionar Pรกgina em Branco", + "edit": "Editar:", + "undo": "Desfazer", + "redo": "Refazer", + "reset": "Redefinir", + "selection": "Seleรงรฃo:", + "selectAll": "Selecionar Tudo", + "deselectAll": "Desmarcar Tudo", + "rotate": "Girar:", + "rotateLeft": "Esquerda", + "rotateRight": "Direita", + "transform": "Transformar:", + "duplicate": "Duplicar", + "split": "Dividir", + "clear": "Limpar:", + "delete": "Excluir", + "download": "Baixar:", + "downloadSelected": "Baixar Selecionadas", + "exportPdf": "Exportar PDF", + "uploadPdfFiles": "Selecionar Arquivos PDF", + "dragAndDrop": "Arraste arquivos PDF aqui ou clique para selecionar", + "selectFiles": "Selecionar Arquivos", + "renderingPages": "Renderizando pรกginas...", + "actions": { + "duplicatePage": "Duplicar esta pรกgina", + "deletePage": "Excluir esta pรกgina", + "insertPdf": "Inserir PDF apรณs esta pรกgina", + "toggleSplit": "Alternar divisรฃo apรณs esta pรกgina" + }, + "pleaseWait": "Aguarde", + "pagesRendering": "As pรกginas ainda estรฃo sendo renderizadas. Por favor, aguarde...", + "noPagesSelected": "Nenhuma Pรกgina Selecionada", + "selectOnePage": "Selecione pelo menos uma pรกgina para baixar.", + "noPages": "Sem Pรกginas", + "noPagesToExport": "Nรฃo hรก pรกginas para exportar.", + "renderingTitle": "Renderizando visualizaรงรตes das pรกginas", + "errorRendering": "Falha ao renderizar miniaturas das pรกginas", + "error": "Erro", + "failedToLoad": "Falha ao carregar" + } +} diff --git a/public/locales/pt/tools.json b/public/locales/pt/tools.json new file mode 100644 index 0000000..eb42770 --- /dev/null +++ b/public/locales/pt/tools.json @@ -0,0 +1,511 @@ +{ + "categories": { + "popularTools": "Ferramentas Populares", + "editAnnotate": "Editar e Anotar", + "convertToPdf": "Converter para PDF", + "convertFromPdf": "Converter de PDF", + "organizeManage": "Organizar e Gerenciar", + "optimizeRepair": "Otimizar e Reparar", + "securePdf": "Seguranรงa de PDF" + }, + "pdfMultiTool": { + "name": "Multiferramenta PDF", + "subtitle": "Mesclar, dividir, organizar, excluir, girar, adicionar pรกginas em branco, extrair e duplicar em uma รบnica interface." + }, + "mergePdf": { + "name": "Mesclar PDF", + "subtitle": "Combine vรกrios PDFs em um รบnico arquivo. Preserva os favoritos (bookmarks)." + }, + "splitPdf": { + "name": "Dividir PDF", + "subtitle": "Extraia um intervalo de pรกginas para um novo PDF." + }, + "compressPdf": { + "name": "Comprimir PDF", + "subtitle": "Reduza o tamanho do arquivo do seu PDF." + }, + "pdfEditor": { + "name": "Editor de PDF", + "subtitle": "Anotar, destacar, redigir, comentar, adicionar formas/imagens, pesquisar e visualizar PDFs." + }, + "jpgToPdf": { + "name": "JPG para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens JPG." + }, + "signPdf": { + "name": "Assinar PDF", + "subtitle": "Desenhe, digite ou faรงa upload da sua assinatura." + }, + "cropPdf": { + "name": "Cortar PDF", + "subtitle": "Corte as margens de cada pรกgina do seu PDF." + }, + "extractPages": { + "name": "Extrair Pรกginas", + "subtitle": "Salve uma seleรงรฃo de pรกginas como novos arquivos." + }, + "duplicateOrganize": { + "name": "Duplicar e Organizar", + "subtitle": "Duplique, reordene e exclua pรกginas." + }, + "deletePages": { + "name": "Excluir Pรกginas", + "subtitle": "Remova pรกginas especรญficas do seu documento." + }, + "editBookmarks": { + "name": "Editar Favoritos", + "subtitle": "Adicione, edite, importe, exclua e extraia favoritos de PDF." + }, + "tableOfContents": { + "name": "Sumรกrio", + "subtitle": "Gere uma pรกgina de sumรกrio a partir dos favoritos do PDF." + }, + "pageNumbers": { + "name": "Nรบmeros de Pรกgina", + "subtitle": "Insira nรบmeros de pรกgina no seu documento." + }, + "addWatermark": { + "name": "Adicionar Marca d'รgua", + "subtitle": "Carimbe texto ou uma imagem sobre as pรกginas do seu PDF." + }, + "headerFooter": { + "name": "Cabeรงalho e Rodapรฉ", + "subtitle": "Adicione texto no topo e no final das pรกginas." + }, + "invertColors": { + "name": "Inverter Cores", + "subtitle": "Crie uma versรฃo em \"modo escuro\" do seu PDF." + }, + "backgroundColor": { + "name": "Cor de Fundo", + "subtitle": "Altere a cor de fundo do seu PDF." + }, + "changeTextColor": { + "name": "Alterar Cor do Texto", + "subtitle": "Altere a cor do texto no seu PDF." + }, + "addStamps": { + "name": "Adicionar Carimbos", + "subtitle": "Adicione carimbos de imagem ao seu PDF usando a barra de ferramentas de anotaรงรฃo.", + "usernameLabel": "Nome do Usuรกrio no Carimbo", + "usernamePlaceholder": "Digite seu nome (para os carimbos)", + "usernameHint": "Este nome aparecerรก nos carimbos que vocรช criar." + }, + "removeAnnotations": { + "name": "Remover Anotaรงรตes", + "subtitle": "Remova comentรกrios, destaques e links." + }, + "pdfFormFiller": { + "name": "Preenchimento de Formulรกrio", + "subtitle": "Preencha formulรกrios diretamente no navegador. Tambรฉm suporta formulรกrios XFA." + }, + "createPdfForm": { + "name": "Criar Formulรกrio PDF", + "subtitle": "Crie formulรกrios PDF preenchรญveis com campos de texto de arrastar e soltar." + }, + "removeBlankPages": { + "name": "Remover Pรกginas em Branco", + "subtitle": "Detecte e exclua automaticamente pรกginas em branco." + }, + "imageToPdf": { + "name": "Imagem para PDF", + "subtitle": "Converta JPG, PNG, WebP, BMP, TIFF, SVG, HEIC para PDF." + }, + "pngToPdf": { + "name": "PNG para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens PNG." + }, + "webpToPdf": { + "name": "WebP para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens WebP." + }, + "svgToPdf": { + "name": "SVG para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens SVG." + }, + "bmpToPdf": { + "name": "BMP para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens BMP." + }, + "heicToPdf": { + "name": "HEIC para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens HEIC." + }, + "tiffToPdf": { + "name": "TIFF para PDF", + "subtitle": "Crie um PDF a partir de uma ou mais imagens TIFF." + }, + "textToPdf": { + "name": "Texto para PDF", + "subtitle": "Converta um arquivo de texto simples (.txt) em PDF." + }, + "jsonToPdf": { + "name": "JSON para PDF", + "subtitle": "Converta arquivos JSON para o formato PDF." + }, + "pdfToJpg": { + "name": "PDF para JPG", + "subtitle": "Converta cada pรกgina do PDF em uma imagem JPG." + }, + "pdfToPng": { + "name": "PDF para PNG", + "subtitle": "Converta cada pรกgina do PDF em uma imagem PNG." + }, + "pdfToWebp": { + "name": "PDF para WebP", + "subtitle": "Converta cada pรกgina do PDF em uma imagem WebP." + }, + "pdfToBmp": { + "name": "PDF para BMP", + "subtitle": "Converta cada pรกgina do PDF em uma imagem BMP." + }, + "pdfToTiff": { + "name": "PDF para TIFF", + "subtitle": "Converta cada pรกgina do PDF em uma imagem TIFF." + }, + "pdfToGreyscale": { + "name": "PDF para Tons de Cinza", + "subtitle": "Converta todas as cores para preto e branco." + }, + "pdfToJson": { + "name": "PDF para JSON", + "subtitle": "Converta arquivos PDF para o formato JSON." + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "Torne um PDF pesquisรกvel e copiรกvel (reconhecimento de texto)." + }, + "alternateMix": { + "name": "Alternar e Misturar Pรกginas", + "subtitle": "Mescle PDFs alternando as pรกginas de cada arquivo. Preserva os favoritos." + }, + "addAttachments": { + "name": "Adicionar Anexos", + "subtitle": "Incorpore um ou mais arquivos dentro do seu PDF." + }, + "extractAttachments": { + "name": "Extrair Anexos", + "subtitle": "Extraia todos os arquivos incorporados de PDF(s) como um ZIP." + }, + "editAttachments": { + "name": "Editar Anexos", + "subtitle": "Visualize ou remova anexos do seu PDF." + }, + "dividePages": { + "name": "Dividir Pรกginas", + "subtitle": "Divida as pรกginas horizontalmente ou verticalmente." + }, + "addBlankPage": { + "name": "Adicionar Pรกgina em Branco", + "subtitle": "Insira uma pรกgina vazia em qualquer lugar do seu PDF." + }, + "reversePages": { + "name": "Inverter Pรกginas", + "subtitle": "Inverta a ordem de todas as pรกginas do seu documento." + }, + "rotatePdf": { + "name": "Girar PDF", + "subtitle": "Gire as pรกginas em incrementos de 90 graus." + }, + "nUpPdf": { + "name": "PDF N-Up", + "subtitle": "Organize vรกrias pรกginas em uma รบnica folha de impressรฃo." + }, + "combineToSinglePage": { + "name": "Combinar em Pรกgina รšnica", + "subtitle": "Costure todas as pรกginas em um รบnico fluxo contรญnuo." + }, + "viewMetadata": { + "name": "Ver Metadados", + "subtitle": "Inspecione as propriedades ocultas do seu PDF." + }, + "editMetadata": { + "name": "Editar Metadados", + "subtitle": "Altere o autor, tรญtulo e outras propriedades." + }, + "pdfsToZip": { + "name": "PDFs para ZIP", + "subtitle": "Empacote vรกrios arquivos PDF em um arquivo compactado ZIP." + }, + "comparePdfs": { + "name": "Comparar PDFs", + "subtitle": "Compare dois PDFs lado a lado." + }, + "posterizePdf": { + "name": "Posterizar PDF", + "subtitle": "Divida uma pรกgina grande em vรกrias pรกginas menores." + }, + "fixPageSize": { + "name": "Ajustar Tamanho da Pรกgina", + "subtitle": "Padronize todas as pรกginas para um tamanho uniforme." + }, + "linearizePdf": { + "name": "Linearizar PDF", + "subtitle": "Otimize o PDF para visualizaรงรฃo rรกpida na web." + }, + "pageDimensions": { + "name": "Dimensรตes da Pรกgina", + "subtitle": "Analise o tamanho, orientaรงรฃo e unidades das pรกginas." + }, + "removeRestrictions": { + "name": "Remover Restriรงรตes", + "subtitle": "Remova proteรงรฃo por senha e restriรงรตes de seguranรงa de arquivos assinados digitalmente." + }, + "repairPdf": { + "name": "Reparar PDF", + "subtitle": "Recupere dados de arquivos PDF corrompidos ou danificados." + }, + "encryptPdf": { + "name": "Criptografar PDF", + "subtitle": "Bloqueie seu PDF adicionando uma senha." + }, + "sanitizePdf": { + "name": "Sanitizar PDF", + "subtitle": "Remova metadados, anotaรงรตes, scripts e outros dados ocultos." + }, + "decryptPdf": { + "name": "Descriptografar PDF", + "subtitle": "Desbloqueie o PDF removendo a proteรงรฃo por senha." + }, + "flattenPdf": { + "name": "Achatar PDF (Flatten)", + "subtitle": "Torne os campos de formulรกrio e anotaรงรตes nรฃo editรกveis." + }, + "removeMetadata": { + "name": "Remover Metadados", + "subtitle": "Limpe dados ocultos do seu PDF." + }, + "changePermissions": { + "name": "Alterar Permissรตes", + "subtitle": "Defina ou altere as permissรตes de usuรกrio em um PDF." + }, + "emailToPdf": { + "name": "Email para PDF", + "subtitle": "Converta arquivos de email (EML, MSG) para PDF. Suporta exportaรงรตes do Outlook e formatos de email padrรฃo.", + "acceptedFormats": "Arquivos EML, MSG", + "convertButton": "Converter para PDF" + }, + "fontToOutline": { + "name": "Fonte para Contorno", + "subtitle": "Converta todas as fontes em contornos vetoriais para renderizaรงรฃo consistente em todos os dispositivos." + }, + "deskewPdf": { + "name": "Desinclinar PDF", + "subtitle": "Endireite automaticamente pรกginas digitalizadas inclinadas usando OpenCV." + }, + "rotateCustom": { + "name": "Rotate by Custom Degrees", + "subtitle": "Rotate pages by any custom angle." + }, + "odtToPdf": { + "name": "ODT to PDF", + "subtitle": "Convert OpenDocument Text files to PDF format. Supports multiple files.", + "acceptedFormats": "ODT files", + "convertButton": "Convert to PDF" + }, + "csvToPdf": { + "name": "CSV to PDF", + "subtitle": "Convert CSV spreadsheet files to PDF format. Supports multiple files.", + "acceptedFormats": "CSV files", + "convertButton": "Convert to PDF" + }, + "rtfToPdf": { + "name": "RTF to PDF", + "subtitle": "Convert Rich Text Format documents to PDF. Supports multiple files.", + "acceptedFormats": "RTF files", + "convertButton": "Convert to PDF" + }, + "wordToPdf": { + "name": "Word to PDF", + "subtitle": "Convert Word documents (DOCX, DOC, ODT, RTF) to PDF format. Supports multiple files.", + "acceptedFormats": "DOCX, DOC, ODT, RTF files", + "convertButton": "Convert to PDF" + }, + "excelToPdf": { + "name": "Excel to PDF", + "subtitle": "Convert Excel spreadsheets (XLSX, XLS, ODS, CSV) to PDF format. Supports multiple files.", + "acceptedFormats": "XLSX, XLS, ODS, CSV files", + "convertButton": "Convert to PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint to PDF", + "subtitle": "Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF format. Supports multiple files.", + "acceptedFormats": "PPTX, PPT, ODP files", + "convertButton": "Convert to PDF" + }, + "markdownToPdf": { + "name": "Markdown to PDF", + "subtitle": "Write or paste Markdown and export it as a beautifully formatted PDF.", + "paneMarkdown": "Markdown", + "panePreview": "Preview", + "btnUpload": "Upload", + "btnSyncScroll": "Sync Scroll", + "btnSettings": "Settings", + "btnExportPdf": "Export PDF", + "settingsTitle": "Markdown Settings", + "settingsPreset": "Preset", + "presetDefault": "Default (GFM-like)", + "presetCommonmark": "CommonMark (strict)", + "presetZero": "Minimal (no features)", + "settingsOptions": "Markdown Options", + "optAllowHtml": "Allow HTML tags", + "optBreaks": "Convert newlines to
", + "optLinkify": "Auto-convert URLs to links", + "optTypographer": "Typographer (smart quotes, etc.)" + }, + "pdfBooklet": { + "name": "PDF Booklet", + "subtitle": "Rearrange pages for double-sided booklet printing. Fold and staple to create a booklet.", + "howItWorks": "How it works:", + "step1": "Upload a PDF file.", + "step2": "Pages will be rearranged in booklet order.", + "step3": "Print double-sided, flip on short edge, fold and staple.", + "paperSize": "Paper Size", + "orientation": "Orientation", + "portrait": "Portrait", + "landscape": "Landscape", + "pagesPerSheet": "Pages per Sheet", + "createBooklet": "Create Booklet", + "processing": "Processing...", + "pageCount": "Page count will be padded to multiple of 4 if needed." + }, + "xpsToPdf": { + "name": "XPS to PDF", + "subtitle": "Convert XPS/OXPS documents to PDF format. Supports multiple files.", + "acceptedFormats": "XPS, OXPS files", + "convertButton": "Convert to PDF" + }, + "mobiToPdf": { + "name": "MOBI to PDF", + "subtitle": "Convert MOBI e-books to PDF format. Supports multiple files.", + "acceptedFormats": "MOBI files", + "convertButton": "Convert to PDF" + }, + "epubToPdf": { + "name": "EPUB to PDF", + "subtitle": "Convert EPUB e-books to PDF format. Supports multiple files.", + "acceptedFormats": "EPUB files", + "convertButton": "Convert to PDF" + }, + "fb2ToPdf": { + "name": "FB2 to PDF", + "subtitle": "Convert FictionBook (FB2) e-books to PDF format. Supports multiple files.", + "acceptedFormats": "FB2 files", + "convertButton": "Convert to PDF" + }, + "cbzToPdf": { + "name": "CBZ to PDF", + "subtitle": "Convert comic book archives (CBZ/CBR) to PDF format. Supports multiple files.", + "acceptedFormats": "CBZ, CBR files", + "convertButton": "Convert to PDF" + }, + "wpdToPdf": { + "name": "WPD to PDF", + "subtitle": "Convert WordPerfect documents (WPD) to PDF format. Supports multiple files.", + "acceptedFormats": "WPD files", + "convertButton": "Convert to PDF" + }, + "wpsToPdf": { + "name": "WPS to PDF", + "subtitle": "Convert WPS Office documents to PDF format. Supports multiple files.", + "acceptedFormats": "WPS files", + "convertButton": "Convert to PDF" + }, + "xmlToPdf": { + "name": "XML to PDF", + "subtitle": "Convert XML documents to PDF format. Supports multiple files.", + "acceptedFormats": "XML files", + "convertButton": "Convert to PDF" + }, + "pagesToPdf": { + "name": "Pages to PDF", + "subtitle": "Convert Apple Pages documents to PDF format. Supports multiple files.", + "acceptedFormats": "Pages files", + "convertButton": "Convert to PDF" + }, + "odgToPdf": { + "name": "ODG to PDF", + "subtitle": "Convert OpenDocument Graphics (ODG) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODG files", + "convertButton": "Convert to PDF" + }, + "odsToPdf": { + "name": "ODS to PDF", + "subtitle": "Convert OpenDocument Spreadsheet (ODS) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODS files", + "convertButton": "Convert to PDF" + }, + "odpToPdf": { + "name": "ODP to PDF", + "subtitle": "Convert OpenDocument Presentation (ODP) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODP files", + "convertButton": "Convert to PDF" + }, + "pubToPdf": { + "name": "PUB to PDF", + "subtitle": "Convert Microsoft Publisher (PUB) files to PDF format. Supports multiple files.", + "acceptedFormats": "PUB files", + "convertButton": "Convert to PDF" + }, + "vsdToPdf": { + "name": "VSD to PDF", + "subtitle": "Convert Microsoft Visio (VSD, VSDX) files to PDF format. Supports multiple files.", + "acceptedFormats": "VSD, VSDX files", + "convertButton": "Convert to PDF" + }, + "psdToPdf": { + "name": "PSD to PDF", + "subtitle": "Convert Adobe Photoshop (PSD) files to PDF format. Supports multiple files.", + "acceptedFormats": "PSD files", + "convertButton": "Convert to PDF" + }, + "pdfToSvg": { + "name": "PDF to SVG", + "subtitle": "Convert each page of a PDF file into a scalable vector graphic (SVG) for perfect quality at any size." + }, + "extractTables": { + "name": "Extract PDF Tables", + "subtitle": "Extract tables from PDF files and export as CSV, JSON, or Markdown." + }, + "pdfToCsv": { + "name": "PDF to CSV", + "subtitle": "Extract tables from PDF and convert to CSV format." + }, + "pdfToExcel": { + "name": "PDF to Excel", + "subtitle": "Extract tables from PDF and convert to Excel (XLSX) format." + }, + "pdfToText": { + "name": "PDF to Text", + "subtitle": "Extract text from PDF files and save as plain text (.txt). Supports multiple files.", + "note": "This tool works ONLY with digitally created PDFs. For scanned documents or image-based PDFs, use our OCR PDF tool instead.", + "convertButton": "Extract Text" + }, + "digitalSignPdf": { + "name": "Assinatura Digital PDF", + "pageTitle": "Assinatura Digital PDF - Adicionar Assinatura Criptogrรกfica | BentoPDF", + "subtitle": "Adicione uma assinatura digital criptogrรกfica ao seu PDF usando certificados X.509. Suporta formatos PKCS#12 (.pfx, .p12) e PEM. Sua chave privada nunca sai do seu navegador.", + "certificateSection": "Certificado", + "uploadCert": "Carregar certificado (.pfx, .p12)", + "certPassword": "Senha do Certificado", + "certPasswordPlaceholder": "Digite a senha", + "certInfo": "Informaรงรตes do Certificado", + "certSubject": "Assunto", + "certIssuer": "Emissor", + "certValidity": "Vรกlido", + "signatureDetails": "Detalhes da Assinatura (Opcional)", + "reason": "Razรฃo", + "reasonPlaceholder": "ex: Eu aprovo este documento", + "location": "Localizaรงรฃo", + "locationPlaceholder": "ex: Lisboa, Portugal", + "contactInfo": "Contato", + "contactPlaceholder": "ex: email@exemplo.com", + "applySignature": "Aplicar Assinatura", + "successMessage": "PDF assinado com sucesso! A assinatura pode ser verificada em qualquer leitor de PDF." + }, + "validateSignaturePdf": { + "name": "Validar Assinatura PDF", + "pageTitle": "Validar Assinatura PDF - Verificar Assinaturas Digitais | BentoPDF", + "subtitle": "Verifique assinaturas digitais em seus arquivos PDF. Verifique a validade do certificado e a integridade do documento." + } +} diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index ee36845..5d34ab5 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -1,318 +1,325 @@ { - "nav": { - "home": "Ana Sayfa", - "about": "Hakkฤฑmฤฑzda", - "contact": "ฤฐletiลŸim", - "licensing": "Lisanslama", - "allTools": "Tรผm Araรงlar", - "openMainMenu": "Ana menรผyรผ aรง", - "language": "Dil" + "nav": { + "home": "Ana Sayfa", + "about": "Hakkฤฑmฤฑzda", + "contact": "ฤฐletiลŸim", + "licensing": "Lisanslama", + "allTools": "Tรผm Araรงlar", + "openMainMenu": "Ana menรผyรผ aรง", + "language": "Dil" + }, + "donation": { + "message": "BentoPDF'i seviyor musunuz? รœcretsiz ve aรงฤฑk kaynaklฤฑ kalmasฤฑna yardฤฑmcฤฑ olun!", + "button": "BaฤŸฤฑลŸ Yap" + }, + "hero": { + "title": " ", + "pdfToolkit": "PDF Toolkit", + "builtForPrivacy": "gizlilik iรงin tasarlandฤฑ", + "noSignups": "Kayฤฑt Gerekmez", + "unlimitedUse": "Sฤฑnฤฑrsฤฑz Kullanฤฑm", + "worksOffline": "ร‡evrimdฤฑลŸฤฑ ร‡alฤฑลŸฤฑr", + "startUsing": "Hemen Kullanmaya BaลŸla" + }, + "usedBy": { + "title": "ลžu ลŸirketler ve รงalฤฑลŸanlarฤฑ tarafฤฑndan kullanฤฑlฤฑyor" + }, + "features": { + "title": "Neden", + "bentoPdf": "BentoPDF'yi seรงmelisiniz?", + "noSignup": { + "title": "Kayฤฑt Gerekmez", + "description": "Hemen baลŸlayฤฑn, hesap veya e-posta gerekmez." }, - "hero": { - "title": " ", - "pdfToolkit": "PDF Toolkit", - "builtForPrivacy": "gizlilik iรงin tasarlandฤฑ", - "noSignups": "Kayฤฑt Gerekmez", - "unlimitedUse": "Sฤฑnฤฑrsฤฑz Kullanฤฑm", - "worksOffline": "ร‡evrimdฤฑลŸฤฑ ร‡alฤฑลŸฤฑr", - "startUsing": "Hemen Kullanmaya BaลŸla" + "noUploads": { + "title": "Yรผkleme Yok", + "description": "%100 istemci tarafฤฑnda รงalฤฑลŸฤฑr, dosyalarฤฑnฤฑz cihazฤฑnฤฑzฤฑ asla terk etmez." }, - "usedBy": { - "title": "ลžu ลŸirketler ve รงalฤฑลŸanlarฤฑ tarafฤฑndan kullanฤฑlฤฑyor" + "foreverFree": { + "title": "Tamamen รœcretsiz", + "description": "Tรผm araรงlar, deneme sรผrรผmรผ yok, รถdeme duvarฤฑ yok." }, - "features": { - "title": "Neden", - "bentoPdf": "BentoPDF'yi seรงmelisiniz?", - "noSignup": { - "title": "Kayฤฑt Gerekmez", - "description": "Hemen baลŸlayฤฑn, hesap veya e-posta gerekmez." - }, - "noUploads": { - "title": "Yรผkleme Yok", - "description": "%100 istemci tarafฤฑnda รงalฤฑลŸฤฑr, dosyalarฤฑnฤฑz cihazฤฑnฤฑzฤฑ asla terk etmez." - }, - "foreverFree": { - "title": "Tamamen รœcretsiz", - "description": "Tรผm araรงlar, deneme sรผrรผmรผ yok, รถdeme duvarฤฑ yok." - }, - "noLimits": { - "title": "Sฤฑnฤฑrsฤฑz", - "description": "ฤฐstediฤŸiniz kadar kullanฤฑn, gizli sฤฑnฤฑrlar yok." - }, - "batchProcessing": { - "title": "Toplu ฤฐลŸlem", - "description": "Sฤฑnฤฑrsฤฑz sayฤฑda PDF'yi tek seferde iลŸleyin." - }, - "lightningFast": { - "title": "ลžimลŸek Hฤฑzฤฑnda", - "description": "PDF'leri anฤฑnda iลŸleyin, bekleme veya gecikme olmadan." - } + "noLimits": { + "title": "Sฤฑnฤฑrsฤฑz", + "description": "ฤฐstediฤŸiniz kadar kullanฤฑn, gizli sฤฑnฤฑrlar yok." }, - "tools": { - "title": "Araรงlarla", - "toolsLabel": "BaลŸlayฤฑn", - "subtitle": "Dosya yรผkleyiciyi aรงmak iรงin bir araรง seรงin", - "searchPlaceholder": "Bir araรง arayฤฑn (รถrn. 'bรถl', 'dรผzenle'...)", - "backToTools": "Araรงlara Dรถn" + "batchProcessing": { + "title": "Toplu ฤฐลŸlem", + "description": "Sฤฑnฤฑrsฤฑz sayฤฑda PDF'yi tek seferde iลŸleyin." }, - "upload": { - "clickToSelect": "Dosya seรงmek iรงin tฤฑklayฤฑn", - "orDragAndDrop": "veya sรผrรผkleyip bฤฑrakฤฑn", - "pdfOrImages": "PDF veya Gรถrseller", - "filesNeverLeave": "Dosyalarฤฑnฤฑz cihazฤฑnฤฑzฤฑ asla terk etmez.", - "addMore": "Daha Fazla Dosya Ekle", - "clearAll": "Tรผmรผnรผ Temizle" - }, - "loader": { - "processing": "ฤฐลŸleniyor..." - }, - "alert": { - "title": "Uyarฤฑ", - "ok": "Tamam" - }, - "preview": { - "title": "Belge ร–nizleme", - "downloadAsPdf": "PDF Olarak ฤฐndir", - "close": "Kapat" - }, - "settings": { - "title": "Ayarlar", - "shortcuts": "Kฤฑsayollar", - "preferences": "Tercihler", - "displayPreferences": "Gรถrรผntรผ Tercihleri", - "searchShortcuts": "Kฤฑsayollarda ara...", - "shortcutsInfo": "Bir kฤฑsayol atamak iรงin tuลŸlara basฤฑlฤฑ tutun. DeฤŸiลŸiklikler otomatik olarak kaydedilir.", - "shortcutsWarning": "โš ๏ธ Gรผvenilir รงalฤฑลŸmayabileceฤŸinden yaygฤฑn tarayฤฑcฤฑ kฤฑsayollarฤฑndan (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N vb.) kaรงฤฑnฤฑn.", - "import": "ฤฐรงe Aktar", - "export": "DฤฑลŸa Aktar", - "resetToDefaults": "Varsayฤฑlanlara Sฤฑfฤฑrla", - "fullWidthMode": "Tam GeniลŸlik Modu", - "fullWidthDescription": "OrtalanmฤฑลŸ bir konteyner yerine tรผm ekran geniลŸliฤŸini kullan", - "settingsAutoSaved": "Ayarlar otomatik olarak kaydedildi", - "clickToSet": "Ayarlamak iรงin tฤฑklayฤฑn", - "pressKeys": "TuลŸlara basฤฑn...", - "warnings": { - "alreadyInUse": "Kฤฑsayol Zaten Kullanฤฑmda", - "assignedTo": "zaten ลŸurada kullanฤฑlฤฑyor:", - "chooseDifferent": "Lรผtfen farklฤฑ bir kฤฑsayol seรงin.", - "reserved": "AyrฤฑlmฤฑลŸ Kฤฑsayol Uyarฤฑsฤฑ", - "commonlyUsed": "genellikle ลŸunun iรงin kullanฤฑlฤฑr:", - "unreliable": "Bu kฤฑsayol gรผvenilir รงalฤฑลŸmayabilir veya tarayฤฑcฤฑ/sistem davranฤฑลŸฤฑyla รงakฤฑลŸabilir.", - "useAnyway": "Yine de kullanmak istiyor musunuz?", - "resetTitle": "Kฤฑsayollarฤฑ Sฤฑfฤฑrla", - "resetMessage": "Tรผm kฤฑsayollarฤฑ varsayฤฑlan ayarlara sฤฑfฤฑrlamak istediฤŸinizden emin misiniz?

Bu iลŸlem geri alฤฑnamaz.", - "importSuccessTitle": "ฤฐรงe Aktarma BaลŸarฤฑlฤฑ", - "importSuccessMessage": "Kฤฑsayollar baลŸarฤฑyla iรงe aktarฤฑldฤฑ!", - "importFailTitle": "ฤฐรงe Aktarma BaลŸarฤฑsฤฑz", - "importFailMessage": "Kฤฑsayollar iรงe aktarฤฑlamadฤฑ. Geรงersiz dosya biรงimi." - } - }, - "warning": { - "title": "Uyarฤฑ", - "cancel": "ฤฐptal", - "proceed": "Devam Et" - }, - "compliance": { - "title": "Verileriniz cihazฤฑnฤฑzฤฑ asla terk etmez", - "weKeep": "Bilgilerinizi", - "yourInfoSafe": "gรผvende tutuyoruz", - "byFollowingStandards": "kรผresel gรผvenlik standartlarฤฑnฤฑ takip ederek.", - "processingLocal": "Tรผm iลŸlemler cihazฤฑnฤฑzda yerel olarak gerรงekleลŸir.", - "gdpr": { - "title": "GDPR uyumluluฤŸu", - "description": "Avrupa BirliฤŸi'ndeki bireylerin kiลŸisel verilerini ve gizliliฤŸini korur." - }, - "ccpa": { - "title": "CCPA uyumluluฤŸu", - "description": "Kaliforniya sakinlerine kiลŸisel bilgilerinin nasฤฑl toplandฤฑฤŸฤฑ, kullanฤฑldฤฑฤŸฤฑ ve paylaลŸฤฑldฤฑฤŸฤฑ konusunda haklar tanฤฑr." - }, - "hipaa": { - "title": "HIPAA uyumluluฤŸu", - "description": "ABD saฤŸlฤฑk sisteminde hassas saฤŸlฤฑk bilgilerinin iลŸlenmesi iรงin gรผvenlik รถnlemleri belirler." - } - }, - "faq": { - "title": "Sฤฑkรงa Sorulan", - "questions": "Sorular", - "isFree": { - "question": "BentoPDF gerรงekten รผcretsiz mi?", - "answer": "Evet, kesinlikle. BentoPDF'deki tรผm araรงlar %100 รผcretsizdir, dosya sฤฑnฤฑrฤฑ yoktur, kayฤฑt gerekmez ve filigran eklenmez. Herkesin รถdeme duvarฤฑ olmadan basit, gรผรงlรผ PDF araรงlarฤฑna eriลŸimi hak ettiฤŸine inanฤฑyoruz." - }, - "areFilesSecure": { - "question": "Dosyalarฤฑm gรผvende mi? Nerede iลŸleniyorlar?", - "answer": "Dosyalarฤฑnฤฑz mรผmkรผn olan en gรผvenli ลŸekildedir รงรผnkรผ bilgisayarฤฑnฤฑzฤฑ asla terk etmezler. Tรผm iลŸlemler doฤŸrudan web tarayฤฑcฤฑnฤฑzda (istemci tarafฤฑnda) gerรงekleลŸir. Dosyalarฤฑnฤฑzฤฑ asla bir sunucuya yรผklemeyiz, bรถylece gizliliฤŸiniz ve belgeleriniz รผzerindeki kontrolรผnรผz tam olarak sizde kalฤฑr." - }, - "platforms": { - "question": "Mac, Windows ve Mobil'de รงalฤฑลŸฤฑyor mu?", - "answer": "Evet! BentoPDF tamamen tarayฤฑcฤฑnฤฑzda รงalฤฑลŸtฤฑฤŸฤฑ iรงin, Windows, macOS, Linux, iOS ve Android dahil modern bir web tarayฤฑcฤฑsฤฑ olan herhangi bir iลŸletim sisteminde รงalฤฑลŸฤฑr." - }, - "gdprCompliant": { - "question": "BentoPDF GDPR uyumlu mu?", - "answer": "Evet. BentoPDF tamamen GDPR uyumludur. Tรผm dosya iลŸlemleri tarayฤฑcฤฑnฤฑzda yerel olarak gerรงekleลŸtiฤŸi ve dosyalarฤฑnฤฑzฤฑ herhangi bir sunucuya asla iletmediฤŸimiz iรงin verilerinize eriลŸimimiz yoktur. Bu, belgeleriniz รผzerindeki kontrolรผn her zaman sizde olduฤŸundan emin olur." - }, - "dataStorage": { - "question": "Dosyalarฤฑmฤฑ saklฤฑyor veya takip ediyor musunuz?", - "answer": "Hayฤฑr. Dosyalarฤฑnฤฑzฤฑ asla saklamฤฑyor, takip etmiyor veya kaydetmiyoruz. BentoPDF'de yaptฤฑฤŸฤฑnฤฑz her ลŸey tarayฤฑcฤฑ belleฤŸinizde gerรงekleลŸir ve sayfayฤฑ kapattฤฑฤŸฤฑnฤฑzda silinir. Yรผkleme, geรงmiลŸ kaydฤฑ veya sunucu yoktur." - }, - "different": { - "question": "BentoPDF'yi diฤŸer PDF araรงlarฤฑndan farklฤฑ kฤฑlan nedir?", - "answer": "ร‡oฤŸu PDF aracฤฑ, iลŸlem iรงin dosyalarฤฑnฤฑzฤฑ bir sunucuya yรผkler. BentoPDF asla bรถyle yapmaz. Dosyalarฤฑnฤฑzฤฑ doฤŸrudan tarayฤฑcฤฑnฤฑzda iลŸlemek iรงin gรผvenli, modern web teknolojileri kullanฤฑrฤฑz. Bu, daha hฤฑzlฤฑ performans, daha gรผรงlรผ gizlilik ve tam bir gรถnรผl rahatlฤฑฤŸฤฑ anlamฤฑna gelir." - }, - "browserBased": { - "question": "Tarayฤฑcฤฑ tabanlฤฑ iลŸlem beni nasฤฑl korur?", - "answer": "Tamamen tarayฤฑcฤฑnฤฑzฤฑn iรงinde รงalฤฑลŸarak, BentoPDF dosyalarฤฑnฤฑzฤฑn cihazฤฑnฤฑzฤฑ asla terk etmemesini saฤŸlar. Bu, sunucu saldฤฑrฤฑlarฤฑ, veri ihlalleri veya yetkisiz eriลŸim risklerini ortadan kaldฤฑrฤฑr. Dosyalarฤฑnฤฑz her zaman sizin kalฤฑr." - }, - "analytics": { - "question": "Beni takip etmek iรงin รงerez veya analiz kullanฤฑyor musunuz?", - "answer": "GizliliฤŸinizi รถnemsiyoruz. BentoPDF kiลŸisel bilgileri takip etmez. Sadece anonim ziyaretรงi sayฤฑlarฤฑnฤฑ gรถrmek iรงin Simple Analytics kullanฤฑyoruz. Bu, sitemizi kaรง kiลŸinin ziyaret ettiฤŸini gรถrebileceฤŸimiz, ancak kim olduฤŸunuzu asla bilemeyeceฤŸimiz anlamฤฑna gelir. Simple Analytics tamamen GDPR uyumludur ve gizliliฤŸinize saygฤฑ gรถsterir." - } - }, - "testimonials": { - "title": "Kullanฤฑcฤฑlarฤฑmฤฑz", - "users": "Ne Diyor", - "say": "" - }, - "support": { - "title": "ร‡alฤฑลŸmamฤฑ BeฤŸendiniz mi?", - "description": "BentoPDF, herkes iรงin รผcretsiz, รถzel ve gรผรงlรผ bir PDF araรง seti saฤŸlamak amacฤฑyla oluลŸturulmuลŸ bir tutku projesidir. Faydalฤฑ bulduysanฤฑz, geliลŸtirilmesini desteklemeyi dรผลŸรผnebilirsiniz. Her kahve yardฤฑmcฤฑ olur!", - "buyMeCoffee": "Bana Kahve Ismarla" - }, - "footer": { - "copyright": "ยฉ 2025 BentoPDF. Tรผm haklarฤฑ saklฤฑdฤฑr.", - "version": "Sรผrรผm", - "company": "ลžirket", - "aboutUs": "Hakkฤฑmฤฑzda", - "faqLink": "SSS", - "contactUs": "ฤฐletiลŸim", - "legal": "Yasal", - "termsAndConditions": "Kullanฤฑm KoลŸullarฤฑ", - "privacyPolicy": "Gizlilik Politikasฤฑ", - "followUs": "Bizi Takip Edin" - }, - "merge": { - "title": "PDF BirleลŸtir", - "description": "Dosyalarฤฑn tamamฤฑnฤฑ birleลŸtirin veya yeni bir belge oluลŸturmak iรงin belirli sayfalarฤฑ seรงin.", - "fileMode": "Dosya Modu", - "pageMode": "Sayfa Modu", - "howItWorks": "Nasฤฑl ร‡alฤฑลŸฤฑr:", - "fileModeInstructions": [ - "Dosyalarฤฑn sฤฑrasฤฑnฤฑ deฤŸiลŸtirmek iรงin simgeyi tฤฑklayฤฑp sรผrรผkleyin.", - "Her dosya iรงin \"Sayfalar\" kutusuna, yalnฤฑzca o sayfalarฤฑ birleลŸtirmek iรงin aralฤฑklar belirtebilirsiniz (รถrn. \"1-3, 5\").", - "Tรผm sayfalarฤฑ dahil etmek iรงin \"Sayfalar\" kutusunu boลŸ bฤฑrakฤฑn." - ], - "pageModeInstructions": [ - "YรผklediฤŸiniz PDF'lerin tรผm sayfalarฤฑ aลŸaฤŸฤฑda gรถsterilmiลŸtir.", - "Yeni dosyanฤฑz iรงin istediฤŸiniz sฤฑrayฤฑ oluลŸturmak รผzere sayfa kรผรงรผk resimlerini sรผrรผkleyip bฤฑrakmanฤฑz yeterlidir." - ], - "mergePdfs": "PDF'leri BirleลŸtir" - }, - "common": { - "page": "Sayfa", - "pages": "Sayfa", - "of": "- ", - "download": "ฤฐndir", - "cancel": "ฤฐptal", - "save": "Kaydet", - "delete": "Sil", - "edit": "Dรผzenle", - "add": "Ekle", - "remove": "Kaldฤฑr", - "loading": "Yรผkleniyor...", - "error": "Hata", - "success": "BaลŸarฤฑlฤฑ", - "file": "Dosya", - "files": "Dosya" - }, - "about": { - "hero": { - "title": "PDF araรงlarฤฑnฤฑn", - "subtitle": "hฤฑzlฤฑ, รถzel ve รผcretsiz olmasฤฑ gerektiฤŸine inanฤฑyoruz.", - "noCompromises": "Taviz yok." - }, - "mission": { - "title": "Misyonumuz", - "description": "GizliliฤŸinize saygฤฑ duyan ve asla รถdeme talep etmeyen en kapsamlฤฑ PDF araรง setini saฤŸlamak. Temel belge araรงlarฤฑnฤฑn her yerde, herkes iรงin eriลŸilebilir olmasฤฑ gerektiฤŸine inanฤฑyoruz." - }, - "philosophy": { - "label": "Temel Felsefemiz", - "title": "ร–ncelik Her Zaman Gizlilik.", - "description": "Verinin bir meta olarak kabul edildiฤŸi bir รงaฤŸda, farklฤฑ bir yaklaลŸฤฑm benimsiyoruz. Bentopdf araรงlarฤฑ iรงin tรผm iลŸlemler tarayฤฑcฤฑnฤฑzda yerel olarak gerรงekleลŸir. Bu, dosyalarฤฑnฤฑzฤฑn sunucularฤฑmฤฑza asla dokunmadฤฑฤŸฤฑ, belgelerinizi asla gรถrmediฤŸimiz ve ne yaptฤฑฤŸฤฑnฤฑzฤฑ takip etmediฤŸimiz anlamฤฑna gelir. Belgeleriniz tamamen ve kesinlikle รถzel kalฤฑr. Bu sadece bir รถzellik deฤŸil, temelimizdir." - }, - "whyBentopdf": { - "title": "Neden", - "speed": { - "title": "Hฤฑz ฤฐรงin Tasarlandฤฑ", - "description": "Sunucuya yรผkleme veya indirme iรงin bekleme yok. WebAssembly gibi modern web teknolojilerini kullanarak dosyalarฤฑ doฤŸrudan tarayฤฑcฤฑnฤฑzda iลŸleyerek, tรผm araรงlarฤฑmฤฑz iรงin benzersiz bir hฤฑz sunuyoruz." - }, - "free": { - "title": "Tamamen รœcretsiz", - "description": "Deneme sรผrรผmรผ yok, abonelik yok, gizli รผcret yok ve \"premium\" รถzellikler rehin alฤฑnmamฤฑลŸ. Gรผรงlรผ PDF araรงlarฤฑnฤฑn bir kar merkezi deฤŸil, bir kamu hizmeti olmasฤฑ gerektiฤŸine inanฤฑyoruz." - }, - "noAccount": { - "title": "Hesap Gerekmez", - "description": "Hemen herhangi bir aracฤฑ kullanmaya baลŸlayฤฑn. E-postanฤฑza, ลŸifrenize veya herhangi bir kiลŸisel bilginize ihtiyacฤฑmฤฑz yok. ฤฐลŸ akฤฑลŸฤฑnฤฑz sรผrtรผnmesiz ve anonim olmalฤฑdฤฑr." - }, - "openSource": { - "title": "Aรงฤฑk Kaynak Ruhu", - "description": "ลžeffaflฤฑk dรผลŸรผnรผlerek oluลŸturuldu. PDF-lib ve PDF.js gibi inanฤฑlmaz aรงฤฑk kaynaklฤฑ kรผtรผphanelerden yararlanฤฑyoruz ve gรผรงlรผ araรงlarฤฑ herkes iรงin eriลŸilebilir kฤฑlmak iรงin topluluk odaklฤฑ รงabaya inanฤฑyoruz." - } - }, - "cta": { - "title": "BaลŸlamaya hazฤฑr mฤฑsฤฑnฤฑz?", - "description": "Gรผnlรผk belge ihtiyaรงlarฤฑ iรงin BentoPDF'ye gรผvenen binlerce kullanฤฑcฤฑya katฤฑlฤฑn. Gizlilik ve performansฤฑn yaratabileceฤŸi farkฤฑ deneyimleyin.", - "button": "Tรผm Araรงlarฤฑ KeลŸfet" - } - }, - "contact": { - "title": "ฤฐletiลŸime Geรงin", - "subtitle": "Sizden haber almak isteriz. Bir sorunuz, geri bildiriminiz veya bir รถzellik isteฤŸiniz varsa, lรผtfen bize ulaลŸmaktan รงekinmeyin.", - "email": "Bize doฤŸrudan ลŸu e-posta adresinden ulaลŸabilirsiniz:" - }, - "licensing": { - "title": "Lisanslama", - "subtitle": "ฤฐhtiyaรงlarฤฑnฤฑza uygun lisansฤฑ seรงin." - }, - "multiTool": { - "uploadPdfs": "PDF Yรผkle", - "upload": "Yรผkle", - "addBlankPage": "BoลŸ Sayfa Ekle", - "edit": "Dรผzenle:", - "undo": "Geri Al", - "redo": "Yinele", - "reset": "Sฤฑfฤฑrla", - "selection": "Seรงim:", - "selectAll": "Tรผmรผnรผ Seรง", - "deselectAll": "Seรงimi Kaldฤฑr", - "rotate": "Dรถndรผr:", - "rotateLeft": "Sola", - "rotateRight": "SaฤŸa", - "transform": "DรถnรผลŸtรผr:", - "duplicate": "ร‡oฤŸalt", - "split": "Bรถl", - "clear": "Temizle:", - "delete": "Sil", - "download": "ฤฐndir:", - "downloadSelected": "Seรงilenleri ฤฐndir", - "exportPdf": "PDF Olarak DฤฑลŸa Aktar", - "uploadPdfFiles": "PDF Dosyalarฤฑnฤฑ Seรงin", - "dragAndDrop": "PDF dosyalarฤฑnฤฑ buraya sรผrรผkleyip bฤฑrakฤฑn veya seรงmek iรงin tฤฑklayฤฑn", - "selectFiles": "Dosya Seรง", - "renderingPages": "Sayfalar oluลŸturuluyor...", - "actions": { - "duplicatePage": "Bu sayfayฤฑ รงoฤŸalt", - "deletePage": "Bu sayfayฤฑ sil", - "insertPdf": "Bu sayfadan sonra PDF ekle", - "toggleSplit": "Bu sayfadan sonra bรถlmeyi aรง/kapat" - }, - "pleaseWait": "Lรผtfen Bekleyin", - "pagesRendering": "Sayfalar hala oluลŸturuluyor. Lรผtfen bekleyin...", - "noPagesSelected": "Hiรงbir Sayfa Seรงilmedi", - "selectOnePage": "Lรผtfen indirmek iรงin en az bir sayfa seรงin.", - "noPages": "Sayfa Yok", - "noPagesToExport": "DฤฑลŸa aktarฤฑlacak sayfa yok.", - "renderingTitle": "Sayfa รถnizlemeleri oluลŸturuluyor", - "errorRendering": "Sayfa kรผรงรผk resimleri oluลŸturulamadฤฑ", - "error": "Hata", - "failedToLoad": "Yรผklenemedi" + "lightningFast": { + "title": "ลžimลŸek Hฤฑzฤฑnda", + "description": "PDF'leri anฤฑnda iลŸleyin, bekleme veya gecikme olmadan." } -} \ No newline at end of file + }, + "tools": { + "title": "Araรงlarla", + "toolsLabel": "BaลŸlayฤฑn", + "subtitle": "Dosya yรผkleyiciyi aรงmak iรงin bir araรง seรงin", + "searchPlaceholder": "Bir araรง arayฤฑn (รถrn. 'bรถl', 'dรผzenle'...)", + "backToTools": "Araรงlara Dรถn", + "firstLoadNotice": "DรถnรผลŸtรผrme motorumuzu indirirken ilk yรผkleme biraz zaman alฤฑr. Sonrasฤฑnda tรผm yรผklemeler anฤฑnda gerรงekleลŸir." + }, + "upload": { + "clickToSelect": "Dosya seรงmek iรงin tฤฑklayฤฑn", + "orDragAndDrop": "veya sรผrรผkleyip bฤฑrakฤฑn", + "pdfOrImages": "PDF veya Gรถrseller", + "filesNeverLeave": "Dosyalarฤฑnฤฑz cihazฤฑnฤฑzฤฑ asla terk etmez.", + "addMore": "Daha Fazla Dosya Ekle", + "clearAll": "Tรผmรผnรผ Temizle", + "clearFiles": "Dosyalarฤฑ temizle" + }, + "loader": { + "processing": "ฤฐลŸleniyor..." + }, + "alert": { + "title": "Uyarฤฑ", + "ok": "Tamam" + }, + "preview": { + "title": "Belge ร–nizleme", + "downloadAsPdf": "PDF Olarak ฤฐndir", + "close": "Kapat" + }, + "settings": { + "title": "Ayarlar", + "shortcuts": "Kฤฑsayollar", + "preferences": "Tercihler", + "displayPreferences": "Gรถrรผntรผ Tercihleri", + "searchShortcuts": "Kฤฑsayollarda ara...", + "shortcutsInfo": "Bir kฤฑsayol atamak iรงin tuลŸlara basฤฑlฤฑ tutun. DeฤŸiลŸiklikler otomatik olarak kaydedilir.", + "shortcutsWarning": "โš ๏ธ Gรผvenilir รงalฤฑลŸmayabileceฤŸinden yaygฤฑn tarayฤฑcฤฑ kฤฑsayollarฤฑndan (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N vb.) kaรงฤฑnฤฑn.", + "import": "ฤฐรงe Aktar", + "export": "DฤฑลŸa Aktar", + "resetToDefaults": "Varsayฤฑlanlara Sฤฑfฤฑrla", + "fullWidthMode": "Tam GeniลŸlik Modu", + "fullWidthDescription": "OrtalanmฤฑลŸ bir konteyner yerine tรผm ekran geniลŸliฤŸini kullan", + "settingsAutoSaved": "Ayarlar otomatik olarak kaydedildi", + "clickToSet": "Ayarlamak iรงin tฤฑklayฤฑn", + "pressKeys": "TuลŸlara basฤฑn...", + "warnings": { + "alreadyInUse": "Kฤฑsayol Zaten Kullanฤฑmda", + "assignedTo": "zaten ลŸurada kullanฤฑlฤฑyor:", + "chooseDifferent": "Lรผtfen farklฤฑ bir kฤฑsayol seรงin.", + "reserved": "AyrฤฑlmฤฑลŸ Kฤฑsayol Uyarฤฑsฤฑ", + "commonlyUsed": "genellikle ลŸunun iรงin kullanฤฑlฤฑr:", + "unreliable": "Bu kฤฑsayol gรผvenilir รงalฤฑลŸmayabilir veya tarayฤฑcฤฑ/sistem davranฤฑลŸฤฑyla รงakฤฑลŸabilir.", + "useAnyway": "Yine de kullanmak istiyor musunuz?", + "resetTitle": "Kฤฑsayollarฤฑ Sฤฑfฤฑrla", + "resetMessage": "Tรผm kฤฑsayollarฤฑ varsayฤฑlan ayarlara sฤฑfฤฑrlamak istediฤŸinizden emin misiniz?

Bu iลŸlem geri alฤฑnamaz.", + "importSuccessTitle": "ฤฐรงe Aktarma BaลŸarฤฑlฤฑ", + "importSuccessMessage": "Kฤฑsayollar baลŸarฤฑyla iรงe aktarฤฑldฤฑ!", + "importFailTitle": "ฤฐรงe Aktarma BaลŸarฤฑsฤฑz", + "importFailMessage": "Kฤฑsayollar iรงe aktarฤฑlamadฤฑ. Geรงersiz dosya biรงimi." + } + }, + "warning": { + "title": "Uyarฤฑ", + "cancel": "ฤฐptal", + "proceed": "Devam Et" + }, + "compliance": { + "title": "Verileriniz cihazฤฑnฤฑzฤฑ asla terk etmez", + "weKeep": "Bilgilerinizi", + "yourInfoSafe": "gรผvende tutuyoruz", + "byFollowingStandards": "kรผresel gรผvenlik standartlarฤฑnฤฑ takip ederek.", + "processingLocal": "Tรผm iลŸlemler cihazฤฑnฤฑzda yerel olarak gerรงekleลŸir.", + "gdpr": { + "title": "GDPR uyumluluฤŸu", + "description": "Avrupa BirliฤŸi'ndeki bireylerin kiลŸisel verilerini ve gizliliฤŸini korur." + }, + "ccpa": { + "title": "CCPA uyumluluฤŸu", + "description": "Kaliforniya sakinlerine kiลŸisel bilgilerinin nasฤฑl toplandฤฑฤŸฤฑ, kullanฤฑldฤฑฤŸฤฑ ve paylaลŸฤฑldฤฑฤŸฤฑ konusunda haklar tanฤฑr." + }, + "hipaa": { + "title": "HIPAA uyumluluฤŸu", + "description": "ABD saฤŸlฤฑk sisteminde hassas saฤŸlฤฑk bilgilerinin iลŸlenmesi iรงin gรผvenlik รถnlemleri belirler." + } + }, + "faq": { + "title": "Sฤฑkรงa Sorulan", + "questions": "Sorular", + "isFree": { + "question": "BentoPDF gerรงekten รผcretsiz mi?", + "answer": "Evet, kesinlikle. BentoPDF'deki tรผm araรงlar %100 รผcretsizdir, dosya sฤฑnฤฑrฤฑ yoktur, kayฤฑt gerekmez ve filigran eklenmez. Herkesin รถdeme duvarฤฑ olmadan basit, gรผรงlรผ PDF araรงlarฤฑna eriลŸimi hak ettiฤŸine inanฤฑyoruz." + }, + "areFilesSecure": { + "question": "Dosyalarฤฑm gรผvende mi? Nerede iลŸleniyorlar?", + "answer": "Dosyalarฤฑnฤฑz mรผmkรผn olan en gรผvenli ลŸekildedir รงรผnkรผ bilgisayarฤฑnฤฑzฤฑ asla terk etmezler. Tรผm iลŸlemler doฤŸrudan web tarayฤฑcฤฑnฤฑzda (istemci tarafฤฑnda) gerรงekleลŸir. Dosyalarฤฑnฤฑzฤฑ asla bir sunucuya yรผklemeyiz, bรถylece gizliliฤŸiniz ve belgeleriniz รผzerindeki kontrolรผnรผz tam olarak sizde kalฤฑr." + }, + "platforms": { + "question": "Mac, Windows ve Mobil'de รงalฤฑลŸฤฑyor mu?", + "answer": "Evet! BentoPDF tamamen tarayฤฑcฤฑnฤฑzda รงalฤฑลŸtฤฑฤŸฤฑ iรงin, Windows, macOS, Linux, iOS ve Android dahil modern bir web tarayฤฑcฤฑsฤฑ olan herhangi bir iลŸletim sisteminde รงalฤฑลŸฤฑr." + }, + "gdprCompliant": { + "question": "BentoPDF GDPR uyumlu mu?", + "answer": "Evet. BentoPDF tamamen GDPR uyumludur. Tรผm dosya iลŸlemleri tarayฤฑcฤฑnฤฑzda yerel olarak gerรงekleลŸtiฤŸi ve dosyalarฤฑnฤฑzฤฑ herhangi bir sunucuya asla iletmediฤŸimiz iรงin verilerinize eriลŸimimiz yoktur. Bu, belgeleriniz รผzerindeki kontrolรผn her zaman sizde olduฤŸundan emin olur." + }, + "dataStorage": { + "question": "Dosyalarฤฑmฤฑ saklฤฑyor veya takip ediyor musunuz?", + "answer": "Hayฤฑr. Dosyalarฤฑnฤฑzฤฑ asla saklamฤฑyor, takip etmiyor veya kaydetmiyoruz. BentoPDF'de yaptฤฑฤŸฤฑnฤฑz her ลŸey tarayฤฑcฤฑ belleฤŸinizde gerรงekleลŸir ve sayfayฤฑ kapattฤฑฤŸฤฑnฤฑzda silinir. Yรผkleme, geรงmiลŸ kaydฤฑ veya sunucu yoktur." + }, + "different": { + "question": "BentoPDF'yi diฤŸer PDF araรงlarฤฑndan farklฤฑ kฤฑlan nedir?", + "answer": "ร‡oฤŸu PDF aracฤฑ, iลŸlem iรงin dosyalarฤฑnฤฑzฤฑ bir sunucuya yรผkler. BentoPDF asla bรถyle yapmaz. Dosyalarฤฑnฤฑzฤฑ doฤŸrudan tarayฤฑcฤฑnฤฑzda iลŸlemek iรงin gรผvenli, modern web teknolojileri kullanฤฑrฤฑz. Bu, daha hฤฑzlฤฑ performans, daha gรผรงlรผ gizlilik ve tam bir gรถnรผl rahatlฤฑฤŸฤฑ anlamฤฑna gelir." + }, + "browserBased": { + "question": "Tarayฤฑcฤฑ tabanlฤฑ iลŸlem beni nasฤฑl korur?", + "answer": "Tamamen tarayฤฑcฤฑnฤฑzฤฑn iรงinde รงalฤฑลŸarak, BentoPDF dosyalarฤฑnฤฑzฤฑn cihazฤฑnฤฑzฤฑ asla terk etmemesini saฤŸlar. Bu, sunucu saldฤฑrฤฑlarฤฑ, veri ihlalleri veya yetkisiz eriลŸim risklerini ortadan kaldฤฑrฤฑr. Dosyalarฤฑnฤฑz her zaman sizin kalฤฑr." + }, + "analytics": { + "question": "Beni takip etmek iรงin รงerez veya analiz kullanฤฑyor musunuz?", + "answer": "GizliliฤŸinizi รถnemsiyoruz. BentoPDF kiลŸisel bilgileri takip etmez. Sadece anonim ziyaretรงi sayฤฑlarฤฑnฤฑ gรถrmek iรงin Simple Analytics kullanฤฑyoruz. Bu, sitemizi kaรง kiลŸinin ziyaret ettiฤŸini gรถrebileceฤŸimiz, ancak kim olduฤŸunuzu asla bilemeyeceฤŸimiz anlamฤฑna gelir. Simple Analytics tamamen GDPR uyumludur ve gizliliฤŸinize saygฤฑ gรถsterir." + } + }, + "testimonials": { + "title": "Kullanฤฑcฤฑlarฤฑmฤฑz", + "users": "Ne Diyor", + "say": "" + }, + "support": { + "title": "ร‡alฤฑลŸmamฤฑ BeฤŸendiniz mi?", + "description": "BentoPDF, herkes iรงin รผcretsiz, รถzel ve gรผรงlรผ bir PDF araรง seti saฤŸlamak amacฤฑyla oluลŸturulmuลŸ bir tutku projesidir. Faydalฤฑ bulduysanฤฑz, geliลŸtirilmesini desteklemeyi dรผลŸรผnebilirsiniz. Her kahve yardฤฑmcฤฑ olur!", + "buyMeCoffee": "Bana Kahve Ismarla" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. Tรผm haklarฤฑ saklฤฑdฤฑr.", + "version": "Sรผrรผm", + "company": "ลžirket", + "aboutUs": "Hakkฤฑmฤฑzda", + "faqLink": "SSS", + "contactUs": "ฤฐletiลŸim", + "legal": "Yasal", + "termsAndConditions": "Kullanฤฑm KoลŸullarฤฑ", + "privacyPolicy": "Gizlilik Politikasฤฑ", + "followUs": "Bizi Takip Edin" + }, + "merge": { + "title": "PDF BirleลŸtir", + "description": "Dosyalarฤฑn tamamฤฑnฤฑ birleลŸtirin veya yeni bir belge oluลŸturmak iรงin belirli sayfalarฤฑ seรงin.", + "fileMode": "Dosya Modu", + "pageMode": "Sayfa Modu", + "howItWorks": "Nasฤฑl ร‡alฤฑลŸฤฑr:", + "fileModeInstructions": [ + "Dosyalarฤฑn sฤฑrasฤฑnฤฑ deฤŸiลŸtirmek iรงin simgeyi tฤฑklayฤฑp sรผrรผkleyin.", + "Her dosya iรงin \"Sayfalar\" kutusuna, yalnฤฑzca o sayfalarฤฑ birleลŸtirmek iรงin aralฤฑklar belirtebilirsiniz (รถrn. \"1-3, 5\").", + "Tรผm sayfalarฤฑ dahil etmek iรงin \"Sayfalar\" kutusunu boลŸ bฤฑrakฤฑn." + ], + "pageModeInstructions": [ + "YรผklediฤŸiniz PDF'lerin tรผm sayfalarฤฑ aลŸaฤŸฤฑda gรถsterilmiลŸtir.", + "Yeni dosyanฤฑz iรงin istediฤŸiniz sฤฑrayฤฑ oluลŸturmak รผzere sayfa kรผรงรผk resimlerini sรผrรผkleyip bฤฑrakmanฤฑz yeterlidir." + ], + "mergePdfs": "PDF'leri BirleลŸtir" + }, + "common": { + "page": "Sayfa", + "pages": "Sayfa", + "of": "- ", + "download": "ฤฐndir", + "cancel": "ฤฐptal", + "save": "Kaydet", + "delete": "Sil", + "edit": "Dรผzenle", + "add": "Ekle", + "remove": "Kaldฤฑr", + "loading": "Yรผkleniyor...", + "error": "Hata", + "success": "BaลŸarฤฑlฤฑ", + "file": "Dosya", + "files": "Dosya", + "close": "Kapat" + }, + "about": { + "hero": { + "title": "PDF araรงlarฤฑnฤฑn", + "subtitle": "hฤฑzlฤฑ, รถzel ve รผcretsiz olmasฤฑ gerektiฤŸine inanฤฑyoruz.", + "noCompromises": "Taviz yok." + }, + "mission": { + "title": "Misyonumuz", + "description": "GizliliฤŸinize saygฤฑ duyan ve asla รถdeme talep etmeyen en kapsamlฤฑ PDF araรง setini saฤŸlamak. Temel belge araรงlarฤฑnฤฑn her yerde, herkes iรงin eriลŸilebilir olmasฤฑ gerektiฤŸine inanฤฑyoruz." + }, + "philosophy": { + "label": "Temel Felsefemiz", + "title": "ร–ncelik Her Zaman Gizlilik.", + "description": "Verinin bir meta olarak kabul edildiฤŸi bir รงaฤŸda, farklฤฑ bir yaklaลŸฤฑm benimsiyoruz. Bentopdf araรงlarฤฑ iรงin tรผm iลŸlemler tarayฤฑcฤฑnฤฑzda yerel olarak gerรงekleลŸir. Bu, dosyalarฤฑnฤฑzฤฑn sunucularฤฑmฤฑza asla dokunmadฤฑฤŸฤฑ, belgelerinizi asla gรถrmediฤŸimiz ve ne yaptฤฑฤŸฤฑnฤฑzฤฑ takip etmediฤŸimiz anlamฤฑna gelir. Belgeleriniz tamamen ve kesinlikle รถzel kalฤฑr. Bu sadece bir รถzellik deฤŸil, temelimizdir." + }, + "whyBentopdf": { + "title": "Neden", + "speed": { + "title": "Hฤฑz ฤฐรงin Tasarlandฤฑ", + "description": "Sunucuya yรผkleme veya indirme iรงin bekleme yok. WebAssembly gibi modern web teknolojilerini kullanarak dosyalarฤฑ doฤŸrudan tarayฤฑcฤฑnฤฑzda iลŸleyerek, tรผm araรงlarฤฑmฤฑz iรงin benzersiz bir hฤฑz sunuyoruz." + }, + "free": { + "title": "Tamamen รœcretsiz", + "description": "Deneme sรผrรผmรผ yok, abonelik yok, gizli รผcret yok ve \"premium\" รถzellikler rehin alฤฑnmamฤฑลŸ. Gรผรงlรผ PDF araรงlarฤฑnฤฑn bir kar merkezi deฤŸil, bir kamu hizmeti olmasฤฑ gerektiฤŸine inanฤฑyoruz." + }, + "noAccount": { + "title": "Hesap Gerekmez", + "description": "Hemen herhangi bir aracฤฑ kullanmaya baลŸlayฤฑn. E-postanฤฑza, ลŸifrenize veya herhangi bir kiลŸisel bilginize ihtiyacฤฑmฤฑz yok. ฤฐลŸ akฤฑลŸฤฑnฤฑz sรผrtรผnmesiz ve anonim olmalฤฑdฤฑr." + }, + "openSource": { + "title": "Aรงฤฑk Kaynak Ruhu", + "description": "ลžeffaflฤฑk dรผลŸรผnรผlerek oluลŸturuldu. PDF-lib ve PDF.js gibi inanฤฑlmaz aรงฤฑk kaynaklฤฑ kรผtรผphanelerden yararlanฤฑyoruz ve gรผรงlรผ araรงlarฤฑ herkes iรงin eriลŸilebilir kฤฑlmak iรงin topluluk odaklฤฑ รงabaya inanฤฑyoruz." + } + }, + "cta": { + "title": "BaลŸlamaya hazฤฑr mฤฑsฤฑnฤฑz?", + "description": "Gรผnlรผk belge ihtiyaรงlarฤฑ iรงin BentoPDF'ye gรผvenen binlerce kullanฤฑcฤฑya katฤฑlฤฑn. Gizlilik ve performansฤฑn yaratabileceฤŸi farkฤฑ deneyimleyin.", + "button": "Tรผm Araรงlarฤฑ KeลŸfet" + } + }, + "contact": { + "title": "ฤฐletiลŸime Geรงin", + "subtitle": "Sizden haber almak isteriz. Bir sorunuz, geri bildiriminiz veya bir รถzellik isteฤŸiniz varsa, lรผtfen bize ulaลŸmaktan รงekinmeyin.", + "email": "Bize doฤŸrudan ลŸu e-posta adresinden ulaลŸabilirsiniz:" + }, + "licensing": { + "title": "Lisanslama", + "subtitle": "ฤฐhtiyaรงlarฤฑnฤฑza uygun lisansฤฑ seรงin." + }, + "multiTool": { + "uploadPdfs": "PDF Yรผkle", + "upload": "Yรผkle", + "addBlankPage": "BoลŸ Sayfa Ekle", + "edit": "Dรผzenle:", + "undo": "Geri Al", + "redo": "Yinele", + "reset": "Sฤฑfฤฑrla", + "selection": "Seรงim:", + "selectAll": "Tรผmรผnรผ Seรง", + "deselectAll": "Seรงimi Kaldฤฑr", + "rotate": "Dรถndรผr:", + "rotateLeft": "Sola", + "rotateRight": "SaฤŸa", + "transform": "DรถnรผลŸtรผr:", + "duplicate": "ร‡oฤŸalt", + "split": "Bรถl", + "clear": "Temizle:", + "delete": "Sil", + "download": "ฤฐndir:", + "downloadSelected": "Seรงilenleri ฤฐndir", + "exportPdf": "PDF Olarak DฤฑลŸa Aktar", + "uploadPdfFiles": "PDF Dosyalarฤฑnฤฑ Seรงin", + "dragAndDrop": "PDF dosyalarฤฑnฤฑ buraya sรผrรผkleyip bฤฑrakฤฑn veya seรงmek iรงin tฤฑklayฤฑn", + "selectFiles": "Dosya Seรง", + "renderingPages": "Sayfalar oluลŸturuluyor...", + "actions": { + "duplicatePage": "Bu sayfayฤฑ รงoฤŸalt", + "deletePage": "Bu sayfayฤฑ sil", + "insertPdf": "Bu sayfadan sonra PDF ekle", + "toggleSplit": "Bu sayfadan sonra bรถlmeyi aรง/kapat" + }, + "pleaseWait": "Lรผtfen Bekleyin", + "pagesRendering": "Sayfalar hala oluลŸturuluyor. Lรผtfen bekleyin...", + "noPagesSelected": "Hiรงbir Sayfa Seรงilmedi", + "selectOnePage": "Lรผtfen indirmek iรงin en az bir sayfa seรงin.", + "noPages": "Sayfa Yok", + "noPagesToExport": "DฤฑลŸa aktarฤฑlacak sayfa yok.", + "renderingTitle": "Sayfa รถnizlemeleri oluลŸturuluyor", + "errorRendering": "Sayfa kรผรงรผk resimleri oluลŸturulamadฤฑ", + "error": "Hata", + "failedToLoad": "Yรผklenemedi" + } +} diff --git a/public/locales/tr/tools.json b/public/locales/tr/tools.json index 8467d25..7f897ad 100644 --- a/public/locales/tr/tools.json +++ b/public/locales/tr/tools.json @@ -284,5 +284,228 @@ "subtitle": "E-posta dosyalarฤฑnฤฑ (EML, MSG) PDF formatฤฑna dรถnรผลŸtรผrรผn. Outlook dฤฑลŸa aktarmalarฤฑnฤฑ ve standart e-posta formatlarฤฑnฤฑ destekler.", "acceptedFormats": "EML, MSG Dosyalarฤฑ", "convertButton": "PDF'ye DรถnรผลŸtรผr" + }, + "fontToOutline": { + "name": "Yazฤฑ Tipi ร‡erรงeveye DรถnรผลŸtรผr", + "subtitle": "Tรผm yazฤฑ tiplerini vektรถr รงerรงevelere dรถnรผลŸtรผrรผn, tรผm cihazlarda tutarlฤฑ gรถrรผntรผ iรงin." + }, + "deskewPdf": { + "name": "PDF EฤŸriliฤŸini Dรผzelt", + "subtitle": "OpenCV kullanarak eฤŸik taranmฤฑลŸ sayfalarฤฑ otomatik olarak dรผzeltin." + }, + "rotateCustom": { + "name": "Rotate by Custom Degrees", + "subtitle": "Rotate pages by any custom angle." + }, + "odtToPdf": { + "name": "ODT to PDF", + "subtitle": "Convert OpenDocument Text files to PDF format. Supports multiple files.", + "acceptedFormats": "ODT files", + "convertButton": "Convert to PDF" + }, + "csvToPdf": { + "name": "CSV to PDF", + "subtitle": "Convert CSV spreadsheet files to PDF format. Supports multiple files.", + "acceptedFormats": "CSV files", + "convertButton": "Convert to PDF" + }, + "rtfToPdf": { + "name": "RTF to PDF", + "subtitle": "Convert Rich Text Format documents to PDF. Supports multiple files.", + "acceptedFormats": "RTF files", + "convertButton": "Convert to PDF" + }, + "wordToPdf": { + "name": "Word to PDF", + "subtitle": "Convert Word documents (DOCX, DOC, ODT, RTF) to PDF format. Supports multiple files.", + "acceptedFormats": "DOCX, DOC, ODT, RTF files", + "convertButton": "Convert to PDF" + }, + "excelToPdf": { + "name": "Excel to PDF", + "subtitle": "Convert Excel spreadsheets (XLSX, XLS, ODS, CSV) to PDF format. Supports multiple files.", + "acceptedFormats": "XLSX, XLS, ODS, CSV files", + "convertButton": "Convert to PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint to PDF", + "subtitle": "Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF format. Supports multiple files.", + "acceptedFormats": "PPTX, PPT, ODP files", + "convertButton": "Convert to PDF" + }, + "markdownToPdf": { + "name": "Markdown to PDF", + "subtitle": "Write or paste Markdown and export it as a beautifully formatted PDF.", + "paneMarkdown": "Markdown", + "panePreview": "Preview", + "btnUpload": "Upload", + "btnSyncScroll": "Sync Scroll", + "btnSettings": "Settings", + "btnExportPdf": "Export PDF", + "settingsTitle": "Markdown Settings", + "settingsPreset": "Preset", + "presetDefault": "Default (GFM-like)", + "presetCommonmark": "CommonMark (strict)", + "presetZero": "Minimal (no features)", + "settingsOptions": "Markdown Options", + "optAllowHtml": "Allow HTML tags", + "optBreaks": "Convert newlines to
", + "optLinkify": "Auto-convert URLs to links", + "optTypographer": "Typographer (smart quotes, etc.)" + }, + "pdfBooklet": { + "name": "PDF Booklet", + "subtitle": "Rearrange pages for double-sided booklet printing. Fold and staple to create a booklet.", + "howItWorks": "How it works:", + "step1": "Upload a PDF file.", + "step2": "Pages will be rearranged in booklet order.", + "step3": "Print double-sided, flip on short edge, fold and staple.", + "paperSize": "Paper Size", + "orientation": "Orientation", + "portrait": "Portrait", + "landscape": "Landscape", + "pagesPerSheet": "Pages per Sheet", + "createBooklet": "Create Booklet", + "processing": "Processing...", + "pageCount": "Page count will be padded to multiple of 4 if needed." + }, + "xpsToPdf": { + "name": "XPS to PDF", + "subtitle": "Convert XPS/OXPS documents to PDF format. Supports multiple files.", + "acceptedFormats": "XPS, OXPS files", + "convertButton": "Convert to PDF" + }, + "mobiToPdf": { + "name": "MOBI to PDF", + "subtitle": "Convert MOBI e-books to PDF format. Supports multiple files.", + "acceptedFormats": "MOBI files", + "convertButton": "Convert to PDF" + }, + "epubToPdf": { + "name": "EPUB to PDF", + "subtitle": "Convert EPUB e-books to PDF format. Supports multiple files.", + "acceptedFormats": "EPUB files", + "convertButton": "Convert to PDF" + }, + "fb2ToPdf": { + "name": "FB2 to PDF", + "subtitle": "Convert FictionBook (FB2) e-books to PDF format. Supports multiple files.", + "acceptedFormats": "FB2 files", + "convertButton": "Convert to PDF" + }, + "cbzToPdf": { + "name": "CBZ to PDF", + "subtitle": "Convert comic book archives (CBZ/CBR) to PDF format. Supports multiple files.", + "acceptedFormats": "CBZ, CBR files", + "convertButton": "Convert to PDF" + }, + "wpdToPdf": { + "name": "WPD to PDF", + "subtitle": "Convert WordPerfect documents (WPD) to PDF format. Supports multiple files.", + "acceptedFormats": "WPD files", + "convertButton": "Convert to PDF" + }, + "wpsToPdf": { + "name": "WPS to PDF", + "subtitle": "Convert WPS Office documents to PDF format. Supports multiple files.", + "acceptedFormats": "WPS files", + "convertButton": "Convert to PDF" + }, + "xmlToPdf": { + "name": "XML to PDF", + "subtitle": "Convert XML documents to PDF format. Supports multiple files.", + "acceptedFormats": "XML files", + "convertButton": "Convert to PDF" + }, + "pagesToPdf": { + "name": "Pages to PDF", + "subtitle": "Convert Apple Pages documents to PDF format. Supports multiple files.", + "acceptedFormats": "Pages files", + "convertButton": "Convert to PDF" + }, + "odgToPdf": { + "name": "ODG to PDF", + "subtitle": "Convert OpenDocument Graphics (ODG) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODG files", + "convertButton": "Convert to PDF" + }, + "odsToPdf": { + "name": "ODS to PDF", + "subtitle": "Convert OpenDocument Spreadsheet (ODS) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODS files", + "convertButton": "Convert to PDF" + }, + "odpToPdf": { + "name": "ODP to PDF", + "subtitle": "Convert OpenDocument Presentation (ODP) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODP files", + "convertButton": "Convert to PDF" + }, + "pubToPdf": { + "name": "PUB to PDF", + "subtitle": "Convert Microsoft Publisher (PUB) files to PDF format. Supports multiple files.", + "acceptedFormats": "PUB files", + "convertButton": "Convert to PDF" + }, + "vsdToPdf": { + "name": "VSD to PDF", + "subtitle": "Convert Microsoft Visio (VSD, VSDX) files to PDF format. Supports multiple files.", + "acceptedFormats": "VSD, VSDX files", + "convertButton": "Convert to PDF" + }, + "psdToPdf": { + "name": "PSD to PDF", + "subtitle": "Convert Adobe Photoshop (PSD) files to PDF format. Supports multiple files.", + "acceptedFormats": "PSD files", + "convertButton": "Convert to PDF" + }, + "pdfToSvg": { + "name": "PDF to SVG", + "subtitle": "Convert each page of a PDF file into a scalable vector graphic (SVG) for perfect quality at any size." + }, + "extractTables": { + "name": "Extract PDF Tables", + "subtitle": "Extract tables from PDF files and export as CSV, JSON, or Markdown." + }, + "pdfToCsv": { + "name": "PDF to CSV", + "subtitle": "Extract tables from PDF and convert to CSV format." + }, + "pdfToExcel": { + "name": "PDF to Excel", + "subtitle": "Extract tables from PDF and convert to Excel (XLSX) format." + }, + "pdfToText": { + "name": "PDF to Text", + "subtitle": "Extract text from PDF files and save as plain text (.txt). Supports multiple files.", + "note": "This tool works ONLY with digitally created PDFs. For scanned documents or image-based PDFs, use our OCR PDF tool instead.", + "convertButton": "Extract Text" + }, + "digitalSignPdf": { + "name": "Digital Signature PDF", + "pageTitle": "Digital Signature PDF - Add Cryptographic Signature | BentoPDF", + "subtitle": "Add a cryptographic digital signature to your PDF using X.509 certificates. Supports PKCS#12 (.pfx, .p12) and PEM formats. Your private key never leaves your browser.", + "certificateSection": "Certificate", + "uploadCert": "Upload certificate (.pfx, .p12)", + "certPassword": "Certificate Password", + "certPasswordPlaceholder": "Enter certificate password", + "certInfo": "Certificate Information", + "certSubject": "Subject", + "certIssuer": "Issuer", + "certValidity": "Valid", + "signatureDetails": "Signature Details (Optional)", + "reason": "Reason", + "reasonPlaceholder": "e.g., I approve this document", + "location": "Location", + "locationPlaceholder": "e.g., New York, USA", + "contactInfo": "Contact Info", + "contactPlaceholder": "e.g., email@example.com", + "applySignature": "Apply Digital Signature", + "successMessage": "PDF signed successfully! The signature can be verified in any PDF reader." + }, + "validateSignaturePdf": { + "name": "Validate PDF Signature", + "pageTitle": "Validate PDF Signature - Verify Digital Signatures | BentoPDF", + "subtitle": "Verify digital signatures in your PDF files. Check certificate validity, view signer details, and confirm document integrity. All processing happens in your browser." } } diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index 5852813..2005ef7 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -1,319 +1,325 @@ { - "nav": { - "home": "Trang chแปง", - "about": "Giแป›i thiแป‡u", - "contact": "Liรชn hแป‡", - "licensing": "Giแบฅy phรฉp", - "allTools": "Tแบฅt cแบฃ cรดng cแปฅ", - "openMainMenu": "MแปŸ menu chรญnh", - "language": "Ngรดn ngแปฏ" + "nav": { + "home": "Trang chแปง", + "about": "Giแป›i thiแป‡u", + "contact": "Liรชn hแป‡", + "licensing": "Giแบฅy phรฉp", + "allTools": "Tแบฅt cแบฃ cรดng cแปฅ", + "openMainMenu": "MแปŸ menu chรญnh", + "language": "Ngรดn ngแปฏ" + }, + "donation": { + "message": "Bแบกn yรชu thรญch BentoPDF? Hรฃy giรบp chรบng tรดi giแปฏ nรณ miแป…n phรญ vร  mรฃ nguแป“n mแปŸ!", + "button": "Quyรชn gรณp" + }, + "hero": { + "title": "Bแป™ cรดng cแปฅ", + "pdfToolkit": "PDF", + "builtForPrivacy": "an toร n vร  riรชng tฦฐ", + "noSignups": "Khรดng cแบงn ฤ‘ฤƒng kรฝ", + "unlimitedUse": "Sแปญ dแปฅng khรดng giแป›i hแบกn", + "worksOffline": "Hoแบกt ฤ‘แป™ng offline", + "startUsing": "Bแบฏt ฤ‘แบงu sแปญ dแปฅng ngay" + }, + "usedBy": { + "title": "ฤฦฐแปฃc sแปญ dแปฅng bแปŸi cรกc cรดng ty vร  nhแปฏng ngฦฐแปi lร m viแป‡c tแบกi" + }, + "features": { + "title": "Tแบกi sao chแปn", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "Khรดng cแบงn ฤ‘ฤƒng kรฝ", + "description": "Bแบฏt ฤ‘แบงu ngay lแบญp tแปฉc, khรดng cแบงn tร i khoแบฃn hay email." }, - "hero": { - "title": "Bแป™ cรดng cแปฅ", - "pdfToolkit": "PDF", - "builtForPrivacy": "an toร n vร  riรชng tฦฐ", - "noSignups": "Khรดng cแบงn ฤ‘ฤƒng kรฝ", - "unlimitedUse": "Sแปญ dแปฅng khรดng giแป›i hแบกn", - "worksOffline": "Hoแบกt ฤ‘แป™ng offline", - "startUsing": "Bแบฏt ฤ‘แบงu sแปญ dแปฅng ngay" + "noUploads": { + "title": "Khรดng tแบฃi lรชn", + "description": "100% xแปญ lรฝ phรญa mรกy khรกch, tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹." }, - "usedBy": { - "title": "ฤฦฐแปฃc sแปญ dแปฅng bแปŸi cรกc cรดng ty vร  nhแปฏng ngฦฐแปi lร m viแป‡c tแบกi" + "foreverFree": { + "title": "Miแป…n phรญ mรฃi mรฃi", + "description": "Tแบฅt cแบฃ cรดng cแปฅ, khรดng dรนng thแปญ, khรดng cรณ tฦฐแปng phรญ." }, - "features": { - "title": "Tแบกi sao chแปn", - "bentoPdf": "BentoPDF?", - "noSignup": { - "title": "Khรดng cแบงn ฤ‘ฤƒng kรฝ", - "description": "Bแบฏt ฤ‘แบงu ngay lแบญp tแปฉc, khรดng cแบงn tร i khoแบฃn hay email." - }, - "noUploads": { - "title": "Khรดng tแบฃi lรชn", - "description": "100% xแปญ lรฝ phรญa mรกy khรกch, tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹." - }, - "foreverFree": { - "title": "Miแป…n phรญ mรฃi mรฃi", - "description": "Tแบฅt cแบฃ cรดng cแปฅ, khรดng dรนng thแปญ, khรดng cรณ tฦฐแปng phรญ." - }, - "noLimits": { - "title": "Khรดng giแป›i hแบกn", - "description": "Sแปญ dแปฅng bao nhiรชu tรนy thรญch, khรดng cรณ giแป›i hแบกn แบฉn." - }, - "batchProcessing": { - "title": "Xแปญ lรฝ hร ng loแบกt", - "description": "Xแปญ lรฝ khรดng giแป›i hแบกn PDF trong mแป™t lแบงn." - }, - "lightningFast": { - "title": "Cแปฑc kแปณ nhanh", - "description": "Xแปญ lรฝ PDF ngay lแบญp tแปฉc, khรดng cแบงn chแป ฤ‘แปฃi hay trรฌ hoรฃn." - } + "noLimits": { + "title": "Khรดng giแป›i hแบกn", + "description": "Sแปญ dแปฅng bao nhiรชu tรนy thรญch, khรดng cรณ giแป›i hแบกn แบฉn." }, - "tools": { - "title": "Bแบฏt ฤ‘แบงu vแป›i", - "toolsLabel": "Cรดng cแปฅ", - "subtitle": "Nhแบฅp vร o mแป™t cรดng cแปฅ ฤ‘แปƒ mแปŸ trรฌnh tแบฃi tแป‡p lรชn", - "searchPlaceholder": "Tรฌm kiแบฟm cรดng cแปฅ (vรญ dแปฅ: 'chia', 'sแบฏp xแบฟp'...)", - "backToTools": "Quay lแบกi Cรดng cแปฅ", - "firstLoadNotice": "Lแบงn tแบฃi ฤ‘แบงu tiรชn sแบฝ mแบฅt mแป™t chรบt thแปi gian vรฌ chรบng tรดi ฤ‘ang tแบฃi xuแป‘ng cรดng cแปฅ chuyแปƒn ฤ‘แป•i. Sau ฤ‘รณ, mแปi lแบงn tแบฃi sแบฝ ngay lแบญp tแปฉc." + "batchProcessing": { + "title": "Xแปญ lรฝ hร ng loแบกt", + "description": "Xแปญ lรฝ khรดng giแป›i hแบกn PDF trong mแป™t lแบงn." }, - "upload": { - "clickToSelect": "Nhแบฅp ฤ‘แปƒ chแปn tแป‡p", - "orDragAndDrop": "hoแบทc kรฉo vร  thแบฃ", - "pdfOrImages": "PDF hoแบทc Hรฌnh แบฃnh", - "filesNeverLeave": "Tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹.", - "addMore": "Thรชm tแป‡p", - "clearAll": "Xรณa tแบฅt cแบฃ" - }, - "loader": { - "processing": "ฤang xแปญ lรฝ..." - }, - "alert": { - "title": "Thรดng bรกo", - "ok": "OK" - }, - "preview": { - "title": "Xem trฦฐแป›c tร i liแป‡u", - "downloadAsPdf": "Tแบฃi xuแป‘ng dฦฐแป›i dแบกng PDF", - "close": "ฤรณng" - }, - "settings": { - "title": "Cร i ฤ‘แบทt", - "shortcuts": "Phรญm tแบฏt", - "preferences": "Tรนy chแปn", - "displayPreferences": "Tรนy chแปn hiแปƒn thแป‹", - "searchShortcuts": "Tรฌm kiแบฟm phรญm tแบฏt...", - "shortcutsInfo": "Nhแบฅn vร  giแปฏ phรญm ฤ‘แปƒ ฤ‘แบทt phรญm tแบฏt. Thay ฤ‘แป•i ฤ‘ฦฐแปฃc lฦฐu tแปฑ ฤ‘แป™ng.", - "shortcutsWarning": "โš ๏ธ Trรกnh cรกc phรญm tแบฏt trรฌnh duyแป‡t phแป• biแบฟn (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N, v.v.) vรฌ chรบng cรณ thแปƒ khรดng hoแบกt ฤ‘แป™ng ฤ‘รกng tin cแบญy.", - "import": "Nhแบญp", - "export": "Xuแบฅt", - "resetToDefaults": "ฤแบทt lแบกi vแป mแบทc ฤ‘แป‹nh", - "fullWidthMode": "Chแบฟ ฤ‘แป™ toร n chiแปu rแป™ng", - "fullWidthDescription": "Sแปญ dแปฅng toร n bแป™ chiแปu rแป™ng mร n hรฌnh cho tแบฅt cแบฃ cรดng cแปฅ thay vรฌ container cฤƒn giแปฏa", - "settingsAutoSaved": "Cร i ฤ‘แบทt ฤ‘ฦฐแปฃc lฦฐu tแปฑ ฤ‘แป™ng", - "clickToSet": "Nhแบฅp ฤ‘แปƒ ฤ‘แบทt", - "pressKeys": "Nhแบฅn phรญm...", - "warnings": { - "alreadyInUse": "Phรญm tแบฏt ฤ‘รฃ ฤ‘ฦฐแปฃc sแปญ dแปฅng", - "assignedTo": "ฤ‘รฃ ฤ‘ฦฐแปฃc gรกn cho:", - "chooseDifferent": "Vui lรฒng chแปn mแป™t phรญm tแบฏt khรกc.", - "reserved": "Cแบฃnh bรกo phรญm tแบฏt dร nh riรชng", - "commonlyUsed": "thฦฐแปng ฤ‘ฦฐแปฃc sแปญ dแปฅng cho:", - "unreliable": "Phรญm tแบฏt nร y cรณ thแปƒ khรดng hoแบกt ฤ‘แป™ng ฤ‘รกng tin cแบญy hoแบทc cรณ thแปƒ xung ฤ‘แป™t vแป›i hร nh vi trรฌnh duyแป‡t/hแป‡ thแป‘ng.", - "useAnyway": "Bแบกn cรณ muแป‘n sแปญ dแปฅng nรณ khรดng?", - "resetTitle": "ฤแบทt lแบกi phรญm tแบฏt", - "resetMessage": "Bแบกn cรณ chแบฏc chแบฏn muแป‘n ฤ‘แบทt lแบกi tแบฅt cแบฃ phรญm tแบฏt vแป mแบทc ฤ‘แป‹nh?

Hร nh ฤ‘แป™ng nร y khรดng thแปƒ hoร n tรกc.", - "importSuccessTitle": "Nhแบญp thร nh cรดng", - "importSuccessMessage": "ฤรฃ nhแบญp phรญm tแบฏt thร nh cรดng!", - "importFailTitle": "Nhแบญp thแบฅt bแบกi", - "importFailMessage": "Khรดng thแปƒ nhแบญp phรญm tแบฏt. ฤแป‹nh dแบกng tแป‡p khรดng hแปฃp lแป‡." - } - }, - "warning": { - "title": "Cแบฃnh bรกo", - "cancel": "Hแปงy", - "proceed": "Tiแบฟp tแปฅc" - }, - "compliance": { - "title": "Dแปฏ liแป‡u cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹", - "weKeep": "Chรบng tรดi giแปฏ", - "yourInfoSafe": "thรดng tin cแปงa bแบกn an toร n", - "byFollowingStandards": "bแบฑng cรกch tuรขn theo cรกc tiรชu chuแบฉn bแบฃo mแบญt toร n cแบงu.", - "processingLocal": "Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ diแป…n ra cแปฅc bแป™ trรชn thiแบฟt bแป‹ cแปงa bแบกn.", - "gdpr": { - "title": "Tuรขn thแปง GDPR", - "description": "Bแบฃo vแป‡ dแปฏ liแป‡u cรก nhรขn vร  quyแปn riรชng tฦฐ cแปงa cรกc cรก nhรขn trong Liรชn minh Chรขu ร‚u." - }, - "ccpa": { - "title": "Tuรขn thแปง CCPA", - "description": "Trao quyแปn cho cฦฐ dรขn California vแป cรกch thรดng tin cรก nhรขn cแปงa hแป ฤ‘ฦฐแปฃc thu thแบญp, sแปญ dแปฅng vร  chia sแบป." - }, - "hipaa": { - "title": "Tuรขn thแปง HIPAA", - "description": "ฤแบทt ra cรกc biแป‡n phรกp bแบฃo vแป‡ ฤ‘แปƒ xแปญ lรฝ thรดng tin sแปฉc khแปe nhแบกy cแบฃm trong hแป‡ thแป‘ng chฤƒm sรณc sแปฉc khแปe Hoa Kแปณ." - } - }, - "faq": { - "title": "Cรขu hแปi", - "questions": "Thฦฐแปng gแบทp", - "isFree": { - "question": "BentoPDF cรณ thแปฑc sแปฑ miแป…n phรญ khรดng?", - "answer": "Cรณ, hoร n toร n miแป…n phรญ. Tแบฅt cแบฃ cรกc cรดng cแปฅ trรชn BentoPDF ฤ‘แปu 100% miแป…n phรญ sแปญ dแปฅng, khรดng giแป›i hแบกn tแป‡p, khรดng cแบงn ฤ‘ฤƒng kรฝ vร  khรดng cรณ watermark. Chรบng tรดi tin rแบฑng mแปi ngฦฐแปi ฤ‘แปu xแปฉng ฤ‘รกng ฤ‘ฦฐแปฃc tiแบฟp cแบญn vแป›i cรกc cรดng cแปฅ PDF ฤ‘ฦกn giแบฃn, mแบกnh mแบฝ mร  khรดng cรณ tฦฐแปng phรญ." - }, - "areFilesSecure": { - "question": "Tแป‡p cแปงa tรดi cรณ an toร n khรดng? Chรบng ฤ‘ฦฐแปฃc xแปญ lรฝ แปŸ ฤ‘รขu?", - "answer": "Tแป‡p cแปงa bแบกn an toร n nhแบฅt cรณ thแปƒ vรฌ chรบng khรดng bao giแป rแปi khแปi mรกy tรญnh cแปงa bแบกn. Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ diแป…n ra trแปฑc tiแบฟp trong trรฌnh duyแป‡t web cแปงa bแบกn (phรญa mรกy khรกch). Chรบng tรดi khรดng bao giแป tแบฃi tแป‡p cแปงa bแบกn lรชn mรกy chแปง, vรฌ vแบญy bแบกn duy trรฌ quyแปn riรชng tฦฐ vร  kiแปƒm soรกt hoร n toร n ฤ‘แป‘i vแป›i tร i liแป‡u cแปงa mรฌnh." - }, - "platforms": { - "question": "Nรณ cรณ hoแบกt ฤ‘แป™ng trรชn Mac, Windows vร  Mobile khรดng?", - "answer": "Cรณ! Vรฌ BentoPDF chแบกy hoร n toร n trong trรฌnh duyแป‡t cแปงa bแบกn, nรณ hoแบกt ฤ‘แป™ng trรชn bแบฅt kแปณ hแป‡ ฤ‘iแปu hร nh nร o cรณ trรฌnh duyแป‡t web hiแป‡n ฤ‘แบกi, bao gแป“m Windows, macOS, Linux, iOS vร  Android." - }, - "gdprCompliant": { - "question": "BentoPDF cรณ tuรขn thแปง GDPR khรดng?", - "answer": "Cรณ. BentoPDF hoร n toร n tuรขn thแปง GDPR. Vรฌ tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ tแป‡p diแป…n ra cแปฅc bแป™ trong trรฌnh duyแป‡t cแปงa bแบกn vร  chรบng tรดi khรดng bao giแป thu thแบญp hoแบทc truyแปn tแป‡p cแปงa bแบกn ฤ‘แบฟn bแบฅt kแปณ mรกy chแปง nร o, chรบng tรดi khรดng cรณ quyแปn truy cแบญp vร o dแปฏ liแป‡u cแปงa bแบกn. ฤiแปu nร y ฤ‘แบฃm bแบฃo bแบกn luรดn kiแปƒm soรกt tร i liแป‡u cแปงa mรฌnh." - }, - "dataStorage": { - "question": "Bแบกn cรณ lฦฐu trแปฏ hoแบทc theo dรตi bแบฅt kแปณ tแป‡p nร o cแปงa tรดi khรดng?", - "answer": "Khรดng. Chรบng tรดi khรดng bao giแป lฦฐu trแปฏ, theo dรตi hoแบทc ghi nhแบญt kรฝ tแป‡p cแปงa bแบกn. Mแปi thแปฉ bแบกn lร m trรชn BentoPDF diแป…n ra trong bแป™ nhแป› trรฌnh duyแป‡t cแปงa bแบกn vร  biแบฟn mแบฅt khi bแบกn ฤ‘รณng trang. Khรดng cรณ tแบฃi lรชn, khรดng cรณ nhแบญt kรฝ lแป‹ch sแปญ vร  khรดng cรณ mรกy chแปง liรชn quan." - }, - "different": { - "question": "ฤiแปu gรฌ lร m cho BentoPDF khรกc biแป‡t so vแป›i cรกc cรดng cแปฅ PDF khรกc?", - "answer": "Hแบงu hแบฟt cรกc cรดng cแปฅ PDF tแบฃi tแป‡p cแปงa bแบกn lรชn mรกy chแปง ฤ‘แปƒ xแปญ lรฝ. BentoPDF khรดng bao giแป lร m ฤ‘iแปu ฤ‘รณ. Chรบng tรดi sแปญ dแปฅng cรดng nghแป‡ web hiแป‡n ฤ‘แบกi, an toร n ฤ‘แปƒ xแปญ lรฝ tแป‡p cแปงa bแบกn trแปฑc tiแบฟp trong trรฌnh duyแป‡t. ฤiแปu nร y cรณ nghฤฉa lร  hiแป‡u suแบฅt nhanh hฦกn, quyแปn riรชng tฦฐ mแบกnh mแบฝ hฦกn vร  hoร n toร n yรชn tรขm." - }, - "browserBased": { - "question": "Xแปญ lรฝ dแปฑa trรชn trรฌnh duyแป‡t giแปฏ tรดi an toร n nhฦฐ thแบฟ nร o?", - "answer": "Bแบฑng cรกch chแบกy hoร n toร n bรชn trong trรฌnh duyแป‡t cแปงa bแบกn, BentoPDF ฤ‘แบฃm bแบฃo rแบฑng tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹. ฤiแปu nร y loแบกi bแป cรกc rแปงi ro vแป hack mรกy chแปง, vi phแบกm dแปฏ liแป‡u hoแบทc truy cแบญp trรกi phรฉp. Tแป‡p cแปงa bแบกn vแบซn thuแป™c vแป bแบกnโ€”luรดn luรดn." - }, - "analytics": { - "question": "Bแบกn cรณ sแปญ dแปฅng cookie hoแบทc phรขn tรญch ฤ‘แปƒ theo dรตi tรดi khรดng?", - "answer": "Chรบng tรดi quan tรขm ฤ‘แบฟn quyแปn riรชng tฦฐ cแปงa bแบกn. BentoPDF khรดng theo dรตi thรดng tin cรก nhรขn. Chรบng tรดi chแป‰ sแปญ dแปฅng Simple Analytics ฤ‘แปƒ xem sแป‘ lฦฐแปฃt truy cแบญp แบฉn danh. ฤiแปu nร y cรณ nghฤฉa lร  chรบng tรดi cรณ thแปƒ biแบฟt cรณ bao nhiรชu ngฦฐแปi dรนng truy cแบญp trang web cแปงa chรบng tรดi, nhฦฐng chรบng tรดi khรดng bao giแป biแบฟt bแบกn lร  ai. Simple Analytics hoร n toร n tuรขn thแปง GDPR vร  tรดn trแปng quyแปn riรชng tฦฐ cแปงa bแบกn." - } - }, - "testimonials": { - "title": "Ngฦฐแปi dรนng", - "users": "cแปงa chรบng tรดi", - "say": "nรณi gรฌ" - }, - "support": { - "title": "Thรญch cรดng viแป‡c cแปงa tรดi?", - "description": "BentoPDF lร  mแป™t dแปฑ รกn ฤ‘am mรช, ฤ‘ฦฐแปฃc xรขy dแปฑng ฤ‘แปƒ cung cแบฅp bแป™ cรดng cแปฅ PDF miแป…n phรญ, riรชng tฦฐ vร  mแบกnh mแบฝ cho mแปi ngฦฐแปi. Nแบฟu bแบกn thแบฅy nรณ hแปฏu รญch, hรฃy cรขn nhแบฏc hแป— trแปฃ phรกt triแปƒn cแปงa nรณ. Mแป—i ly cร  phรช ฤ‘แปu giรบp รญch!", - "buyMeCoffee": "Mua cho tรดi mแป™t ly cร  phรช" - }, - "footer": { - "copyright": "ยฉ 2025 BentoPDF. Bแบฃo lฦฐu mแปi quyแปn.", - "version": "Phiรชn bแบฃn", - "company": "Cรดng ty", - "aboutUs": "Vแป chรบng tรดi", - "faqLink": "FAQ", - "contactUs": "Liรชn hแป‡", - "legal": "Phรกp lรฝ", - "termsAndConditions": "ฤiแปu khoแบฃn vร  ฤiแปu kiแป‡n", - "privacyPolicy": "Chรญnh sรกch Bแบฃo mแบญt", - "followUs": "Theo dรตi chรบng tรดi" - }, - "merge": { - "title": "Gแป™p PDF", - "description": "Kแบฟt hแปฃp toร n bแป™ tแป‡p hoแบทc chแปn cรกc trang cแปฅ thแปƒ ฤ‘แปƒ gแป™p thร nh tร i liแป‡u mแป›i.", - "fileMode": "Chแบฟ ฤ‘แป™ tแป‡p", - "pageMode": "Chแบฟ ฤ‘แป™ trang", - "howItWorks": "Cรกch hoแบกt ฤ‘แป™ng:", - "fileModeInstructions": [ - "Nhแบฅp vร  kรฉo biแปƒu tฦฐแปฃng ฤ‘แปƒ thay ฤ‘แป•i thแปฉ tแปฑ cรกc tแป‡p.", - "Trong hแป™p \"Trang\" cho mแป—i tแป‡p, bแบกn cรณ thแปƒ chแป‰ ฤ‘แป‹nh phแบกm vi (vรญ dแปฅ: \"1-3, 5\") ฤ‘แปƒ chแป‰ gแป™p nhแปฏng trang ฤ‘รณ.", - "ฤแปƒ trแป‘ng hแป™p \"Trang\" ฤ‘แปƒ bao gแป“m tแบฅt cแบฃ cรกc trang tแปซ tแป‡p ฤ‘รณ." - ], - "pageModeInstructions": [ - "Tแบฅt cแบฃ cรกc trang tแปซ PDF ฤ‘รฃ tแบฃi lรชn cแปงa bแบกn ฤ‘ฦฐแปฃc hiแปƒn thแป‹ bรชn dฦฐแป›i.", - "Chแป‰ cแบงn kรฉo vร  thแบฃ cรกc hรฌnh thu nhแป trang riรชng lแบป ฤ‘แปƒ tแบกo thแปฉ tแปฑ chรญnh xรกc bแบกn muแป‘n cho tแป‡p mแป›i cแปงa mรฌnh." - ], - "mergePdfs": "Gแป™p PDF" - }, - "common": { - "page": "Trang", - "pages": "Trang", - "of": "cแปงa", - "download": "Tแบฃi xuแป‘ng", - "cancel": "Hแปงy", - "save": "Lฦฐu", - "delete": "Xรณa", - "edit": "Chแป‰nh sแปญa", - "add": "Thรชm", - "remove": "Xรณa", - "loading": "ฤang tแบฃi...", - "error": "Lแป—i", - "success": "Thร nh cรดng", - "file": "Tแป‡p", - "files": "Tแป‡p" - }, - "about": { - "hero": { - "title": "Chรบng tรดi tin rแบฑng cรดng cแปฅ PDF nรชn", - "subtitle": "nhanh, riรชng tฦฐ vร  miแป…n phรญ.", - "noCompromises": "Khรดng thแปa hiแป‡p." - }, - "mission": { - "title": "Sแปฉ mแป‡nh cแปงa chรบng tรดi", - "description": "Cung cแบฅp bแป™ cรดng cแปฅ PDF toร n diแป‡n nhแบฅt tรดn trแปng quyแปn riรชng tฦฐ cแปงa bแบกn vร  khรดng bao giแป yรชu cแบงu thanh toรกn. Chรบng tรดi tin rแบฑng cรกc cรดng cแปฅ tร i liแป‡u thiแบฟt yแบฟu nรชn cรณ thแปƒ truy cแบญp ฤ‘ฦฐแปฃc cho mแปi ngฦฐแปi, แปŸ mแปi nฦกi, khรดng cรณ rร o cแบฃn." - }, - "philosophy": { - "label": "Triแบฟt lรฝ cแป‘t lรตi cแปงa chรบng tรดi", - "title": "Quyแปn riรชng tฦฐ trฦฐแป›c tiรชn. Luรดn luรดn.", - "description": "Trong thแปi ฤ‘แบกi mร  dแปฏ liแป‡u lร  hร ng hรณa, chรบng tรดi cรณ cรกch tiแบฟp cแบญn khรกc. Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ cho cรกc cรดng cแปฅ Bentopdf diแป…n ra cแปฅc bแป™ trong trรฌnh duyแป‡t cแปงa bแบกn. ฤiแปu nร y cรณ nghฤฉa lร  tแป‡p cแปงa bแบกn khรดng bao giแป chแบกm vร o mรกy chแปง cแปงa chรบng tรดi, chรบng tรดi khรดng bao giแป thแบฅy tร i liแป‡u cแปงa bแบกn vร  chรบng tรดi khรดng theo dรตi nhแปฏng gรฌ bแบกn lร m. Tร i liแป‡u cแปงa bแบกn vแบซn hoร n toร n vร  rรต rร ng lร  riรชng tฦฐ. ฤรณ khรดng chแป‰ lร  mแป™t tรญnh nฤƒng; ฤ‘รณ lร  nแปn tแบฃng cแปงa chรบng tรดi." - }, - "whyBentopdf": { - "title": "Tแบกi sao chแปn", - "speed": { - "title": "ฤฦฐแปฃc xรขy dแปฑng cho tแป‘c ฤ‘แป™", - "description": "Khรดng cแบงn chแป tแบฃi lรชn hoแบทc tแบฃi xuแป‘ng lรชn mรกy chแปง. Bแบฑng cรกch xแปญ lรฝ tแป‡p trแปฑc tiแบฟp trong trรฌnh duyแป‡t cแปงa bแบกn bแบฑng cรดng nghแป‡ web hiแป‡n ฤ‘แบกi nhฦฐ WebAssembly, chรบng tรดi cung cแบฅp tแป‘c ฤ‘แป™ vรด song cho tแบฅt cแบฃ cรกc cรดng cแปฅ cแปงa chรบng tรดi." - }, - "free": { - "title": "Hoร n toร n miแป…n phรญ", - "description": "Khรดng dรนng thแปญ, khรดng ฤ‘ฤƒng kรฝ, khรดng phรญ แบฉn vร  khรดng cรณ tรญnh nฤƒng \"premium\" bแป‹ giแปฏ lแบกi. Chรบng tรดi tin rแบฑng cรกc cรดng cแปฅ PDF mแบกnh mแบฝ nรชn lร  tiแป‡n รญch cรดng cแป™ng, khรดng phแบฃi trung tรขm lแปฃi nhuแบญn." - }, - "noAccount": { - "title": "Khรดng cแบงn tร i khoแบฃn", - "description": "Bแบฏt ฤ‘แบงu sแปญ dแปฅng bแบฅt kแปณ cรดng cแปฅ nร o ngay lแบญp tแปฉc. Chรบng tรดi khรดng cแบงn email, mแบญt khแบฉu hoแบทc bแบฅt kแปณ thรดng tin cรก nhรขn nร o cแปงa bแบกn. Quy trรฌnh lร m viแป‡c cแปงa bแบกn nรชn khรดng ma sรกt vร  แบฉn danh." - }, - "openSource": { - "title": "Tinh thแบงn mรฃ nguแป“n mแปŸ", - "description": "ฤฦฐแปฃc xรขy dแปฑng vแป›i tinh thแบงn minh bแบกch. Chรบng tรดi tแบญn dแปฅng cรกc thฦฐ viแป‡n mรฃ nguแป“n mแปŸ tuyแป‡t vแปi nhฦฐ PDF-lib vร  PDF.js, vร  tin vร o nแป— lแปฑc do cแป™ng ฤ‘แป“ng thรบc ฤ‘แบฉy ฤ‘แปƒ lร m cho cรกc cรดng cแปฅ mแบกnh mแบฝ cรณ thแปƒ truy cแบญp ฤ‘ฦฐแปฃc cho mแปi ngฦฐแปi." - } - }, - "cta": { - "title": "Sแบตn sร ng bแบฏt ฤ‘แบงu?", - "description": "Tham gia cรนng hร ng nghรฌn ngฦฐแปi dรนng tin tฦฐแปŸng Bentopdf cho nhu cแบงu tร i liแป‡u hร ng ngร y cแปงa hแป. Trแบฃi nghiแป‡m sแปฑ khรกc biแป‡t mร  quyแปn riรชng tฦฐ vร  hiแป‡u suแบฅt cรณ thแปƒ tแบกo ra.", - "button": "Khรกm phรก tแบฅt cแบฃ cรดng cแปฅ" - } - }, - "contact": { - "title": "Liรชn hแป‡", - "subtitle": "Chรบng tรดi rแบฅt muแป‘n nghe tแปซ bแบกn. Cho dรน bแบกn cรณ cรขu hแปi, phแบฃn hแป“i hay yรชu cแบงu tรญnh nฤƒng, vui lรฒng ฤ‘แปซng ngแบงn ngแบกi liรชn hแป‡.", - "email": "Bแบกn cรณ thแปƒ liรชn hแป‡ trแปฑc tiแบฟp vแป›i chรบng tรดi qua email tแบกi:" - }, - "licensing": { - "title": "Giแบฅy phรฉp cho", - "subtitle": "Chแปn giแบฅy phรฉp phรน hแปฃp vแป›i nhu cแบงu cแปงa bแบกn." - }, - "multiTool": { - "uploadPdfs": "Tแบฃi lรชn PDF", - "upload": "Tแบฃi lรชn", - "addBlankPage": "Thรชm trang trแป‘ng", - "edit": "Chแป‰nh sแปญa:", - "undo": "Hoร n tรกc", - "redo": "Lร m lแบกi", - "reset": "ฤแบทt lแบกi", - "selection": "Chแปn:", - "selectAll": "Chแปn tแบฅt cแบฃ", - "deselectAll": "Bแป chแปn tแบฅt cแบฃ", - "rotate": "Xoay:", - "rotateLeft": "Trรกi", - "rotateRight": "Phแบฃi", - "transform": "Biแบฟn ฤ‘แป•i:", - "duplicate": "Nhรขn bแบฃn", - "split": "Chia", - "clear": "Xรณa:", - "delete": "Xรณa", - "download": "Tแบฃi xuแป‘ng:", - "downloadSelected": "Tแบฃi xuแป‘ng ฤ‘รฃ chแปn", - "exportPdf": "Xuแบฅt PDF", - "uploadPdfFiles": "Chแปn tแป‡p PDF", - "dragAndDrop": "Kรฉo vร  thแบฃ tแป‡p PDF vร o ฤ‘รขy, hoแบทc nhแบฅp ฤ‘แปƒ chแปn", - "selectFiles": "Chแปn tแป‡p", - "renderingPages": "ฤang kแบฟt xuแบฅt trang...", - "actions": { - "duplicatePage": "Nhรขn bแบฃn trang nร y", - "deletePage": "Xรณa trang nร y", - "insertPdf": "Chรจn PDF sau trang nร y", - "toggleSplit": "Bแบญt/tแบฏt chia sau trang nร y" - }, - "pleaseWait": "Vui lรฒng ฤ‘แปฃi", - "pagesRendering": "Cรกc trang vแบซn ฤ‘ang ฤ‘ฦฐแปฃc kแบฟt xuแบฅt. Vui lรฒng ฤ‘แปฃi...", - "noPagesSelected": "Chฦฐa chแปn trang nร o", - "selectOnePage": "Vui lรฒng chแปn รญt nhแบฅt mแป™t trang ฤ‘แปƒ tแบฃi xuแป‘ng.", - "noPages": "Khรดng cรณ trang", - "noPagesToExport": "Khรดng cรณ trang nร o ฤ‘แปƒ xuแบฅt.", - "renderingTitle": "ฤang kแบฟt xuแบฅt xem trฦฐแป›c trang", - "errorRendering": "Khรดng thแปƒ kแบฟt xuแบฅt hรฌnh thu nhแป trang", - "error": "Lแป—i", - "failedToLoad": "Khรดng thแปƒ tแบฃi" + "lightningFast": { + "title": "Cแปฑc kแปณ nhanh", + "description": "Xแปญ lรฝ PDF ngay lแบญp tแปฉc, khรดng cแบงn chแป ฤ‘แปฃi hay trรฌ hoรฃn." } -} \ No newline at end of file + }, + "tools": { + "title": "Bแบฏt ฤ‘แบงu vแป›i", + "toolsLabel": "Cรดng cแปฅ", + "subtitle": "Nhแบฅp vร o mแป™t cรดng cแปฅ ฤ‘แปƒ mแปŸ trรฌnh tแบฃi tแป‡p lรชn", + "searchPlaceholder": "Tรฌm kiแบฟm cรดng cแปฅ (vรญ dแปฅ: 'chia', 'sแบฏp xแบฟp'...)", + "backToTools": "Quay lแบกi Cรดng cแปฅ", + "firstLoadNotice": "Lแบงn tแบฃi ฤ‘แบงu tiรชn sแบฝ mแบฅt mแป™t chรบt thแปi gian vรฌ chรบng tรดi ฤ‘ang tแบฃi xuแป‘ng cรดng cแปฅ chuyแปƒn ฤ‘แป•i. Sau ฤ‘รณ, mแปi lแบงn tแบฃi sแบฝ ngay lแบญp tแปฉc." + }, + "upload": { + "clickToSelect": "Nhแบฅp ฤ‘แปƒ chแปn tแป‡p", + "orDragAndDrop": "hoแบทc kรฉo vร  thแบฃ", + "pdfOrImages": "PDF hoแบทc Hรฌnh แบฃnh", + "filesNeverLeave": "Tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹.", + "addMore": "Thรชm tแป‡p", + "clearAll": "Xรณa tแบฅt cแบฃ", + "clearFiles": "Xรณa tแป‡p" + }, + "loader": { + "processing": "ฤang xแปญ lรฝ..." + }, + "alert": { + "title": "Thรดng bรกo", + "ok": "OK" + }, + "preview": { + "title": "Xem trฦฐแป›c tร i liแป‡u", + "downloadAsPdf": "Tแบฃi xuแป‘ng dฦฐแป›i dแบกng PDF", + "close": "ฤรณng" + }, + "settings": { + "title": "Cร i ฤ‘แบทt", + "shortcuts": "Phรญm tแบฏt", + "preferences": "Tรนy chแปn", + "displayPreferences": "Tรนy chแปn hiแปƒn thแป‹", + "searchShortcuts": "Tรฌm kiแบฟm phรญm tแบฏt...", + "shortcutsInfo": "Nhแบฅn vร  giแปฏ phรญm ฤ‘แปƒ ฤ‘แบทt phรญm tแบฏt. Thay ฤ‘แป•i ฤ‘ฦฐแปฃc lฦฐu tแปฑ ฤ‘แป™ng.", + "shortcutsWarning": "โš ๏ธ Trรกnh cรกc phรญm tแบฏt trรฌnh duyแป‡t phแป• biแบฟn (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N, v.v.) vรฌ chรบng cรณ thแปƒ khรดng hoแบกt ฤ‘แป™ng ฤ‘รกng tin cแบญy.", + "import": "Nhแบญp", + "export": "Xuแบฅt", + "resetToDefaults": "ฤแบทt lแบกi vแป mแบทc ฤ‘แป‹nh", + "fullWidthMode": "Chแบฟ ฤ‘แป™ toร n chiแปu rแป™ng", + "fullWidthDescription": "Sแปญ dแปฅng toร n bแป™ chiแปu rแป™ng mร n hรฌnh cho tแบฅt cแบฃ cรดng cแปฅ thay vรฌ container cฤƒn giแปฏa", + "settingsAutoSaved": "Cร i ฤ‘แบทt ฤ‘ฦฐแปฃc lฦฐu tแปฑ ฤ‘แป™ng", + "clickToSet": "Nhแบฅp ฤ‘แปƒ ฤ‘แบทt", + "pressKeys": "Nhแบฅn phรญm...", + "warnings": { + "alreadyInUse": "Phรญm tแบฏt ฤ‘รฃ ฤ‘ฦฐแปฃc sแปญ dแปฅng", + "assignedTo": "ฤ‘รฃ ฤ‘ฦฐแปฃc gรกn cho:", + "chooseDifferent": "Vui lรฒng chแปn mแป™t phรญm tแบฏt khรกc.", + "reserved": "Cแบฃnh bรกo phรญm tแบฏt dร nh riรชng", + "commonlyUsed": "thฦฐแปng ฤ‘ฦฐแปฃc sแปญ dแปฅng cho:", + "unreliable": "Phรญm tแบฏt nร y cรณ thแปƒ khรดng hoแบกt ฤ‘แป™ng ฤ‘รกng tin cแบญy hoแบทc cรณ thแปƒ xung ฤ‘แป™t vแป›i hร nh vi trรฌnh duyแป‡t/hแป‡ thแป‘ng.", + "useAnyway": "Bแบกn cรณ muแป‘n sแปญ dแปฅng nรณ khรดng?", + "resetTitle": "ฤแบทt lแบกi phรญm tแบฏt", + "resetMessage": "Bแบกn cรณ chแบฏc chแบฏn muแป‘n ฤ‘แบทt lแบกi tแบฅt cแบฃ phรญm tแบฏt vแป mแบทc ฤ‘แป‹nh?

Hร nh ฤ‘แป™ng nร y khรดng thแปƒ hoร n tรกc.", + "importSuccessTitle": "Nhแบญp thร nh cรดng", + "importSuccessMessage": "ฤรฃ nhแบญp phรญm tแบฏt thร nh cรดng!", + "importFailTitle": "Nhแบญp thแบฅt bแบกi", + "importFailMessage": "Khรดng thแปƒ nhแบญp phรญm tแบฏt. ฤแป‹nh dแบกng tแป‡p khรดng hแปฃp lแป‡." + } + }, + "warning": { + "title": "Cแบฃnh bรกo", + "cancel": "Hแปงy", + "proceed": "Tiแบฟp tแปฅc" + }, + "compliance": { + "title": "Dแปฏ liแป‡u cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹", + "weKeep": "Chรบng tรดi giแปฏ", + "yourInfoSafe": "thรดng tin cแปงa bแบกn an toร n", + "byFollowingStandards": "bแบฑng cรกch tuรขn theo cรกc tiรชu chuแบฉn bแบฃo mแบญt toร n cแบงu.", + "processingLocal": "Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ diแป…n ra cแปฅc bแป™ trรชn thiแบฟt bแป‹ cแปงa bแบกn.", + "gdpr": { + "title": "Tuรขn thแปง GDPR", + "description": "Bแบฃo vแป‡ dแปฏ liแป‡u cรก nhรขn vร  quyแปn riรชng tฦฐ cแปงa cรกc cรก nhรขn trong Liรชn minh Chรขu ร‚u." + }, + "ccpa": { + "title": "Tuรขn thแปง CCPA", + "description": "Trao quyแปn cho cฦฐ dรขn California vแป cรกch thรดng tin cรก nhรขn cแปงa hแป ฤ‘ฦฐแปฃc thu thแบญp, sแปญ dแปฅng vร  chia sแบป." + }, + "hipaa": { + "title": "Tuรขn thแปง HIPAA", + "description": "ฤแบทt ra cรกc biแป‡n phรกp bแบฃo vแป‡ ฤ‘แปƒ xแปญ lรฝ thรดng tin sแปฉc khแปe nhแบกy cแบฃm trong hแป‡ thแป‘ng chฤƒm sรณc sแปฉc khแปe Hoa Kแปณ." + } + }, + "faq": { + "title": "Cรขu hแปi", + "questions": "Thฦฐแปng gแบทp", + "isFree": { + "question": "BentoPDF cรณ thแปฑc sแปฑ miแป…n phรญ khรดng?", + "answer": "Cรณ, hoร n toร n miแป…n phรญ. Tแบฅt cแบฃ cรกc cรดng cแปฅ trรชn BentoPDF ฤ‘แปu 100% miแป…n phรญ sแปญ dแปฅng, khรดng giแป›i hแบกn tแป‡p, khรดng cแบงn ฤ‘ฤƒng kรฝ vร  khรดng cรณ watermark. Chรบng tรดi tin rแบฑng mแปi ngฦฐแปi ฤ‘แปu xแปฉng ฤ‘รกng ฤ‘ฦฐแปฃc tiแบฟp cแบญn vแป›i cรกc cรดng cแปฅ PDF ฤ‘ฦกn giแบฃn, mแบกnh mแบฝ mร  khรดng cรณ tฦฐแปng phรญ." + }, + "areFilesSecure": { + "question": "Tแป‡p cแปงa tรดi cรณ an toร n khรดng? Chรบng ฤ‘ฦฐแปฃc xแปญ lรฝ แปŸ ฤ‘รขu?", + "answer": "Tแป‡p cแปงa bแบกn an toร n nhแบฅt cรณ thแปƒ vรฌ chรบng khรดng bao giแป rแปi khแปi mรกy tรญnh cแปงa bแบกn. Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ diแป…n ra trแปฑc tiแบฟp trong trรฌnh duyแป‡t web cแปงa bแบกn (phรญa mรกy khรกch). Chรบng tรดi khรดng bao giแป tแบฃi tแป‡p cแปงa bแบกn lรชn mรกy chแปง, vรฌ vแบญy bแบกn duy trรฌ quyแปn riรชng tฦฐ vร  kiแปƒm soรกt hoร n toร n ฤ‘แป‘i vแป›i tร i liแป‡u cแปงa mรฌnh." + }, + "platforms": { + "question": "Nรณ cรณ hoแบกt ฤ‘แป™ng trรชn Mac, Windows vร  Mobile khรดng?", + "answer": "Cรณ! Vรฌ BentoPDF chแบกy hoร n toร n trong trรฌnh duyแป‡t cแปงa bแบกn, nรณ hoแบกt ฤ‘แป™ng trรชn bแบฅt kแปณ hแป‡ ฤ‘iแปu hร nh nร o cรณ trรฌnh duyแป‡t web hiแป‡n ฤ‘แบกi, bao gแป“m Windows, macOS, Linux, iOS vร  Android." + }, + "gdprCompliant": { + "question": "BentoPDF cรณ tuรขn thแปง GDPR khรดng?", + "answer": "Cรณ. BentoPDF hoร n toร n tuรขn thแปง GDPR. Vรฌ tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ tแป‡p diแป…n ra cแปฅc bแป™ trong trรฌnh duyแป‡t cแปงa bแบกn vร  chรบng tรดi khรดng bao giแป thu thแบญp hoแบทc truyแปn tแป‡p cแปงa bแบกn ฤ‘แบฟn bแบฅt kแปณ mรกy chแปง nร o, chรบng tรดi khรดng cรณ quyแปn truy cแบญp vร o dแปฏ liแป‡u cแปงa bแบกn. ฤiแปu nร y ฤ‘แบฃm bแบฃo bแบกn luรดn kiแปƒm soรกt tร i liแป‡u cแปงa mรฌnh." + }, + "dataStorage": { + "question": "Bแบกn cรณ lฦฐu trแปฏ hoแบทc theo dรตi bแบฅt kแปณ tแป‡p nร o cแปงa tรดi khรดng?", + "answer": "Khรดng. Chรบng tรดi khรดng bao giแป lฦฐu trแปฏ, theo dรตi hoแบทc ghi nhแบญt kรฝ tแป‡p cแปงa bแบกn. Mแปi thแปฉ bแบกn lร m trรชn BentoPDF diแป…n ra trong bแป™ nhแป› trรฌnh duyแป‡t cแปงa bแบกn vร  biแบฟn mแบฅt khi bแบกn ฤ‘รณng trang. Khรดng cรณ tแบฃi lรชn, khรดng cรณ nhแบญt kรฝ lแป‹ch sแปญ vร  khรดng cรณ mรกy chแปง liรชn quan." + }, + "different": { + "question": "ฤiแปu gรฌ lร m cho BentoPDF khรกc biแป‡t so vแป›i cรกc cรดng cแปฅ PDF khรกc?", + "answer": "Hแบงu hแบฟt cรกc cรดng cแปฅ PDF tแบฃi tแป‡p cแปงa bแบกn lรชn mรกy chแปง ฤ‘แปƒ xแปญ lรฝ. BentoPDF khรดng bao giแป lร m ฤ‘iแปu ฤ‘รณ. Chรบng tรดi sแปญ dแปฅng cรดng nghแป‡ web hiแป‡n ฤ‘แบกi, an toร n ฤ‘แปƒ xแปญ lรฝ tแป‡p cแปงa bแบกn trแปฑc tiแบฟp trong trรฌnh duyแป‡t. ฤiแปu nร y cรณ nghฤฉa lร  hiแป‡u suแบฅt nhanh hฦกn, quyแปn riรชng tฦฐ mแบกnh mแบฝ hฦกn vร  hoร n toร n yรชn tรขm." + }, + "browserBased": { + "question": "Xแปญ lรฝ dแปฑa trรชn trรฌnh duyแป‡t giแปฏ tรดi an toร n nhฦฐ thแบฟ nร o?", + "answer": "Bแบฑng cรกch chแบกy hoร n toร n bรชn trong trรฌnh duyแป‡t cแปงa bแบกn, BentoPDF ฤ‘แบฃm bแบฃo rแบฑng tแป‡p cแปงa bแบกn khรดng bao giแป rแปi khแปi thiแบฟt bแป‹. ฤiแปu nร y loแบกi bแป cรกc rแปงi ro vแป hack mรกy chแปง, vi phแบกm dแปฏ liแป‡u hoแบทc truy cแบญp trรกi phรฉp. Tแป‡p cแปงa bแบกn vแบซn thuแป™c vแป bแบกnโ€”luรดn luรดn." + }, + "analytics": { + "question": "Bแบกn cรณ sแปญ dแปฅng cookie hoแบทc phรขn tรญch ฤ‘แปƒ theo dรตi tรดi khรดng?", + "answer": "Chรบng tรดi quan tรขm ฤ‘แบฟn quyแปn riรชng tฦฐ cแปงa bแบกn. BentoPDF khรดng theo dรตi thรดng tin cรก nhรขn. Chรบng tรดi chแป‰ sแปญ dแปฅng Simple Analytics ฤ‘แปƒ xem sแป‘ lฦฐแปฃt truy cแบญp แบฉn danh. ฤiแปu nร y cรณ nghฤฉa lร  chรบng tรดi cรณ thแปƒ biแบฟt cรณ bao nhiรชu ngฦฐแปi dรนng truy cแบญp trang web cแปงa chรบng tรดi, nhฦฐng chรบng tรดi khรดng bao giแป biแบฟt bแบกn lร  ai. Simple Analytics hoร n toร n tuรขn thแปง GDPR vร  tรดn trแปng quyแปn riรชng tฦฐ cแปงa bแบกn." + } + }, + "testimonials": { + "title": "Ngฦฐแปi dรนng", + "users": "cแปงa chรบng tรดi", + "say": "nรณi gรฌ" + }, + "support": { + "title": "Thรญch cรดng viแป‡c cแปงa tรดi?", + "description": "BentoPDF lร  mแป™t dแปฑ รกn ฤ‘am mรช, ฤ‘ฦฐแปฃc xรขy dแปฑng ฤ‘แปƒ cung cแบฅp bแป™ cรดng cแปฅ PDF miแป…n phรญ, riรชng tฦฐ vร  mแบกnh mแบฝ cho mแปi ngฦฐแปi. Nแบฟu bแบกn thแบฅy nรณ hแปฏu รญch, hรฃy cรขn nhแบฏc hแป— trแปฃ phรกt triแปƒn cแปงa nรณ. Mแป—i ly cร  phรช ฤ‘แปu giรบp รญch!", + "buyMeCoffee": "Mua cho tรดi mแป™t ly cร  phรช" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. Bแบฃo lฦฐu mแปi quyแปn.", + "version": "Phiรชn bแบฃn", + "company": "Cรดng ty", + "aboutUs": "Vแป chรบng tรดi", + "faqLink": "FAQ", + "contactUs": "Liรชn hแป‡", + "legal": "Phรกp lรฝ", + "termsAndConditions": "ฤiแปu khoแบฃn vร  ฤiแปu kiแป‡n", + "privacyPolicy": "Chรญnh sรกch Bแบฃo mแบญt", + "followUs": "Theo dรตi chรบng tรดi" + }, + "merge": { + "title": "Gแป™p PDF", + "description": "Kแบฟt hแปฃp toร n bแป™ tแป‡p hoแบทc chแปn cรกc trang cแปฅ thแปƒ ฤ‘แปƒ gแป™p thร nh tร i liแป‡u mแป›i.", + "fileMode": "Chแบฟ ฤ‘แป™ tแป‡p", + "pageMode": "Chแบฟ ฤ‘แป™ trang", + "howItWorks": "Cรกch hoแบกt ฤ‘แป™ng:", + "fileModeInstructions": [ + "Nhแบฅp vร  kรฉo biแปƒu tฦฐแปฃng ฤ‘แปƒ thay ฤ‘แป•i thแปฉ tแปฑ cรกc tแป‡p.", + "Trong hแป™p \"Trang\" cho mแป—i tแป‡p, bแบกn cรณ thแปƒ chแป‰ ฤ‘แป‹nh phแบกm vi (vรญ dแปฅ: \"1-3, 5\") ฤ‘แปƒ chแป‰ gแป™p nhแปฏng trang ฤ‘รณ.", + "ฤแปƒ trแป‘ng hแป™p \"Trang\" ฤ‘แปƒ bao gแป“m tแบฅt cแบฃ cรกc trang tแปซ tแป‡p ฤ‘รณ." + ], + "pageModeInstructions": [ + "Tแบฅt cแบฃ cรกc trang tแปซ PDF ฤ‘รฃ tแบฃi lรชn cแปงa bแบกn ฤ‘ฦฐแปฃc hiแปƒn thแป‹ bรชn dฦฐแป›i.", + "Chแป‰ cแบงn kรฉo vร  thแบฃ cรกc hรฌnh thu nhแป trang riรชng lแบป ฤ‘แปƒ tแบกo thแปฉ tแปฑ chรญnh xรกc bแบกn muแป‘n cho tแป‡p mแป›i cแปงa mรฌnh." + ], + "mergePdfs": "Gแป™p PDF" + }, + "common": { + "page": "Trang", + "pages": "Trang", + "of": "cแปงa", + "download": "Tแบฃi xuแป‘ng", + "cancel": "Hแปงy", + "save": "Lฦฐu", + "delete": "Xรณa", + "edit": "Chแป‰nh sแปญa", + "add": "Thรชm", + "remove": "Xรณa", + "loading": "ฤang tแบฃi...", + "error": "Lแป—i", + "success": "Thร nh cรดng", + "file": "Tแป‡p", + "files": "Tแป‡p", + "close": "ฤรณng" + }, + "about": { + "hero": { + "title": "Chรบng tรดi tin rแบฑng cรดng cแปฅ PDF nรชn", + "subtitle": "nhanh, riรชng tฦฐ vร  miแป…n phรญ.", + "noCompromises": "Khรดng thแปa hiแป‡p." + }, + "mission": { + "title": "Sแปฉ mแป‡nh cแปงa chรบng tรดi", + "description": "Cung cแบฅp bแป™ cรดng cแปฅ PDF toร n diแป‡n nhแบฅt tรดn trแปng quyแปn riรชng tฦฐ cแปงa bแบกn vร  khรดng bao giแป yรชu cแบงu thanh toรกn. Chรบng tรดi tin rแบฑng cรกc cรดng cแปฅ tร i liแป‡u thiแบฟt yแบฟu nรชn cรณ thแปƒ truy cแบญp ฤ‘ฦฐแปฃc cho mแปi ngฦฐแปi, แปŸ mแปi nฦกi, khรดng cรณ rร o cแบฃn." + }, + "philosophy": { + "label": "Triแบฟt lรฝ cแป‘t lรตi cแปงa chรบng tรดi", + "title": "Quyแปn riรชng tฦฐ trฦฐแป›c tiรชn. Luรดn luรดn.", + "description": "Trong thแปi ฤ‘แบกi mร  dแปฏ liแป‡u lร  hร ng hรณa, chรบng tรดi cรณ cรกch tiแบฟp cแบญn khรกc. Tแบฅt cแบฃ quรก trรฌnh xแปญ lรฝ cho cรกc cรดng cแปฅ Bentopdf diแป…n ra cแปฅc bแป™ trong trรฌnh duyแป‡t cแปงa bแบกn. ฤiแปu nร y cรณ nghฤฉa lร  tแป‡p cแปงa bแบกn khรดng bao giแป chแบกm vร o mรกy chแปง cแปงa chรบng tรดi, chรบng tรดi khรดng bao giแป thแบฅy tร i liแป‡u cแปงa bแบกn vร  chรบng tรดi khรดng theo dรตi nhแปฏng gรฌ bแบกn lร m. Tร i liแป‡u cแปงa bแบกn vแบซn hoร n toร n vร  rรต rร ng lร  riรชng tฦฐ. ฤรณ khรดng chแป‰ lร  mแป™t tรญnh nฤƒng; ฤ‘รณ lร  nแปn tแบฃng cแปงa chรบng tรดi." + }, + "whyBentopdf": { + "title": "Tแบกi sao chแปn", + "speed": { + "title": "ฤฦฐแปฃc xรขy dแปฑng cho tแป‘c ฤ‘แป™", + "description": "Khรดng cแบงn chแป tแบฃi lรชn hoแบทc tแบฃi xuแป‘ng lรชn mรกy chแปง. Bแบฑng cรกch xแปญ lรฝ tแป‡p trแปฑc tiแบฟp trong trรฌnh duyแป‡t cแปงa bแบกn bแบฑng cรดng nghแป‡ web hiแป‡n ฤ‘แบกi nhฦฐ WebAssembly, chรบng tรดi cung cแบฅp tแป‘c ฤ‘แป™ vรด song cho tแบฅt cแบฃ cรกc cรดng cแปฅ cแปงa chรบng tรดi." + }, + "free": { + "title": "Hoร n toร n miแป…n phรญ", + "description": "Khรดng dรนng thแปญ, khรดng ฤ‘ฤƒng kรฝ, khรดng phรญ แบฉn vร  khรดng cรณ tรญnh nฤƒng \"premium\" bแป‹ giแปฏ lแบกi. Chรบng tรดi tin rแบฑng cรกc cรดng cแปฅ PDF mแบกnh mแบฝ nรชn lร  tiแป‡n รญch cรดng cแป™ng, khรดng phแบฃi trung tรขm lแปฃi nhuแบญn." + }, + "noAccount": { + "title": "Khรดng cแบงn tร i khoแบฃn", + "description": "Bแบฏt ฤ‘แบงu sแปญ dแปฅng bแบฅt kแปณ cรดng cแปฅ nร o ngay lแบญp tแปฉc. Chรบng tรดi khรดng cแบงn email, mแบญt khแบฉu hoแบทc bแบฅt kแปณ thรดng tin cรก nhรขn nร o cแปงa bแบกn. Quy trรฌnh lร m viแป‡c cแปงa bแบกn nรชn khรดng ma sรกt vร  แบฉn danh." + }, + "openSource": { + "title": "Tinh thแบงn mรฃ nguแป“n mแปŸ", + "description": "ฤฦฐแปฃc xรขy dแปฑng vแป›i tinh thแบงn minh bแบกch. Chรบng tรดi tแบญn dแปฅng cรกc thฦฐ viแป‡n mรฃ nguแป“n mแปŸ tuyแป‡t vแปi nhฦฐ PDF-lib vร  PDF.js, vร  tin vร o nแป— lแปฑc do cแป™ng ฤ‘แป“ng thรบc ฤ‘แบฉy ฤ‘แปƒ lร m cho cรกc cรดng cแปฅ mแบกnh mแบฝ cรณ thแปƒ truy cแบญp ฤ‘ฦฐแปฃc cho mแปi ngฦฐแปi." + } + }, + "cta": { + "title": "Sแบตn sร ng bแบฏt ฤ‘แบงu?", + "description": "Tham gia cรนng hร ng nghรฌn ngฦฐแปi dรนng tin tฦฐแปŸng Bentopdf cho nhu cแบงu tร i liแป‡u hร ng ngร y cแปงa hแป. Trแบฃi nghiแป‡m sแปฑ khรกc biแป‡t mร  quyแปn riรชng tฦฐ vร  hiแป‡u suแบฅt cรณ thแปƒ tแบกo ra.", + "button": "Khรกm phรก tแบฅt cแบฃ cรดng cแปฅ" + } + }, + "contact": { + "title": "Liรชn hแป‡", + "subtitle": "Chรบng tรดi rแบฅt muแป‘n nghe tแปซ bแบกn. Cho dรน bแบกn cรณ cรขu hแปi, phแบฃn hแป“i hay yรชu cแบงu tรญnh nฤƒng, vui lรฒng ฤ‘แปซng ngแบงn ngแบกi liรชn hแป‡.", + "email": "Bแบกn cรณ thแปƒ liรชn hแป‡ trแปฑc tiแบฟp vแป›i chรบng tรดi qua email tแบกi:" + }, + "licensing": { + "title": "Giแบฅy phรฉp cho", + "subtitle": "Chแปn giแบฅy phรฉp phรน hแปฃp vแป›i nhu cแบงu cแปงa bแบกn." + }, + "multiTool": { + "uploadPdfs": "Tแบฃi lรชn PDF", + "upload": "Tแบฃi lรชn", + "addBlankPage": "Thรชm trang trแป‘ng", + "edit": "Chแป‰nh sแปญa:", + "undo": "Hoร n tรกc", + "redo": "Lร m lแบกi", + "reset": "ฤแบทt lแบกi", + "selection": "Chแปn:", + "selectAll": "Chแปn tแบฅt cแบฃ", + "deselectAll": "Bแป chแปn tแบฅt cแบฃ", + "rotate": "Xoay:", + "rotateLeft": "Trรกi", + "rotateRight": "Phแบฃi", + "transform": "Biแบฟn ฤ‘แป•i:", + "duplicate": "Nhรขn bแบฃn", + "split": "Chia", + "clear": "Xรณa:", + "delete": "Xรณa", + "download": "Tแบฃi xuแป‘ng:", + "downloadSelected": "Tแบฃi xuแป‘ng ฤ‘รฃ chแปn", + "exportPdf": "Xuแบฅt PDF", + "uploadPdfFiles": "Chแปn tแป‡p PDF", + "dragAndDrop": "Kรฉo vร  thแบฃ tแป‡p PDF vร o ฤ‘รขy, hoแบทc nhแบฅp ฤ‘แปƒ chแปn", + "selectFiles": "Chแปn tแป‡p", + "renderingPages": "ฤang kแบฟt xuแบฅt trang...", + "actions": { + "duplicatePage": "Nhรขn bแบฃn trang nร y", + "deletePage": "Xรณa trang nร y", + "insertPdf": "Chรจn PDF sau trang nร y", + "toggleSplit": "Bแบญt/tแบฏt chia sau trang nร y" + }, + "pleaseWait": "Vui lรฒng ฤ‘แปฃi", + "pagesRendering": "Cรกc trang vแบซn ฤ‘ang ฤ‘ฦฐแปฃc kแบฟt xuแบฅt. Vui lรฒng ฤ‘แปฃi...", + "noPagesSelected": "Chฦฐa chแปn trang nร o", + "selectOnePage": "Vui lรฒng chแปn รญt nhแบฅt mแป™t trang ฤ‘แปƒ tแบฃi xuแป‘ng.", + "noPages": "Khรดng cรณ trang", + "noPagesToExport": "Khรดng cรณ trang nร o ฤ‘แปƒ xuแบฅt.", + "renderingTitle": "ฤang kแบฟt xuแบฅt xem trฦฐแป›c trang", + "errorRendering": "Khรดng thแปƒ kแบฟt xuแบฅt hรฌnh thu nhแป trang", + "error": "Lแป—i", + "failedToLoad": "Khรดng thแปƒ tแบฃi" + } +} diff --git a/public/locales/vi/tools.json b/public/locales/vi/tools.json index 21df991..04b37af 100644 --- a/public/locales/vi/tools.json +++ b/public/locales/vi/tools.json @@ -521,5 +521,13 @@ "subtitle": "Chuyแปƒn ฤ‘แป•i tแป‡p email (EML, MSG) sang ฤ‘แป‹nh dแบกng PDF. Hแป— trแปฃ xuแบฅt Outlook vร  ฤ‘แป‹nh dแบกng email tiรชu chuแบฉn.", "acceptedFormats": "Tแป‡p EML, MSG", "convertButton": "Chuyแปƒn ฤ‘แป•i sang PDF" + }, + "fontToOutline": { + "name": "Phรดng chแปฏ thร nh ฤ‘ฦฐแปng viแปn", + "subtitle": "Chuyแปƒn ฤ‘แป•i tแบฅt cแบฃ phรดng chแปฏ thร nh ฤ‘ฦฐแปng viแปn vector ฤ‘แปƒ hiแปƒn thแป‹ nhแบฅt quรกn trรชn mแปi thiแบฟt bแป‹." + }, + "deskewPdf": { + "name": "Chแป‰nh nghiรชng PDF", + "subtitle": "Tแปฑ ฤ‘แป™ng lร m thแบณng cรกc trang quรฉt bแป‹ nghiรชng bแบฑng OpenCV." } } diff --git a/public/locales/zh-TW/common.json b/public/locales/zh-TW/common.json new file mode 100644 index 0000000..2b2b033 --- /dev/null +++ b/public/locales/zh-TW/common.json @@ -0,0 +1,325 @@ +{ + "nav": { + "home": "้ฆ–้ ", + "about": "้—œๆ–ผๆˆ‘ๅ€‘", + "contact": "่ฏ็ตกๆˆ‘ๅ€‘", + "licensing": "็”ขๅ“ๆŽˆๆฌŠ", + "allTools": "ๆ‰€ๆœ‰ๅทฅๅ…ท", + "openMainMenu": "้–‹ๅ•Ÿไธป้ธๅ–ฎ", + "language": "่ชž่จ€" + }, + "donation": { + "message": "ๅ–œๆญก BentoPDF๏ผŸๅนซๅŠฉๆˆ‘ๅ€‘ไฟๆŒๅ…่ฒปๅ’Œ้–‹ๆบ๏ผ", + "button": "ๆ่ดˆ" + }, + "hero": { + "title": "ๅฐˆ็‚บ้šฑ็งๆ‰“้€ ็š„", + "pdfToolkit": "PDF ๅทฅๅ…ท็ฎฑ", + "builtForPrivacy": " ", + "noSignups": "ไธ้ ˆ่จปๅ†Š", + "unlimitedUse": "็„ก้™ไฝฟ็”จ", + "worksOffline": "้›ข็ทšๅฏ็”จ", + "startUsing": "็ซ‹ๅˆป้–‹ๅง‹ไฝฟ็”จ" + }, + "usedBy": { + "title": "่ขซไธ‹ๅˆ—ๅ…ฌๅธๅŠๅ…ถๅ“กๅทฅๆŽก็”จ" + }, + "features": { + "title": "็‚บไฝ•ไฝ ่ฉฒ้ธๆ“‡", + "bentoPdf": "BentoPDF๏ผŸ", + "noSignup": { + "title": "ไธ้ ˆ่จปๅ†Š", + "description": "็ซ‹ๅณๅฏ็”จ๏ผŒไธ้ ˆๅธณ่™Ÿๆˆ–้›ปๅญ้ƒตไปถใ€‚" + }, + "noUploads": { + "title": "ไธ้ ˆไธŠๅ‚ณ", + "description": "ๆ‰€ๆœ‰ๆ–‡ไปถ้ƒฝๅœจ็”จๆˆถ็ซฏ่™•็†๏ผŒๆฐธ้ ไธๆœƒ้›ข้–‹ไฝ ็š„่ฃ็ฝฎใ€‚" + }, + "foreverFree": { + "title": "ๆฐธ้ ๅ…่ฒป", + "description": "ๆ‰€ๆœ‰ๅทฅๅ…ทๅ…่ฒปไฝฟ็”จ๏ผŒๆฒ’ๆœ‰่ฉฆ็”จๆœŸ๏ผŒไนŸๆฒ’ๆœ‰ไป˜่ฒป็‰†ใ€‚" + }, + "noLimits": { + "title": "ๆฒ’ๆœ‰้™ๅˆถ", + "description": "้šจๅฟƒๆ‰€ๆฌฒ็š„ไฝฟ็”จ๏ผŒๆฒ’ๆœ‰ไปปไฝ•้šฑ่—้™ๅˆถใ€‚" + }, + "batchProcessing": { + "title": "ๆ‰น้‡่™•็†", + "description": "ไธ€ๆฌก่™•็†็„ก้™้‡็š„ PDF ๆช”ๆกˆใ€‚" + }, + "lightningFast": { + "title": "ๅฟซๅฆ‚้–ƒ้›ป", + "description": "็žฌ้–“่™•็† PDF๏ผŒ็„ก้ ˆๅฟๅ—ไปปไฝ•็ญ‰ๅพ…ๆˆ–ๅปถ้ฒใ€‚" + } + }, + "tools": { + "title": "้–‹ๅง‹ไฝฟ็”จ", + "toolsLabel": "ๅทฅๅ…ท", + "subtitle": "้ปžๆ“Šไปปๆ„ๅทฅๅ…ทไปฅ้–‹ๅง‹ไธŠๅ‚ณๆช”ๆกˆ", + "searchPlaceholder": "ๆœๅฐ‹ๅทฅๅ…ท๏ผˆไพ‹ๅฆ‚ใ€Œๅˆไฝตใ€ๆˆ–ใ€Œๅˆ†ๅ‰ฒใ€...๏ผ‰", + "backToTools": "่ฟ”ๅ›žๅทฅๅ…ทๅˆ—่กจ", + "firstLoadNotice": "้ฆ–ๆฌก่ผ‰ๅ…ฅ้œ€่ฆไธ€้ปžๆ™‚้–“๏ผŒๅ› ็‚บๆˆ‘ๅ€‘ๆญฃๅœจไธ‹่ผ‰่ฝ‰ๆ›ๅผ•ๆ“Žใ€‚ไน‹ๅพŒๆ‰€ๆœ‰่ผ‰ๅ…ฅๅฐ‡ๅณๆ™‚ๅฎŒๆˆใ€‚" + }, + "upload": { + "clickToSelect": "้ปžๆ“Šไปฅ้ธๆ“‡ๆช”ๆกˆ", + "orDragAndDrop": "ๆˆ–ๅฐ‡ๆช”ๆกˆๆ‹–ๆ”พๅˆฐๆญค่™•", + "pdfOrImages": "PDF ๆˆ–ๅœ–็‰‡", + "filesNeverLeave": "ไฝ ็š„ๆช”ๆกˆๆฐธ้ ไธๆœƒ้›ข้–‹ไฝ ็š„่ฃ็ฝฎใ€‚", + "addMore": "ๆทปๅŠ ๆ›ดๅคšๆช”ๆกˆ", + "clearAll": "ๆธ…้™คๅ…จ้ƒจ", + "clearFiles": "ๆธ…้™คๆช”ๆกˆ" + }, + "loader": { + "processing": "ๆญฃๅœจ่™•็†..." + }, + "alert": { + "title": "ๆ็คบ", + "ok": "็ขบ่ช" + }, + "preview": { + "title": "ๆ–‡ไปถ้ ่ฆฝ", + "downloadAsPdf": "ไธ‹่ผ‰็‚บ PDF", + "close": "้—œ้–‰" + }, + "settings": { + "title": "่จญๅฎš", + "shortcuts": "ๅฟซๆท้ต", + "preferences": "ๅๅฅฝ่จญๅฎš", + "displayPreferences": "้กฏ็คบ่จญๅฎš", + "searchShortcuts": "ๆœๅฐ‹ๅฟซๆท้ต...", + "shortcutsInfo": "ๆŒ‰ไธ‹ไธฆๆŒ‰ไฝๆŒ‰้ตไปฅ่จญๅฎšๅฟซๆท้ตใ€‚่ฎŠๆ›ดๅฐ‡่‡ชๅ‹•ๅ„ฒๅญ˜ใ€‚", + "shortcutsWarning": "โš ๏ธ ้ฟๅ…ไฝฟ็”จ็€่ฆฝๅ™จๅธธ็”จๅฟซๆท้ต๏ผˆCmd/Ctrl+Wใ€Cmd/Ctrl+Tใ€Cmd/Ctrl+N ็ญ‰๏ผ‰๏ผŒๅฎƒๅ€‘ๅฏ่ƒฝ็„กๆณ•็ฉฉๅฎš้‹ไฝœใ€‚", + "import": "ๅŒฏๅ…ฅ", + "export": "ๅŒฏๅ‡บ", + "resetToDefaults": "ๆขๅพฉ้ ่จญๅ€ผ", + "fullWidthMode": "ๅ…จๅฏฌๆจกๅผ", + "fullWidthDescription": "ไฝฟ็”จๅ…จ่žขๅน•ๅฏฌๅบฆ่€Œ้ž็ฝฎไธญๅฎนๅ™จ้กฏ็คบๆ‰€ๆœ‰ๅทฅๅ…ท", + "settingsAutoSaved": "่จญๅฎšๆœƒ่‡ชๅ‹•ๅ„ฒๅญ˜", + "clickToSet": "้ปžๆ“Šไปฅ่จญๅฎš", + "pressKeys": "ๆŒ‰ไธ‹ๆŒ‰้ต...", + "warnings": { + "alreadyInUse": "ๅฟซๆท้ตๅทฒ่ขซๅ ็”จ", + "assignedTo": "ๅทฒ่ขซๆŒ‡ๅฎš็‚บ๏ผš", + "chooseDifferent": "่ซ‹้ธๆ“‡ไธ€ๅ€‹ไธๅŒ็š„ๅฟซๆท้ตใ€‚", + "reserved": "ไฟ็•™ๅฟซๆท้ต่ญฆๅ‘Š", + "commonlyUsed": "ๅธธ่ขซ็”จๆ–ผ๏ผš", + "unreliable": "้€™ๅ€‹ๅฟซๆท้ตๅฏ่ƒฝ่ˆ‡็ณป็ตฑ/็€่ฆฝๅ™จ่กŒ็‚บ่ก็ชๆˆ–็„กๆณ•็ฉฉๅฎš้‹ไฝœใ€‚", + "useAnyway": "ไป่ฆไฝฟ็”จๅ—Ž๏ผŸ", + "resetTitle": "้‡่จญๅฟซๆท้ต", + "resetMessage": "็ขบๅฎš่ฆๅฐ‡ๆ‰€ๆœ‰ๅฟซๆท้ตๆขๅพฉ็‚บ้ ่จญๅ€ผๅ—Ž๏ผŸ

้€™ๅ€‹ๆ“ไฝœ็„กๆณ•่ขซๆ’คๅ›žใ€‚", + "importSuccessTitle": "ๅŒฏๅ…ฅๆˆๅŠŸ", + "importSuccessMessage": "ๅฟซๆท้ตๅŒฏๅ…ฅๆˆๅŠŸ๏ผ", + "importFailTitle": "ๅŒฏๅ…ฅๅคฑๆ•—", + "importFailMessage": "ๅŒฏๅ…ฅๅฟซๆท้ตๅคฑๆ•—ใ€‚็„กๆ•ˆ็š„ๆช”ๆกˆๆ ผๅผใ€‚" + } + }, + "warning": { + "title": "่ญฆๅ‘Š", + "cancel": "ๅ–ๆถˆ", + "proceed": "็นผ็บŒ" + }, + "compliance": { + "title": "ไฝ ็š„่ณ‡ๆ–™ๆฐธ้ ไธๆœƒ้›ข้–‹ไฝ ็š„่ฃ็ฝฎ", + "weKeep": "ๆˆ‘ๅ€‘็ขบไฟ", + "yourInfoSafe": "ไฝ ็š„่ณ‡่จŠๅฎ‰ๅ…จ", + "byFollowingStandards": "้ตๅพชๅ…จ็ƒๅฎ‰ๅ…จๆจ™ๆบ–ใ€‚", + "processingLocal": "ๆ‰€ๆœ‰่™•็†้Ž็จ‹้ƒฝๅœจไฝ ็š„่ฃ็ฝฎไธŠ้€ฒ่กŒใ€‚", + "gdpr": { + "title": "็ฌฆๅˆ GDPR ่ฆ็ฏ„", + "description": "ไฟ่ญทๆญ็›Ÿๅขƒๅ…งๅ€‹ไบบ็š„ๆ•ธๆ“šๅŠ้šฑ็งใ€‚" + }, + "ccpa": { + "title": "็ฌฆๅˆ CCPA ่ฆ็ฏ„", + "description": "่ณฆไบˆๅŠ ๅทžๅฑ…ๆฐ‘ๅฐๅ…ถๅ€‹ไบบ่ณ‡่จŠๅฆ‚ไฝ•่ขซ่’้›†ใ€ไฝฟ็”จๅŠๅˆ†ไบซ็š„ๆฌŠๅˆฉใ€‚" + }, + "hipaa": { + "title": "็ฌฆๅˆ HIPAA ่ฆ็ฏ„", + "description": "ๅˆถๅฎš่™•็†็พŽๅœ‹ๅฅไฟ็ณป็ตฑไธญๆ•ๆ„Ÿๅฅๅบท่ณ‡่จŠ็š„่ฆ็ฏ„ใ€‚" + } + }, + "faq": { + "title": "ๅธธ่ฆ‹", + "questions": "ๅ•้กŒ", + "isFree": { + "question": "BentoPDF ็œŸ็š„ๆ˜ฏๅ…่ฒป็š„ๅ—Ž๏ผŸ", + "answer": "ๆฒ’้Œฏ๏ผŒๅฎŒๅ…จๅ…่ฒปใ€‚BentoPDF ไธŠ็š„ๆ‰€ๆœ‰ๅทฅๅ…ทๅ‡็‚บ 100% ๅ…่ฒปไฝฟ็”จ๏ผŒไธฆไธ”ๆฒ’ๆœ‰ๆช”ๆกˆ้™ๅˆถใ€็„ก้ ˆ่จปๅ†Šไธ”็„กๆตฎๆฐดๅฐใ€‚ๆˆ‘ๅ€‘็›ธไฟกๆฏๅ€‹ไบบ้ƒฝๅ€ผๅพ—ๅ…่ฒปไฝฟ็”จ็ฐกๅ–ฎไธ”ๅผทๅคง็š„ PDF ๅทฅๅ…ทใ€‚" + }, + "areFilesSecure": { + "question": "ๆˆ‘็š„ๆช”ๆกˆ้ƒฝๆ˜ฏๅฎ‰ๅ…จ็š„ๅ—Ž๏ผŸๅฎƒๅ€‘้ƒฝๅœจๅ“ช่ฃก่ขซ่™•็†๏ผŸ", + "answer": "ไฝ ็š„ๆช”ๆกˆ้ƒฝ้žๅธธๅฎ‰ๅ…จ๏ผŒๅ› ็‚บๅฎƒๅ€‘ๅพžๆœช้›ข้–‹ไฝ ็š„้›ป่…ฆใ€‚ๆ‰€ๆœ‰่™•็†้Ž็จ‹้ƒฝ็›ดๆŽฅๅœจไฝ ็š„็ถฒ้ ็€่ฆฝๅ™จไธญ้€ฒ่กŒ๏ผˆ็”จๆˆถ็ซฏ๏ผ‰ใ€‚ๆˆ‘ๅ€‘ๆฐธ้ ไธๆœƒๅฐ‡ไฝ ็š„ๆช”ๆกˆไธŠๅ‚ณๅˆฐไผบๆœๅ™จ๏ผŒๅ› ๆญคไฝ ๅฐไฝ ็š„ๆ–‡ไปถไฟๆœ‰ๅฎŒๅ…จ็š„้šฑ็ง่ˆ‡ๆŽงๅˆถๆฌŠใ€‚" + }, + "platforms": { + "question": "ๆˆ‘่ƒฝๅœจ Macใ€Windows ๅ’Œ่กŒๅ‹•่ฃ็ฝฎไธŠไฝฟ็”จๅ—Ž๏ผŸ", + "answer": "ๅฏไปฅ๏ผ็”ฑๆ–ผ BentoPDF ๅฎŒๅ…จๅœจไฝ ็š„็€่ฆฝๅ™จไธญ้‹ไฝœ๏ผŒๅฎƒๅœจไปปไฝ•ๆœ‰่‘—็พไปฃ็ถฒ้ ็€่ฆฝๅ™จ็š„็ณป็ตฑไธญ้ƒฝ่ƒฝ้‹่กŒ๏ผŒๅŒ…ๅซ Windowsใ€macOSใ€Linuxใ€iOS ๅ’Œ Androidใ€‚" + }, + "gdprCompliant": { + "question": "BentoPDF ็ฌฆๅˆ GDPR ่ฆ็ฏ„ๅ—Ž๏ผŸ", + "answer": "ๆ˜ฏ็š„ใ€‚BentoPDF ๅฎŒๅ…จ็ฌฆๅˆ GDPR ่ฆ็ฏ„ใ€‚็”ฑๆ–ผๆ‰€ๆœ‰ๆช”ๆกˆ่™•็†้ƒฝๅœจไฝ ็š„็€่ฆฝๅ™จๆœฌๅœฐ็™ผ็”Ÿไธ”ๆˆ‘ๅ€‘ๆฐธไธ่’้›†ๆˆ–ๅ‚ณ่ผธไฝ ็š„ๆช”ๆกˆ่‡ณไปปไฝ•ไผบๆœๅ™จ๏ผŒๆˆ‘ๅ€‘็„กๆณ•ๅญ˜ๅ–ไฝ ็š„่ณ‡ๆ–™ใ€‚้€™็ขบไฟไฝ ็š„ๆ–‡ไปถๆฐธ้ ้ƒฝๅœจไฝ ็š„ๆŽงๅˆถไน‹ไธญใ€‚" + }, + "dataStorage": { + "question": "ไฝ ๆœƒไฟๅญ˜ๆˆ–่ฟฝ่นคๆˆ‘็š„ๆช”ๆกˆๅ—Ž๏ผŸ", + "answer": "ไธใ€‚ๆˆ‘ๅ€‘ๆฐธไธๅ„ฒๅญ˜ใ€่ฟฝ่นคๆˆ–่จ˜้Œ„ไฝ ็š„ๆช”ๆกˆใ€‚ไฝ ๅœจ BentoPDF ไธŠ้€ฒ่กŒ็š„ไปปไฝ•ๆ“ไฝœ้ƒฝ็™ผ็”Ÿๅœจไฝ ็š„็€่ฆฝๅ™จ่จ˜ๆ†ถ้ซ”ไธญ๏ผŒไธฆไธ”ๆœƒๅœจไฝ ้—œ้–‰้ ้ขๅพŒ็ซ‹ๅณๆถˆๅคฑใ€‚ๆฒ’ๆœ‰ไธŠๅ‚ณใ€ๆฒ’ๆœ‰ๆญทๅฒ็ด€้Œ„ไธ”็„กไผบๆœๅ™จๅƒ่ˆ‡ใ€‚" + }, + "different": { + "question": "BentoPDF ่ทŸๅ…ถไป–็š„ PDF ๅทฅๅ…ทๆœ‰ไฝ•ไธๅŒไน‹่™•๏ผŸ", + "answer": "ๅคงๅคšๆ•ธ PDF ๅทฅๅ…ท้ƒฝ้€้Žๅฐ‡ไฝ ็š„ๆช”ๆกˆไธŠๅ‚ณ่‡ณไผบๆœๅ™จๅฅฝ้€ฒ่กŒ่™•็†ใ€‚BentoPDF ๆฐธ้ ไธๆœƒ้‚ฃ้บผๅšใ€‚ๆˆ‘ๅ€‘ไฝฟ็”จๅฎ‰ๅ…จไธ”็พไปฃ็š„็ถฒ้ ็ง‘ๆŠ€ไปฅๅœจไฝ ็š„็€่ฆฝๅ™จไธญ็›ดๆŽฅ่™•็†ๆช”ๆกˆใ€‚้€™ๆ„ๅ‘ณ่‘—ๆ›ดๅฟซ็š„ๆ€ง่ƒฝใ€ๆ›ดๅผท็š„้šฑ็ง่ˆ‡ๅฎŒๅ…จ็š„ๅฎ‰ๅฟƒใ€‚" + }, + "browserBased": { + "question": "็€่ฆฝๅ™จ็ซฏ่™•็†ๅฆ‚ไฝ•ไฟ้šœๆˆ‘็š„ๅฎ‰ๅ…จ๏ผŸ", + "answer": "้€้ŽๅฎŒๅ…จๅœจไฝ ็š„็€่ฆฝๅ™จๅ…ง้‹ไฝœ๏ผŒBentoPDF ็ขบไฟไฝ ็š„ๆ–‡ไปถๅพžๆœช้›ข้–‹ไฝ ็š„่ฃ็ฝฎใ€‚้€™ๆถˆ้™คไบ†ไผบๆœๅ™จ้ญ้งญใ€่ณ‡ๆ–™ๅค–ๆดฉ่ˆ‡ๆœชๆŽˆๆฌŠ่จชๅ•็š„้ขจ้šชใ€‚ไฝ ็š„ๆช”ๆกˆๆฐธ้ ้ƒฝๅฑฌๆ–ผไฝ ใ€‚" + }, + "analytics": { + "question": "ไฝ ๆœƒไฝฟ็”จ Cookies ๆˆ–็ถฒ็ซ™ๅˆ†ๆžไพ†่ฟฝ่นคๆˆ‘ๅ—Ž๏ผŸ", + "answer": "ๆˆ‘ๅ€‘ๅœจไนŽไฝ ็š„้šฑ็งใ€‚BentoPDF ไธฆไธ่ฟฝ่นคๅ€‹ไบบ่ณ‡่จŠใ€‚ๆˆ‘ๅ€‘ๅƒ…ไฝฟ็”จ Simple Analytics ไพ†ๆŸฅ็œ‹ๅŒฟๅ่จชๅ•ๆฌกๆ•ธใ€‚้€™ไปฃ่กจๆˆ‘ๅ€‘่ƒฝ็Ÿฅ้“ๆœ‰ๅคšๅฐ‘ไฝฟ็”จ่€…้€ ่จช้Žๆˆ‘ๅ€‘็š„็ถฒ็ซ™๏ผŒไฝ†ๆˆ‘ๅ€‘ๆฐธ้ ้ƒฝไธๆœƒ็Ÿฅ้“ไฝ ๆ˜ฏ่ชฐใ€‚Simple Analytics ๅฎŒๅ…จ็ฌฆๅˆ GDPR ่ฆ็ฏ„ไธ”ๅฐŠ้‡ไฝ ็š„้šฑ็งใ€‚" + } + }, + "testimonials": { + "title": "็œ‹็œ‹ๆˆ‘ๅ€‘็š„", + "users": "ไฝฟ็”จ่€…", + "say": "ๆ€Ž้บผ่ชช" + }, + "support": { + "title": "ๅ–œๆญกๆˆ‘็š„ไฝœๅ“ๅ—Ž๏ผŸ", + "description": "BentoPDF ๆ˜ฏไธ€ๅ€‹ๅ‡บๆ–ผ็†ฑๆƒ…้–‹็™ผ็š„ๅฐˆๆกˆ๏ผŒๆ—จๅœจ็‚บๆฏๅ€‹ไบบๆไพ›ไธ€ๅ€‹ๅ…่ฒปใ€ๆณจ้‡้šฑ็งไธ”ๅผทๅคง็š„ PDF ๅทฅๅ…ท็ต„ใ€‚ๅฆ‚ๆžœๆœ‰ๅนซไธŠไฝ ็š„ๅฟ™๏ผŒ่ซ‹่€ƒๆ…ฎๆ”ฏๆŒๅฎƒ็š„้–‹็™ผใ€‚ๆฏๆฏๅ’–ๅ•ก้ƒฝๆ„็พฉ้‡ๅคง๏ผ", + "buyMeCoffee": "่ฒทๆฏๅ’–ๅ•ก็ตฆๆˆ‘" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDFใ€‚็‰ˆๆฌŠๆ‰€ๆœ‰ใ€‚", + "version": "็‰ˆๆœฌ", + "company": "ๅ…ฌๅธ", + "aboutUs": "้—œๆ–ผๆˆ‘ๅ€‘", + "faqLink": "ๅธธ่ฆ‹ๅ•้กŒ", + "contactUs": "่ฏ็ตกๆˆ‘ๅ€‘", + "legal": "ๆณ•ๅพ‹", + "termsAndConditions": "ๆœๅ‹™ๆขๆฌพ", + "privacyPolicy": "้šฑ็งๆ”ฟ็ญ–", + "followUs": "้—œๆณจๆˆ‘ๅ€‘" + }, + "merge": { + "title": "ๅˆไฝต PDF", + "description": "ๅˆไฝตๆ•ดๅ€‹ๆช”ๆกˆ๏ผŒๆˆ–้ธๆ“‡็‰นๅฎš้ ้ขๅˆไฝต็‚บๆ–ฐๆ–‡ไปถใ€‚", + "fileMode": "ๆช”ๆกˆๆจกๅผ", + "pageMode": "้ ้ขๆจกๅผ", + "howItWorks": "ไฝฟ็”จ่ชชๆ˜Ž๏ผš", + "fileModeInstructions": [ + "้ปžๆ“ŠไธฆๆŠ“ๅ–ๅœ–ๆจ™ไพ†ๆ”น่ฎŠๆช”ๆกˆ้ †ๅบใ€‚", + "ๅœจๆฏๅ€‹ๆ–‡ไปถ็š„ใ€Œ้ ็ขผใ€ๆก†ไธญ๏ผŒไฝ ๅฏไปฅๅƒ…ๆŒ‡ๅฎšๆƒณ่ฆๅˆไฝต็š„้ ้ข็ฏ„ๅœ๏ผˆไพ‹ๅฆ‚ใ€Œ1-3, 5ใ€๏ผ‰ใ€‚", + "ๅฐ‡ใ€Œ้ ็ขผใ€ๆก†็•™็ฉบไปฅๅŒ…ๅซ่ฉฒๆช”ๆกˆ็š„ๆ‰€ๆœ‰้ ้ขใ€‚" + ], + "pageModeInstructions": [ + "ไธ‹ๅˆ—ๆ˜ฏไฝ ไธŠๅ‚ณ็š„ PDF ไธญ็š„ๆ‰€ๆœ‰้ ้ขใ€‚", + "ๅช่ฆๅฐ‡ๅ€‹ๅˆฅ้ ้ข็ธฎๅœ–ๆ‹–ๆ”พๅˆฐๆŒ‡ๅฎšไฝ็ฝฎ๏ผŒๅณๅฏ็‚บๆ–ฐๆช”ๆกˆๅปบ็ซ‹ๆ‚จๆƒณ่ฆ็š„็ฒพ็ขบๆŽ’ๅบใ€‚" + ], + "mergePdfs": "ๅˆไฝต PDF" + }, + "common": { + "page": "้ ", + "pages": "้ ", + "of": " / ", + "download": "ไธ‹่ผ‰", + "cancel": "ๅ–ๆถˆ", + "save": "ๅ„ฒๅญ˜", + "delete": "ๅˆช้™ค", + "edit": "็ทจ่ผฏ", + "add": "ๆทปๅŠ ", + "remove": "็งป้™ค", + "loading": "่ผ‰ๅ…ฅไธญ...", + "error": "้Œฏ่ชค", + "success": "ๆˆๅŠŸ", + "file": "ๆช”ๆกˆ", + "files": "ๆช”ๆกˆ", + "close": "้—œ้–‰" + }, + "about": { + "hero": { + "title": "ๆˆ‘ๅ€‘็›ธไฟก PDF ๅทฅๅ…ทๆ‡‰่ฉฒ", + "subtitle": "ๅฟซ้€Ÿใ€็งๅฏ†ไธ”ๅ…่ฒปใ€‚", + "noCompromises": "็ต•ไธๅฆฅๅ”ใ€‚" + }, + "mission": { + "title": "ๆˆ‘ๅ€‘็š„ไปปๅ‹™", + "description": "ๅœจๅฐŠ้‡ไฝ ็š„้šฑ็งไธ”ๅพžไธ่ฆๆฑ‚ๆ”ถ่ฒป็š„ๅŒๆ™‚ๆไพ›ๆœ€ๅ…จ้ข็š„ PDF ๅทฅๅ…ท็ฎฑใ€‚ๆˆ‘ๅ€‘็›ธไฟกๆ ธๅฟƒๆ–‡ไปถๅทฅๅ…ทๆ‡‰่ฎ“ไปปไฝ•ไบบ้šจๆ™‚้šจๅœฐไธๅ—้™็š„ไฝฟ็”จใ€‚" + }, + "philosophy": { + "label": "ๆˆ‘ๅ€‘็š„ๆ ธๅฟƒ็†ๅฟต", + "title": "ๆฐธ้ ไปฅ้šฑ็ง็‚บ้‡ใ€‚", + "description": "ๅœจๆ•ธๆ“š่ขซๅ•†ๅ“ๅŒ–็š„ๆ™‚ไปฃ๏ผŒๆˆ‘ๅ€‘ๆŽกๅ–ๆˆช็„ถไธๅŒ็š„ๅšๆณ•ใ€‚ๆ‰€ๆœ‰ BentoPDF ๅทฅๅ…ท็š„่™•็†ๆต็จ‹็š†ๅœจไฝ ็š„็€่ฆฝๅ™จๆœฌๅœฐๅฎŒๆˆใ€‚้€™ๆ„ๅ‘ณ่‘—ไฝ ็š„ๆช”ๆกˆ็ต•ไธ่งธๅŠๆˆ‘ๅ€‘็š„ไผบๆœๅ™จ๏ผŒๆˆ‘ๅ€‘ๅพžๆœช็œ‹่ฆ‹ไฝ ็š„ๆ–‡ไปถๅ…งๅฎน๏ผŒๆ›ดไธๆœƒ่ฟฝ่นคไฝ ็š„่กŒ็‚บใ€‚ไฝ ็š„ๆ–‡ไปถๅฐ‡ๅง‹็ต‚ไฟๆŒ็„กๅฏ็ฝฎ็–‘็š„็งๅฏ†ๆ€งใ€‚้€™ไธๅƒ…ๆ˜ฏๅŠŸ่ƒฝ๏ผŒๆ›ดๆ˜ฏๆˆ‘ๅ€‘็š„็ซ‹่บซไน‹ๆœฌใ€‚" + }, + "whyBentopdf": { + "title": "็‚บไฝ•้ธๆ“‡", + "speed": { + "title": "็”Ÿไพ†่ฟ…ๆท", + "description": "็„ก้œ€็ญ‰ๅพ…่ˆ‡ไผบๆœๅ™จ้–“็š„ไธŠๅ‚ณๅ’Œไธ‹่ผ‰ใ€‚้€้Žๅœจไฝ ็š„็€่ฆฝๅ™จไธญไฝฟ็”จ WebAssembly ็ญ‰็พไปฃ็ถฒ่ทฏ็ง‘ๆŠ€่™•็†ๆช”ๆกˆ๏ผŒๆˆ‘ๅ€‘ๅพ—ไปฅ็‚บๆ‰€ๆœ‰ๅทฅๅ…ทๆไพ›็„ก่ˆ‡ๅ€ซๆฏ”็š„้€Ÿๅบฆใ€‚" + }, + "free": { + "title": "ๅฎŒๅ…จๅ…่ฒป", + "description": "ๆฒ’ๆœ‰่ฉฆ็”จๆœŸใ€่จ‚้–ฑใ€้šฑ่—่ฒป็”จ่ˆ‡ๆ‰€่ฌ‚็š„ใ€Œ้ซ˜็ดšใ€ๅŠŸ่ƒฝใ€‚ๆˆ‘ๅ€‘็›ธไฟกๅผทๅคง็š„ PDF ๅทฅๅ…ทๆ‡‰่ฉฒๆ˜ฏไธ€็จฎๅ…ฌๅ…ฑ่จญๆ–ฝ๏ผŒ่€Œ้žไปฅ็‡Ÿๅˆฉ็‚บ้‡ใ€‚" + }, + "noAccount": { + "title": "็„ก้ ˆๅธณ่™Ÿ", + "description": "็ซ‹ๅณ้–‹ๅง‹ไฝฟ็”จไปปไฝ•ๅทฅๅ…ทใ€‚ๆˆ‘ๅ€‘ไธ้œ€่ฆไฝ ็š„้›ปๅญ้ƒตไปถใ€ๅฏ†็ขผๆˆ–ไปปไฝ•ๅ€‹ไบบ่ณ‡่จŠใ€‚ไฝ ็š„ๅทฅไฝœๆต็จ‹ๆ‡‰็•ถๅŒฟๅไธ”ไธๅ—้˜ป็ค™ใ€‚" + }, + "openSource": { + "title": "้–‹ๆบ็ฒพ็ฅž", + "description": "ๅฐ‡้€ๆ˜Žๆ€ง่ฆ–็‚บๆ ธๅฟƒๆ‰“้€ ใ€‚ๆˆ‘ๅ€‘ไฝฟ็”จไบ†ๅฆ‚ PDF-lib ๅ’Œ PDF.js ็ญ‰ๅ„ช็ง€็š„้–‹ๆบๅบซ๏ผŒไธฆไธ”็›ธไฟก็คพ็พค้ฉ…ๅ‹•ๅŠ›่ƒฝ่ฎ“ๅผทๅคง็š„ๅทฅๅ…ทๆƒ ๅŠๆฏไธ€ๅ€‹ไบบใ€‚" + } + }, + "cta": { + "title": "ๆบ–ๅ‚™ๅฅฝ้–‹ๅง‹ไบ†ๅ—Ž๏ผŸ", + "description": "ๅŠ ๅ…ฅๆˆๅƒไธŠ่ฌไฟกไปป BentoPDF ่ƒฝๅ‹ไปปไป–ๅ€‘ๆ—ฅๅธธๆ–‡ไปถ้œ€ๆฑ‚็š„ไฝฟ็”จ่€…ๅ€‘ใ€‚้ซ”้ฉ—้šฑ็ง่ˆ‡ๆ€ง่ƒฝๆ‰€ๅธถไพ†็š„ๅทฎ่ทใ€‚", + "button": "ๆŽข็ดขๆ‰€ๆœ‰ๅทฅๅ…ท" + } + }, + "contact": { + "title": "ไฟๆŒ่ฏ็ตก", + "subtitle": "ๆˆ‘ๅ€‘ๅพˆๆจ‚ๆ„ๆ”ถๅˆฐไฝ ็š„่จŠๆฏใ€‚็„ก่ซ–ไฝ ๆƒณๆๅ‡บ็š„ๆ˜ฏๅ•้กŒใ€ๅ›ž้ฅ‹ๆˆ–ๅŠŸ่ƒฝ่ซ‹ๆฑ‚๏ผŒ้ƒฝ่ซ‹้šจๆ™‚่ฏ็นซๆˆ‘ๅ€‘ใ€‚", + "email": "ไฝ ๅฏไปฅ็›ดๆŽฅ้€้Ž้›ปๅญ้ƒตไปถ่ฏ็นซๆˆ‘ๅ€‘๏ผš" + }, + "licensing": { + "title": "ๆŽˆๆฌŠไฝฟ็”จ", + "subtitle": "้ธๆ“‡้ฉๅˆ้œ€ๆฑ‚็š„็”ขๅ“ๆŽˆๆฌŠใ€‚" + }, + "multiTool": { + "uploadPdfs": "ไธŠๅ‚ณ PDF", + "upload": "ไธŠๅ‚ณ", + "addBlankPage": "ๆทปๅŠ ็ฉบ็™ฝ้ ้ข", + "edit": "็ทจ่ผฏ๏ผš", + "undo": "ๅพฉๅŽŸ", + "redo": "ๅ–ๆถˆๅพฉๅŽŸ", + "reset": "้‡่จญ", + "selection": "้ธๅ–๏ผš", + "selectAll": "้ธๅ–ๅ…จ้ƒจ", + "deselectAll": "ๅ–ๆถˆ้ธๅ–ๅ…จ้ƒจ", + "rotate": "ๆ—‹่ฝ‰๏ผš", + "rotateLeft": "ๅทฆ", + "rotateRight": "ๅณ", + "transform": "่ฎŠๆ›๏ผš", + "duplicate": "่ค‡่ฃฝ", + "split": "ๅˆ†ๅ‰ฒ", + "clear": "ๆธ…้™ค๏ผš", + "delete": "ๅˆช้™ค", + "download": "ไธ‹่ผ‰๏ผš", + "downloadSelected": "ไธ‹่ผ‰้ธๅ–็š„้ …็›ฎ", + "exportPdf": "ๅŒฏๅ‡บ PDF", + "uploadPdfFiles": "้ธๆ“‡ PDF ๆช”ๆกˆ", + "dragAndDrop": "ๆ‹–ๆ”พ PDF ๆช”ๆกˆ่‡ณๆญค่™•๏ผŒๆˆ–ๆ˜ฏ้ปžๆ“Šไปฅ้ธๅ–", + "selectFiles": "้ธๆ“‡ๆช”ๆกˆ", + "renderingPages": "ๆธฒๆŸ“้ ้ข...", + "actions": { + "duplicatePage": "่ค‡่ฃฝๆญค้ ", + "deletePage": "ๅˆช้™คๆญค้ ", + "insertPdf": "ๅœจๆญค้ ๅพŒๆ’ๅ…ฅ PDF", + "toggleSplit": "ๅœจๆญค้ ๅพŒๅˆ‡ๆ›ๅˆ†ๅ‰ฒ" + }, + "pleaseWait": "่ซ‹็จๅพŒ", + "pagesRendering": "ๆญฃๅœจๆธฒๆŸ“้ ้ขใ€‚่ซ‹็จๅพŒ...", + "noPagesSelected": "ๆœช้ธๆ“‡้ ้ข", + "selectOnePage": "่ซ‹่‡ณๅฐ‘้ธๆ“‡ไธ€้ ไปฅ้–‹ๅง‹ไธ‹่ผ‰ใ€‚", + "noPages": "็„ก้ ้ข", + "noPagesToExport": "็„กๅฏๅŒฏๅ‡บ็š„้ ้ขใ€‚", + "renderingTitle": "ๆญฃๅœจๆธฒๆŸ“้ ้ข้ ่ฆฝ", + "errorRendering": "็„กๆณ•ๆธฒๆŸ“้ ้ข็ธฎๅœ–", + "error": "้Œฏ่ชค", + "failedToLoad": "่ผ‰ๅ…ฅๅคฑๆ•—" + } +} diff --git a/public/locales/zh-TW/tools.json b/public/locales/zh-TW/tools.json new file mode 100644 index 0000000..6ef2fe0 --- /dev/null +++ b/public/locales/zh-TW/tools.json @@ -0,0 +1,511 @@ +{ + "categories": { + "popularTools": "็†ฑ้–€ๅทฅๅ…ท", + "editAnnotate": "็ทจ่ผฏ่ˆ‡่จป่งฃ", + "convertToPdf": "่ฝ‰ๆ›็‚บ PDF", + "convertFromPdf": "ๅพž PDF ่ฝ‰ๆ›", + "organizeManage": "็ต„็น”่ˆ‡็ฎก็†", + "optimizeRepair": "ๅ„ชๅŒ–่ˆ‡ไฟฎๅพฉ", + "securePdf": "ๅฎ‰ๅ…จ PDF" + }, + "pdfMultiTool": { + "name": "PDF ๅคšๅŠŸ่ƒฝๅทฅๅ…ท", + "subtitle": "ๅœจ็ตฑไธ€็š„้ ้ขไธญๅˆไฝตใ€ๅˆ†ๅ‰ฒใ€็ต„็น”ใ€ๅˆช้™คใ€ๆ—‹่ฝ‰ใ€ๆทปๅŠ ็ฉบ็™ฝ้ ้ขใ€ๆๅ–่ˆ‡่ค‡่ฃฝใ€‚" + }, + "mergePdf": { + "name": "ๅˆไฝต PDF", + "subtitle": "ๅฐ‡ๅคšๅ€‹ PDF ๅˆไฝต็‚บไธ€ๅ€‹ๆช”ๆกˆใ€‚ไฟ็•™ๆ›ธ็ฑคใ€‚" + }, + "splitPdf": { + "name": "ๅˆ†ๅ‰ฒ PDF", + "subtitle": "ๅฐ‡ๆŒ‡ๅฎš็ฏ„ๅœ็š„้ ้ขๆๅ–็‚บๆ–ฐ็š„ PDFใ€‚" + }, + "compressPdf": { + "name": "ๅฃ“็ธฎ PDF", + "subtitle": "้™ไฝŽไฝ ็š„ PDF ๆช”ๆกˆๅคงๅฐใ€‚" + }, + "pdfEditor": { + "name": "PDF ็ทจ่ผฏๅ™จ", + "subtitle": "่จป่งฃใ€่žขๅ…‰ใ€ๅก—้ป‘ใ€่ฉ•่ซ–ใ€ๆทปๅŠ ๅœ–ๅฝขๆˆ–ๅœ–็‰‡ใ€ๆœๅฐ‹่ˆ‡ๆŸฅ็œ‹ PDFใ€‚" + }, + "jpgToPdf": { + "name": "JPG ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต JPG ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "signPdf": { + "name": "็ฐฝ็ฝฒ PDF", + "subtitle": "็นช่ฃฝใ€่ผธๅ…ฅๆˆ–ไธŠๅ‚ณไฝ ็š„็ฐฝๅใ€‚" + }, + "cropPdf": { + "name": "่ฃๅˆ‡ PDF", + "subtitle": "ไฟฎๅ‰ชไฝ ็š„ PDF ไธญๆ‰€ๆœ‰้ ้ข็š„้‚Š็•Œใ€‚" + }, + "extractPages": { + "name": "ๆๅ–้ ้ข", + "subtitle": "ๅฐ‡้ธๅ–็š„้ ้ขไฟๅญ˜็‚บๆ–ฐ็š„ๆช”ๆกˆใ€‚" + }, + "duplicateOrganize": { + "name": "่ค‡่ฃฝ่ˆ‡็ต„็น”", + "subtitle": "่ค‡่ฃฝใ€้‡ๆ–ฐๆŽ’ๅบ่ˆ‡ๅˆช้™ค้ ้ขใ€‚" + }, + "deletePages": { + "name": "ๅˆช้™ค้ ้ข", + "subtitle": "็งป้™คไฝ ็š„ๆ–‡ไปถไธญ็š„็‰นๅฎš้ ้ขใ€‚" + }, + "editBookmarks": { + "name": "็ทจ่ผฏๆ›ธ็ฑค", + "subtitle": "ๆทปๅŠ ใ€็ทจ่ผฏใ€ๅŒฏๅ…ฅใ€ๅˆช้™ค่ˆ‡ๆๅ– PDF ๆ›ธ็ฑคใ€‚" + }, + "tableOfContents": { + "name": "็›ฎ้Œ„", + "subtitle": "ๅพž PDF ๆ›ธ็ฑค็”Ÿๆˆ็›ฎ้Œ„้ ใ€‚" + }, + "pageNumbers": { + "name": "้ ็ขผ", + "subtitle": "ๅœจไฝ ็š„ๆ–‡ไปถไธญๆ’ๅ…ฅ้ ็ขผใ€‚" + }, + "addWatermark": { + "name": "ๆทปๅŠ ๆตฎๆฐดๅฐ", + "subtitle": "ๅœจไฝ ็š„ PDF ้ ้ขไธŠๅฃ“ๅฐๆ–‡ๅญ—ๆˆ–ๅœ–็‰‡ใ€‚" + }, + "headerFooter": { + "name": "้ ้ฆ–่ˆ‡้ ๅฐพ", + "subtitle": "ๅœจ้ ้ข็š„้ ‚้ƒจ่ˆ‡ๅบ•้ƒจๆ–ฐๅขžๆ–‡ๅญ—ใ€‚" + }, + "invertColors": { + "name": "ๅ่ฝ‰้ก่‰ฒ", + "subtitle": "็‚บไฝ ็š„ PDF ๅปบ็ซ‹ๆทฑ่‰ฒ็‰ˆๆœฌใ€‚" + }, + "backgroundColor": { + "name": "่ƒŒๆ™ฏ้ก่‰ฒ", + "subtitle": "ๆ›ดๆ”นไฝ ็š„ PDF ็š„่ƒŒๆ™ฏ้ก่‰ฒใ€‚" + }, + "changeTextColor": { + "name": "ๆ›ดๆ”นๆ–‡ๅญ—้ก่‰ฒ", + "subtitle": "ๆ›ดๆ”นไฝ ็š„ PDF ไธญ็š„ๆ–‡ๅญ—้ก่‰ฒใ€‚" + }, + "addStamps": { + "name": "ๆทปๅŠ ๅฐ็ซ ", + "subtitle": "ไฝฟ็”จ่จป่งฃๅทฅๅ…ทๅˆ—ๅœจไฝ ็š„ PDF ไธญๆทปๅŠ ๅœ–็‰‡ๅฐ็ซ ใ€‚", + "usernameLabel": "ๅฐ็ซ ไฝฟ็”จ่€…ๅ็จฑ", + "usernamePlaceholder": "่ผธๅ…ฅไฝ ็š„ๅ็จฑ๏ผˆๅฐ็ซ ็”จ๏ผ‰", + "usernameHint": "่ฉฒๅ็จฑๆœƒๅ‡บ็พๅœจไฝ ๅปบ็ซ‹็š„ๅฐ็ซ ไธŠใ€‚" + }, + "removeAnnotations": { + "name": "็งป้™ค่จป่งฃ", + "subtitle": "ๅŽป้™ค็•™่จ€ใ€่žขๅ…‰่ˆ‡้€ฃ็ตใ€‚" + }, + "pdfFormFiller": { + "name": "PDF ่กจๅ–ฎๅกซๅฏซๅ™จ", + "subtitle": "็›ดๆŽฅๅœจไฝ ็š„็€่ฆฝๅ™จไธญๅกซๅฏซ่กจๅ–ฎใ€‚ๆ”ฏๆด XFA ่กจๅ–ฎใ€‚" + }, + "createPdfForm": { + "name": "ๅปบ็ซ‹ PDF ่กจๅ–ฎ", + "subtitle": "้€้Žๆ‹–ๆ”พๆ–‡ๅญ—ๆก†ๅปบ็ซ‹ๅฏๅกซๅฏซ็š„ PDF ่กจๅ–ฎใ€‚" + }, + "removeBlankPages": { + "name": "็งป้™ค็ฉบ็™ฝ้ ้ข", + "subtitle": "่‡ชๅ‹•ๅตๆธฌไธฆๅˆช้™ค็ฉบ็™ฝ้ ้ขใ€‚" + }, + "imageToPdf": { + "name": "ๅœ–็‰‡่ฝ‰ PDF", + "subtitle": "ๅฐ‡ JPGใ€PNGใ€WebPใ€BMPใ€TIFFใ€SVG ่ˆ‡ HEIC ่ฝ‰ๆ›็‚บ PDFใ€‚" + }, + "pngToPdf": { + "name": "PNG ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต PNG ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "webpToPdf": { + "name": "WebP ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต WebP ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "svgToPdf": { + "name": "SVG ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต SVG ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "bmpToPdf": { + "name": "BMP ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต BMP ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "heicToPdf": { + "name": "HEIC ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต HEIC ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "tiffToPdf": { + "name": "TIFF ่ฝ‰ PDF", + "subtitle": "ๅพžไธ€ๅผตๆˆ–ๅคšๅผต TIFF ๅœ–็‰‡ๅปบ็ซ‹ PDFใ€‚" + }, + "textToPdf": { + "name": "Text ่ฝ‰ PDF", + "subtitle": "ๅฐ‡็ด”ๆ–‡ๅญ—ๆช”ๆกˆ่ฝ‰ๆ›็‚บ PDFใ€‚" + }, + "jsonToPdf": { + "name": "JSON ่ฝ‰ PDF", + "subtitle": "ๅฐ‡ JSON ๆช”ๆกˆ่ฝ‰ๆ›็‚บ PDF ๆ ผๅผใ€‚" + }, + "pdfToJpg": { + "name": "PDF ่ฝ‰ JPG", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ้ ้ข่ฝ‰ๆ›็‚บ JPG ๅœ–็‰‡ใ€‚" + }, + "pdfToPng": { + "name": "PDF ่ฝ‰ PNG", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ้ ้ข่ฝ‰ๆ›็‚บ PNG ๅœ–็‰‡ใ€‚" + }, + "pdfToWebp": { + "name": "PDF ่ฝ‰ WebP", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ้ ้ข่ฝ‰ๆ›็‚บ WebP ๅœ–็‰‡ใ€‚" + }, + "pdfToBmp": { + "name": "PDF ่ฝ‰ BMP", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ้ ้ข่ฝ‰ๆ›็‚บ BMP ๅœ–็‰‡ใ€‚" + }, + "pdfToTiff": { + "name": "PDF ่ฝ‰ TIFF", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ้ ้ข่ฝ‰ๆ›็‚บ TIFF ๅœ–็‰‡ใ€‚" + }, + "pdfToGreyscale": { + "name": "PDF ่ฝ‰็ฐ้šŽ", + "subtitle": "ๅฐ‡ๆ‰€ๆœ‰้ก่‰ฒ่ฝ‰ๆ›็‚บ้ป‘็™ฝใ€‚" + }, + "pdfToJson": { + "name": "PDF ่ฝ‰ JSON", + "subtitle": "ๅฐ‡ PDF ๆช”ๆกˆ่ฝ‰ๆ›็‚บ JSON ๆ ผๅผใ€‚" + }, + "ocrPdf": { + "name": "OCR PDF", + "subtitle": "ไฝฟ PDF ๅฏๆœๅฐ‹ไธ”ๅฏ่ค‡่ฃฝใ€‚" + }, + "alternateMix": { + "name": "ไบค้Œฏๆททๅˆ้ ้ข", + "subtitle": "ๅฐ‡ๆฏๅ€‹ PDF ็š„้ ้ขไบค้Œฏๅˆไฝตใ€‚ไฟ็•™ๆ›ธ็ฑคใ€‚" + }, + "addAttachments": { + "name": "ๆทปๅŠ ้™„ไปถ", + "subtitle": "ๅตŒๅ…ฅไธ€ๅ€‹ๆˆ–ๅคšๅ€‹ๆช”ๆกˆ่‡ณไฝ ็š„ PDF ไธญใ€‚" + }, + "extractAttachments": { + "name": "ๆๅ–้™„ไปถ", + "subtitle": "ๅพž PDF ไธญๆๅ–ๆ‰€ๆœ‰ๅตŒๅ…ฅ็š„ๆช”ๆกˆ็‚บ ZIPใ€‚" + }, + "editAttachments": { + "name": "็ทจ่ผฏ้™„ไปถ", + "subtitle": "ๆŸฅ็œ‹ๆˆ–็งป้™คไฝ ็š„ PDF ไธญ็š„้™„ไปถใ€‚" + }, + "dividePages": { + "name": "ๅˆ†ๅ‰ฒ้ ้ข", + "subtitle": "ๅž‚็›ดๆˆ–ๆฐดๅนณๅˆ†ๅ‰ฒ้ ้ขใ€‚" + }, + "addBlankPage": { + "name": "ๆทปๅŠ ็ฉบ็™ฝ้ ้ข", + "subtitle": "ๅœจไฝ ็š„ PDF ไธญ็š„ไปปไธ€ไฝ็ฝฎๆ’ๅ…ฅ็ฉบ็™ฝ้ ้ขใ€‚" + }, + "reversePages": { + "name": "ๅ่ฝ‰้ ้ข", + "subtitle": "ๅ่ฝ‰ไฝ ็š„ๆ–‡ไปถไธญๆ‰€ๆœ‰้ ้ข็š„้ †ๅบใ€‚" + }, + "rotatePdf": { + "name": "ๆ—‹่ฝ‰ PDF", + "subtitle": "ไปฅ 90 ๅบฆๅขž้‡ๆ—‹่ฝ‰้ ้ขใ€‚" + }, + "nUpPdf": { + "name": "N-Up PDF", + "subtitle": "ๅฐ‡ๅคšๅ€‹้ ้ขๆŽ’ๅˆ—ๅœจๅ–ฎๅผต็ด™ไธŠใ€‚" + }, + "combineToSinglePage": { + "name": "ๅˆไฝต็‚บๅ–ฎไธ€้ ้ข", + "subtitle": "ๅฐ‡ๆ‰€ๆœ‰้ ้ข็ธซๅˆ็‚บไธ€ๅ€‹ๅ–ฎไธ€ไธ”้€ฃ็บŒ็š„ๆปพๅ‹•้ ้ขใ€‚" + }, + "viewMetadata": { + "name": "ๆŸฅ็œ‹ๅ…ƒ่ณ‡ๆ–™", + "subtitle": "ๆชข่ฆ–ไฝ ็š„ PDF ไธญ็š„้šฑ่—ๅฑฌๆ€งใ€‚" + }, + "editMetadata": { + "name": "็ทจ่ผฏๅ…ƒ่ณ‡ๆ–™", + "subtitle": "ๆ›ดๆ”นไฝœ่€…ใ€ๆจ™้กŒๅ’Œๅ…ถไป–ๅฑฌๆ€งใ€‚" + }, + "pdfsToZip": { + "name": "PDF ่ฝ‰ ZIP", + "subtitle": "ๅฐ‡ๅคšๅ€‹ PDF ๆช”ๆกˆๆ‰“ๅŒ…็‚บ ZIP ๅฃ“็ธฎๆช”ใ€‚" + }, + "comparePdfs": { + "name": "ๆฏ”่ผƒ PDF", + "subtitle": "ไธฆๆŽ’ๆฏ”่ผƒๅ…ฉๅ€‹ PDFใ€‚" + }, + "posterizePdf": { + "name": "ๆตทๅ ฑๅŒ– PDF", + "subtitle": "ๅฐ‡ๅคง้ ้ขๅˆ†ๅ‰ฒ็‚บๅคšๅ€‹่ผƒๅฐ็š„้ ้ขใ€‚" + }, + "fixPageSize": { + "name": "ไฟฎๅพฉ้ ้ขๅคงๅฐ", + "subtitle": "ๅฐ‡ๆ‰€ๆœ‰้ ้ขๆจ™ๆบ–ๅŒ–็‚บ็ตฑไธ€ๅฐบๅฏธใ€‚" + }, + "linearizePdf": { + "name": "็ทšๆ€งๅŒ– PDF", + "subtitle": "็‚บๅฟซ้€Ÿ็ถฒ้ ็€่ฆฝๅ„ชๅŒ– PDFใ€‚" + }, + "pageDimensions": { + "name": "้ ้ขๅฐบๅฏธ", + "subtitle": "ๅˆ†ๆž้ ้ขๅคงๅฐใ€ๆ–นๅ‘ๅ’Œๅ–ฎไฝใ€‚" + }, + "removeRestrictions": { + "name": "็งป้™ค้™ๅˆถ", + "subtitle": "็งป้™ค่ˆ‡ๆ•ธไฝ็ฐฝๅ็š„ PDF ๆช”ๆกˆ็›ธ้—œ็š„ๅฏ†็ขผไฟ่ญท่ˆ‡ๅฎ‰ๅ…จ้™ๅˆถใ€‚" + }, + "repairPdf": { + "name": "ไฟฎๅพฉ PDF", + "subtitle": "ๅพžๅ—ๆ็š„ PDF ๆช”ๆกˆไธญๅพฉๅŽŸ่ณ‡ๆ–™ใ€‚" + }, + "encryptPdf": { + "name": "ๅŠ ๅฏ† PDF", + "subtitle": "้€้ŽๆทปๅŠ ๅฏ†็ขผ็‚บไฝ ็š„ PDF ไธŠ้Ž–ใ€‚" + }, + "sanitizePdf": { + "name": "ๆธ…็† PDF", + "subtitle": "็งป้™คๅ…ƒ่ณ‡ๆ–™ใ€่จป่งฃใ€่…ณๆœฌ่ˆ‡ๅ…ถไป–่ณ‡ๆ–™ใ€‚" + }, + "decryptPdf": { + "name": "่งฃๅฏ† PDF", + "subtitle": "้€้Ž็งป้™คๅฏ†็ขผไฟ่ญท่งฃ้Ž– PDFใ€‚" + }, + "flattenPdf": { + "name": "ๅนณ้ขๅŒ– PDF", + "subtitle": "ไฝฟ่กจๅ–ฎๆฌ„ไฝๅ’Œ่จป่งฃไธๅฏ็ทจ่ผฏใ€‚" + }, + "removeMetadata": { + "name": "็งป้™คๅ…ƒ่ณ‡ๆ–™", + "subtitle": "้™คๅŽปไฝ ็š„ PDF ไธญ็š„้šฑ่—่ณ‡ๆ–™ใ€‚" + }, + "changePermissions": { + "name": "ๆ›ดๆ”นๆฌŠ้™", + "subtitle": "่จญๅฎšๆˆ–่ฎŠๆ›ด PDF ไธŠ็š„ไฝฟ็”จ่€…ๆฌŠ้™ใ€‚" + }, + "emailToPdf": { + "name": "Email ่ฝ‰ PDF", + "subtitle": "ๅฐ‡้›ปๅญ้ƒตไปถๆช”ๆกˆ (EML, MSG) ่ฝ‰ๆ›็‚บ PDF ๆ ผๅผใ€‚ๆ”ฏๆด Outlook ๅŒฏๅ‡บๅ’Œๆจ™ๆบ–้›ปๅญ้ƒตไปถๆ ผๅผใ€‚", + "acceptedFormats": "EML, MSG ๆช”ๆกˆ", + "convertButton": "่ฝ‰ๆ›็‚บ PDF" + }, + "fontToOutline": { + "name": "ๅญ—ๅž‹่ฝ‰ๅค–ๆก†", + "subtitle": "ๅฐ‡ๆ‰€ๆœ‰ๅญ—ๅž‹่ฝ‰ๆ›็‚บๅ‘้‡ๅค–ๆก†๏ผŒ็ขบไฟๅœจๆ‰€ๆœ‰่ฃ็ฝฎไธŠๅ‘ˆ็พไธ€่‡ดใ€‚" + }, + "deskewPdf": { + "name": "PDF ๆญชๆ–œไฟฎๆญฃ", + "subtitle": "ไฝฟ็”จ OpenCV ่‡ชๅ‹•่ชฟๆญฃๅ‚พๆ–œ็š„ๆŽƒๆ้ ้ขใ€‚" + }, + "rotateCustom": { + "name": "Rotate by Custom Degrees", + "subtitle": "Rotate pages by any custom angle." + }, + "odtToPdf": { + "name": "ODT to PDF", + "subtitle": "Convert OpenDocument Text files to PDF format. Supports multiple files.", + "acceptedFormats": "ODT files", + "convertButton": "Convert to PDF" + }, + "csvToPdf": { + "name": "CSV to PDF", + "subtitle": "Convert CSV spreadsheet files to PDF format. Supports multiple files.", + "acceptedFormats": "CSV files", + "convertButton": "Convert to PDF" + }, + "rtfToPdf": { + "name": "RTF to PDF", + "subtitle": "Convert Rich Text Format documents to PDF. Supports multiple files.", + "acceptedFormats": "RTF files", + "convertButton": "Convert to PDF" + }, + "wordToPdf": { + "name": "Word to PDF", + "subtitle": "Convert Word documents (DOCX, DOC, ODT, RTF) to PDF format. Supports multiple files.", + "acceptedFormats": "DOCX, DOC, ODT, RTF files", + "convertButton": "Convert to PDF" + }, + "excelToPdf": { + "name": "Excel to PDF", + "subtitle": "Convert Excel spreadsheets (XLSX, XLS, ODS, CSV) to PDF format. Supports multiple files.", + "acceptedFormats": "XLSX, XLS, ODS, CSV files", + "convertButton": "Convert to PDF" + }, + "powerpointToPdf": { + "name": "PowerPoint to PDF", + "subtitle": "Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF format. Supports multiple files.", + "acceptedFormats": "PPTX, PPT, ODP files", + "convertButton": "Convert to PDF" + }, + "markdownToPdf": { + "name": "Markdown to PDF", + "subtitle": "Write or paste Markdown and export it as a beautifully formatted PDF.", + "paneMarkdown": "Markdown", + "panePreview": "Preview", + "btnUpload": "Upload", + "btnSyncScroll": "Sync Scroll", + "btnSettings": "Settings", + "btnExportPdf": "Export PDF", + "settingsTitle": "Markdown Settings", + "settingsPreset": "Preset", + "presetDefault": "Default (GFM-like)", + "presetCommonmark": "CommonMark (strict)", + "presetZero": "Minimal (no features)", + "settingsOptions": "Markdown Options", + "optAllowHtml": "Allow HTML tags", + "optBreaks": "Convert newlines to
", + "optLinkify": "Auto-convert URLs to links", + "optTypographer": "Typographer (smart quotes, etc.)" + }, + "pdfBooklet": { + "name": "PDF Booklet", + "subtitle": "Rearrange pages for double-sided booklet printing. Fold and staple to create a booklet.", + "howItWorks": "How it works:", + "step1": "Upload a PDF file.", + "step2": "Pages will be rearranged in booklet order.", + "step3": "Print double-sided, flip on short edge, fold and staple.", + "paperSize": "Paper Size", + "orientation": "Orientation", + "portrait": "Portrait", + "landscape": "Landscape", + "pagesPerSheet": "Pages per Sheet", + "createBooklet": "Create Booklet", + "processing": "Processing...", + "pageCount": "Page count will be padded to multiple of 4 if needed." + }, + "xpsToPdf": { + "name": "XPS to PDF", + "subtitle": "Convert XPS/OXPS documents to PDF format. Supports multiple files.", + "acceptedFormats": "XPS, OXPS files", + "convertButton": "Convert to PDF" + }, + "mobiToPdf": { + "name": "MOBI to PDF", + "subtitle": "Convert MOBI e-books to PDF format. Supports multiple files.", + "acceptedFormats": "MOBI files", + "convertButton": "Convert to PDF" + }, + "epubToPdf": { + "name": "EPUB to PDF", + "subtitle": "Convert EPUB e-books to PDF format. Supports multiple files.", + "acceptedFormats": "EPUB files", + "convertButton": "Convert to PDF" + }, + "fb2ToPdf": { + "name": "FB2 to PDF", + "subtitle": "Convert FictionBook (FB2) e-books to PDF format. Supports multiple files.", + "acceptedFormats": "FB2 files", + "convertButton": "Convert to PDF" + }, + "cbzToPdf": { + "name": "CBZ to PDF", + "subtitle": "Convert comic book archives (CBZ/CBR) to PDF format. Supports multiple files.", + "acceptedFormats": "CBZ, CBR files", + "convertButton": "Convert to PDF" + }, + "wpdToPdf": { + "name": "WPD to PDF", + "subtitle": "Convert WordPerfect documents (WPD) to PDF format. Supports multiple files.", + "acceptedFormats": "WPD files", + "convertButton": "Convert to PDF" + }, + "wpsToPdf": { + "name": "WPS to PDF", + "subtitle": "Convert WPS Office documents to PDF format. Supports multiple files.", + "acceptedFormats": "WPS files", + "convertButton": "Convert to PDF" + }, + "xmlToPdf": { + "name": "XML to PDF", + "subtitle": "Convert XML documents to PDF format. Supports multiple files.", + "acceptedFormats": "XML files", + "convertButton": "Convert to PDF" + }, + "pagesToPdf": { + "name": "Pages to PDF", + "subtitle": "Convert Apple Pages documents to PDF format. Supports multiple files.", + "acceptedFormats": "Pages files", + "convertButton": "Convert to PDF" + }, + "odgToPdf": { + "name": "ODG to PDF", + "subtitle": "Convert OpenDocument Graphics (ODG) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODG files", + "convertButton": "Convert to PDF" + }, + "odsToPdf": { + "name": "ODS to PDF", + "subtitle": "Convert OpenDocument Spreadsheet (ODS) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODS files", + "convertButton": "Convert to PDF" + }, + "odpToPdf": { + "name": "ODP to PDF", + "subtitle": "Convert OpenDocument Presentation (ODP) files to PDF format. Supports multiple files.", + "acceptedFormats": "ODP files", + "convertButton": "Convert to PDF" + }, + "pubToPdf": { + "name": "PUB to PDF", + "subtitle": "Convert Microsoft Publisher (PUB) files to PDF format. Supports multiple files.", + "acceptedFormats": "PUB files", + "convertButton": "Convert to PDF" + }, + "vsdToPdf": { + "name": "VSD to PDF", + "subtitle": "Convert Microsoft Visio (VSD, VSDX) files to PDF format. Supports multiple files.", + "acceptedFormats": "VSD, VSDX files", + "convertButton": "Convert to PDF" + }, + "psdToPdf": { + "name": "PSD to PDF", + "subtitle": "Convert Adobe Photoshop (PSD) files to PDF format. Supports multiple files.", + "acceptedFormats": "PSD files", + "convertButton": "Convert to PDF" + }, + "pdfToSvg": { + "name": "PDF to SVG", + "subtitle": "Convert each page of a PDF file into a scalable vector graphic (SVG) for perfect quality at any size." + }, + "extractTables": { + "name": "Extract PDF Tables", + "subtitle": "Extract tables from PDF files and export as CSV, JSON, or Markdown." + }, + "pdfToCsv": { + "name": "PDF to CSV", + "subtitle": "Extract tables from PDF and convert to CSV format." + }, + "pdfToExcel": { + "name": "PDF to Excel", + "subtitle": "Extract tables from PDF and convert to Excel (XLSX) format." + }, + "pdfToText": { + "name": "PDF to Text", + "subtitle": "Extract text from PDF files and save as plain text (.txt). Supports multiple files.", + "note": "This tool works ONLY with digitally created PDFs. For scanned documents or image-based PDFs, use our OCR PDF tool instead.", + "convertButton": "Extract Text" + }, + "digitalSignPdf": { + "name": "Digital Signature PDF", + "pageTitle": "Digital Signature PDF - Add Cryptographic Signature | BentoPDF", + "subtitle": "Add a cryptographic digital signature to your PDF using X.509 certificates. Supports PKCS#12 (.pfx, .p12) and PEM formats. Your private key never leaves your browser.", + "certificateSection": "Certificate", + "uploadCert": "Upload certificate (.pfx, .p12)", + "certPassword": "Certificate Password", + "certPasswordPlaceholder": "Enter certificate password", + "certInfo": "Certificate Information", + "certSubject": "Subject", + "certIssuer": "Issuer", + "certValidity": "Valid", + "signatureDetails": "Signature Details (Optional)", + "reason": "Reason", + "reasonPlaceholder": "e.g., I approve this document", + "location": "Location", + "locationPlaceholder": "e.g., New York, USA", + "contactInfo": "Contact Info", + "contactPlaceholder": "e.g., email@example.com", + "applySignature": "Apply Digital Signature", + "successMessage": "PDF signed successfully! The signature can be verified in any PDF reader." + }, + "validateSignaturePdf": { + "name": "Validate PDF Signature", + "pageTitle": "Validate PDF Signature - Verify Digital Signatures | BentoPDF", + "subtitle": "Verify digital signatures in your PDF files. Check certificate validity, view signer details, and confirm document integrity. All processing happens in your browser." + } +} diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 7bdfffa..be7e069 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -1,319 +1,325 @@ { - "nav": { - "home": "้ฆ–้กต", - "about": "ๅ…ณไบŽๆˆ‘ไปฌ", - "contact": "่”็ณปๆˆ‘ไปฌ", - "licensing": "่ฎธๅฏ", - "allTools": "ๆ‰€ๆœ‰ๅทฅๅ…ท", - "openMainMenu": "ๆ‰“ๅผ€ไธป่œๅ•", - "language": "่ฏญ่จ€" + "nav": { + "home": "้ฆ–้กต", + "about": "ๅ…ณไบŽๆˆ‘ไปฌ", + "contact": "่”็ณปๆˆ‘ไปฌ", + "licensing": "่ฎธๅฏ", + "allTools": "ๆ‰€ๆœ‰ๅทฅๅ…ท", + "openMainMenu": "ๆ‰“ๅผ€ไธป่œๅ•", + "language": "่ฏญ่จ€" + }, + "donation": { + "message": "ๅ–œๆฌข BentoPDF๏ผŸๅธฎๅŠฉๆˆ‘ไปฌไฟๆŒๅ…่ดนๅ’Œๅผ€ๆบ๏ผ", + "button": "ๆ่ต " + }, + "hero": { + "title": "ไธ“ไธบ้š็งๆ‰“้€ ็š„", + "pdfToolkit": "PDF ๅทฅๅ…ท็ฎฑ", + "builtForPrivacy": " ", + "noSignups": "ๆ— ้œ€ๆณจๅ†Œ", + "unlimitedUse": "ๆ— ้™ไฝฟ็”จ", + "worksOffline": "็ฆป็บฟๅฏ็”จ", + "startUsing": "็ซ‹ๅณๅผ€ๅง‹" + }, + "usedBy": { + "title": "่ขซไผ—ๅคšๅ…ฌๅธๅ’Œไธชไบบไฟก่ต–๏ผŒๅŒ…ๆ‹ฌ" + }, + "features": { + "title": "ไธบไป€ไนˆ้€‰ๆ‹ฉ", + "bentoPdf": "BentoPDF?", + "noSignup": { + "title": "ๆ— ้œ€ๆณจๅ†Œ", + "description": "ๅณๅˆปๅผ€ๅง‹๏ผŒๆ— ้œ€่ดฆๆˆทๆˆ–็”ตๅญ้‚ฎไปถใ€‚" }, - "hero": { - "title": "ไธ“ไธบ้š็งๆ‰“้€ ็š„", - "pdfToolkit": "PDF ๅทฅๅ…ท็ฎฑ", - "builtForPrivacy": " ", - "noSignups": "ๆ— ้œ€ๆณจๅ†Œ", - "unlimitedUse": "ๆ— ้™ไฝฟ็”จ", - "worksOffline": "็ฆป็บฟๅฏ็”จ", - "startUsing": "็ซ‹ๅณๅผ€ๅง‹" + "noUploads": { + "title": "ๆ— ้œ€ไธŠไผ ", + "description": "100% ๅฎขๆˆท็ซฏๅค„็†๏ผŒๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚" }, - "usedBy": { - "title": "่ขซไผ—ๅคšๅ…ฌๅธๅ’Œไธชไบบไฟก่ต–๏ผŒๅŒ…ๆ‹ฌ" + "foreverFree": { + "title": "ๆฐธไน…ๅ…่ดน", + "description": "ๆ‰€ๆœ‰ๅทฅๅ…ทๅ…่ดน๏ผŒๆ— ่ฏ•็”จๆœŸ๏ผŒๆ— ไป˜่ดนๅข™ใ€‚" }, - "features": { - "title": "ไธบไป€ไนˆ้€‰ๆ‹ฉ", - "bentoPdf": "BentoPDF?", - "noSignup": { - "title": "ๆ— ้œ€ๆณจๅ†Œ", - "description": "ๅณๅˆปๅผ€ๅง‹๏ผŒๆ— ้œ€่ดฆๆˆทๆˆ–็”ตๅญ้‚ฎไปถใ€‚" - }, - "noUploads": { - "title": "ๆ— ้œ€ไธŠไผ ", - "description": "100% ๅฎขๆˆท็ซฏๅค„็†๏ผŒๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚" - }, - "foreverFree": { - "title": "ๆฐธไน…ๅ…่ดน", - "description": "ๆ‰€ๆœ‰ๅทฅๅ…ทๅ…่ดน๏ผŒๆ— ่ฏ•็”จๆœŸ๏ผŒๆ— ไป˜่ดนๅข™ใ€‚" - }, - "noLimits": { - "title": "ๆ— ้™ๅˆถ", - "description": "้šๅฟƒไฝฟ็”จ๏ผŒๆ— ไปปไฝ•้šๅฝข้™ๅˆถใ€‚" - }, - "batchProcessing": { - "title": "ๆ‰น้‡ๅค„็†", - "description": "ไธ€ๆฌกๅค„็†ๆ— ้™ๆ•ฐ้‡็š„ PDF ๆ–‡ไปถใ€‚" - }, - "lightningFast": { - "title": "ๆž้€Ÿๅค„็†", - "description": "็žฌ้—ดๅค„็† PDF, ๆ— ้œ€็ญ‰ๅพ…ใ€‚" - } + "noLimits": { + "title": "ๆ— ้™ๅˆถ", + "description": "้šๅฟƒไฝฟ็”จ๏ผŒๆ— ไปปไฝ•้šๅฝข้™ๅˆถใ€‚" }, - "tools": { - "title": "ๅผ€ๅง‹ไฝฟ็”จ", - "toolsLabel": "ๅทฅๅ…ท", - "subtitle": "็‚นๅ‡ปๅทฅๅ…ทไปฅๆ‰“ๅผ€ๆ–‡ไปถไธŠไผ ", - "searchPlaceholder": "ๆœ็ดขๅทฅๅ…ท (ไพ‹ๅฆ‚ 'ๅˆๅนถ', 'ๅˆ†ๅ‰ฒ'...)", - "backToTools": "่ฟ”ๅ›žๅทฅๅ…ทๅˆ—่กจ", - "firstLoadNotice": "้ฆ–ๆฌกๅŠ ่ฝฝ้œ€่ฆไธ€็‚นๆ—ถ้—ด๏ผŒๅ› ไธบๆˆ‘ไปฌๆญฃๅœจไธ‹่ฝฝ่ฝฌๆขๅผ•ๆ“Žใ€‚ไน‹ๅŽๆ‰€ๆœ‰ๅŠ ่ฝฝๅฐ†ๅณๆ—ถๅฎŒๆˆใ€‚" + "batchProcessing": { + "title": "ๆ‰น้‡ๅค„็†", + "description": "ไธ€ๆฌกๅค„็†ๆ— ้™ๆ•ฐ้‡็š„ PDF ๆ–‡ไปถใ€‚" }, - "upload": { - "clickToSelect": "็‚นๅ‡ป้€‰ๆ‹ฉๆ–‡ไปถ", - "orDragAndDrop": "ๆˆ–ๅฐ†ๆ–‡ไปถๆ‹–ๆ”พๅˆฐๆญคๅค„", - "pdfOrImages": "PDF ๆˆ–ๅ›พ็‰‡", - "filesNeverLeave": "ๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚", - "addMore": "ๆทปๅŠ ๆ›ดๅคšๆ–‡ไปถ", - "clearAll": "ๆธ…็ฉบๆ‰€ๆœ‰" - }, - "loader": { - "processing": "ๅค„็†ไธญ..." - }, - "alert": { - "title": "ๆ็คบ", - "ok": "็กฎๅฎš" - }, - "preview": { - "title": "ๆ–‡ๆกฃ้ข„่งˆ", - "downloadAsPdf": "ไธ‹่ฝฝ PDF", - "close": "ๅ…ณ้—ญ" - }, - "settings": { - "title": "่ฎพ็ฝฎ", - "shortcuts": "ๅฟซๆท้”ฎ", - "preferences": "ๅๅฅฝ่ฎพ็ฝฎ", - "displayPreferences": "ๆ˜พ็คบ่ฎพ็ฝฎ", - "searchShortcuts": "ๆœ็ดขๅฟซๆท้”ฎ...", - "shortcutsInfo": "ๆŒ‰ไธ‹ๅนถๆŒ‰ไฝๆŒ‰้”ฎไปฅ่ฎพ็ฝฎๅฟซๆท้”ฎใ€‚ๆ›ดๆ”นๅฐ†่‡ชๅŠจไฟๅญ˜ใ€‚", - "shortcutsWarning": "โš ๏ธ ้ฟๅ…ไฝฟ็”จ้€š็”จ็š„ๆต่งˆๅ™จๅฟซๆท้”ฎ (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N ็ญ‰)๏ผŒๅ› ไธบๅฎƒไปฌๅฏ่ƒฝๆ— ๆณ•็จณๅฎšๅทฅไฝœใ€‚", - "import": "ๅฏผๅ…ฅ", - "export": "ๅฏผๅ‡บ", - "resetToDefaults": "ๆขๅค้ป˜่ฎค", - "fullWidthMode": "ๅ…จๅฎฝๆจกๅผ", - "fullWidthDescription": "ไฝฟ็”จๅ…จๅฑๅฎฝๅบฆๅฑ•็คบๆ‰€ๆœ‰ๅทฅๅ…ท๏ผŒ่€Œ้žๅฑ…ไธญๆ˜พ็คบ", - "settingsAutoSaved": "่ฎพ็ฝฎๅทฒ่‡ชๅŠจไฟๅญ˜", - "clickToSet": "็‚นๅ‡ป่ฎพ็ฝฎ", - "pressKeys": "ๆŒ‰ไธ‹ๆŒ‰้”ฎ...", - "warnings": { - "alreadyInUse": "ๅฟซๆท้”ฎๅทฒ่ขซไฝฟ็”จ", - "assignedTo": "ๅทฒๅˆ†้…็ป™๏ผš", - "chooseDifferent": "่ฏท้€‰ๆ‹ฉๅ…ถไป–ๅฟซๆท้”ฎใ€‚", - "reserved": "ไฟ็•™ๅฟซๆท้”ฎ่ญฆๅ‘Š", - "commonlyUsed": "้€šๅธธ็”จไบŽ๏ผš", - "unreliable": "ๆญคๅฟซๆท้”ฎๅฏ่ƒฝๆ— ๆณ•็จณๅฎšๅทฅไฝœ๏ผŒๆˆ–ไธŽๆต่งˆๅ™จ/็ณป็ปŸๅฟซๆท้”ฎๅ†ฒ็ชใ€‚", - "useAnyway": "ไป่ฆไฝฟ็”จๅ—๏ผŸ", - "resetTitle": "้‡็ฝฎๅฟซๆท้”ฎ", - "resetMessage": "็กฎๅฎš่ฆๅฐ†ๆ‰€ๆœ‰ๅฟซๆท้”ฎ้‡็ฝฎไธบ้ป˜่ฎคๅ€ผๅ—๏ผŸ

ๆญคๆ“ไฝœๆ— ๆณ•ๆ’ค้”€ใ€‚", - "importSuccessTitle": "ๅฏผๅ…ฅๆˆๅŠŸ", - "importSuccessMessage": "ๅฟซๆท้”ฎๅฏผๅ…ฅๆˆๅŠŸ๏ผ", - "importFailTitle": "ๅฏผๅ…ฅๅคฑ่ดฅ", - "importFailMessage": "ๅฏผๅ…ฅๅฟซๆท้”ฎๅคฑ่ดฅใ€‚ๆ–‡ไปถๆ ผๅผๆ— ๆ•ˆใ€‚" - } - }, - "warning": { - "title": "่ญฆๅ‘Š", - "cancel": "ๅ–ๆถˆ", - "proceed": "็ปง็ปญ" - }, - "compliance": { - "title": "ๆ‚จ็š„ๆ•ฐๆฎไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡", - "weKeep": "ๆˆ‘ไปฌไผšไฟๆŒ", - "yourInfoSafe": "ๆ‚จ็š„ไฟกๆฏๅฎ‰ๅ…จ", - "byFollowingStandards": "๏ผŒ้ตๅพชๅ…จ็ƒๅฎ‰ๅ…จๆ ‡ๅ‡†ใ€‚", - "processingLocal": "ๆ‰€ๆœ‰ๅค„็†้ƒฝๅœจๆ‚จ็š„่ฎพๅค‡ไธŠๆœฌๅœฐ่ฟ›่กŒใ€‚", - "gdpr": { - "title": "GDPR ๅˆ่ง„", - "description": "ไฟๆŠคๆฌง็›Ÿๅขƒๅ†…ไธชไบบ็š„ไธชไบบๆ•ฐๆฎๅ’Œ้š็งใ€‚" - }, - "ccpa": { - "title": "CCPA ๅˆ่ง„", - "description": "่ต‹ไบˆๅŠ ๅทžๅฑ…ๆฐ‘ๅฏนๅ…ถไธชไบบไฟกๆฏ็š„ๆ”ถ้›†ใ€ไฝฟ็”จๅ’Œๅ…ฑไบซ็š„ๆƒๅˆฉใ€‚" - }, - "hipaa": { - "title": "HIPAA ๅˆ่ง„", - "description": "ๅˆถๅฎš็พŽๅ›ฝๅŒป็–—็ณป็ปŸไธญๅค„็†ๆ•ๆ„Ÿๅฅๅบทไฟกๆฏ็š„ไฟ้šœๆŽชๆ–ฝใ€‚" - } - }, - "faq": { - "title": "ๅธธ่ง", - "questions": "้—ฎ้ข˜", - "isFree": { - "question": "BentoPDF ็œŸ็š„ๅ…่ดนๅ—๏ผŸ", - "answer": "ๆ˜ฏ็š„๏ผŒๅฎŒๅ…จๅ…่ดนใ€‚BentoPDF ไธŠ็š„ๆ‰€ๆœ‰ๅทฅๅ…ทๅ‡ๅฏ 100% ๅ…่ดนไฝฟ็”จ๏ผŒๆฒกๆœ‰ๆ–‡ไปถ้™ๅˆถ๏ผŒๆ— ้œ€ๆณจๅ†Œ๏ผŒไนŸๆฒกๆœ‰ๆฐดๅฐใ€‚ๆˆ‘ไปฌ็›ธไฟกๆฏไธชไบบ้ƒฝๅบ”่ฏฅ่ƒฝๅคŸไฝฟ็”จ็ฎ€ๅ•ใ€ๅผบๅคง็š„ PDF ๅทฅๅ…ท๏ผŒ่€Œๆ— ้œ€้€š่ฟ‡ไป˜่ดนๅข™ใ€‚" - }, - "areFilesSecure": { - "question": "ๆˆ‘็š„ๆ–‡ไปถๅฎ‰ๅ…จๅ—๏ผŸๅฎƒไปฌๅœจๅ“ช้‡Œๅค„็†๏ผŸ", - "answer": "ๆ‚จ็š„ๆ–‡ไปถ้žๅธธๅฎ‰ๅ…จ๏ผŒๅ› ไธบๅฎƒไปฌไปŽๆœช็ฆปๅผ€ๆ‚จ็š„็”ต่„‘ใ€‚ๆ‰€ๆœ‰ๅค„็†้ƒฝ็›ดๆŽฅๅœจๆ‚จ็š„็ฝ‘็ปœๆต่งˆๅ™จ๏ผˆๅฎขๆˆท็ซฏ๏ผ‰ไธญ่ฟ›่กŒใ€‚ๆˆ‘ไปฌไปŽไธๅฐ†ๆ‚จ็š„ๆ–‡ไปถไธŠไผ ๅˆฐๆœๅŠกๅ™จ๏ผŒๅ› ๆญคๆ‚จๅฏไปฅๅฏนๆ–‡ๆกฃไฟๆŒๅฎŒๅ…จ็š„้š็งๅ’ŒๆŽงๅˆถใ€‚" - }, - "platforms": { - "question": "ๅฎƒ้€‚็”จไบŽ Macใ€Windows ๅ’Œๆ‰‹ๆœบๅ—๏ผŸ", - "answer": "ๆ˜ฏ็š„๏ผ็”ฑไบŽ BentoPDF ๅฎŒๅ…จๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญ่ฟ่กŒ๏ผŒๅ› ๆญคๅฎƒ้€‚็”จไบŽไปปไฝ•ๅธฆๆœ‰็Žฐไปฃ็ฝ‘็ปœๆต่งˆๅ™จ็š„ๆ“ไฝœ็ณป็ปŸ๏ผŒๅŒ…ๆ‹ฌ Windowsใ€macOSใ€Linuxใ€iOS ๅ’Œ Androidใ€‚" - }, - "gdprCompliant": { - "question": "BentoPDF ็ฌฆๅˆ GDPR ๅ—๏ผŸ", - "answer": "ๆ˜ฏ็š„ใ€‚BentoPDF ๅฎŒๅ…จ็ฌฆๅˆ GDPRใ€‚็”ฑไบŽๆ‰€ๆœ‰ๆ–‡ไปถๅค„็†้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๆœฌๅœฐ่ฟ›่กŒ๏ผŒๅนถไธ”ๆˆ‘ไปฌไปŽไธๆ”ถ้›†ๆˆ–ๅฐ†ๆ‚จ็š„ๆ–‡ไปถไผ ่พ“ๅˆฐไปปไฝ•ๆœๅŠกๅ™จ๏ผŒๅ› ๆญคๆˆ‘ไปฌๆ— ๆณ•่ฎฟ้—ฎๆ‚จ็š„ๆ•ฐๆฎใ€‚่ฟ™็กฎไฟๆ‚จๅง‹็ปˆๆŽŒๆŽงๆ‚จ็š„ๆ–‡ๆกฃใ€‚" - }, - "dataStorage": { - "question": "ไฝ ไปฌไผšๅญ˜ๅ‚จๆˆ–่ทŸ่ธชๆˆ‘็š„ไปปไฝ•ๆ–‡ไปถๅ—๏ผŸ", - "answer": "ไธใ€‚ๆˆ‘ไปฌไปŽไธๅญ˜ๅ‚จใ€่ทŸ่ธชๆˆ–่ฎฐๅฝ•ๆ‚จ็š„ๆ–‡ไปถใ€‚ๆ‚จๅœจ BentoPDF ไธŠๆ‰€ๅš็š„ๆ‰€ๆœ‰ๆ“ไฝœ้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จๅ†…ๅญ˜ไธญ่ฟ›่กŒ๏ผŒๅนถๅœจๆ‚จๅ…ณ้—ญ้กต้ขๅŽๆถˆๅคฑใ€‚ๆฒกๆœ‰ไธŠไผ ๏ผŒๆฒกๆœ‰ๅކๅฒ่ฎฐๅฝ•๏ผŒไนŸๆฒกๆœ‰ๆถ‰ๅŠๆœๅŠกๅ™จใ€‚" - }, - "different": { - "question": "BentoPDF ไธŽๅ…ถไป– PDF ๅทฅๅ…ทๆœ‰ไฝ•ไธๅŒ๏ผŸ", - "answer": "ๅคงๅคšๆ•ฐ PDF ๅทฅๅ…ทๅฐ†ๆ‚จ็š„ๆ–‡ไปถไธŠไผ ๅˆฐๆœๅŠกๅ™จ่ฟ›่กŒๅค„็†ใ€‚BentoPDF ไปŽไธ่ฟ™ๆ ทๅšใ€‚ๆˆ‘ไปฌไฝฟ็”จๅฎ‰ๅ…จใ€็Žฐไปฃ็š„็ฝ‘็ปœๆŠ€ๆœฏ็›ดๆŽฅๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๅค„็†ๆ‚จ็š„ๆ–‡ไปถใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆ›ดๅฟซ็š„ๆ€ง่ƒฝใ€ๆ›ดๅผบ็š„้š็งๅ’ŒๅฎŒๅ…จ็š„ๅฎ‰ๅฟƒใ€‚" - }, - "browserBased": { - "question": "ๅŸบไบŽๆต่งˆๅ™จ็š„ๅค„็†ๅฆ‚ไฝ•ไฟๆŠคๆˆ‘็š„ๅฎ‰ๅ…จ๏ผŸ", - "answer": "้€š่ฟ‡ๅฎŒๅ…จๅœจๆ‚จ็š„ๆต่งˆๅ™จๅ†…้ƒจ่ฟ่กŒ๏ผŒBentoPDF ็กฎไฟๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚่ฟ™ๆถˆ้™คไบ†ๆœๅŠกๅ™จ้ป‘ๅฎขๆ”ปๅ‡ปใ€ๆ•ฐๆฎๆณ„้œฒๆˆ–ๆœช็ปๆŽˆๆƒ่ฎฟ้—ฎ็š„้ฃŽ้™ฉใ€‚ๆ‚จ็š„ๆ–‡ไปถๅง‹็ปˆๅฑžไบŽๆ‚จใ€‚" - }, - "analytics": { - "question": "ไฝ ไปฌไฝฟ็”จ Cookie ๆˆ–ๅˆ†ๆžๆฅ่ทŸ่ธชๆˆ‘ๅ—๏ผŸ", - "answer": "ๆˆ‘ไปฌๅ…ณๅฟƒๆ‚จ็š„้š็งใ€‚BentoPDF ไธไผš่ทŸ่ธชไธชไบบไฟกๆฏใ€‚ๆˆ‘ไปฌไป…ไฝฟ็”จ Simple Analytics ๆŸฅ็œ‹ๅŒฟๅ่ฎฟ้—ฎ่ฎกๆ•ฐใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆˆ‘ไปฌๅฏไปฅ็Ÿฅ้“ๆœ‰ๅคšๅฐ‘็”จๆˆท่ฎฟ้—ฎๆˆ‘ไปฌ็š„็ฝ‘็ซ™๏ผŒไฝ†ๆˆ‘ไปฌๆฐธ่ฟœไธ็Ÿฅ้“ๆ‚จๆ˜ฏ่ฐใ€‚Simple Analytics ๅฎŒๅ…จ็ฌฆๅˆ GDPR ๅนถๅฐŠ้‡ๆ‚จ็š„้š็งใ€‚" - } - }, - "testimonials": { - "title": "ๆˆ‘ไปฌ็š„", - "users": "็”จๆˆท", - "say": "่ฏ„ไปท" - }, - "support": { - "title": "ๅ–œๆฌข่ฟ™ไธช้กน็›ฎ๏ผŸ", - "description": "BentoPDF ๆ˜ฏไธ€ไธชๅ……ๆปกๆฟ€ๆƒ…็š„้กน็›ฎ๏ผŒๆ—จๅœจไธบๆฏไธชไบบๆไพ›ๅ…่ดนใ€็งๅฏ†ไธ”ๅผบๅคง็š„ PDF ๅทฅๅ…ท็ฎฑใ€‚ๅฆ‚ๆžœๆ‚จ่ง‰ๅพ—ๅฎƒๆœ‰็”จ๏ผŒ่ฏท่€ƒ่™‘ๆ”ฏๆŒๅฎƒ็š„ๅผ€ๅ‘ใ€‚ๆฏไธ€ๆฏๅ’–ๅ•ก้ƒฝๆ˜ฏ่Žซๅคง็š„ๆ”ฏๆŒ๏ผ", - "buyMeCoffee": "่ฏทๆˆ‘ๅ–ๆฏๅ’–ๅ•ก" - }, - "footer": { - "copyright": "ยฉ 2025 BentoPDF. ไฟ็•™ๆ‰€ๆœ‰ๆƒๅˆฉใ€‚", - "version": "็‰ˆๆœฌ", - "company": "ๅ…ฌๅธ", - "aboutUs": "ๅ…ณไบŽๆˆ‘ไปฌ", - "faqLink": "ๅธธ่ง้—ฎ้ข˜", - "contactUs": "่”็ณปๆˆ‘ไปฌ", - "legal": "ๆณ•ๅพ‹", - "termsAndConditions": "ๆœๅŠกๆกๆฌพ", - "privacyPolicy": "้š็งๆ”ฟ็ญ–", - "followUs": "ๅ…ณๆณจๆˆ‘ไปฌ" - }, - "merge": { - "title": "ๅˆๅนถ PDF", - "description": "ๅˆๅนถๆ•ดไธชๆ–‡ไปถ๏ผŒๆˆ–้€‰ๆ‹ฉ็‰นๅฎš้กต้ขๅˆๅนถๅˆฐๆ–ฐๆ–‡ๆกฃไธญใ€‚", - "fileMode": "ๆ–‡ไปถๆจกๅผ", - "pageMode": "้กต้ขๆจกๅผ", - "howItWorks": "ไฝฟ็”จ่ฏดๆ˜Ž๏ผš", - "fileModeInstructions": [ - "็‚นๅ‡ปๅนถๆ‹–ๅŠจๅ›พๆ ‡ไปฅๆ›ดๆ”นๆ–‡ไปถ็š„้กบๅบใ€‚", - "ๅœจๆฏไธชๆ–‡ไปถ็š„ '้กต็ ' ๆก†ไธญ๏ผŒๆ‚จๅฏไปฅๆŒ‡ๅฎš่Œƒๅ›ด๏ผˆไพ‹ๅฆ‚ '1-3, 5'๏ผ‰ไปฅไป…ๅˆๅนถ่ฟ™ไบ›้กต้ขใ€‚", - "ๅฐ† '้กต็ ' ๆก†็•™็ฉบไปฅๅŒ…ๅซ่ฏฅๆ–‡ไปถ็š„ๆ‰€ๆœ‰้กต้ขใ€‚" - ], - "pageModeInstructions": [ - "ๆ‚จไธŠไผ ็š„ PDF ็š„ๆ‰€ๆœ‰้กต้ขๆ˜พ็คบๅœจไธ‹ๆ–นใ€‚", - "ๅช้œ€ๆ‹–ๆ”พๅ•ไธช้กต้ข็ผฉ็•ฅๅ›พ๏ผŒๅณๅฏไธบๆ‚จๆ–ฐๆ–‡ไปถๅฏน้กต้ข่ฟ›่กŒๆŽ’ๅบใ€‚" - ], - "mergePdfs": "ๅˆๅนถ PDF" - }, - "common": { - "page": "้กต", - "pages": "้กต", - "of": " / ", - "download": "ไธ‹่ฝฝ", - "cancel": "ๅ–ๆถˆ", - "save": "ไฟๅญ˜", - "delete": "ๅˆ ้™ค", - "edit": "็ผ–่พ‘", - "add": "ๆทปๅŠ ", - "remove": "็งป้™ค", - "loading": "ๅŠ ่ฝฝไธญ...", - "error": "้”™่ฏฏ", - "success": "ๆˆๅŠŸ", - "file": "ๆ–‡ไปถ", - "files": "ๆ–‡ไปถ" - }, - "about": { - "hero": { - "title": "ๆˆ‘ไปฌ็›ธไฟก PDF ๅทฅๅ…ทๅบ”่ฏฅๆ˜ฏ", - "subtitle": "ๅฟซ้€Ÿใ€็งๅฏ†ไธ”ๅ…่ดน็š„ใ€‚", - "noCompromises": "็ปไธๅฆฅๅใ€‚" - }, - "mission": { - "title": "ๆˆ‘ไปฌ็š„ไฝฟๅ‘ฝ", - "description": "ๆไพ›ๆœ€ๅ…จ้ข็š„ PDF ๅทฅๅ…ท็ฎฑ๏ผŒๅฐŠ้‡ๆ‚จ็š„้š็ง๏ผŒไธ”ๆฐธไธๆ”ถ่ดนใ€‚ๆˆ‘ไปฌ็›ธไฟกๅŸบๆœฌ็š„ๆ–‡ๆกฃๅทฅๅ…ทๅบ”่ฏฅๅฏนๆ‰€ๆœ‰ไบบใ€ๅœจไปปไฝ•ๅœฐๆ–น้ƒฝ่งฆๆ‰‹ๅฏๅŠ๏ผŒๆฒกๆœ‰ไปปไฝ•้šœ็ขใ€‚" - }, - "philosophy": { - "label": "ๆˆ‘ไปฌ็š„ๆ ธๅฟƒ็†ๅฟต", - "title": "้š็ง่‡ณไธŠใ€‚ๅง‹็ปˆๅฆ‚ไธ€ใ€‚", - "description": "ๅœจๆ•ฐๆฎ่ขซๅ•†ๅ“ๅŒ–็š„ๆ—ถไปฃ๏ผŒๆˆ‘ไปฌ้‡‡ๅ–ไธๅŒ็š„ๆ–นๅผใ€‚BentoPDF ๅทฅๅ…ท็š„ๆ‰€ๆœ‰ๅค„็†้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จๆœฌๅœฐ่ฟ›่กŒใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆ‚จ็š„ๆ–‡ไปถไปŽๆœชๆŽฅ่งฆๆˆ‘ไปฌ็š„ๆœๅŠกๅ™จ๏ผŒๆˆ‘ไปฌไปŽไธๆŸฅ็œ‹ๆ‚จ็š„ๆ–‡ๆกฃ๏ผŒไนŸไธ่ทŸ่ธชๆ‚จ็š„ๆ“ไฝœใ€‚ๆ‚จ็š„ๆ–‡ๆกฃไฟๆŒ็ปๅฏน็š„็งๅฏ†ๆ€งใ€‚่ฟ™ไธไป…ๆ˜ฏไธ€้กนๅŠŸ่ƒฝ๏ผ›่ฟ™ๆ˜ฏๆˆ‘ไปฌ็š„ๅŸบ็Ÿณใ€‚" - }, - "whyBentopdf": { - "title": "ไธบไป€ไนˆ้€‰ๆ‹ฉ", - "speed": { - "title": "ไธบ้€Ÿๅบฆ่€Œ็”Ÿ", - "description": "ๆ— ้œ€็ญ‰ๅพ…ไธŠไผ ๆˆ–ไปŽๆœๅŠกๅ™จไธ‹่ฝฝใ€‚้€š่ฟ‡ไฝฟ็”จ WebAssembly ็ญ‰็Žฐไปฃ็ฝ‘็ปœๆŠ€ๆœฏ็›ดๆŽฅๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๅค„็†ๆ–‡ไปถ๏ผŒๆˆ‘ไปฌไธบๆ‰€ๆœ‰ๅทฅๅ…ทๆไพ›ไบ†ๆ— ไธŽไผฆๆฏ”็š„้€Ÿๅบฆใ€‚" - }, - "free": { - "title": "ๅฎŒๅ…จๅ…่ดน", - "description": "ๆ— ่ฏ•็”จ๏ผŒๆ— ่ฎข้˜…๏ผŒๆ— ้š่—่ดน็”จ๏ผŒไนŸๆฒกๆœ‰่ขซ้”ๅฎš็š„ '้ซ˜็บง' ๅŠŸ่ƒฝใ€‚ๆˆ‘ไปฌ็›ธไฟกๅผบๅคง็š„ PDF ๅทฅๅ…ทๅบ”่ฏฅๆ˜ฏไธ€็งๅ…ฌๅ…ฑ่ฎพๆ–ฝ๏ผŒ่€Œไธๆ˜ฏ็›ˆๅˆฉไธญๅฟƒใ€‚" - }, - "noAccount": { - "title": "ๆ— ้œ€่ดฆๆˆท", - "description": "็ซ‹ๅณๅผ€ๅง‹ไฝฟ็”จไปปไฝ•ๅทฅๅ…ทใ€‚ๆˆ‘ไปฌไธ้œ€่ฆๆ‚จ็š„็”ตๅญ้‚ฎไปถใ€ๅฏ†็ ๆˆ–ไปปไฝ•ไธชไบบไฟกๆฏใ€‚ๆ‚จ็š„ๅทฅไฝœๆต็จ‹ๅบ”่ฏฅๆ˜ฏๆ— ๆ‘ฉๆ“ฆไธ”ๅŒฟๅ็š„ใ€‚" - }, - "openSource": { - "title": "ๅผ€ๆบ็ฒพ็ฅž", - "description": "ไปฅ้€ๆ˜Žๅบฆไธบๆ ธๅฟƒๆž„ๅปบใ€‚ๆˆ‘ไปฌๅˆฉ็”จไบ†ๅƒ PDF-lib ๅ’Œ PDF.js ่ฟ™ๆ ทไผ˜็ง€็š„ๅผ€ๆบๅบ“๏ผŒๅนถ็›ธไฟก็คพๅŒบ้ฉฑๅŠจ็š„ๅŠ›้‡่ƒฝไฝฟๅผบๅคง็š„ๅทฅๅ…ทๆƒ ๅŠๆฏไธ€ไธชไบบใ€‚" - } - }, - "cta": { - "title": "ๅ‡†ๅค‡ๅฅฝๅผ€ๅง‹ไบ†ๅ—๏ผŸ", - "description": "ๅŠ ๅ…ฅๆˆๅƒไธŠไธ‡ไฟกไปป BentoPDF ๆปก่ถณๆ—ฅๅธธๆ–‡ๆกฃ้œ€ๆฑ‚็š„็”จๆˆทใ€‚ไฝ“้ชŒ้š็งๅ’Œๆ€ง่ƒฝๅธฆๆฅ็š„ไธๅŒใ€‚", - "button": "ๆŽข็ดขๆ‰€ๆœ‰ๅทฅๅ…ท" - } - }, - "contact": { - "title": "่”็ณปๆˆ‘ไปฌ", - "subtitle": "ๆˆ‘ไปฌๅพˆไนๆ„ๅฌๅˆฐๆ‚จ็š„ๅฃฐ้Ÿณใ€‚ๆ— ่ฎบๆ‚จๆœ‰้—ฎ้ข˜ใ€ๅ้ฆˆ่ฟ˜ๆ˜ฏๅŠŸ่ƒฝ่ฏทๆฑ‚๏ผŒ่ฏท้šๆ—ถ่”็ณปๆˆ‘ไปฌใ€‚", - "email": "ๆ‚จๅฏไปฅ็›ดๆŽฅ้€š่ฟ‡็”ตๅญ้‚ฎไปถ่”็ณปๆˆ‘ไปฌ๏ผš" - }, - "licensing": { - "title": "่ฎธๅฏ้€‚็”จ", - "subtitle": "้€‰ๆ‹ฉ้€‚ๅˆๆ‚จ้œ€ๆฑ‚็š„่ฎธๅฏใ€‚" - }, - "multiTool": { - "uploadPdfs": "ไธŠไผ  PDF", - "upload": "ไธŠไผ ", - "addBlankPage": "ๆทปๅŠ ็ฉบ็™ฝ้กต", - "edit": "็ผ–่พ‘:", - "undo": "ๆ’ค้”€", - "redo": "้‡ๅš", - "reset": "้‡็ฝฎ", - "selection": "้€‰ๆ‹ฉ:", - "selectAll": "ๅ…จ้€‰", - "deselectAll": "ๅ–ๆถˆๅ…จ้€‰", - "rotate": "ๆ—‹่ฝฌ:", - "rotateLeft": "ๅ‘ๅทฆ", - "rotateRight": "ๅ‘ๅณ", - "transform": "ๅ˜ๆข:", - "duplicate": "ๅคๅˆถ", - "split": "ๆ‹†ๅˆ†", - "clear": "ๆธ…้™ค:", - "delete": "ๅˆ ้™ค", - "download": "ไธ‹่ฝฝ:", - "downloadSelected": "ไธ‹่ฝฝ้€‰ไธญ", - "exportPdf": "ๅฏผๅ‡บ PDF", - "uploadPdfFiles": "้€‰ๆ‹ฉ PDF ๆ–‡ไปถ", - "dragAndDrop": "ๅฐ† PDF ๆ–‡ไปถๆ‹–ๆ”พๅˆฐๆญคๅค„๏ผŒๆˆ–็‚นๅ‡ป้€‰ๆ‹ฉ", - "selectFiles": "้€‰ๆ‹ฉๆ–‡ไปถ", - "renderingPages": "ๆญฃๅœจๆธฒๆŸ“้กต้ข...", - "actions": { - "duplicatePage": "ๅคๅˆถๆญค้กต", - "deletePage": "ๅˆ ้™คๆญค้กต", - "insertPdf": "ๅœจๆญค้กตๅŽๆ’ๅ…ฅ PDF", - "toggleSplit": "ๅœจๆญค้กตๅŽๅˆ‡ๆขๆ‹†ๅˆ†" - }, - "pleaseWait": "่ฏท็จๅ€™", - "pagesRendering": "้กต้ขๆญฃๅœจๆธฒๆŸ“ไธญ๏ผŒ่ฏท็จๅ€™...", - "noPagesSelected": "ๆœช้€‰ๆ‹ฉ้กต้ข", - "selectOnePage": "่ฏท่‡ณๅฐ‘้€‰ๆ‹ฉไธ€้กตไปฅ่ฟ›่กŒไธ‹่ฝฝใ€‚", - "noPages": "ๆฒกๆœ‰้กต้ข", - "noPagesToExport": "ๆฒกๆœ‰ๅฏๅฏผๅ‡บ็š„้กต้ขใ€‚", - "renderingTitle": "ๆญฃๅœจๆธฒๆŸ“้กต้ข้ข„่งˆ", - "errorRendering": "ๆธฒๆŸ“้กต้ข็ผฉ็•ฅๅ›พๅคฑ่ดฅ", - "error": "้”™่ฏฏ", - "failedToLoad": "ๅŠ ่ฝฝๅคฑ่ดฅ" + "lightningFast": { + "title": "ๆž้€Ÿๅค„็†", + "description": "็žฌ้—ดๅค„็† PDF, ๆ— ้œ€็ญ‰ๅพ…ใ€‚" } -} \ No newline at end of file + }, + "tools": { + "title": "ๅผ€ๅง‹ไฝฟ็”จ", + "toolsLabel": "ๅทฅๅ…ท", + "subtitle": "็‚นๅ‡ปๅทฅๅ…ทไปฅๆ‰“ๅผ€ๆ–‡ไปถไธŠไผ ", + "searchPlaceholder": "ๆœ็ดขๅทฅๅ…ท (ไพ‹ๅฆ‚ 'ๅˆๅนถ', 'ๅˆ†ๅ‰ฒ'...)", + "backToTools": "่ฟ”ๅ›žๅทฅๅ…ทๅˆ—่กจ", + "firstLoadNotice": "้ฆ–ๆฌกๅŠ ่ฝฝ้œ€่ฆไธ€็‚นๆ—ถ้—ด๏ผŒๅ› ไธบๆˆ‘ไปฌๆญฃๅœจไธ‹่ฝฝ่ฝฌๆขๅผ•ๆ“Žใ€‚ไน‹ๅŽๆ‰€ๆœ‰ๅŠ ่ฝฝๅฐ†ๅณๆ—ถๅฎŒๆˆใ€‚" + }, + "upload": { + "clickToSelect": "็‚นๅ‡ป้€‰ๆ‹ฉๆ–‡ไปถ", + "orDragAndDrop": "ๆˆ–ๅฐ†ๆ–‡ไปถๆ‹–ๆ”พๅˆฐๆญคๅค„", + "pdfOrImages": "PDF ๆˆ–ๅ›พ็‰‡", + "filesNeverLeave": "ๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚", + "addMore": "ๆทปๅŠ ๆ›ดๅคšๆ–‡ไปถ", + "clearAll": "ๆธ…็ฉบๆ‰€ๆœ‰", + "clearFiles": "ๆธ…้™คๆ–‡ไปถ" + }, + "loader": { + "processing": "ๅค„็†ไธญ..." + }, + "alert": { + "title": "ๆ็คบ", + "ok": "็กฎๅฎš" + }, + "preview": { + "title": "ๆ–‡ๆกฃ้ข„่งˆ", + "downloadAsPdf": "ไธ‹่ฝฝ PDF", + "close": "ๅ…ณ้—ญ" + }, + "settings": { + "title": "่ฎพ็ฝฎ", + "shortcuts": "ๅฟซๆท้”ฎ", + "preferences": "ๅๅฅฝ่ฎพ็ฝฎ", + "displayPreferences": "ๆ˜พ็คบ่ฎพ็ฝฎ", + "searchShortcuts": "ๆœ็ดขๅฟซๆท้”ฎ...", + "shortcutsInfo": "ๆŒ‰ไธ‹ๅนถๆŒ‰ไฝๆŒ‰้”ฎไปฅ่ฎพ็ฝฎๅฟซๆท้”ฎใ€‚ๆ›ดๆ”นๅฐ†่‡ชๅŠจไฟๅญ˜ใ€‚", + "shortcutsWarning": "โš ๏ธ ้ฟๅ…ไฝฟ็”จ้€š็”จ็š„ๆต่งˆๅ™จๅฟซๆท้”ฎ (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N ็ญ‰)๏ผŒๅ› ไธบๅฎƒไปฌๅฏ่ƒฝๆ— ๆณ•็จณๅฎšๅทฅไฝœใ€‚", + "import": "ๅฏผๅ…ฅ", + "export": "ๅฏผๅ‡บ", + "resetToDefaults": "ๆขๅค้ป˜่ฎค", + "fullWidthMode": "ๅ…จๅฎฝๆจกๅผ", + "fullWidthDescription": "ไฝฟ็”จๅ…จๅฑๅฎฝๅบฆๅฑ•็คบๆ‰€ๆœ‰ๅทฅๅ…ท๏ผŒ่€Œ้žๅฑ…ไธญๆ˜พ็คบ", + "settingsAutoSaved": "่ฎพ็ฝฎๅทฒ่‡ชๅŠจไฟๅญ˜", + "clickToSet": "็‚นๅ‡ป่ฎพ็ฝฎ", + "pressKeys": "ๆŒ‰ไธ‹ๆŒ‰้”ฎ...", + "warnings": { + "alreadyInUse": "ๅฟซๆท้”ฎๅทฒ่ขซไฝฟ็”จ", + "assignedTo": "ๅทฒๅˆ†้…็ป™๏ผš", + "chooseDifferent": "่ฏท้€‰ๆ‹ฉๅ…ถไป–ๅฟซๆท้”ฎใ€‚", + "reserved": "ไฟ็•™ๅฟซๆท้”ฎ่ญฆๅ‘Š", + "commonlyUsed": "้€šๅธธ็”จไบŽ๏ผš", + "unreliable": "ๆญคๅฟซๆท้”ฎๅฏ่ƒฝๆ— ๆณ•็จณๅฎšๅทฅไฝœ๏ผŒๆˆ–ไธŽๆต่งˆๅ™จ/็ณป็ปŸๅฟซๆท้”ฎๅ†ฒ็ชใ€‚", + "useAnyway": "ไป่ฆไฝฟ็”จๅ—๏ผŸ", + "resetTitle": "้‡็ฝฎๅฟซๆท้”ฎ", + "resetMessage": "็กฎๅฎš่ฆๅฐ†ๆ‰€ๆœ‰ๅฟซๆท้”ฎ้‡็ฝฎไธบ้ป˜่ฎคๅ€ผๅ—๏ผŸ

ๆญคๆ“ไฝœๆ— ๆณ•ๆ’ค้”€ใ€‚", + "importSuccessTitle": "ๅฏผๅ…ฅๆˆๅŠŸ", + "importSuccessMessage": "ๅฟซๆท้”ฎๅฏผๅ…ฅๆˆๅŠŸ๏ผ", + "importFailTitle": "ๅฏผๅ…ฅๅคฑ่ดฅ", + "importFailMessage": "ๅฏผๅ…ฅๅฟซๆท้”ฎๅคฑ่ดฅใ€‚ๆ–‡ไปถๆ ผๅผๆ— ๆ•ˆใ€‚" + } + }, + "warning": { + "title": "่ญฆๅ‘Š", + "cancel": "ๅ–ๆถˆ", + "proceed": "็ปง็ปญ" + }, + "compliance": { + "title": "ๆ‚จ็š„ๆ•ฐๆฎไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡", + "weKeep": "ๆˆ‘ไปฌไผšไฟๆŒ", + "yourInfoSafe": "ๆ‚จ็š„ไฟกๆฏๅฎ‰ๅ…จ", + "byFollowingStandards": "๏ผŒ้ตๅพชๅ…จ็ƒๅฎ‰ๅ…จๆ ‡ๅ‡†ใ€‚", + "processingLocal": "ๆ‰€ๆœ‰ๅค„็†้ƒฝๅœจๆ‚จ็š„่ฎพๅค‡ไธŠๆœฌๅœฐ่ฟ›่กŒใ€‚", + "gdpr": { + "title": "GDPR ๅˆ่ง„", + "description": "ไฟๆŠคๆฌง็›Ÿๅขƒๅ†…ไธชไบบ็š„ไธชไบบๆ•ฐๆฎๅ’Œ้š็งใ€‚" + }, + "ccpa": { + "title": "CCPA ๅˆ่ง„", + "description": "่ต‹ไบˆๅŠ ๅทžๅฑ…ๆฐ‘ๅฏนๅ…ถไธชไบบไฟกๆฏ็š„ๆ”ถ้›†ใ€ไฝฟ็”จๅ’Œๅ…ฑไบซ็š„ๆƒๅˆฉใ€‚" + }, + "hipaa": { + "title": "HIPAA ๅˆ่ง„", + "description": "ๅˆถๅฎš็พŽๅ›ฝๅŒป็–—็ณป็ปŸไธญๅค„็†ๆ•ๆ„Ÿๅฅๅบทไฟกๆฏ็š„ไฟ้šœๆŽชๆ–ฝใ€‚" + } + }, + "faq": { + "title": "ๅธธ่ง", + "questions": "้—ฎ้ข˜", + "isFree": { + "question": "BentoPDF ็œŸ็š„ๅ…่ดนๅ—๏ผŸ", + "answer": "ๆ˜ฏ็š„๏ผŒๅฎŒๅ…จๅ…่ดนใ€‚BentoPDF ไธŠ็š„ๆ‰€ๆœ‰ๅทฅๅ…ทๅ‡ๅฏ 100% ๅ…่ดนไฝฟ็”จ๏ผŒๆฒกๆœ‰ๆ–‡ไปถ้™ๅˆถ๏ผŒๆ— ้œ€ๆณจๅ†Œ๏ผŒไนŸๆฒกๆœ‰ๆฐดๅฐใ€‚ๆˆ‘ไปฌ็›ธไฟกๆฏไธชไบบ้ƒฝๅบ”่ฏฅ่ƒฝๅคŸไฝฟ็”จ็ฎ€ๅ•ใ€ๅผบๅคง็š„ PDF ๅทฅๅ…ท๏ผŒ่€Œๆ— ้œ€้€š่ฟ‡ไป˜่ดนๅข™ใ€‚" + }, + "areFilesSecure": { + "question": "ๆˆ‘็š„ๆ–‡ไปถๅฎ‰ๅ…จๅ—๏ผŸๅฎƒไปฌๅœจๅ“ช้‡Œๅค„็†๏ผŸ", + "answer": "ๆ‚จ็š„ๆ–‡ไปถ้žๅธธๅฎ‰ๅ…จ๏ผŒๅ› ไธบๅฎƒไปฌไปŽๆœช็ฆปๅผ€ๆ‚จ็š„็”ต่„‘ใ€‚ๆ‰€ๆœ‰ๅค„็†้ƒฝ็›ดๆŽฅๅœจๆ‚จ็š„็ฝ‘็ปœๆต่งˆๅ™จ๏ผˆๅฎขๆˆท็ซฏ๏ผ‰ไธญ่ฟ›่กŒใ€‚ๆˆ‘ไปฌไปŽไธๅฐ†ๆ‚จ็š„ๆ–‡ไปถไธŠไผ ๅˆฐๆœๅŠกๅ™จ๏ผŒๅ› ๆญคๆ‚จๅฏไปฅๅฏนๆ–‡ๆกฃไฟๆŒๅฎŒๅ…จ็š„้š็งๅ’ŒๆŽงๅˆถใ€‚" + }, + "platforms": { + "question": "ๅฎƒ้€‚็”จไบŽ Macใ€Windows ๅ’Œๆ‰‹ๆœบๅ—๏ผŸ", + "answer": "ๆ˜ฏ็š„๏ผ็”ฑไบŽ BentoPDF ๅฎŒๅ…จๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญ่ฟ่กŒ๏ผŒๅ› ๆญคๅฎƒ้€‚็”จไบŽไปปไฝ•ๅธฆๆœ‰็Žฐไปฃ็ฝ‘็ปœๆต่งˆๅ™จ็š„ๆ“ไฝœ็ณป็ปŸ๏ผŒๅŒ…ๆ‹ฌ Windowsใ€macOSใ€Linuxใ€iOS ๅ’Œ Androidใ€‚" + }, + "gdprCompliant": { + "question": "BentoPDF ็ฌฆๅˆ GDPR ๅ—๏ผŸ", + "answer": "ๆ˜ฏ็š„ใ€‚BentoPDF ๅฎŒๅ…จ็ฌฆๅˆ GDPRใ€‚็”ฑไบŽๆ‰€ๆœ‰ๆ–‡ไปถๅค„็†้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๆœฌๅœฐ่ฟ›่กŒ๏ผŒๅนถไธ”ๆˆ‘ไปฌไปŽไธๆ”ถ้›†ๆˆ–ๅฐ†ๆ‚จ็š„ๆ–‡ไปถไผ ่พ“ๅˆฐไปปไฝ•ๆœๅŠกๅ™จ๏ผŒๅ› ๆญคๆˆ‘ไปฌๆ— ๆณ•่ฎฟ้—ฎๆ‚จ็š„ๆ•ฐๆฎใ€‚่ฟ™็กฎไฟๆ‚จๅง‹็ปˆๆŽŒๆŽงๆ‚จ็š„ๆ–‡ๆกฃใ€‚" + }, + "dataStorage": { + "question": "ไฝ ไปฌไผšๅญ˜ๅ‚จๆˆ–่ทŸ่ธชๆˆ‘็š„ไปปไฝ•ๆ–‡ไปถๅ—๏ผŸ", + "answer": "ไธใ€‚ๆˆ‘ไปฌไปŽไธๅญ˜ๅ‚จใ€่ทŸ่ธชๆˆ–่ฎฐๅฝ•ๆ‚จ็š„ๆ–‡ไปถใ€‚ๆ‚จๅœจ BentoPDF ไธŠๆ‰€ๅš็š„ๆ‰€ๆœ‰ๆ“ไฝœ้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จๅ†…ๅญ˜ไธญ่ฟ›่กŒ๏ผŒๅนถๅœจๆ‚จๅ…ณ้—ญ้กต้ขๅŽๆถˆๅคฑใ€‚ๆฒกๆœ‰ไธŠไผ ๏ผŒๆฒกๆœ‰ๅކๅฒ่ฎฐๅฝ•๏ผŒไนŸๆฒกๆœ‰ๆถ‰ๅŠๆœๅŠกๅ™จใ€‚" + }, + "different": { + "question": "BentoPDF ไธŽๅ…ถไป– PDF ๅทฅๅ…ทๆœ‰ไฝ•ไธๅŒ๏ผŸ", + "answer": "ๅคงๅคšๆ•ฐ PDF ๅทฅๅ…ทๅฐ†ๆ‚จ็š„ๆ–‡ไปถไธŠไผ ๅˆฐๆœๅŠกๅ™จ่ฟ›่กŒๅค„็†ใ€‚BentoPDF ไปŽไธ่ฟ™ๆ ทๅšใ€‚ๆˆ‘ไปฌไฝฟ็”จๅฎ‰ๅ…จใ€็Žฐไปฃ็š„็ฝ‘็ปœๆŠ€ๆœฏ็›ดๆŽฅๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๅค„็†ๆ‚จ็š„ๆ–‡ไปถใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆ›ดๅฟซ็š„ๆ€ง่ƒฝใ€ๆ›ดๅผบ็š„้š็งๅ’ŒๅฎŒๅ…จ็š„ๅฎ‰ๅฟƒใ€‚" + }, + "browserBased": { + "question": "ๅŸบไบŽๆต่งˆๅ™จ็š„ๅค„็†ๅฆ‚ไฝ•ไฟๆŠคๆˆ‘็š„ๅฎ‰ๅ…จ๏ผŸ", + "answer": "้€š่ฟ‡ๅฎŒๅ…จๅœจๆ‚จ็š„ๆต่งˆๅ™จๅ†…้ƒจ่ฟ่กŒ๏ผŒBentoPDF ็กฎไฟๆ‚จ็š„ๆ–‡ไปถไปŽๆœช็ฆปๅผ€ๆ‚จ็š„่ฎพๅค‡ใ€‚่ฟ™ๆถˆ้™คไบ†ๆœๅŠกๅ™จ้ป‘ๅฎขๆ”ปๅ‡ปใ€ๆ•ฐๆฎๆณ„้œฒๆˆ–ๆœช็ปๆŽˆๆƒ่ฎฟ้—ฎ็š„้ฃŽ้™ฉใ€‚ๆ‚จ็š„ๆ–‡ไปถๅง‹็ปˆๅฑžไบŽๆ‚จใ€‚" + }, + "analytics": { + "question": "ไฝ ไปฌไฝฟ็”จ Cookie ๆˆ–ๅˆ†ๆžๆฅ่ทŸ่ธชๆˆ‘ๅ—๏ผŸ", + "answer": "ๆˆ‘ไปฌๅ…ณๅฟƒๆ‚จ็š„้š็งใ€‚BentoPDF ไธไผš่ทŸ่ธชไธชไบบไฟกๆฏใ€‚ๆˆ‘ไปฌไป…ไฝฟ็”จ Simple Analytics ๆŸฅ็œ‹ๅŒฟๅ่ฎฟ้—ฎ่ฎกๆ•ฐใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆˆ‘ไปฌๅฏไปฅ็Ÿฅ้“ๆœ‰ๅคšๅฐ‘็”จๆˆท่ฎฟ้—ฎๆˆ‘ไปฌ็š„็ฝ‘็ซ™๏ผŒไฝ†ๆˆ‘ไปฌๆฐธ่ฟœไธ็Ÿฅ้“ๆ‚จๆ˜ฏ่ฐใ€‚Simple Analytics ๅฎŒๅ…จ็ฌฆๅˆ GDPR ๅนถๅฐŠ้‡ๆ‚จ็š„้š็งใ€‚" + } + }, + "testimonials": { + "title": "ๆˆ‘ไปฌ็š„", + "users": "็”จๆˆท", + "say": "่ฏ„ไปท" + }, + "support": { + "title": "ๅ–œๆฌข่ฟ™ไธช้กน็›ฎ๏ผŸ", + "description": "BentoPDF ๆ˜ฏไธ€ไธชๅ……ๆปกๆฟ€ๆƒ…็š„้กน็›ฎ๏ผŒๆ—จๅœจไธบๆฏไธชไบบๆไพ›ๅ…่ดนใ€็งๅฏ†ไธ”ๅผบๅคง็š„ PDF ๅทฅๅ…ท็ฎฑใ€‚ๅฆ‚ๆžœๆ‚จ่ง‰ๅพ—ๅฎƒๆœ‰็”จ๏ผŒ่ฏท่€ƒ่™‘ๆ”ฏๆŒๅฎƒ็š„ๅผ€ๅ‘ใ€‚ๆฏไธ€ๆฏๅ’–ๅ•ก้ƒฝๆ˜ฏ่Žซๅคง็š„ๆ”ฏๆŒ๏ผ", + "buyMeCoffee": "่ฏทๆˆ‘ๅ–ๆฏๅ’–ๅ•ก" + }, + "footer": { + "copyright": "ยฉ 2026 BentoPDF. ไฟ็•™ๆ‰€ๆœ‰ๆƒๅˆฉใ€‚", + "version": "็‰ˆๆœฌ", + "company": "ๅ…ฌๅธ", + "aboutUs": "ๅ…ณไบŽๆˆ‘ไปฌ", + "faqLink": "ๅธธ่ง้—ฎ้ข˜", + "contactUs": "่”็ณปๆˆ‘ไปฌ", + "legal": "ๆณ•ๅพ‹", + "termsAndConditions": "ๆœๅŠกๆกๆฌพ", + "privacyPolicy": "้š็งๆ”ฟ็ญ–", + "followUs": "ๅ…ณๆณจๆˆ‘ไปฌ" + }, + "merge": { + "title": "ๅˆๅนถ PDF", + "description": "ๅˆๅนถๆ•ดไธชๆ–‡ไปถ๏ผŒๆˆ–้€‰ๆ‹ฉ็‰นๅฎš้กต้ขๅˆๅนถๅˆฐๆ–ฐๆ–‡ๆกฃไธญใ€‚", + "fileMode": "ๆ–‡ไปถๆจกๅผ", + "pageMode": "้กต้ขๆจกๅผ", + "howItWorks": "ไฝฟ็”จ่ฏดๆ˜Ž๏ผš", + "fileModeInstructions": [ + "็‚นๅ‡ปๅนถๆ‹–ๅŠจๅ›พๆ ‡ไปฅๆ›ดๆ”นๆ–‡ไปถ็š„้กบๅบใ€‚", + "ๅœจๆฏไธชๆ–‡ไปถ็š„ '้กต็ ' ๆก†ไธญ๏ผŒๆ‚จๅฏไปฅๆŒ‡ๅฎš่Œƒๅ›ด๏ผˆไพ‹ๅฆ‚ '1-3, 5'๏ผ‰ไปฅไป…ๅˆๅนถ่ฟ™ไบ›้กต้ขใ€‚", + "ๅฐ† '้กต็ ' ๆก†็•™็ฉบไปฅๅŒ…ๅซ่ฏฅๆ–‡ไปถ็š„ๆ‰€ๆœ‰้กต้ขใ€‚" + ], + "pageModeInstructions": [ + "ๆ‚จไธŠไผ ็š„ PDF ็š„ๆ‰€ๆœ‰้กต้ขๆ˜พ็คบๅœจไธ‹ๆ–นใ€‚", + "ๅช้œ€ๆ‹–ๆ”พๅ•ไธช้กต้ข็ผฉ็•ฅๅ›พ๏ผŒๅณๅฏไธบๆ‚จๆ–ฐๆ–‡ไปถๅฏน้กต้ข่ฟ›่กŒๆŽ’ๅบใ€‚" + ], + "mergePdfs": "ๅˆๅนถ PDF" + }, + "common": { + "page": "้กต", + "pages": "้กต", + "of": " / ", + "download": "ไธ‹่ฝฝ", + "cancel": "ๅ–ๆถˆ", + "save": "ไฟๅญ˜", + "delete": "ๅˆ ้™ค", + "edit": "็ผ–่พ‘", + "add": "ๆทปๅŠ ", + "remove": "็งป้™ค", + "loading": "ๅŠ ่ฝฝไธญ...", + "error": "้”™่ฏฏ", + "success": "ๆˆๅŠŸ", + "file": "ๆ–‡ไปถ", + "files": "ๆ–‡ไปถ", + "close": "ๅ…ณ้—ญ" + }, + "about": { + "hero": { + "title": "ๆˆ‘ไปฌ็›ธไฟก PDF ๅทฅๅ…ทๅบ”่ฏฅๆ˜ฏ", + "subtitle": "ๅฟซ้€Ÿใ€็งๅฏ†ไธ”ๅ…่ดน็š„ใ€‚", + "noCompromises": "็ปไธๅฆฅๅใ€‚" + }, + "mission": { + "title": "ๆˆ‘ไปฌ็š„ไฝฟๅ‘ฝ", + "description": "ๆไพ›ๆœ€ๅ…จ้ข็š„ PDF ๅทฅๅ…ท็ฎฑ๏ผŒๅฐŠ้‡ๆ‚จ็š„้š็ง๏ผŒไธ”ๆฐธไธๆ”ถ่ดนใ€‚ๆˆ‘ไปฌ็›ธไฟกๅŸบๆœฌ็š„ๆ–‡ๆกฃๅทฅๅ…ทๅบ”่ฏฅๅฏนๆ‰€ๆœ‰ไบบใ€ๅœจไปปไฝ•ๅœฐๆ–น้ƒฝ่งฆๆ‰‹ๅฏๅŠ๏ผŒๆฒกๆœ‰ไปปไฝ•้šœ็ขใ€‚" + }, + "philosophy": { + "label": "ๆˆ‘ไปฌ็š„ๆ ธๅฟƒ็†ๅฟต", + "title": "้š็ง่‡ณไธŠใ€‚ๅง‹็ปˆๅฆ‚ไธ€ใ€‚", + "description": "ๅœจๆ•ฐๆฎ่ขซๅ•†ๅ“ๅŒ–็š„ๆ—ถไปฃ๏ผŒๆˆ‘ไปฌ้‡‡ๅ–ไธๅŒ็š„ๆ–นๅผใ€‚BentoPDF ๅทฅๅ…ท็š„ๆ‰€ๆœ‰ๅค„็†้ƒฝๅœจๆ‚จ็š„ๆต่งˆๅ™จๆœฌๅœฐ่ฟ›่กŒใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆ‚จ็š„ๆ–‡ไปถไปŽๆœชๆŽฅ่งฆๆˆ‘ไปฌ็š„ๆœๅŠกๅ™จ๏ผŒๆˆ‘ไปฌไปŽไธๆŸฅ็œ‹ๆ‚จ็š„ๆ–‡ๆกฃ๏ผŒไนŸไธ่ทŸ่ธชๆ‚จ็š„ๆ“ไฝœใ€‚ๆ‚จ็š„ๆ–‡ๆกฃไฟๆŒ็ปๅฏน็š„็งๅฏ†ๆ€งใ€‚่ฟ™ไธไป…ๆ˜ฏไธ€้กนๅŠŸ่ƒฝ๏ผ›่ฟ™ๆ˜ฏๆˆ‘ไปฌ็š„ๅŸบ็Ÿณใ€‚" + }, + "whyBentopdf": { + "title": "ไธบไป€ไนˆ้€‰ๆ‹ฉ", + "speed": { + "title": "ไธบ้€Ÿๅบฆ่€Œ็”Ÿ", + "description": "ๆ— ้œ€็ญ‰ๅพ…ไธŠไผ ๆˆ–ไปŽๆœๅŠกๅ™จไธ‹่ฝฝใ€‚้€š่ฟ‡ไฝฟ็”จ WebAssembly ็ญ‰็Žฐไปฃ็ฝ‘็ปœๆŠ€ๆœฏ็›ดๆŽฅๅœจๆ‚จ็š„ๆต่งˆๅ™จไธญๅค„็†ๆ–‡ไปถ๏ผŒๆˆ‘ไปฌไธบๆ‰€ๆœ‰ๅทฅๅ…ทๆไพ›ไบ†ๆ— ไธŽไผฆๆฏ”็š„้€Ÿๅบฆใ€‚" + }, + "free": { + "title": "ๅฎŒๅ…จๅ…่ดน", + "description": "ๆ— ่ฏ•็”จ๏ผŒๆ— ่ฎข้˜…๏ผŒๆ— ้š่—่ดน็”จ๏ผŒไนŸๆฒกๆœ‰่ขซ้”ๅฎš็š„ '้ซ˜็บง' ๅŠŸ่ƒฝใ€‚ๆˆ‘ไปฌ็›ธไฟกๅผบๅคง็š„ PDF ๅทฅๅ…ทๅบ”่ฏฅๆ˜ฏไธ€็งๅ…ฌๅ…ฑ่ฎพๆ–ฝ๏ผŒ่€Œไธๆ˜ฏ็›ˆๅˆฉไธญๅฟƒใ€‚" + }, + "noAccount": { + "title": "ๆ— ้œ€่ดฆๆˆท", + "description": "็ซ‹ๅณๅผ€ๅง‹ไฝฟ็”จไปปไฝ•ๅทฅๅ…ทใ€‚ๆˆ‘ไปฌไธ้œ€่ฆๆ‚จ็š„็”ตๅญ้‚ฎไปถใ€ๅฏ†็ ๆˆ–ไปปไฝ•ไธชไบบไฟกๆฏใ€‚ๆ‚จ็š„ๅทฅไฝœๆต็จ‹ๅบ”่ฏฅๆ˜ฏๆ— ๆ‘ฉๆ“ฆไธ”ๅŒฟๅ็š„ใ€‚" + }, + "openSource": { + "title": "ๅผ€ๆบ็ฒพ็ฅž", + "description": "ไปฅ้€ๆ˜Žๅบฆไธบๆ ธๅฟƒๆž„ๅปบใ€‚ๆˆ‘ไปฌๅˆฉ็”จไบ†ๅƒ PDF-lib ๅ’Œ PDF.js ่ฟ™ๆ ทไผ˜็ง€็š„ๅผ€ๆบๅบ“๏ผŒๅนถ็›ธไฟก็คพๅŒบ้ฉฑๅŠจ็š„ๅŠ›้‡่ƒฝไฝฟๅผบๅคง็š„ๅทฅๅ…ทๆƒ ๅŠๆฏไธ€ไธชไบบใ€‚" + } + }, + "cta": { + "title": "ๅ‡†ๅค‡ๅฅฝๅผ€ๅง‹ไบ†ๅ—๏ผŸ", + "description": "ๅŠ ๅ…ฅๆˆๅƒไธŠไธ‡ไฟกไปป BentoPDF ๆปก่ถณๆ—ฅๅธธๆ–‡ๆกฃ้œ€ๆฑ‚็š„็”จๆˆทใ€‚ไฝ“้ชŒ้š็งๅ’Œๆ€ง่ƒฝๅธฆๆฅ็š„ไธๅŒใ€‚", + "button": "ๆŽข็ดขๆ‰€ๆœ‰ๅทฅๅ…ท" + } + }, + "contact": { + "title": "่”็ณปๆˆ‘ไปฌ", + "subtitle": "ๆˆ‘ไปฌๅพˆไนๆ„ๅฌๅˆฐๆ‚จ็š„ๅฃฐ้Ÿณใ€‚ๆ— ่ฎบๆ‚จๆœ‰้—ฎ้ข˜ใ€ๅ้ฆˆ่ฟ˜ๆ˜ฏๅŠŸ่ƒฝ่ฏทๆฑ‚๏ผŒ่ฏท้šๆ—ถ่”็ณปๆˆ‘ไปฌใ€‚", + "email": "ๆ‚จๅฏไปฅ็›ดๆŽฅ้€š่ฟ‡็”ตๅญ้‚ฎไปถ่”็ณปๆˆ‘ไปฌ๏ผš" + }, + "licensing": { + "title": "่ฎธๅฏ้€‚็”จ", + "subtitle": "้€‰ๆ‹ฉ้€‚ๅˆๆ‚จ้œ€ๆฑ‚็š„่ฎธๅฏใ€‚" + }, + "multiTool": { + "uploadPdfs": "ไธŠไผ  PDF", + "upload": "ไธŠไผ ", + "addBlankPage": "ๆทปๅŠ ็ฉบ็™ฝ้กต", + "edit": "็ผ–่พ‘:", + "undo": "ๆ’ค้”€", + "redo": "้‡ๅš", + "reset": "้‡็ฝฎ", + "selection": "้€‰ๆ‹ฉ:", + "selectAll": "ๅ…จ้€‰", + "deselectAll": "ๅ–ๆถˆๅ…จ้€‰", + "rotate": "ๆ—‹่ฝฌ:", + "rotateLeft": "ๅ‘ๅทฆ", + "rotateRight": "ๅ‘ๅณ", + "transform": "ๅ˜ๆข:", + "duplicate": "ๅคๅˆถ", + "split": "ๆ‹†ๅˆ†", + "clear": "ๆธ…้™ค:", + "delete": "ๅˆ ้™ค", + "download": "ไธ‹่ฝฝ:", + "downloadSelected": "ไธ‹่ฝฝ้€‰ไธญ", + "exportPdf": "ๅฏผๅ‡บ PDF", + "uploadPdfFiles": "้€‰ๆ‹ฉ PDF ๆ–‡ไปถ", + "dragAndDrop": "ๅฐ† PDF ๆ–‡ไปถๆ‹–ๆ”พๅˆฐๆญคๅค„๏ผŒๆˆ–็‚นๅ‡ป้€‰ๆ‹ฉ", + "selectFiles": "้€‰ๆ‹ฉๆ–‡ไปถ", + "renderingPages": "ๆญฃๅœจๆธฒๆŸ“้กต้ข...", + "actions": { + "duplicatePage": "ๅคๅˆถๆญค้กต", + "deletePage": "ๅˆ ้™คๆญค้กต", + "insertPdf": "ๅœจๆญค้กตๅŽๆ’ๅ…ฅ PDF", + "toggleSplit": "ๅœจๆญค้กตๅŽๅˆ‡ๆขๆ‹†ๅˆ†" + }, + "pleaseWait": "่ฏท็จๅ€™", + "pagesRendering": "้กต้ขๆญฃๅœจๆธฒๆŸ“ไธญ๏ผŒ่ฏท็จๅ€™...", + "noPagesSelected": "ๆœช้€‰ๆ‹ฉ้กต้ข", + "selectOnePage": "่ฏท่‡ณๅฐ‘้€‰ๆ‹ฉไธ€้กตไปฅ่ฟ›่กŒไธ‹่ฝฝใ€‚", + "noPages": "ๆฒกๆœ‰้กต้ข", + "noPagesToExport": "ๆฒกๆœ‰ๅฏๅฏผๅ‡บ็š„้กต้ขใ€‚", + "renderingTitle": "ๆญฃๅœจๆธฒๆŸ“้กต้ข้ข„่งˆ", + "errorRendering": "ๆธฒๆŸ“้กต้ข็ผฉ็•ฅๅ›พๅคฑ่ดฅ", + "error": "้”™่ฏฏ", + "failedToLoad": "ๅŠ ่ฝฝๅคฑ่ดฅ" + } +} diff --git a/public/locales/zh/tools.json b/public/locales/zh/tools.json index fca82d6..a93c822 100644 --- a/public/locales/zh/tools.json +++ b/public/locales/zh/tools.json @@ -518,5 +518,13 @@ "subtitle": "ๅฐ†็”ตๅญ้‚ฎไปถๆ–‡ไปถ (EML, MSG) ่ฝฌๆขไธบ PDF ๆ ผๅผใ€‚ๆ”ฏๆŒ Outlook ๅฏผๅ‡บๅ’Œๆ ‡ๅ‡†้‚ฎไปถๆ ผๅผใ€‚", "acceptedFormats": "EML, MSG ๆ–‡ไปถ", "convertButton": "่ฝฌๆขไธบ PDF" + }, + "fontToOutline": { + "name": "ๅญ—ไฝ“่ฝฌ่ฝฎๅป“", + "subtitle": "ๅฐ†ๆ‰€ๆœ‰ๅญ—ไฝ“่ฝฌๆขไธบ็Ÿข้‡่ฝฎๅป“๏ผŒ็กฎไฟๅœจๆ‰€ๆœ‰่ฎพๅค‡ไธŠไธ€่‡ดๅ‘ˆ็Žฐใ€‚" + }, + "deskewPdf": { + "name": "ๆ กๆญฃ PDF", + "subtitle": "ไฝฟ็”จ OpenCV ่‡ชๅŠจๆ กๆญฃๅ€พๆ–œ็š„ๆ‰ซๆ้กต้ขใ€‚" } } diff --git a/public/pdfjs-viewer/viewer.css b/public/pdfjs-viewer/viewer.css index f127b2a..4dcd817 100644 --- a/public/pdfjs-viewer/viewer.css +++ b/public/pdfjs-viewer/viewer.css @@ -13,2431 +13,2651 @@ * limitations under the License. */ -.messageBar{ - --closing-button-icon:url(images/messageBar_closingButton.svg); - --message-bar-close-button-color:var(--text-primary-color); - --message-bar-close-button-color-hover:var(--text-primary-color); - --message-bar-close-button-border-radius:4px; - --message-bar-close-button-border:none; - --csstools-light-dark-toggle--31:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.14); - --message-bar-close-button-hover-bg-color:var(--csstools-light-dark-toggle--31, rgb(21 20 26 / 0.14)); - --csstools-light-dark-toggle--32:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.21); - --message-bar-close-button-active-bg-color:var(--csstools-light-dark-toggle--32, rgb(21 20 26 / 0.21)); - --csstools-light-dark-toggle--33:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.07); - --message-bar-close-button-focus-bg-color:var(--csstools-light-dark-toggle--33, rgb(21 20 26 / 0.07)); -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.messageBar{ - --message-bar-close-button-hover-bg-color:light-dark( - rgb(21 20 26 / 0.14), - rgb(251 251 254 / 0.14) +.messageBar { + --closing-button-icon: url(images/messageBar_closingButton.svg); + --message-bar-close-button-color: var(--text-primary-color); + --message-bar-close-button-color-hover: var(--text-primary-color); + --message-bar-close-button-border-radius: 4px; + --message-bar-close-button-border: none; + --csstools-light-dark-toggle--31: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.14); + --message-bar-close-button-hover-bg-color: var( + --csstools-light-dark-toggle--31, + rgb(21 20 26 / 0.14) ); - --message-bar-close-button-active-bg-color:light-dark( - rgb(21 20 26 / 0.21), - rgb(251 251 254 / 0.21) + --csstools-light-dark-toggle--32: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.21); + --message-bar-close-button-active-bg-color: var( + --csstools-light-dark-toggle--32, + rgb(21 20 26 / 0.21) ); - --message-bar-close-button-focus-bg-color:light-dark( - rgb(21 20 26 / 0.07), - rgb(251 251 254 / 0.07) + --csstools-light-dark-toggle--33: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.07); + --message-bar-close-button-focus-bg-color: var( + --csstools-light-dark-toggle--33, + rgb(21 20 26 / 0.07) ); } -} -@supports not (color: light-dark(tan, tan)){ - -.messageBar *{ - --csstools-light-dark-toggle--31:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.14); - --message-bar-close-button-hover-bg-color:var(--csstools-light-dark-toggle--31, rgb(21 20 26 / 0.14)); - --csstools-light-dark-toggle--32:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.21); - --message-bar-close-button-active-bg-color:var(--csstools-light-dark-toggle--32, rgb(21 20 26 / 0.21)); - --csstools-light-dark-toggle--33:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.07); - --message-bar-close-button-focus-bg-color:var(--csstools-light-dark-toggle--33, rgb(21 20 26 / 0.07)); +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .messageBar { + --message-bar-close-button-hover-bg-color: light-dark( + rgb(21 20 26 / 0.14), + rgb(251 251 254 / 0.14) + ); + --message-bar-close-button-active-bg-color: light-dark( + rgb(21 20 26 / 0.21), + rgb(251 251 254 / 0.21) + ); + --message-bar-close-button-focus-bg-color: light-dark( + rgb(21 20 26 / 0.07), + rgb(251 251 254 / 0.07) + ); } } -@media screen and (forced-colors: active){ - -.messageBar{ - --message-bar-close-button-color:ButtonText; - --message-bar-close-button-border:1px solid ButtonText; - --message-bar-close-button-hover-bg-color:ButtonText; - --message-bar-close-button-active-bg-color:ButtonText; - --message-bar-close-button-focus-bg-color:ButtonText; - --message-bar-close-button-color-hover:HighlightText; -} +@supports not (color: light-dark(tan, tan)) { + .messageBar * { + --csstools-light-dark-toggle--31: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.14); + --message-bar-close-button-hover-bg-color: var( + --csstools-light-dark-toggle--31, + rgb(21 20 26 / 0.14) + ); + --csstools-light-dark-toggle--32: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.21); + --message-bar-close-button-active-bg-color: var( + --csstools-light-dark-toggle--32, + rgb(21 20 26 / 0.21) + ); + --csstools-light-dark-toggle--33: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.07); + --message-bar-close-button-focus-bg-color: var( + --csstools-light-dark-toggle--33, + rgb(21 20 26 / 0.07) + ); } - -.messageBar{ - - display:flex; - position:relative; - padding:8px 8px 8px 16px; - flex-direction:column; - justify-content:center; - align-items:center; - gap:8px; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - - border-radius:4px; - - border:1px solid var(--message-bar-border-color); - background:var(--message-bar-bg-color); - color:var(--message-bar-fg-color); } -.messageBar > div{ - display:flex; - align-items:flex-start; - gap:8px; - align-self:stretch; +@media screen and (forced-colors: active) { + .messageBar { + --message-bar-close-button-color: ButtonText; + --message-bar-close-button-border: 1px solid ButtonText; + --message-bar-close-button-hover-bg-color: ButtonText; + --message-bar-close-button-active-bg-color: ButtonText; + --message-bar-close-button-focus-bg-color: ButtonText; + --message-bar-close-button-color-hover: HighlightText; } - -:is(.messageBar > div)::before{ - content:""; - display:inline-block; - width:16px; - height:16px; - -webkit-mask-image:var(--message-bar-icon); - mask-image:var(--message-bar-icon); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--message-bar-icon-color); - flex-shrink:0; - } - -.messageBar button{ - cursor:pointer; - } - -:is(.messageBar button):focus-visible{ - outline:var(--focus-ring-outline); - outline-offset:2px; - } - -.messageBar .closeButton{ - width:32px; - height:32px; - background:none; - border-radius:var(--message-bar-close-button-border-radius); - border:var(--message-bar-close-button-border); - - display:flex; - align-items:center; - justify-content:center; - } - -:is(.messageBar .closeButton)::before{ - content:""; - display:inline-block; - width:16px; - height:16px; - -webkit-mask-image:var(--closing-button-icon); - mask-image:var(--closing-button-icon); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--message-bar-close-button-color); - } - -:is(.messageBar .closeButton):is(:hover,:active,:focus)::before{ - background-color:var(--message-bar-close-button-color-hover); - } - -:is(.messageBar .closeButton):hover{ - background-color:var(--message-bar-close-button-hover-bg-color); - } - -:is(.messageBar .closeButton):active{ - background-color:var(--message-bar-close-button-active-bg-color); - } - -:is(.messageBar .closeButton):focus{ - background-color:var(--message-bar-close-button-focus-bg-color); - } - -:is(.messageBar .closeButton) > span{ - display:inline-block; - width:0; - height:0; - overflow:hidden; - } - -#editorUndoBar{ - --csstools-light-dark-toggle--34:var(--csstools-color-scheme--light) #fbfbfe; - --text-primary-color:var(--csstools-light-dark-toggle--34, #15141a); - - --message-bar-icon:url(images/messageBar_info.svg); - --csstools-light-dark-toggle--35:var(--csstools-color-scheme--light) #73a7f3; - --message-bar-icon-color:var(--csstools-light-dark-toggle--35, #0060df); - --csstools-light-dark-toggle--36:var(--csstools-color-scheme--light) #003070; - --message-bar-bg-color:var(--csstools-light-dark-toggle--36, #deeafc); - --message-bar-fg-color:var(--text-primary-color); - --csstools-light-dark-toggle--37:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - --message-bar-border-color:var(--csstools-light-dark-toggle--37, rgb(0 0 0 / 0.08)); - - --csstools-light-dark-toggle--38:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - - --undo-button-bg-color:var(--csstools-light-dark-toggle--38, rgb(21 20 26 / 0.07)); - --csstools-light-dark-toggle--39:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.14); - --undo-button-bg-color-hover:var(--csstools-light-dark-toggle--39, rgb(21 20 26 / 0.14)); - --csstools-light-dark-toggle--40:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.21); - --undo-button-bg-color-active:var(--csstools-light-dark-toggle--40, rgb(21 20 26 / 0.21)); - - --csstools-light-dark-toggle--41:var(--csstools-color-scheme--light) #0df; - - --undo-button-border:1px solid var(--csstools-light-dark-toggle--41, #0060df); - - --undo-button-fg-color:var(--message-bar-fg-color); - --undo-button-fg-color-hover:var(--undo-button-fg-color); - --undo-button-fg-color-active:var(--undo-button-fg-color); } -@supports (color: light-dark(red, red)){ -#editorUndoBar{ - --text-primary-color:light-dark(#15141a, #fbfbfe); - --message-bar-icon-color:light-dark(#0060df, #73a7f3); - --message-bar-bg-color:light-dark(#deeafc, #003070); -} +.messageBar { + display: flex; + position: relative; + padding: 8px 8px 8px 16px; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 8px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + + border-radius: 4px; + + border: 1px solid var(--message-bar-border-color); + background: var(--message-bar-bg-color); + color: var(--message-bar-fg-color); } -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -#editorUndoBar{ - --message-bar-border-color:light-dark( - rgb(0 0 0 / 0.08), - rgb(255 255 255 / 0.08) +.messageBar > div { + display: flex; + align-items: flex-start; + gap: 8px; + align-self: stretch; +} + +:is(.messageBar > div)::before { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + -webkit-mask-image: var(--message-bar-icon); + mask-image: var(--message-bar-icon); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--message-bar-icon-color); + flex-shrink: 0; +} + +.messageBar button { + cursor: pointer; +} + +:is(.messageBar button):focus-visible { + outline: var(--focus-ring-outline); + outline-offset: 2px; +} + +.messageBar .closeButton { + width: 32px; + height: 32px; + background: none; + border-radius: var(--message-bar-close-button-border-radius); + border: var(--message-bar-close-button-border); + + display: flex; + align-items: center; + justify-content: center; +} + +:is(.messageBar .closeButton)::before { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + -webkit-mask-image: var(--closing-button-icon); + mask-image: var(--closing-button-icon); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--message-bar-close-button-color); +} + +:is(.messageBar .closeButton):is(:hover, :active, :focus)::before { + background-color: var(--message-bar-close-button-color-hover); +} + +:is(.messageBar .closeButton):hover { + background-color: var(--message-bar-close-button-hover-bg-color); +} + +:is(.messageBar .closeButton):active { + background-color: var(--message-bar-close-button-active-bg-color); +} + +:is(.messageBar .closeButton):focus { + background-color: var(--message-bar-close-button-focus-bg-color); +} + +:is(.messageBar .closeButton) > span { + display: inline-block; + width: 0; + height: 0; + overflow: hidden; +} + +#editorUndoBar { + --csstools-light-dark-toggle--34: var(--csstools-color-scheme--light) #fbfbfe; + --text-primary-color: var(--csstools-light-dark-toggle--34, #15141a); + + --message-bar-icon: url(images/messageBar_info.svg); + --csstools-light-dark-toggle--35: var(--csstools-color-scheme--light) #73a7f3; + --message-bar-icon-color: var(--csstools-light-dark-toggle--35, #0060df); + --csstools-light-dark-toggle--36: var(--csstools-color-scheme--light) #003070; + --message-bar-bg-color: var(--csstools-light-dark-toggle--36, #deeafc); + --message-bar-fg-color: var(--text-primary-color); + --csstools-light-dark-toggle--37: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + --message-bar-border-color: var( + --csstools-light-dark-toggle--37, + rgb(0 0 0 / 0.08) ); - --undo-button-bg-color:light-dark( - rgb(21 20 26 / 0.07), - rgb(255 255 255 / 0.08) + --csstools-light-dark-toggle--38: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + + --undo-button-bg-color: var( + --csstools-light-dark-toggle--38, + rgb(21 20 26 / 0.07) ); - --undo-button-bg-color-hover:light-dark( - rgb(21 20 26 / 0.14), - rgb(255 255 255 / 0.14) + --csstools-light-dark-toggle--39: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.14); + --undo-button-bg-color-hover: var( + --csstools-light-dark-toggle--39, + rgb(21 20 26 / 0.14) ); - --undo-button-bg-color-active:light-dark( - rgb(21 20 26 / 0.21), - rgb(255 255 255 / 0.21) + --csstools-light-dark-toggle--40: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.21); + --undo-button-bg-color-active: var( + --csstools-light-dark-toggle--40, + rgb(21 20 26 / 0.21) ); -} + + --csstools-light-dark-toggle--41: var(--csstools-color-scheme--light) #0df; + + --undo-button-border: 1px solid var(--csstools-light-dark-toggle--41, #0060df); + + --undo-button-fg-color: var(--message-bar-fg-color); + --undo-button-fg-color-hover: var(--undo-button-fg-color); + --undo-button-fg-color-active: var(--undo-button-fg-color); } -@supports (color: light-dark(red, red)){ -#editorUndoBar{ - - --undo-button-border:1px solid light-dark(#0060df, #0df); -} -} - -@supports not (color: light-dark(tan, tan)){ - -#editorUndoBar *{ - --csstools-light-dark-toggle--34:var(--csstools-color-scheme--light) #fbfbfe; - --text-primary-color:var(--csstools-light-dark-toggle--34, #15141a); - --csstools-light-dark-toggle--35:var(--csstools-color-scheme--light) #73a7f3; - --message-bar-icon-color:var(--csstools-light-dark-toggle--35, #0060df); - --csstools-light-dark-toggle--36:var(--csstools-color-scheme--light) #003070; - --message-bar-bg-color:var(--csstools-light-dark-toggle--36, #deeafc); - --csstools-light-dark-toggle--37:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - --message-bar-border-color:var(--csstools-light-dark-toggle--37, rgb(0 0 0 / 0.08)); - - --csstools-light-dark-toggle--38:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - - --undo-button-bg-color:var(--csstools-light-dark-toggle--38, rgb(21 20 26 / 0.07)); - --csstools-light-dark-toggle--39:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.14); - --undo-button-bg-color-hover:var(--csstools-light-dark-toggle--39, rgb(21 20 26 / 0.14)); - --csstools-light-dark-toggle--40:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.21); - --undo-button-bg-color-active:var(--csstools-light-dark-toggle--40, rgb(21 20 26 / 0.21)); - - --csstools-light-dark-toggle--41:var(--csstools-color-scheme--light) #0df; - - --undo-button-border:1px solid var(--csstools-light-dark-toggle--41, #0060df); +@supports (color: light-dark(red, red)) { + #editorUndoBar { + --text-primary-color: light-dark(#15141a, #fbfbfe); + --message-bar-icon-color: light-dark(#0060df, #73a7f3); + --message-bar-bg-color: light-dark(#deeafc, #003070); } } -@media screen and (forced-colors: active){ +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + #editorUndoBar { + --message-bar-border-color: light-dark( + rgb(0 0 0 / 0.08), + rgb(255 255 255 / 0.08) + ); -#editorUndoBar{ - --text-primary-color:CanvasText; - - --message-bar-icon-color:CanvasText; - --message-bar-bg-color:Canvas; - --message-bar-border-color:CanvasText; - - --undo-button-bg-color:ButtonText; - --undo-button-bg-color-hover:SelectedItem; - --undo-button-bg-color-active:SelectedItem; - - --undo-button-fg-color:ButtonFace; - --undo-button-fg-color-hover:SelectedItemText; - --undo-button-fg-color-active:SelectedItemText; - - --undo-button-border:none; -} + --undo-button-bg-color: light-dark( + rgb(21 20 26 / 0.07), + rgb(255 255 255 / 0.08) + ); + --undo-button-bg-color-hover: light-dark( + rgb(21 20 26 / 0.14), + rgb(255 255 255 / 0.14) + ); + --undo-button-bg-color-active: light-dark( + rgb(21 20 26 / 0.21), + rgb(255 255 255 / 0.21) + ); } - -#editorUndoBar{ - - position:fixed; - top:50px; - left:50%; - transform:translateX(-50%); - z-index:10; - - padding-block:8px; - padding-inline:16px 8px; - - font:menu; - font-size:15px; - - cursor:default; } -#editorUndoBar button{ - cursor:pointer; +@supports (color: light-dark(red, red)) { + #editorUndoBar { + --undo-button-border: 1px solid light-dark(#0060df, #0df); } +} -#editorUndoBar #editorUndoBarUndoButton{ - border-radius:4px; - font-weight:590; - line-height:19.5px; - color:var(--undo-button-fg-color); - border:var(--undo-button-border); - padding:4px 16px; - margin-inline-start:8px; - height:32px; +@supports not (color: light-dark(tan, tan)) { + #editorUndoBar * { + --csstools-light-dark-toggle--34: var(--csstools-color-scheme--light) + #fbfbfe; + --text-primary-color: var(--csstools-light-dark-toggle--34, #15141a); + --csstools-light-dark-toggle--35: var(--csstools-color-scheme--light) + #73a7f3; + --message-bar-icon-color: var(--csstools-light-dark-toggle--35, #0060df); + --csstools-light-dark-toggle--36: var(--csstools-color-scheme--light) + #003070; + --message-bar-bg-color: var(--csstools-light-dark-toggle--36, #deeafc); + --csstools-light-dark-toggle--37: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + --message-bar-border-color: var( + --csstools-light-dark-toggle--37, + rgb(0 0 0 / 0.08) + ); - background-color:var(--undo-button-bg-color); + --csstools-light-dark-toggle--38: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + + --undo-button-bg-color: var( + --csstools-light-dark-toggle--38, + rgb(21 20 26 / 0.07) + ); + --csstools-light-dark-toggle--39: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.14); + --undo-button-bg-color-hover: var( + --csstools-light-dark-toggle--39, + rgb(21 20 26 / 0.14) + ); + --csstools-light-dark-toggle--40: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.21); + --undo-button-bg-color-active: var( + --csstools-light-dark-toggle--40, + rgb(21 20 26 / 0.21) + ); + + --csstools-light-dark-toggle--41: var(--csstools-color-scheme--light) #0df; + + --undo-button-border: 1px solid + var(--csstools-light-dark-toggle--41, #0060df); } +} -:is(#editorUndoBar #editorUndoBarUndoButton):hover{ - background-color:var(--undo-button-bg-color-hover); - color:var(--undo-button-fg-color-hover); - } +@media screen and (forced-colors: active) { + #editorUndoBar { + --text-primary-color: CanvasText; -:is(#editorUndoBar #editorUndoBarUndoButton):active{ - background-color:var(--undo-button-bg-color-active); - color:var(--undo-button-fg-color-active); - } + --message-bar-icon-color: CanvasText; + --message-bar-bg-color: Canvas; + --message-bar-border-color: CanvasText; -#editorUndoBar > div{ - align-items:center; + --undo-button-bg-color: ButtonText; + --undo-button-bg-color-hover: SelectedItem; + --undo-button-bg-color-active: SelectedItem; + + --undo-button-fg-color: ButtonFace; + --undo-button-fg-color-hover: SelectedItemText; + --undo-button-fg-color-active: SelectedItemText; + + --undo-button-border: none; } +} -.dialog{ - --csstools-light-dark-toggle--42:var(--csstools-color-scheme--light) #1c1b22; - --dialog-bg-color:var(--csstools-light-dark-toggle--42, white); - --csstools-light-dark-toggle--43:var(--csstools-color-scheme--light) #1c1b22; - --dialog-border-color:var(--csstools-light-dark-toggle--43, white); - --csstools-light-dark-toggle--44:var(--csstools-color-scheme--light) #15141a; - --dialog-shadow:0 2px 14px 0 var(--csstools-light-dark-toggle--44, rgb(58 57 68 / 0.2)); - --csstools-light-dark-toggle--45:var(--csstools-color-scheme--light) #fbfbfe; - --text-primary-color:var(--csstools-light-dark-toggle--45, #15141a); - --csstools-light-dark-toggle--46:var(--csstools-color-scheme--light) #cfcfd8; - --text-secondary-color:var(--csstools-light-dark-toggle--46, #5b5b66); - --hover-filter:brightness(0.9); - --csstools-light-dark-toggle--47:var(--csstools-color-scheme--light) #0df; - --link-fg-color:var(--csstools-light-dark-toggle--47, #0060df); - --csstools-light-dark-toggle--48:var(--csstools-color-scheme--light) #80ebff; - --link-hover-fg-color:var(--csstools-light-dark-toggle--48, #0250bb); - --csstools-light-dark-toggle--49:var(--csstools-color-scheme--light) #52525e; - --separator-color:var(--csstools-light-dark-toggle--49, #f0f0f4); +#editorUndoBar { + position: fixed; + top: 50px; + left: 50%; + transform: translateX(-50%); + z-index: 10; - --textarea-border-color:#8f8f9d; - --csstools-light-dark-toggle--50:var(--csstools-color-scheme--light) #42414d; - --textarea-bg-color:var(--csstools-light-dark-toggle--50, white); - --textarea-fg-color:var(--text-secondary-color); + padding-block: 8px; + padding-inline: 16px 8px; - --csstools-light-dark-toggle--51:var(--csstools-color-scheme--light) #2b2a33; + font: menu; + font-size: 15px; - --radio-bg-color:var(--csstools-light-dark-toggle--51, #f0f0f4); - --csstools-light-dark-toggle--52:var(--csstools-color-scheme--light) #15141a; - --radio-checked-bg-color:var(--csstools-light-dark-toggle--52, #fbfbfe); - --radio-border-color:#8f8f9d; - --csstools-light-dark-toggle--53:var(--csstools-color-scheme--light) #0df; - --radio-checked-border-color:var(--csstools-light-dark-toggle--53, #0060df); + cursor: default; +} - --csstools-light-dark-toggle--54:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.07); +#editorUndoBar button { + cursor: pointer; +} - --button-secondary-bg-color:var(--csstools-light-dark-toggle--54, rgb(21 20 26 / 0.07)); - --button-secondary-fg-color:var(--text-primary-color); - --button-secondary-border-color:var(--button-secondary-bg-color); - --csstools-light-dark-toggle--55:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.21); - --button-secondary-active-bg-color:var(--csstools-light-dark-toggle--55, rgb(21 20 26 / 0.21)); - --button-secondary-active-fg-color:var(--button-secondary-fg-color); - --button-secondary-active-border-color:var(--button-secondary-bg-color); - --csstools-light-dark-toggle--56:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.14); - --button-secondary-hover-bg-color:var(--csstools-light-dark-toggle--56, rgb(21 20 26 / 0.14)); - --button-secondary-hover-fg-color:var(--button-secondary-fg-color); - --button-secondary-hover-border-color:var(--button-secondary-hover-bg-color); - --button-secondary-disabled-bg-color:var(--button-secondary-bg-color); - --button-secondary-disabled-border-color:var( +#editorUndoBar #editorUndoBarUndoButton { + border-radius: 4px; + font-weight: 590; + line-height: 19.5px; + color: var(--undo-button-fg-color); + border: var(--undo-button-border); + padding: 4px 16px; + margin-inline-start: 8px; + height: 32px; + + background-color: var(--undo-button-bg-color); +} + +:is(#editorUndoBar #editorUndoBarUndoButton):hover { + background-color: var(--undo-button-bg-color-hover); + color: var(--undo-button-fg-color-hover); +} + +:is(#editorUndoBar #editorUndoBarUndoButton):active { + background-color: var(--undo-button-bg-color-active); + color: var(--undo-button-fg-color-active); +} + +#editorUndoBar > div { + align-items: center; +} + +.dialog { + --csstools-light-dark-toggle--42: var(--csstools-color-scheme--light) #1c1b22; + --dialog-bg-color: var(--csstools-light-dark-toggle--42, white); + --csstools-light-dark-toggle--43: var(--csstools-color-scheme--light) #1c1b22; + --dialog-border-color: var(--csstools-light-dark-toggle--43, white); + --csstools-light-dark-toggle--44: var(--csstools-color-scheme--light) #15141a; + --dialog-shadow: 0 2px 14px 0 + var(--csstools-light-dark-toggle--44, rgb(58 57 68 / 0.2)); + --csstools-light-dark-toggle--45: var(--csstools-color-scheme--light) #fbfbfe; + --text-primary-color: var(--csstools-light-dark-toggle--45, #15141a); + --csstools-light-dark-toggle--46: var(--csstools-color-scheme--light) #cfcfd8; + --text-secondary-color: var(--csstools-light-dark-toggle--46, #5b5b66); + --hover-filter: brightness(0.9); + --csstools-light-dark-toggle--47: var(--csstools-color-scheme--light) #0df; + --link-fg-color: var(--csstools-light-dark-toggle--47, #0060df); + --csstools-light-dark-toggle--48: var(--csstools-color-scheme--light) #80ebff; + --link-hover-fg-color: var(--csstools-light-dark-toggle--48, #0250bb); + --csstools-light-dark-toggle--49: var(--csstools-color-scheme--light) #52525e; + --separator-color: var(--csstools-light-dark-toggle--49, #f0f0f4); + + --textarea-border-color: #8f8f9d; + --csstools-light-dark-toggle--50: var(--csstools-color-scheme--light) #42414d; + --textarea-bg-color: var(--csstools-light-dark-toggle--50, white); + --textarea-fg-color: var(--text-secondary-color); + + --csstools-light-dark-toggle--51: var(--csstools-color-scheme--light) #2b2a33; + + --radio-bg-color: var(--csstools-light-dark-toggle--51, #f0f0f4); + --csstools-light-dark-toggle--52: var(--csstools-color-scheme--light) #15141a; + --radio-checked-bg-color: var(--csstools-light-dark-toggle--52, #fbfbfe); + --radio-border-color: #8f8f9d; + --csstools-light-dark-toggle--53: var(--csstools-color-scheme--light) #0df; + --radio-checked-border-color: var(--csstools-light-dark-toggle--53, #0060df); + + --csstools-light-dark-toggle--54: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.07); + + --button-secondary-bg-color: var( + --csstools-light-dark-toggle--54, + rgb(21 20 26 / 0.07) + ); + --button-secondary-fg-color: var(--text-primary-color); + --button-secondary-border-color: var(--button-secondary-bg-color); + --csstools-light-dark-toggle--55: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.21); + --button-secondary-active-bg-color: var( + --csstools-light-dark-toggle--55, + rgb(21 20 26 / 0.21) + ); + --button-secondary-active-fg-color: var(--button-secondary-fg-color); + --button-secondary-active-border-color: var(--button-secondary-bg-color); + --csstools-light-dark-toggle--56: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.14); + --button-secondary-hover-bg-color: var( + --csstools-light-dark-toggle--56, + rgb(21 20 26 / 0.14) + ); + --button-secondary-hover-fg-color: var(--button-secondary-fg-color); + --button-secondary-hover-border-color: var(--button-secondary-hover-bg-color); + --button-secondary-disabled-bg-color: var(--button-secondary-bg-color); + --button-secondary-disabled-border-color: var( --button-secondary-border-color ); - --button-secondary-disabled-fg-color:var(--button-secondary-fg-color); + --button-secondary-disabled-fg-color: var(--button-secondary-fg-color); - --csstools-light-dark-toggle--57:var(--csstools-color-scheme--light) #0df; + --csstools-light-dark-toggle--57: var(--csstools-color-scheme--light) #0df; - --button-primary-bg-color:var(--csstools-light-dark-toggle--57, #0060df); - --csstools-light-dark-toggle--58:var(--csstools-color-scheme--light) #15141a; - --button-primary-fg-color:var(--csstools-light-dark-toggle--58, #fbfbfe); - --button-primary-border-color:var(--button-primary-bg-color); - --csstools-light-dark-toggle--59:var(--csstools-color-scheme--light) #aaf2ff; - --button-primary-active-bg-color:var(--csstools-light-dark-toggle--59, #054096); - --button-primary-active-fg-color:var(--button-primary-fg-color); - --button-primary-active-border-color:var(--button-primary-active-bg-color); - --csstools-light-dark-toggle--60:var(--csstools-color-scheme--light) #80ebff; - --button-primary-hover-bg-color:var(--csstools-light-dark-toggle--60, #0250bb); - --button-primary-hover-fg-color:var(--button-primary-fg-color); - --button-primary-hover-border-color:var(--button-primary-hover-bg-color); - --button-primary-disabled-bg-color:var(--button-primary-bg-color); - --button-primary-disabled-border-color:var(--button-primary-border-color); - --button-primary-disabled-fg-color:var(--button-primary-fg-color); - --button-disabled-opacity:0.4; - - --csstools-light-dark-toggle--61:var(--csstools-color-scheme--light) #42414d; - - --input-text-bg-color:var(--csstools-light-dark-toggle--61, white); - --input-text-fg-color:var(--text-primary-color); -} - -@supports (color: light-dark(red, red)){ -.dialog{ - --dialog-bg-color:light-dark(white, #1c1b22); - --dialog-border-color:light-dark(white, #1c1b22); -} -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.dialog{ - --dialog-shadow:0 2px 14px 0 light-dark(rgb(58 57 68 / 0.2), #15141a); -} -} - -@supports (color: light-dark(red, red)){ -.dialog{ - --text-primary-color:light-dark(#15141a, #fbfbfe); - --text-secondary-color:light-dark(#5b5b66, #cfcfd8); - --link-fg-color:light-dark(#0060df, #0df); - --link-hover-fg-color:light-dark(#0250bb, #80ebff); - --separator-color:light-dark(#f0f0f4, #52525e); - --textarea-bg-color:light-dark(white, #42414d); - - --radio-bg-color:light-dark(#f0f0f4, #2b2a33); - --radio-checked-bg-color:light-dark(#fbfbfe, #15141a); - --radio-checked-border-color:light-dark(#0060df, #0df); -} -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.dialog{ - - --button-secondary-bg-color:light-dark( - rgb(21 20 26 / 0.07), - rgb(251 251 254 / 0.07) + --button-primary-bg-color: var(--csstools-light-dark-toggle--57, #0060df); + --csstools-light-dark-toggle--58: var(--csstools-color-scheme--light) #15141a; + --button-primary-fg-color: var(--csstools-light-dark-toggle--58, #fbfbfe); + --button-primary-border-color: var(--button-primary-bg-color); + --csstools-light-dark-toggle--59: var(--csstools-color-scheme--light) #aaf2ff; + --button-primary-active-bg-color: var( + --csstools-light-dark-toggle--59, + #054096 ); - --button-secondary-active-bg-color:light-dark( - rgb(21 20 26 / 0.21), - rgb(251 251 254 / 0.21) + --button-primary-active-fg-color: var(--button-primary-fg-color); + --button-primary-active-border-color: var(--button-primary-active-bg-color); + --csstools-light-dark-toggle--60: var(--csstools-color-scheme--light) #80ebff; + --button-primary-hover-bg-color: var( + --csstools-light-dark-toggle--60, + #0250bb ); - --button-secondary-hover-bg-color:light-dark( - rgb(21 20 26 / 0.14), - rgb(251 251 254 / 0.14) + --button-primary-hover-fg-color: var(--button-primary-fg-color); + --button-primary-hover-border-color: var(--button-primary-hover-bg-color); + --button-primary-disabled-bg-color: var(--button-primary-bg-color); + --button-primary-disabled-border-color: var(--button-primary-border-color); + --button-primary-disabled-fg-color: var(--button-primary-fg-color); + --button-disabled-opacity: 0.4; + + --csstools-light-dark-toggle--61: var(--csstools-color-scheme--light) #42414d; + + --input-text-bg-color: var(--csstools-light-dark-toggle--61, white); + --input-text-fg-color: var(--text-primary-color); +} + +@supports (color: light-dark(red, red)) { + .dialog { + --dialog-bg-color: light-dark(white, #1c1b22); + --dialog-border-color: light-dark(white, #1c1b22); + } +} + +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .dialog { + --dialog-shadow: 0 2px 14px 0 light-dark(rgb(58 57 68 / 0.2), #15141a); + } +} + +@supports (color: light-dark(red, red)) { + .dialog { + --text-primary-color: light-dark(#15141a, #fbfbfe); + --text-secondary-color: light-dark(#5b5b66, #cfcfd8); + --link-fg-color: light-dark(#0060df, #0df); + --link-hover-fg-color: light-dark(#0250bb, #80ebff); + --separator-color: light-dark(#f0f0f4, #52525e); + --textarea-bg-color: light-dark(white, #42414d); + + --radio-bg-color: light-dark(#f0f0f4, #2b2a33); + --radio-checked-bg-color: light-dark(#fbfbfe, #15141a); + --radio-checked-border-color: light-dark(#0060df, #0df); + } +} + +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .dialog { + --button-secondary-bg-color: light-dark( + rgb(21 20 26 / 0.07), + rgb(251 251 254 / 0.07) + ); + --button-secondary-active-bg-color: light-dark( + rgb(21 20 26 / 0.21), + rgb(251 251 254 / 0.21) + ); + --button-secondary-hover-bg-color: light-dark( + rgb(21 20 26 / 0.14), + rgb(251 251 254 / 0.14) + ); + } +} + +@supports (color: light-dark(red, red)) { + .dialog { + --button-primary-bg-color: light-dark(#0060df, #0df); + --button-primary-fg-color: light-dark(#fbfbfe, #15141a); + --button-primary-active-bg-color: light-dark(#054096, #aaf2ff); + --button-primary-hover-bg-color: light-dark(#0250bb, #80ebff); + + --input-text-bg-color: light-dark(white, #42414d); + } +} + +@supports not (color: light-dark(tan, tan)) { + .dialog * { + --csstools-light-dark-toggle--42: var(--csstools-color-scheme--light) + #1c1b22; + --dialog-bg-color: var(--csstools-light-dark-toggle--42, white); + --csstools-light-dark-toggle--43: var(--csstools-color-scheme--light) + #1c1b22; + --dialog-border-color: var(--csstools-light-dark-toggle--43, white); + --csstools-light-dark-toggle--44: var(--csstools-color-scheme--light) + #15141a; + --dialog-shadow: 0 2px 14px 0 + var(--csstools-light-dark-toggle--44, rgb(58 57 68 / 0.2)); + --csstools-light-dark-toggle--45: var(--csstools-color-scheme--light) + #fbfbfe; + --text-primary-color: var(--csstools-light-dark-toggle--45, #15141a); + --csstools-light-dark-toggle--46: var(--csstools-color-scheme--light) + #cfcfd8; + --text-secondary-color: var(--csstools-light-dark-toggle--46, #5b5b66); + --csstools-light-dark-toggle--47: var(--csstools-color-scheme--light) #0df; + --link-fg-color: var(--csstools-light-dark-toggle--47, #0060df); + --csstools-light-dark-toggle--48: var(--csstools-color-scheme--light) + #80ebff; + --link-hover-fg-color: var(--csstools-light-dark-toggle--48, #0250bb); + --csstools-light-dark-toggle--49: var(--csstools-color-scheme--light) + #52525e; + --separator-color: var(--csstools-light-dark-toggle--49, #f0f0f4); + --csstools-light-dark-toggle--50: var(--csstools-color-scheme--light) + #42414d; + --textarea-bg-color: var(--csstools-light-dark-toggle--50, white); + + --csstools-light-dark-toggle--51: var(--csstools-color-scheme--light) + #2b2a33; + + --radio-bg-color: var(--csstools-light-dark-toggle--51, #f0f0f4); + --csstools-light-dark-toggle--52: var(--csstools-color-scheme--light) + #15141a; + --radio-checked-bg-color: var(--csstools-light-dark-toggle--52, #fbfbfe); + --csstools-light-dark-toggle--53: var(--csstools-color-scheme--light) #0df; + --radio-checked-border-color: var( + --csstools-light-dark-toggle--53, + #0060df + ); + + --csstools-light-dark-toggle--54: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.07); + + --button-secondary-bg-color: var( + --csstools-light-dark-toggle--54, + rgb(21 20 26 / 0.07) + ); + --csstools-light-dark-toggle--55: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.21); + --button-secondary-active-bg-color: var( + --csstools-light-dark-toggle--55, + rgb(21 20 26 / 0.21) + ); + --csstools-light-dark-toggle--56: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.14); + --button-secondary-hover-bg-color: var( + --csstools-light-dark-toggle--56, + rgb(21 20 26 / 0.14) + ); + + --csstools-light-dark-toggle--57: var(--csstools-color-scheme--light) #0df; + + --button-primary-bg-color: var(--csstools-light-dark-toggle--57, #0060df); + --csstools-light-dark-toggle--58: var(--csstools-color-scheme--light) + #15141a; + --button-primary-fg-color: var(--csstools-light-dark-toggle--58, #fbfbfe); + --csstools-light-dark-toggle--59: var(--csstools-color-scheme--light) + #aaf2ff; + --button-primary-active-bg-color: var( + --csstools-light-dark-toggle--59, + #054096 + ); + --csstools-light-dark-toggle--60: var(--csstools-color-scheme--light) + #80ebff; + --button-primary-hover-bg-color: var( + --csstools-light-dark-toggle--60, + #0250bb + ); + + --csstools-light-dark-toggle--61: var(--csstools-color-scheme--light) + #42414d; + + --input-text-bg-color: var(--csstools-light-dark-toggle--61, white); + } +} + +@media (prefers-color-scheme: dark) { + .dialog { + --hover-filter: brightness(1.4); + --button-disabled-opacity: 0.6; + } +} + +@media screen and (forced-colors: active) { + .dialog { + --dialog-bg-color: Canvas; + --dialog-border-color: CanvasText; + --dialog-shadow: none; + --text-primary-color: CanvasText; + --text-secondary-color: CanvasText; + --hover-filter: none; + --link-fg-color: LinkText; + --link-hover-fg-color: LinkText; + --separator-color: CanvasText; + + --textarea-border-color: ButtonBorder; + --textarea-bg-color: Field; + --textarea-fg-color: ButtonText; + + --radio-bg-color: ButtonFace; + --radio-checked-bg-color: ButtonFace; + --radio-border-color: ButtonText; + --radio-checked-border-color: ButtonText; + + --button-secondary-bg-color: ButtonFace; + --button-secondary-fg-color: ButtonText; + --button-secondary-border-color: ButtonText; + --button-secondary-active-bg-color: HighlightText; + --button-secondary-active-fg-color: SelectedItem; + --button-secondary-active-border-color: ButtonText; + --button-secondary-hover-bg-color: HighlightText; + --button-secondary-hover-fg-color: SelectedItem; + --button-secondary-hover-border-color: SelectedItem; + --button-secondary-disabled-fg-color: GrayText; + --button-secondary-disabled-border-color: GrayText; + + --button-primary-bg-color: ButtonText; + --button-primary-fg-color: ButtonFace; + --button-primary-border-color: ButtonText; + --button-primary-active-bg-color: SelectedItem; + --button-primary-active-fg-color: HighlightText; + --button-primary-active-border-color: ButtonText; + --button-primary-hover-bg-color: SelectedItem; + --button-primary-hover-fg-color: HighlightText; + --button-primary-hover-border-color: SelectedItem; + --button-primary-disabled-bg-color: GrayText; + --button-primary-disabled-fg-color: ButtonFace; + --button-primary-disabled-border-color: GrayText; + --button-disabled-opacity: 1; + + --input-text-bg-color: Field; + --input-text-fg-color: FieldText; + } +} + +.dialog { + font: message-box; + font-size: 13px; + font-weight: 400; + line-height: 150%; + border-radius: 4px; + padding: 12px 16px; + border: 1px solid var(--dialog-border-color); + background: var(--dialog-bg-color); + color: var(--text-primary-color); + box-shadow: var(--dialog-shadow); +} + +:is(.dialog .mainContainer) *:focus-visible { + outline: var(--focus-ring-outline); + outline-offset: 2px; +} + +:is(.dialog .mainContainer) .title { + display: flex; + width: auto; + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + gap: 12px; +} + +:is(:is(.dialog .mainContainer) .title) > span { + font-size: 13px; + font-style: normal; + font-weight: 590; + line-height: 150%; +} + +:is(.dialog .mainContainer) .dialogSeparator { + width: 100%; + height: 0; + margin-block: 4px; + border-top: 1px solid var(--separator-color); + border-bottom: none; +} + +:is(.dialog .mainContainer) .dialogButtonsGroup { + display: flex; + gap: 12px; + align-self: flex-end; +} + +:is(.dialog .mainContainer) .radio { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; +} + +:is(:is(.dialog .mainContainer) .radio) > .radioButton { + display: flex; + gap: 8px; + align-self: stretch; + align-items: center; +} + +:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + box-sizing: border-box; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: var(--radio-bg-color); + border: 1px solid var(--radio-border-color); +} + +:is(:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input):hover { + filter: var(--hover-filter); +} + +:is(:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input):checked { + background-color: var(--radio-checked-bg-color); + border: 4px solid var(--radio-checked-border-color); +} + +:is(:is(.dialog .mainContainer) .radio) > .radioLabel { + display: flex; + padding-inline-start: 24px; + align-items: flex-start; + gap: 10px; + align-self: stretch; +} + +:is(:is(:is(.dialog .mainContainer) .radio) > .radioLabel) > span { + flex: 1 0 0; + font-size: 11px; + color: var(--text-secondary-color); +} + +:is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) { + border-radius: 4px; + border: 1px solid; + font: menu; + font-weight: 590; + font-size: 13px; + padding: 4px 16px; + width: auto; + height: 32px; +} + +:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) +):hover { + cursor: pointer; + filter: var(--hover-filter); +} + +:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ) + > span { + color: inherit; + font: inherit; +} + +.secondaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) +) { + color: var(--button-secondary-fg-color); + background-color: var(--button-secondary-bg-color); + border-color: var(--button-secondary-border-color); +} + +.secondaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):hover { + color: var(--button-secondary-hover-fg-color); + background-color: var(--button-secondary-hover-bg-color); + border-color: var(--button-secondary-hover-border-color); +} + +.secondaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):active { + color: var(--button-secondary-active-fg-color); + background-color: var(--button-secondary-active-bg-color); + border-color: var(--button-secondary-active-border-color); +} + +.secondaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):disabled { + background-color: var(--button-secondary-disabled-bg-color); + border-color: var(--button-secondary-disabled-border-color); + color: var(--button-secondary-disabled-fg-color); + opacity: var(--button-disabled-opacity); +} + +.primaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) +) { + color: var(--button-primary-fg-color); + background-color: var(--button-primary-bg-color); + border-color: var(--button-primary-border-color); + opacity: 1; +} + +.primaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):hover { + color: var(--button-primary-hover-fg-color); + background-color: var(--button-primary-hover-bg-color); + border-color: var(--button-primary-hover-border-color); +} + +.primaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):active { + color: var(--button-primary-active-fg-color); + background-color: var(--button-primary-active-bg-color); + border-color: var(--button-primary-active-border-color); +} + +.primaryButton:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) + ):disabled { + background-color: var(--button-primary-disabled-bg-color); + border-color: var(--button-primary-disabled-border-color); + color: var(--button-primary-disabled-fg-color); + opacity: var(--button-disabled-opacity); +} + +:is( + :is(.dialog .mainContainer) + button:not(:is(.toggle-button, .closeButton, .clearInputButton)) +):disabled { + pointer-events: none; +} + +:is(.dialog .mainContainer) a { + color: var(--link-fg-color); +} + +:is(:is(.dialog .mainContainer) a):hover { + color: var(--link-hover-fg-color); +} + +:is(.dialog .mainContainer) textarea { + font: inherit; + padding: 8px; + resize: none; + margin: 0; + box-sizing: border-box; + border-radius: 4px; + border: 1px solid var(--textarea-border-color); + background: var(--textarea-bg-color); + color: var(--textarea-fg-color); +} + +:is(:is(.dialog .mainContainer) textarea):focus { + outline-offset: 0; + border-color: transparent; +} + +:is(:is(.dialog .mainContainer) textarea):disabled { + pointer-events: none; + opacity: 0.4; +} + +:is(.dialog .mainContainer) input[type='text'] { + background-color: var(--input-text-bg-color); + color: var(--input-text-fg-color); +} + +:is(.dialog .mainContainer) .messageBar { + --csstools-light-dark-toggle--62: var(--csstools-color-scheme--light) #5a3100; + --message-bar-bg-color: var(--csstools-light-dark-toggle--62, #ffebcd); + --csstools-light-dark-toggle--63: var(--csstools-color-scheme--light) #fbfbfe; + --message-bar-fg-color: var(--csstools-light-dark-toggle--63, #15141a); + --csstools-light-dark-toggle--64: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + --message-bar-border-color: var( + --csstools-light-dark-toggle--64, + rgb(0 0 0 / 0.08) ); -} + --message-bar-icon: url(images/messageBar_warning.svg); + --csstools-light-dark-toggle--65: var(--csstools-color-scheme--light) #e49c49; + --message-bar-icon-color: var(--csstools-light-dark-toggle--65, #cd411e); } -@supports (color: light-dark(red, red)){ -.dialog{ - - --button-primary-bg-color:light-dark(#0060df, #0df); - --button-primary-fg-color:light-dark(#fbfbfe, #15141a); - --button-primary-active-bg-color:light-dark(#054096, #aaf2ff); - --button-primary-hover-bg-color:light-dark(#0250bb, #80ebff); - - --input-text-bg-color:light-dark(white, #42414d); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.dialog *{ - --csstools-light-dark-toggle--42:var(--csstools-color-scheme--light) #1c1b22; - --dialog-bg-color:var(--csstools-light-dark-toggle--42, white); - --csstools-light-dark-toggle--43:var(--csstools-color-scheme--light) #1c1b22; - --dialog-border-color:var(--csstools-light-dark-toggle--43, white); - --csstools-light-dark-toggle--44:var(--csstools-color-scheme--light) #15141a; - --dialog-shadow:0 2px 14px 0 var(--csstools-light-dark-toggle--44, rgb(58 57 68 / 0.2)); - --csstools-light-dark-toggle--45:var(--csstools-color-scheme--light) #fbfbfe; - --text-primary-color:var(--csstools-light-dark-toggle--45, #15141a); - --csstools-light-dark-toggle--46:var(--csstools-color-scheme--light) #cfcfd8; - --text-secondary-color:var(--csstools-light-dark-toggle--46, #5b5b66); - --csstools-light-dark-toggle--47:var(--csstools-color-scheme--light) #0df; - --link-fg-color:var(--csstools-light-dark-toggle--47, #0060df); - --csstools-light-dark-toggle--48:var(--csstools-color-scheme--light) #80ebff; - --link-hover-fg-color:var(--csstools-light-dark-toggle--48, #0250bb); - --csstools-light-dark-toggle--49:var(--csstools-color-scheme--light) #52525e; - --separator-color:var(--csstools-light-dark-toggle--49, #f0f0f4); - --csstools-light-dark-toggle--50:var(--csstools-color-scheme--light) #42414d; - --textarea-bg-color:var(--csstools-light-dark-toggle--50, white); - - --csstools-light-dark-toggle--51:var(--csstools-color-scheme--light) #2b2a33; - - --radio-bg-color:var(--csstools-light-dark-toggle--51, #f0f0f4); - --csstools-light-dark-toggle--52:var(--csstools-color-scheme--light) #15141a; - --radio-checked-bg-color:var(--csstools-light-dark-toggle--52, #fbfbfe); - --csstools-light-dark-toggle--53:var(--csstools-color-scheme--light) #0df; - --radio-checked-border-color:var(--csstools-light-dark-toggle--53, #0060df); - - --csstools-light-dark-toggle--54:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.07); - - --button-secondary-bg-color:var(--csstools-light-dark-toggle--54, rgb(21 20 26 / 0.07)); - --csstools-light-dark-toggle--55:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.21); - --button-secondary-active-bg-color:var(--csstools-light-dark-toggle--55, rgb(21 20 26 / 0.21)); - --csstools-light-dark-toggle--56:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.14); - --button-secondary-hover-bg-color:var(--csstools-light-dark-toggle--56, rgb(21 20 26 / 0.14)); - - --csstools-light-dark-toggle--57:var(--csstools-color-scheme--light) #0df; - - --button-primary-bg-color:var(--csstools-light-dark-toggle--57, #0060df); - --csstools-light-dark-toggle--58:var(--csstools-color-scheme--light) #15141a; - --button-primary-fg-color:var(--csstools-light-dark-toggle--58, #fbfbfe); - --csstools-light-dark-toggle--59:var(--csstools-color-scheme--light) #aaf2ff; - --button-primary-active-bg-color:var(--csstools-light-dark-toggle--59, #054096); - --csstools-light-dark-toggle--60:var(--csstools-color-scheme--light) #80ebff; - --button-primary-hover-bg-color:var(--csstools-light-dark-toggle--60, #0250bb); - - --csstools-light-dark-toggle--61:var(--csstools-color-scheme--light) #42414d; - - --input-text-bg-color:var(--csstools-light-dark-toggle--61, white); +@supports (color: light-dark(red, red)) { + :is(.dialog .mainContainer) .messageBar { + --message-bar-bg-color: light-dark(#ffebcd, #5a3100); + --message-bar-fg-color: light-dark(#15141a, #fbfbfe); } } -@media (prefers-color-scheme: dark){ - -.dialog{ - --hover-filter:brightness(1.4); - --button-disabled-opacity:0.6; -} - } - -@media screen and (forced-colors: active){ - -.dialog{ - --dialog-bg-color:Canvas; - --dialog-border-color:CanvasText; - --dialog-shadow:none; - --text-primary-color:CanvasText; - --text-secondary-color:CanvasText; - --hover-filter:none; - --link-fg-color:LinkText; - --link-hover-fg-color:LinkText; - --separator-color:CanvasText; - - --textarea-border-color:ButtonBorder; - --textarea-bg-color:Field; - --textarea-fg-color:ButtonText; - - --radio-bg-color:ButtonFace; - --radio-checked-bg-color:ButtonFace; - --radio-border-color:ButtonText; - --radio-checked-border-color:ButtonText; - - --button-secondary-bg-color:ButtonFace; - --button-secondary-fg-color:ButtonText; - --button-secondary-border-color:ButtonText; - --button-secondary-active-bg-color:HighlightText; - --button-secondary-active-fg-color:SelectedItem; - --button-secondary-active-border-color:ButtonText; - --button-secondary-hover-bg-color:HighlightText; - --button-secondary-hover-fg-color:SelectedItem; - --button-secondary-hover-border-color:SelectedItem; - --button-secondary-disabled-fg-color:GrayText; - --button-secondary-disabled-border-color:GrayText; - - --button-primary-bg-color:ButtonText; - --button-primary-fg-color:ButtonFace; - --button-primary-border-color:ButtonText; - --button-primary-active-bg-color:SelectedItem; - --button-primary-active-fg-color:HighlightText; - --button-primary-active-border-color:ButtonText; - --button-primary-hover-bg-color:SelectedItem; - --button-primary-hover-fg-color:HighlightText; - --button-primary-hover-border-color:SelectedItem; - --button-primary-disabled-bg-color:GrayText; - --button-primary-disabled-fg-color:ButtonFace; - --button-primary-disabled-border-color:GrayText; - --button-disabled-opacity:1; - - --input-text-bg-color:Field; - --input-text-fg-color:FieldText; -} - } - -.dialog{ - - font:message-box; - font-size:13px; - font-weight:400; - line-height:150%; - border-radius:4px; - padding:12px 16px; - border:1px solid var(--dialog-border-color); - background:var(--dialog-bg-color); - color:var(--text-primary-color); - box-shadow:var(--dialog-shadow); -} - -:is(.dialog .mainContainer) *:focus-visible{ - outline:var(--focus-ring-outline); - outline-offset:2px; - } - -:is(.dialog .mainContainer) .title{ - display:flex; - width:auto; - flex-direction:column; - justify-content:flex-end; - align-items:flex-start; - gap:12px; - } - -:is(:is(.dialog .mainContainer) .title) > span{ - font-size:13px; - font-style:normal; - font-weight:590; - line-height:150%; - } - -:is(.dialog .mainContainer) .dialogSeparator{ - width:100%; - height:0; - margin-block:4px; - border-top:1px solid var(--separator-color); - border-bottom:none; - } - -:is(.dialog .mainContainer) .dialogButtonsGroup{ - display:flex; - gap:12px; - align-self:flex-end; - } - -:is(.dialog .mainContainer) .radio{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:4px; - } - -:is(:is(.dialog .mainContainer) .radio) > .radioButton{ - display:flex; - gap:8px; - align-self:stretch; - align-items:center; - } - -:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input{ - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - box-sizing:border-box; - width:16px; - height:16px; - border-radius:50%; - background-color:var(--radio-bg-color); - border:1px solid var(--radio-border-color); - } - -:is(:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input):hover{ - filter:var(--hover-filter); - } - -:is(:is(:is(:is(.dialog .mainContainer) .radio) > .radioButton) input):checked{ - background-color:var(--radio-checked-bg-color); - border:4px solid var(--radio-checked-border-color); - } - -:is(:is(.dialog .mainContainer) .radio) > .radioLabel{ - display:flex; - padding-inline-start:24px; - align-items:flex-start; - gap:10px; - align-self:stretch; - } - -:is(:is(:is(.dialog .mainContainer) .radio) > .radioLabel) > span{ - flex:1 0 0; - font-size:11px; - color:var(--text-secondary-color); - } - -:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton)){ - border-radius:4px; - border:1px solid; - font:menu; - font-weight:590; - font-size:13px; - padding:4px 16px; - width:auto; - height:32px; - } - -:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):hover{ - cursor:pointer; - filter:var(--hover-filter); - } - -:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))) > span{ - color:inherit; - font:inherit; - } - -.secondaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))){ - color:var(--button-secondary-fg-color); - background-color:var(--button-secondary-bg-color); - border-color:var(--button-secondary-border-color); - } - -.secondaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):hover{ - color:var(--button-secondary-hover-fg-color); - background-color:var(--button-secondary-hover-bg-color); - border-color:var(--button-secondary-hover-border-color); - } - -.secondaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):active{ - color:var(--button-secondary-active-fg-color); - background-color:var(--button-secondary-active-bg-color); - border-color:var(--button-secondary-active-border-color); - } - -.secondaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):disabled{ - background-color:var(--button-secondary-disabled-bg-color); - border-color:var(--button-secondary-disabled-border-color); - color:var(--button-secondary-disabled-fg-color); - opacity:var(--button-disabled-opacity); - } - -.primaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))){ - color:var(--button-primary-fg-color); - background-color:var(--button-primary-bg-color); - border-color:var(--button-primary-border-color); - opacity:1; - } - -.primaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):hover{ - color:var(--button-primary-hover-fg-color); - background-color:var(--button-primary-hover-bg-color); - border-color:var(--button-primary-hover-border-color); - } - -.primaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):active{ - color:var(--button-primary-active-fg-color); - background-color:var(--button-primary-active-bg-color); - border-color:var(--button-primary-active-border-color); - } - -.primaryButton:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):disabled{ - background-color:var(--button-primary-disabled-bg-color); - border-color:var(--button-primary-disabled-border-color); - color:var(--button-primary-disabled-fg-color); - opacity:var(--button-disabled-opacity); - } - -:is(:is(.dialog .mainContainer) button:not(:is(.toggle-button,.closeButton,.clearInputButton))):disabled{ - pointer-events:none; - } - -:is(.dialog .mainContainer) a{ - color:var(--link-fg-color); - } - -:is(:is(.dialog .mainContainer) a):hover{ - color:var(--link-hover-fg-color); - } - -:is(.dialog .mainContainer) textarea{ - font:inherit; - padding:8px; - resize:none; - margin:0; - box-sizing:border-box; - border-radius:4px; - border:1px solid var(--textarea-border-color); - background:var(--textarea-bg-color); - color:var(--textarea-fg-color); - } - -:is(:is(.dialog .mainContainer) textarea):focus{ - outline-offset:0; - border-color:transparent; - } - -:is(:is(.dialog .mainContainer) textarea):disabled{ - pointer-events:none; - opacity:0.4; - } - -:is(.dialog .mainContainer) input[type="text"]{ - background-color:var(--input-text-bg-color); - color:var(--input-text-fg-color); - } - -:is(.dialog .mainContainer) .messageBar{ - --csstools-light-dark-toggle--62:var(--csstools-color-scheme--light) #5a3100; - --message-bar-bg-color:var(--csstools-light-dark-toggle--62, #ffebcd); - --csstools-light-dark-toggle--63:var(--csstools-color-scheme--light) #fbfbfe; - --message-bar-fg-color:var(--csstools-light-dark-toggle--63, #15141a); - --csstools-light-dark-toggle--64:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - --message-bar-border-color:var(--csstools-light-dark-toggle--64, rgb(0 0 0 / 0.08)); - --message-bar-icon:url(images/messageBar_warning.svg); - --csstools-light-dark-toggle--65:var(--csstools-color-scheme--light) #e49c49; - --message-bar-icon-color:var(--csstools-light-dark-toggle--65, #cd411e); - } - -@supports (color: light-dark(red, red)){ -:is(.dialog .mainContainer) .messageBar{ - --message-bar-bg-color:light-dark(#ffebcd, #5a3100); - --message-bar-fg-color:light-dark(#15141a, #fbfbfe); - } -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -:is(.dialog .mainContainer) .messageBar{ - --message-bar-border-color:light-dark( - rgb(0 0 0 / 0.08), - rgb(255 255 255 / 0.08) - ); - } -} - -@supports (color: light-dark(red, red)){ -:is(.dialog .mainContainer) .messageBar{ - --message-bar-icon-color:light-dark(#cd411e, #e49c49); - } -} - -@supports not (color: light-dark(tan, tan)){ - -:is(:is(.dialog .mainContainer) .messageBar) *{ - --csstools-light-dark-toggle--62:var(--csstools-color-scheme--light) #5a3100; - --message-bar-bg-color:var(--csstools-light-dark-toggle--62, #ffebcd); - --csstools-light-dark-toggle--63:var(--csstools-color-scheme--light) #fbfbfe; - --message-bar-fg-color:var(--csstools-light-dark-toggle--63, #15141a); - --csstools-light-dark-toggle--64:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.08); - --message-bar-border-color:var(--csstools-light-dark-toggle--64, rgb(0 0 0 / 0.08)); - --csstools-light-dark-toggle--65:var(--csstools-color-scheme--light) #e49c49; - --message-bar-icon-color:var(--csstools-light-dark-toggle--65, #cd411e); +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + :is(.dialog .mainContainer) .messageBar { + --message-bar-border-color: light-dark( + rgb(0 0 0 / 0.08), + rgb(255 255 255 / 0.08) + ); } } -@media screen and (forced-colors: active){ - -:is(.dialog .mainContainer) .messageBar{ - --message-bar-bg-color:HighlightText; - --message-bar-fg-color:CanvasText; - --message-bar-border-color:CanvasText; - --message-bar-icon-color:CanvasText; - } - } - -:is(.dialog .mainContainer) .messageBar{ - - align-self:stretch; - } - -:is(:is(:is(.dialog .mainContainer) .messageBar) > div)::before,:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div{ - margin-block:4px; - } - -:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:8px; - flex:1 0 0; - } - -:is(:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div) .title{ - font-size:13px; - font-weight:590; - } - -:is(:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div) .description{ - font-size:13px; - } - -:is(.dialog .mainContainer) .toggler{ - display:flex; - align-items:center; - gap:8px; - align-self:stretch; - } - -:is(:is(.dialog .mainContainer) .toggler) > .togglerLabel{ - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -.textLayer{ - position:absolute; - text-align:initial; - inset:0; - overflow:clip; - opacity:1; - line-height:1; - -webkit-text-size-adjust:none; - -moz-text-size-adjust:none; - text-size-adjust:none; - forced-color-adjust:none; - transform-origin:0 0; - caret-color:CanvasText; - z-index:0; -} - -.textLayer.highlighting{ - touch-action:none; - } - -.textLayer :is(span,br){ - color:transparent; - position:absolute; - white-space:pre; - cursor:text; - transform-origin:0% 0%; - } - -.textLayer > :not(.markedContent),.textLayer .markedContent span:not(.markedContent){ - z-index:1; - } - -.textLayer span.markedContent{ - top:0; - height:0; - } - -.textLayer span[role="img"]{ - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - cursor:default; - } - -.textLayer .highlight{ - --highlight-bg-color:rgb(180 0 170 / 0.25); - --highlight-selected-bg-color:rgb(0 100 0 / 0.25); - --highlight-backdrop-filter:none; - --highlight-selected-backdrop-filter:none; - } - -@media screen and (forced-colors: active){ - -.textLayer .highlight{ - --highlight-bg-color:transparent; - --highlight-selected-bg-color:transparent; - --highlight-backdrop-filter:var(--hcm-highlight-filter); - --highlight-selected-backdrop-filter:var( - --hcm-highlight-selected-filter - ); - } - } - -.textLayer .highlight{ - - margin:-1px; - padding:1px; - background-color:var(--highlight-bg-color); - -webkit-backdrop-filter:var(--highlight-backdrop-filter); - backdrop-filter:var(--highlight-backdrop-filter); - border-radius:4px; - } - -.appended:is(.textLayer .highlight){ - position:initial; - } - -.begin:is(.textLayer .highlight){ - border-radius:4px 0 0 4px; - } - -.end:is(.textLayer .highlight){ - border-radius:0 4px 4px 0; - } - -.middle:is(.textLayer .highlight){ - border-radius:0; - } - -.selected:is(.textLayer .highlight){ - background-color:var(--highlight-selected-bg-color); - -webkit-backdrop-filter:var(--highlight-selected-backdrop-filter); - backdrop-filter:var(--highlight-selected-backdrop-filter); - } - -.textLayer ::-moz-selection{ - background:rgba(0 0 255 / 0.25); - background:color-mix(in srgb, AccentColor, transparent 75%); - } - -.textLayer ::selection{ - background:rgba(0 0 255 / 0.25); - background:color-mix(in srgb, AccentColor, transparent 75%); - } - -.textLayer br::-moz-selection{ - background:transparent; - } - -.textLayer br::selection{ - background:transparent; - } - -.textLayer .endOfContent{ - display:block; - position:absolute; - inset:100% 0 0; - z-index:0; - cursor:default; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -.textLayer.selecting .endOfContent{ - top:0; - } - -.annotationLayer{ - --csstools-color-scheme--light:initial; - color-scheme:only light; - - --annotation-unfocused-field-background:url("data:image/svg+xml;charset=UTF-8,"); - --input-focus-border-color:Highlight; - --input-focus-outline:1px solid Canvas; - --input-unfocused-border-color:transparent; - --input-disabled-border-color:transparent; - --input-hover-border-color:black; - --link-outline:none; -} - -@media screen and (forced-colors: active){ - -.annotationLayer{ - --input-focus-border-color:CanvasText; - --input-unfocused-border-color:ActiveText; - --input-disabled-border-color:GrayText; - --input-hover-border-color:Highlight; - --link-outline:1.5px solid LinkText; -} - - .annotationLayer .textWidgetAnnotation :is(input,textarea):required,.annotationLayer .choiceWidgetAnnotation select:required,.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input:required{ - outline:1.5px solid selectedItem; - } - - .annotationLayer .linkAnnotation{ - outline:var(--link-outline); - } - - :is(.annotationLayer .linkAnnotation):hover{ - -webkit-backdrop-filter:var(--hcm-highlight-filter); - backdrop-filter:var(--hcm-highlight-filter); - } - - :is(.annotationLayer .linkAnnotation) > a:hover{ - opacity:0 !important; - background:none !important; - box-shadow:none; - } - - .annotationLayer .popupAnnotation .popup{ - outline:calc(1.5px * var(--total-scale-factor)) solid CanvasText !important; - background-color:ButtonFace !important; - color:ButtonText !important; - } - - .annotationLayer .highlightArea:hover::after{ - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - -webkit-backdrop-filter:var(--hcm-highlight-filter); - backdrop-filter:var(--hcm-highlight-filter); - content:""; - pointer-events:none; - } - - .annotationLayer .popupAnnotation.focused .popup{ - outline:calc(3px * var(--total-scale-factor)) solid Highlight !important; - } - } - -.annotationLayer{ - - position:absolute; - top:0; - left:0; - pointer-events:none; - transform-origin:0 0; -} - -.annotationLayer[data-main-rotation="90"] .norotate{ - transform:rotate(270deg) translateX(-100%); - } - -.annotationLayer[data-main-rotation="180"] .norotate{ - transform:rotate(180deg) translate(-100%, -100%); - } - -.annotationLayer[data-main-rotation="270"] .norotate{ - transform:rotate(90deg) translateY(-100%); - } - -.annotationLayer.disabled section,.annotationLayer.disabled .popup{ - pointer-events:none; - } - -.annotationLayer .annotationContent{ - position:absolute; - width:100%; - height:100%; - pointer-events:none; - } - -.freetext:is(.annotationLayer .annotationContent){ - background:transparent; - border:none; - inset:0; - overflow:visible; - white-space:nowrap; - font:10px sans-serif; - line-height:1.35; - } - -.annotationLayer section{ - position:absolute; - text-align:initial; - pointer-events:auto; - box-sizing:border-box; - transform-origin:0 0; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -:is(.annotationLayer section):has(div.annotationContent) canvas.annotationContent{ - display:none; - } - -:is(.annotationLayer section) .overlaidText{ - position:absolute; - top:0; - left:0; - width:0; - height:0; - display:inline-block; - overflow:hidden; - } - -.textLayer.selecting ~ .annotationLayer section{ - pointer-events:none; - } - -.annotationLayer :is(.linkAnnotation,.buttonWidgetAnnotation.pushButton) > a{ - position:absolute; - font-size:1em; - top:0; - left:0; - width:100%; - height:100%; - } - -.annotationLayer :is(.linkAnnotation,.buttonWidgetAnnotation.pushButton):not(.hasBorder) > a:hover{ - opacity:0.2; - background-color:rgb(255 255 0); - } - -.annotationLayer .linkAnnotation.hasBorder:hover{ - background-color:rgb(255 255 0 / 0.2); - } - -.annotationLayer .hasBorder{ - background-size:100% 100%; - } - -.annotationLayer .textAnnotation img{ - position:absolute; - cursor:pointer; - width:100%; - height:100%; - top:0; - left:0; - } - -.annotationLayer .textWidgetAnnotation :is(input,textarea),.annotationLayer .choiceWidgetAnnotation select,.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input{ - background-image:var(--annotation-unfocused-field-background); - border:2px solid var(--input-unfocused-border-color); - box-sizing:border-box; - font:calc(9px * var(--total-scale-factor)) sans-serif; - height:100%; - margin:0; - vertical-align:top; - width:100%; - } - -.annotationLayer .textWidgetAnnotation :is(input,textarea):required,.annotationLayer .choiceWidgetAnnotation select:required,.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input:required{ - outline:1.5px solid red; - } - -.annotationLayer .choiceWidgetAnnotation select option{ - padding:0; - } - -.annotationLayer .buttonWidgetAnnotation.radioButton input{ - border-radius:50%; - } - -.annotationLayer .textWidgetAnnotation textarea{ - resize:none; - } - -.annotationLayer .textWidgetAnnotation [disabled]:is(input,textarea),.annotationLayer .choiceWidgetAnnotation select[disabled],.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input[disabled]{ - background:none; - border:2px solid var(--input-disabled-border-color); - cursor:not-allowed; - } - -.annotationLayer .textWidgetAnnotation :is(input,textarea):hover,.annotationLayer .choiceWidgetAnnotation select:hover,.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input:hover{ - border:2px solid var(--input-hover-border-color); - } - -.annotationLayer .textWidgetAnnotation :is(input,textarea):hover,.annotationLayer .choiceWidgetAnnotation select:hover,.annotationLayer .buttonWidgetAnnotation.checkBox input:hover{ - border-radius:2px; - } - -.annotationLayer .textWidgetAnnotation :is(input,textarea):focus,.annotationLayer .choiceWidgetAnnotation select:focus{ - background:none; - border:2px solid var(--input-focus-border-color); - border-radius:2px; - outline:var(--input-focus-outline); - } - -.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) :focus{ - background-image:none; - background-color:transparent; - } - -.annotationLayer .buttonWidgetAnnotation.checkBox :focus{ - border:2px solid var(--input-focus-border-color); - border-radius:2px; - outline:var(--input-focus-outline); - } - -.annotationLayer .buttonWidgetAnnotation.radioButton :focus{ - border:2px solid var(--input-focus-border-color); - outline:var(--input-focus-outline); - } - -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after,.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before{ - background-color:CanvasText; - content:""; - display:block; - position:absolute; - } - -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after{ - height:80%; - left:45%; - width:1px; - } - -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before{ - transform:rotate(45deg); - } - -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after{ - transform:rotate(-45deg); - } - -.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before{ - border-radius:50%; - height:50%; - left:25%; - top:25%; - width:50%; - } - -.annotationLayer .textWidgetAnnotation input.comb{ - font-family:monospace; - padding-left:2px; - padding-right:0; - } - -.annotationLayer .textWidgetAnnotation input.comb:focus{ - width:103%; - } - -.annotationLayer .buttonWidgetAnnotation:is(.checkBox,.radioButton) input{ - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - } - -.annotationLayer .fileAttachmentAnnotation .popupTriggerArea{ - height:100%; - width:100%; - } - -.annotationLayer .popupAnnotation{ - position:absolute; - font-size:calc(9px * var(--total-scale-factor)); - pointer-events:none; - width:-moz-max-content; - width:max-content; - max-width:45%; - height:auto; - } - -.annotationLayer .popup{ - background-color:rgb(255 255 153); - color:black; - box-shadow:0 calc(2px * var(--total-scale-factor)) calc(5px * var(--total-scale-factor)) rgb(136 136 136); - border-radius:calc(2px * var(--total-scale-factor)); - outline:1.5px solid rgb(255 255 74); - padding:calc(6px * var(--total-scale-factor)); - cursor:pointer; - font:message-box; - white-space:normal; - word-wrap:break-word; - pointer-events:auto; - -webkit-user-select:text; - -moz-user-select:text; - user-select:text; - } - -.annotationLayer .popupAnnotation.focused .popup{ - outline-width:3px; - } - -.annotationLayer .popup *{ - font-size:calc(9px * var(--total-scale-factor)); - } - -.annotationLayer .popup > .header{ - display:inline-block; - } - -.annotationLayer .popup > .header > .title{ - display:inline; - font-weight:bold; - } - -.annotationLayer .popup > .header .popupDate{ - display:inline-block; - margin-left:calc(5px * var(--total-scale-factor)); - width:-moz-fit-content; - width:fit-content; - } - -.annotationLayer .popupContent{ - border-top:1px solid rgb(51 51 51); - margin-top:calc(2px * var(--total-scale-factor)); - padding-top:calc(2px * var(--total-scale-factor)); - } - -.annotationLayer .richText > *{ - white-space:pre-wrap; - font-size:calc(9px * var(--total-scale-factor)); - } - -.annotationLayer .popupTriggerArea{ - cursor:pointer; - } - -:is(.annotationLayer .popupTriggerArea):hover{ - -webkit-backdrop-filter:var(--hcm-highlight-filter); - backdrop-filter:var(--hcm-highlight-filter); - } - -.annotationLayer section svg{ - position:absolute; - width:100%; - height:100%; - top:0; - left:0; - } - -.annotationLayer .annotationTextContent{ - position:absolute; - width:100%; - height:100%; - opacity:0; - color:transparent; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - pointer-events:none; - } - -:is(.annotationLayer .annotationTextContent) span{ - width:100%; - display:inline-block; - } - -.annotationLayer svg.quadrilateralsContainer{ - contain:strict; - width:0; - height:0; - position:absolute; - top:0; - left:0; - z-index:-1; - } - -:root{ - --xfa-unfocused-field-background:url("data:image/svg+xml;charset=UTF-8,"); - --xfa-focus-outline:auto; -} - -@media screen and (forced-colors: active){ - :root{ - --xfa-focus-outline:2px solid CanvasText; - } - .xfaLayer *:required{ - outline:1.5px solid selectedItem; +@supports (color: light-dark(red, red)) { + :is(.dialog .mainContainer) .messageBar { + --message-bar-icon-color: light-dark(#cd411e, #e49c49); } } -.xfaLayer{ - --csstools-color-scheme--light:initial; - color-scheme:only light; - - background-color:transparent; +@supports not (color: light-dark(tan, tan)) { + :is(:is(.dialog .mainContainer) .messageBar) * { + --csstools-light-dark-toggle--62: var(--csstools-color-scheme--light) + #5a3100; + --message-bar-bg-color: var(--csstools-light-dark-toggle--62, #ffebcd); + --csstools-light-dark-toggle--63: var(--csstools-color-scheme--light) + #fbfbfe; + --message-bar-fg-color: var(--csstools-light-dark-toggle--63, #15141a); + --csstools-light-dark-toggle--64: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.08); + --message-bar-border-color: var( + --csstools-light-dark-toggle--64, + rgb(0 0 0 / 0.08) + ); + --csstools-light-dark-toggle--65: var(--csstools-color-scheme--light) + #e49c49; + --message-bar-icon-color: var(--csstools-light-dark-toggle--65, #cd411e); + } } -.xfaLayer .highlight{ - margin:-1px; - padding:1px; - background-color:rgb(239 203 237); - border-radius:4px; +@media screen and (forced-colors: active) { + :is(.dialog .mainContainer) .messageBar { + --message-bar-bg-color: HighlightText; + --message-bar-fg-color: CanvasText; + --message-bar-border-color: CanvasText; + --message-bar-icon-color: CanvasText; + } } -.xfaLayer .highlight.appended{ - position:initial; +:is(.dialog .mainContainer) .messageBar { + align-self: stretch; } -.xfaLayer .highlight.begin{ - border-radius:4px 0 0 4px; +:is(:is(:is(.dialog .mainContainer) .messageBar) > div)::before, +:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div { + margin-block: 4px; } -.xfaLayer .highlight.end{ - border-radius:0 4px 4px 0; +:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + flex: 1 0 0; } -.xfaLayer .highlight.middle{ - border-radius:0; +:is(:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div) .title { + font-size: 13px; + font-weight: 590; } -.xfaLayer .highlight.selected{ - background-color:rgb(203 223 203); +:is(:is(:is(:is(.dialog .mainContainer) .messageBar) > div) > div) + .description { + font-size: 13px; } -.xfaPage{ - overflow:hidden; - position:relative; +:is(.dialog .mainContainer) .toggler { + display: flex; + align-items: center; + gap: 8px; + align-self: stretch; } -.xfaContentarea{ - position:absolute; +:is(:is(.dialog .mainContainer) .toggler) > .togglerLabel { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; } -.xfaPrintOnly{ - display:none; +.textLayer { + position: absolute; + text-align: initial; + inset: 0; + overflow: clip; + opacity: 1; + line-height: 1; + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + text-size-adjust: none; + forced-color-adjust: none; + transform-origin: 0 0; + caret-color: CanvasText; + z-index: 0; } -.xfaLayer{ - position:absolute; - text-align:initial; - top:0; - left:0; - transform-origin:0 0; - line-height:1.2; +.textLayer.highlighting { + touch-action: none; } -.xfaLayer *{ - color:inherit; - font:inherit; - font-style:inherit; - font-weight:inherit; - font-kerning:inherit; - letter-spacing:-0.01px; - text-align:inherit; - text-decoration:inherit; - box-sizing:border-box; - background-color:transparent; - padding:0; - margin:0; - pointer-events:auto; - line-height:inherit; +.textLayer :is(span, br) { + color: transparent; + position: absolute; + white-space: pre; + cursor: text; + transform-origin: 0% 0%; } -.xfaLayer *:required{ - outline:1.5px solid red; +.textLayer > :not(.markedContent), +.textLayer .markedContent span:not(.markedContent) { + z-index: 1; +} + +.textLayer span.markedContent { + top: 0; + height: 0; +} + +.textLayer span[role='img'] { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; +} + +.textLayer .highlight { + --highlight-bg-color: rgb(180 0 170 / 0.25); + --highlight-selected-bg-color: rgb(0 100 0 / 0.25); + --highlight-backdrop-filter: none; + --highlight-selected-backdrop-filter: none; +} + +@media screen and (forced-colors: active) { + .textLayer .highlight { + --highlight-bg-color: transparent; + --highlight-selected-bg-color: transparent; + --highlight-backdrop-filter: var(--hcm-highlight-filter); + --highlight-selected-backdrop-filter: var(--hcm-highlight-selected-filter); + } +} + +.textLayer .highlight { + margin: -1px; + padding: 1px; + background-color: var(--highlight-bg-color); + -webkit-backdrop-filter: var(--highlight-backdrop-filter); + backdrop-filter: var(--highlight-backdrop-filter); + border-radius: 4px; +} + +.appended:is(.textLayer .highlight) { + position: initial; +} + +.begin:is(.textLayer .highlight) { + border-radius: 4px 0 0 4px; +} + +.end:is(.textLayer .highlight) { + border-radius: 0 4px 4px 0; +} + +.middle:is(.textLayer .highlight) { + border-radius: 0; +} + +.selected:is(.textLayer .highlight) { + background-color: var(--highlight-selected-bg-color); + -webkit-backdrop-filter: var(--highlight-selected-backdrop-filter); + backdrop-filter: var(--highlight-selected-backdrop-filter); +} + +.textLayer ::-moz-selection { + background: rgba(0 0 255 / 0.25); + background: color-mix(in srgb, AccentColor, transparent 75%); +} + +.textLayer ::selection { + background: rgba(0 0 255 / 0.25); + background: color-mix(in srgb, AccentColor, transparent 75%); +} + +.textLayer br::-moz-selection { + background: transparent; +} + +.textLayer br::selection { + background: transparent; +} + +.textLayer .endOfContent { + display: block; + position: absolute; + inset: 100% 0 0; + z-index: 0; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.textLayer.selecting .endOfContent { + top: 0; +} + +.annotationLayer { + --csstools-color-scheme--light: initial; + color-scheme: only light; + + --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --input-focus-border-color: Highlight; + --input-focus-outline: 1px solid Canvas; + --input-unfocused-border-color: transparent; + --input-disabled-border-color: transparent; + --input-hover-border-color: black; + --link-outline: none; +} + +@media screen and (forced-colors: active) { + .annotationLayer { + --input-focus-border-color: CanvasText; + --input-unfocused-border-color: ActiveText; + --input-disabled-border-color: GrayText; + --input-hover-border-color: Highlight; + --link-outline: 1.5px solid LinkText; + } + + .annotationLayer .textWidgetAnnotation :is(input, textarea):required, + .annotationLayer .choiceWidgetAnnotation select:required, + .annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:required { + outline: 1.5px solid selectedItem; + } + + .annotationLayer .linkAnnotation { + outline: var(--link-outline); + } + + :is(.annotationLayer .linkAnnotation):hover { + -webkit-backdrop-filter: var(--hcm-highlight-filter); + backdrop-filter: var(--hcm-highlight-filter); + } + + :is(.annotationLayer .linkAnnotation) > a:hover { + opacity: 0 !important; + background: none !important; + box-shadow: none; + } + + .annotationLayer .popupAnnotation .popup { + outline: calc(1.5px * var(--total-scale-factor)) solid CanvasText !important; + background-color: ButtonFace !important; + color: ButtonText !important; + } + + .annotationLayer .highlightArea:hover::after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-backdrop-filter: var(--hcm-highlight-filter); + backdrop-filter: var(--hcm-highlight-filter); + content: ''; + pointer-events: none; + } + + .annotationLayer .popupAnnotation.focused .popup { + outline: calc(3px * var(--total-scale-factor)) solid Highlight !important; + } +} + +.annotationLayer { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + transform-origin: 0 0; +} + +.annotationLayer[data-main-rotation='90'] .norotate { + transform: rotate(270deg) translateX(-100%); +} + +.annotationLayer[data-main-rotation='180'] .norotate { + transform: rotate(180deg) translate(-100%, -100%); +} + +.annotationLayer[data-main-rotation='270'] .norotate { + transform: rotate(90deg) translateY(-100%); +} + +.annotationLayer.disabled section, +.annotationLayer.disabled .popup { + pointer-events: none; +} + +.annotationLayer .annotationContent { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; +} + +.freetext:is(.annotationLayer .annotationContent) { + background: transparent; + border: none; + inset: 0; + overflow: visible; + white-space: nowrap; + font: 10px sans-serif; + line-height: 1.35; +} + +.annotationLayer section { + position: absolute; + text-align: initial; + pointer-events: auto; + box-sizing: border-box; + transform-origin: 0 0; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +:is(.annotationLayer section):has(div.annotationContent) + canvas.annotationContent { + display: none; +} + +:is(.annotationLayer section) .overlaidText { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + display: inline-block; + overflow: hidden; +} + +.textLayer.selecting ~ .annotationLayer section { + pointer-events: none; +} + +.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a { + position: absolute; + font-size: 1em; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.annotationLayer + :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) + > a:hover { + opacity: 0.2; + background-color: rgb(255 255 0); +} + +.annotationLayer .linkAnnotation.hasBorder:hover { + background-color: rgb(255 255 0 / 0.2); +} + +.annotationLayer .hasBorder { + background-size: 100% 100%; +} + +.annotationLayer .textAnnotation img { + position: absolute; + cursor: pointer; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea), +.annotationLayer .choiceWidgetAnnotation select, +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + background-image: var(--annotation-unfocused-field-background); + border: 2px solid var(--input-unfocused-border-color); + box-sizing: border-box; + font: calc(9px * var(--total-scale-factor)) sans-serif; + height: 100%; + margin: 0; + vertical-align: top; + width: 100%; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):required, +.annotationLayer .choiceWidgetAnnotation select:required, +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:required { + outline: 1.5px solid red; +} + +.annotationLayer .choiceWidgetAnnotation select option { + padding: 0; +} + +.annotationLayer .buttonWidgetAnnotation.radioButton input { + border-radius: 50%; +} + +.annotationLayer .textWidgetAnnotation textarea { + resize: none; +} + +.annotationLayer .textWidgetAnnotation [disabled]:is(input, textarea), +.annotationLayer .choiceWidgetAnnotation select[disabled], +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input[disabled] { + background: none; + border: 2px solid var(--input-disabled-border-color); + cursor: not-allowed; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, +.annotationLayer .choiceWidgetAnnotation select:hover, +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:hover { + border: 2px solid var(--input-hover-border-color); +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, +.annotationLayer .choiceWidgetAnnotation select:hover, +.annotationLayer .buttonWidgetAnnotation.checkBox input:hover { + border-radius: 2px; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):focus, +.annotationLayer .choiceWidgetAnnotation select:focus { + background: none; + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) :focus { + background-image: none; + background-color: transparent; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox :focus { + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation.radioButton :focus { + border: 2px solid var(--input-focus-border-color); + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after, +.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { + background-color: CanvasText; + content: ''; + display: block; + position: absolute; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { + height: 80%; + left: 45%; + width: 1px; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before { + transform: rotate(45deg); +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { + transform: rotate(-45deg); +} + +.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { + border-radius: 50%; + height: 50%; + left: 25%; + top: 25%; + width: 50%; +} + +.annotationLayer .textWidgetAnnotation input.comb { + font-family: monospace; + padding-left: 2px; + padding-right: 0; +} + +.annotationLayer .textWidgetAnnotation input.comb:focus { + width: 103%; +} + +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.annotationLayer .fileAttachmentAnnotation .popupTriggerArea { + height: 100%; + width: 100%; +} + +.annotationLayer .popupAnnotation { + position: absolute; + font-size: calc(9px * var(--total-scale-factor)); + pointer-events: none; + width: -moz-max-content; + width: max-content; + max-width: 45%; + height: auto; +} + +.annotationLayer .popup { + background-color: rgb(255 255 153); + color: black; + box-shadow: 0 calc(2px * var(--total-scale-factor)) + calc(5px * var(--total-scale-factor)) rgb(136 136 136); + border-radius: calc(2px * var(--total-scale-factor)); + outline: 1.5px solid rgb(255 255 74); + padding: calc(6px * var(--total-scale-factor)); + cursor: pointer; + font: message-box; + white-space: normal; + word-wrap: break-word; + pointer-events: auto; + -webkit-user-select: text; + -moz-user-select: text; + user-select: text; +} + +.annotationLayer .popupAnnotation.focused .popup { + outline-width: 3px; +} + +.annotationLayer .popup * { + font-size: calc(9px * var(--total-scale-factor)); +} + +.annotationLayer .popup > .header { + display: inline-block; +} + +.annotationLayer .popup > .header > .title { + display: inline; + font-weight: bold; +} + +.annotationLayer .popup > .header .popupDate { + display: inline-block; + margin-left: calc(5px * var(--total-scale-factor)); + width: -moz-fit-content; + width: fit-content; +} + +.annotationLayer .popupContent { + border-top: 1px solid rgb(51 51 51); + margin-top: calc(2px * var(--total-scale-factor)); + padding-top: calc(2px * var(--total-scale-factor)); +} + +.annotationLayer .richText > * { + white-space: pre-wrap; + font-size: calc(9px * var(--total-scale-factor)); +} + +.annotationLayer .popupTriggerArea { + cursor: pointer; +} + +:is(.annotationLayer .popupTriggerArea):hover { + -webkit-backdrop-filter: var(--hcm-highlight-filter); + backdrop-filter: var(--hcm-highlight-filter); +} + +.annotationLayer section svg { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.annotationLayer .annotationTextContent { + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + color: transparent; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + pointer-events: none; +} + +:is(.annotationLayer .annotationTextContent) span { + width: 100%; + display: inline-block; +} + +.annotationLayer svg.quadrilateralsContainer { + contain: strict; + width: 0; + height: 0; + position: absolute; + top: 0; + left: 0; + z-index: -1; +} + +:root { + --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --xfa-focus-outline: auto; +} + +@media screen and (forced-colors: active) { + :root { + --xfa-focus-outline: 2px solid CanvasText; + } + .xfaLayer *:required { + outline: 1.5px solid selectedItem; + } +} + +.xfaLayer { + --csstools-color-scheme--light: initial; + color-scheme: only light; + + background-color: transparent; +} + +.xfaLayer .highlight { + margin: -1px; + padding: 1px; + background-color: rgb(239 203 237); + border-radius: 4px; +} + +.xfaLayer .highlight.appended { + position: initial; +} + +.xfaLayer .highlight.begin { + border-radius: 4px 0 0 4px; +} + +.xfaLayer .highlight.end { + border-radius: 0 4px 4px 0; +} + +.xfaLayer .highlight.middle { + border-radius: 0; +} + +.xfaLayer .highlight.selected { + background-color: rgb(203 223 203); +} + +.xfaPage { + overflow: hidden; + position: relative; +} + +.xfaContentarea { + position: absolute; +} + +.xfaPrintOnly { + display: none; +} + +.xfaLayer { + position: absolute; + text-align: initial; + top: 0; + left: 0; + transform-origin: 0 0; + line-height: 1.2; +} + +.xfaLayer * { + color: inherit; + font: inherit; + font-style: inherit; + font-weight: inherit; + font-kerning: inherit; + letter-spacing: -0.01px; + text-align: inherit; + text-decoration: inherit; + box-sizing: border-box; + background-color: transparent; + padding: 0; + margin: 0; + pointer-events: auto; + line-height: inherit; +} + +.xfaLayer *:required { + outline: 1.5px solid red; } .xfaLayer div, .xfaLayer svg, -.xfaLayer svg *{ - pointer-events:none; +.xfaLayer svg * { + pointer-events: none; } -.xfaLayer a{ - color:blue; +.xfaLayer a { + color: blue; } -.xfaRich li{ - margin-left:3em; +.xfaRich li { + margin-left: 3em; } -.xfaFont{ - color:black; - font-weight:normal; - font-kerning:none; - font-size:10px; - font-style:normal; - letter-spacing:0; - text-decoration:none; - vertical-align:0; +.xfaFont { + color: black; + font-weight: normal; + font-kerning: none; + font-size: 10px; + font-style: normal; + letter-spacing: 0; + text-decoration: none; + vertical-align: 0; } -.xfaCaption{ - overflow:hidden; - flex:0 0 auto; +.xfaCaption { + overflow: hidden; + flex: 0 0 auto; } -.xfaCaptionForCheckButton{ - overflow:hidden; - flex:1 1 auto; +.xfaCaptionForCheckButton { + overflow: hidden; + flex: 1 1 auto; } -.xfaLabel{ - height:100%; - width:100%; +.xfaLabel { + height: 100%; + width: 100%; } -.xfaLeft{ - display:flex; - flex-direction:row; - align-items:center; +.xfaLeft { + display: flex; + flex-direction: row; + align-items: center; } -.xfaRight{ - display:flex; - flex-direction:row-reverse; - align-items:center; +.xfaRight { + display: flex; + flex-direction: row-reverse; + align-items: center; } -:is(.xfaLeft, .xfaRight) > :is(.xfaCaption, .xfaCaptionForCheckButton){ - max-height:100%; +:is(.xfaLeft, .xfaRight) > :is(.xfaCaption, .xfaCaptionForCheckButton) { + max-height: 100%; } -.xfaTop{ - display:flex; - flex-direction:column; - align-items:flex-start; +.xfaTop { + display: flex; + flex-direction: column; + align-items: flex-start; } -.xfaBottom{ - display:flex; - flex-direction:column-reverse; - align-items:flex-start; +.xfaBottom { + display: flex; + flex-direction: column-reverse; + align-items: flex-start; } -:is(.xfaTop, .xfaBottom) > :is(.xfaCaption, .xfaCaptionForCheckButton){ - width:100%; +:is(.xfaTop, .xfaBottom) > :is(.xfaCaption, .xfaCaptionForCheckButton) { + width: 100%; } -.xfaBorder{ - background-color:transparent; - position:absolute; - pointer-events:none; +.xfaBorder { + background-color: transparent; + position: absolute; + pointer-events: none; } -.xfaWrapped{ - width:100%; - height:100%; +.xfaWrapped { + width: 100%; + height: 100%; } -:is(.xfaTextfield, .xfaSelect):focus{ - background-image:none; - background-color:transparent; - outline:var(--xfa-focus-outline); - outline-offset:-1px; +:is(.xfaTextfield, .xfaSelect):focus { + background-image: none; + background-color: transparent; + outline: var(--xfa-focus-outline); + outline-offset: -1px; } -:is(.xfaCheckbox, .xfaRadio):focus{ - outline:var(--xfa-focus-outline); +:is(.xfaCheckbox, .xfaRadio):focus { + outline: var(--xfa-focus-outline); } .xfaTextfield, -.xfaSelect{ - height:100%; - width:100%; - flex:1 1 auto; - border:none; - resize:none; - background-image:var(--xfa-unfocused-field-background); +.xfaSelect { + height: 100%; + width: 100%; + flex: 1 1 auto; + border: none; + resize: none; + background-image: var(--xfa-unfocused-field-background); } -.xfaSelect{ - padding-inline:2px; +.xfaSelect { + padding-inline: 2px; } -:is(.xfaTop, .xfaBottom) > :is(.xfaTextfield, .xfaSelect){ - flex:0 1 auto; +:is(.xfaTop, .xfaBottom) > :is(.xfaTextfield, .xfaSelect) { + flex: 0 1 auto; } -.xfaButton{ - cursor:pointer; - width:100%; - height:100%; - border:none; - text-align:center; +.xfaButton { + cursor: pointer; + width: 100%; + height: 100%; + border: none; + text-align: center; } -.xfaLink{ - width:100%; - height:100%; - position:absolute; - top:0; - left:0; +.xfaLink { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; } .xfaCheckbox, -.xfaRadio{ - width:100%; - height:100%; - flex:0 0 auto; - border:none; +.xfaRadio { + width: 100%; + height: 100%; + flex: 0 0 auto; + border: none; } -.xfaRich{ - white-space:pre-wrap; - width:100%; - height:100%; +.xfaRich { + white-space: pre-wrap; + width: 100%; + height: 100%; } -.xfaImage{ - -o-object-position:left top; - object-position:left top; - -o-object-fit:contain; - object-fit:contain; - width:100%; - height:100%; +.xfaImage { + -o-object-position: left top; + object-position: left top; + -o-object-fit: contain; + object-fit: contain; + width: 100%; + height: 100%; } .xfaLrTb, .xfaRlTb, -.xfaTb{ - display:flex; - flex-direction:column; - align-items:stretch; +.xfaTb { + display: flex; + flex-direction: column; + align-items: stretch; } -.xfaLr{ - display:flex; - flex-direction:row; - align-items:stretch; +.xfaLr { + display: flex; + flex-direction: row; + align-items: stretch; } -.xfaRl{ - display:flex; - flex-direction:row-reverse; - align-items:stretch; +.xfaRl { + display: flex; + flex-direction: row-reverse; + align-items: stretch; } -.xfaTb > div{ - justify-content:left; +.xfaTb > div { + justify-content: left; } -.xfaPosition{ - position:relative; +.xfaPosition { + position: relative; } -.xfaArea{ - position:relative; +.xfaArea { + position: relative; } -.xfaValignMiddle{ - display:flex; - align-items:center; +.xfaValignMiddle { + display: flex; + align-items: center; } -.xfaTable{ - display:flex; - flex-direction:column; - align-items:stretch; +.xfaTable { + display: flex; + flex-direction: column; + align-items: stretch; } -.xfaTable .xfaRow{ - display:flex; - flex-direction:row; - align-items:stretch; +.xfaTable .xfaRow { + display: flex; + flex-direction: row; + align-items: stretch; } -.xfaTable .xfaRlRow{ - display:flex; - flex-direction:row-reverse; - align-items:stretch; - flex:1; +.xfaTable .xfaRlRow { + display: flex; + flex-direction: row-reverse; + align-items: stretch; + flex: 1; } -.xfaTable .xfaRlRow > div{ - flex:1; +.xfaTable .xfaRlRow > div { + flex: 1; } -:is(.xfaNonInteractive, .xfaDisabled, .xfaReadOnly) :is(input, textarea){ - background:initial; +:is(.xfaNonInteractive, .xfaDisabled, .xfaReadOnly) :is(input, textarea) { + background: initial; } -@media print{ +@media print { .xfaTextfield, - .xfaSelect{ - background:transparent; + .xfaSelect { + background: transparent; } - .xfaSelect{ - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - text-indent:1px; - text-overflow:""; + .xfaSelect { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + text-indent: 1px; + text-overflow: ''; } } -.canvasWrapper svg{ - transform:none; +.canvasWrapper svg { + transform: none; +} + +.moving:is(.canvasWrapper svg) { + z-index: 100000; +} + +[data-main-rotation='90']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + mask, +[data-main-rotation='90']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + use:not(.clip, .mask) { + transform: matrix(0, 1, -1, 0, 1, 0); +} + +[data-main-rotation='180']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + mask, +[data-main-rotation='180']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + use:not(.clip, .mask) { + transform: matrix(-1, 0, 0, -1, 1, 1); +} + +[data-main-rotation='270']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + mask, +[data-main-rotation='270']:is( + .highlight:is(.canvasWrapper svg), + .highlightOutline:is(.canvasWrapper svg) + ) + use:not(.clip, .mask) { + transform: matrix(0, -1, 1, 0, 0, 1); +} + +.draw:is(.canvasWrapper svg) { + position: absolute; + mix-blend-mode: normal; +} + +.draw[data-draw-rotation='90']:is(.canvasWrapper svg) { + transform: rotate(90deg); +} + +.draw[data-draw-rotation='180']:is(.canvasWrapper svg) { + transform: rotate(180deg); +} + +.draw[data-draw-rotation='270']:is(.canvasWrapper svg) { + transform: rotate(270deg); +} + +.highlight:is(.canvasWrapper svg) { + --blend-mode: multiply; +} + +@media screen and (forced-colors: active) { + .highlight:is(.canvasWrapper svg) { + --blend-mode: difference; } +} -.moving:is(.canvasWrapper svg){ - z-index:100000; - } +.highlight:is(.canvasWrapper svg) { + position: absolute; + mix-blend-mode: var(--blend-mode); +} -[data-main-rotation="90"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) mask,[data-main-rotation="90"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) use:not(.clip,.mask){ - transform:matrix(0, 1, -1, 0, 1, 0); - } +.highlight:is(.canvasWrapper svg):not(.free) { + fill-rule: evenodd; +} -[data-main-rotation="180"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) mask,[data-main-rotation="180"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) use:not(.clip,.mask){ - transform:matrix(-1, 0, 0, -1, 1, 1); - } +.highlightOutline:is(.canvasWrapper svg) { + position: absolute; + mix-blend-mode: normal; + fill-rule: evenodd; + fill: none; +} -[data-main-rotation="270"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) mask,[data-main-rotation="270"]:is(.highlight:is(.canvasWrapper svg),.highlightOutline:is(.canvasWrapper svg)) use:not(.clip,.mask){ - transform:matrix(0, -1, 1, 0, 0, 1); - } +.highlightOutline.hovered:is(.canvasWrapper svg):not(.free):not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: var(--outline-width); +} -.draw:is(.canvasWrapper svg){ - position:absolute; - mix-blend-mode:normal; - } +.highlightOutline.selected:is(.canvasWrapper svg):not(.free) .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc(var(--outline-width) + 2 * var(--outline-around-width)); +} -.draw[data-draw-rotation="90"]:is(.canvasWrapper svg){ - transform:rotate(90deg); - } +.highlightOutline.selected:is(.canvasWrapper svg):not(.free) .secondaryOutline { + stroke: var(--outline-color); + stroke-width: var(--outline-width); +} -.draw[data-draw-rotation="180"]:is(.canvasWrapper svg){ - transform:rotate(180deg); - } +.highlightOutline.free.hovered:is(.canvasWrapper svg):not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: calc(2 * var(--outline-width)); +} -.draw[data-draw-rotation="270"]:is(.canvasWrapper svg){ - transform:rotate(270deg); - } +.highlightOutline.free.selected:is(.canvasWrapper svg) .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc(2 * (var(--outline-width) + var(--outline-around-width))); +} -.highlight:is(.canvasWrapper svg){ - --blend-mode:multiply; - } +.highlightOutline.free.selected:is(.canvasWrapper svg) .secondaryOutline { + stroke: var(--outline-color); + stroke-width: calc(2 * var(--outline-width)); +} -@media screen and (forced-colors: active){ - -.highlight:is(.canvasWrapper svg){ - --blend-mode:difference; - } - } - -.highlight:is(.canvasWrapper svg){ - - position:absolute; - mix-blend-mode:var(--blend-mode); - } - -.highlight:is(.canvasWrapper svg):not(.free){ - fill-rule:evenodd; - } - -.highlightOutline:is(.canvasWrapper svg){ - position:absolute; - mix-blend-mode:normal; - fill-rule:evenodd; - fill:none; - } - -.highlightOutline.hovered:is(.canvasWrapper svg):not(.free):not(.selected){ - stroke:var(--hover-outline-color); - stroke-width:var(--outline-width); - } - -.highlightOutline.selected:is(.canvasWrapper svg):not(.free) .mainOutline{ - stroke:var(--outline-around-color); - stroke-width:calc( - var(--outline-width) + 2 * var(--outline-around-width) - ); - } - -.highlightOutline.selected:is(.canvasWrapper svg):not(.free) .secondaryOutline{ - stroke:var(--outline-color); - stroke-width:var(--outline-width); - } - -.highlightOutline.free.hovered:is(.canvasWrapper svg):not(.selected){ - stroke:var(--hover-outline-color); - stroke-width:calc(2 * var(--outline-width)); - } - -.highlightOutline.free.selected:is(.canvasWrapper svg) .mainOutline{ - stroke:var(--outline-around-color); - stroke-width:calc( - 2 * (var(--outline-width) + var(--outline-around-width)) - ); - } - -.highlightOutline.free.selected:is(.canvasWrapper svg) .secondaryOutline{ - stroke:var(--outline-color); - stroke-width:calc(2 * var(--outline-width)); - } - -.toggle-button{ - --button-background-color:color-mix(in srgb, currentColor 7%, transparent); - --button-background-color-hover:color-mix( +.toggle-button { + --button-background-color: color-mix(in srgb, currentColor 7%, transparent); + --button-background-color-hover: color-mix( in srgb, currentColor 14%, transparent ); - --button-background-color-active:color-mix( + --button-background-color-active: color-mix( in srgb, currentColor 21%, transparent ); - --csstools-light-dark-toggle--66:var(--csstools-color-scheme--light) #0df; - --color-accent-primary:var(--csstools-light-dark-toggle--66, #0060df); - --csstools-light-dark-toggle--67:var(--csstools-color-scheme--light) #80ebff; - --color-accent-primary-hover:var(--csstools-light-dark-toggle--67, #0250bb); - --csstools-light-dark-toggle--68:var(--csstools-color-scheme--light) #aaf2ff; - --color-accent-primary-active:var(--csstools-light-dark-toggle--68, #054096); - --border-radius-circle:9999px; - --border-width:1px; - --size-item-small:16px; - --size-item-large:32px; - --csstools-light-dark-toggle--69:var(--csstools-color-scheme--light) #1c1b22; - --color-canvas:var(--csstools-light-dark-toggle--69, white); - --background-color-canvas:var(--color-canvas); - --csstools-light-dark-toggle--70:var(--csstools-color-scheme--light) #f9f9fa; - --border-color-interactive:var(--csstools-light-dark-toggle--70, #8f8f9d); - --border-color-interactive-hover:var(--border-color-interactive); - --border-color-interactive-active:var(--border-color-interactive); + --csstools-light-dark-toggle--66: var(--csstools-color-scheme--light) #0df; + --color-accent-primary: var(--csstools-light-dark-toggle--66, #0060df); + --csstools-light-dark-toggle--67: var(--csstools-color-scheme--light) #80ebff; + --color-accent-primary-hover: var(--csstools-light-dark-toggle--67, #0250bb); + --csstools-light-dark-toggle--68: var(--csstools-color-scheme--light) #aaf2ff; + --color-accent-primary-active: var(--csstools-light-dark-toggle--68, #054096); + --border-radius-circle: 9999px; + --border-width: 1px; + --size-item-small: 16px; + --size-item-large: 32px; + --csstools-light-dark-toggle--69: var(--csstools-color-scheme--light) #1c1b22; + --color-canvas: var(--csstools-light-dark-toggle--69, white); + --background-color-canvas: var(--color-canvas); + --csstools-light-dark-toggle--70: var(--csstools-color-scheme--light) #f9f9fa; + --border-color-interactive: var(--csstools-light-dark-toggle--70, #8f8f9d); + --border-color-interactive-hover: var(--border-color-interactive); + --border-color-interactive-active: var(--border-color-interactive); } -@supports (color: light-dark(red, red)){ -.toggle-button{ - --color-accent-primary:light-dark(#0060df, #0df); - --color-accent-primary-hover:light-dark(#0250bb, #80ebff); - --color-accent-primary-active:light-dark(#054096, #aaf2ff); - --color-canvas:light-dark(white, #1c1b22); - --border-color-interactive:light-dark(#8f8f9d, #f9f9fa); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.toggle-button *{ - --csstools-light-dark-toggle--66:var(--csstools-color-scheme--light) #0df; - --color-accent-primary:var(--csstools-light-dark-toggle--66, #0060df); - --csstools-light-dark-toggle--67:var(--csstools-color-scheme--light) #80ebff; - --color-accent-primary-hover:var(--csstools-light-dark-toggle--67, #0250bb); - --csstools-light-dark-toggle--68:var(--csstools-color-scheme--light) #aaf2ff; - --color-accent-primary-active:var(--csstools-light-dark-toggle--68, #054096); - --csstools-light-dark-toggle--69:var(--csstools-color-scheme--light) #1c1b22; - --color-canvas:var(--csstools-light-dark-toggle--69, white); - --csstools-light-dark-toggle--70:var(--csstools-color-scheme--light) #f9f9fa; - --border-color-interactive:var(--csstools-light-dark-toggle--70, #8f8f9d); +@supports (color: light-dark(red, red)) { + .toggle-button { + --color-accent-primary: light-dark(#0060df, #0df); + --color-accent-primary-hover: light-dark(#0250bb, #80ebff); + --color-accent-primary-active: light-dark(#054096, #aaf2ff); + --color-canvas: light-dark(white, #1c1b22); + --border-color-interactive: light-dark(#8f8f9d, #f9f9fa); } } -@media (forced-colors: active){ - -.toggle-button{ - --color-accent-primary:ButtonText; - --color-accent-primary-hover:SelectedItem; - --color-accent-primary-active:SelectedItem; - --button-background-color:ButtonFace; - --border-color-interactive:ButtonText; - --border-color-interactive-hover:SelectedItem; - --border-color-interactive-active:ButtonText; - --color-canvas:ButtonText; - --background-color-canvas:Canvas; -} +@supports not (color: light-dark(tan, tan)) { + .toggle-button * { + --csstools-light-dark-toggle--66: var(--csstools-color-scheme--light) #0df; + --color-accent-primary: var(--csstools-light-dark-toggle--66, #0060df); + --csstools-light-dark-toggle--67: var(--csstools-color-scheme--light) + #80ebff; + --color-accent-primary-hover: var( + --csstools-light-dark-toggle--67, + #0250bb + ); + --csstools-light-dark-toggle--68: var(--csstools-color-scheme--light) + #aaf2ff; + --color-accent-primary-active: var( + --csstools-light-dark-toggle--68, + #054096 + ); + --csstools-light-dark-toggle--69: var(--csstools-color-scheme--light) + #1c1b22; + --color-canvas: var(--csstools-light-dark-toggle--69, white); + --csstools-light-dark-toggle--70: var(--csstools-color-scheme--light) + #f9f9fa; + --border-color-interactive: var(--csstools-light-dark-toggle--70, #8f8f9d); } +} -.toggle-button{ - --toggle-background-color:var(--button-background-color); - --toggle-background-color-hover:var(--button-background-color-hover); - --toggle-background-color-active:var(--button-background-color-active); - --toggle-background-color-pressed:var(--color-accent-primary); - --toggle-background-color-pressed-hover:var(--color-accent-primary-hover); - --toggle-background-color-pressed-active:var(--color-accent-primary-active); - --toggle-border-color:var(--border-color-interactive); - --toggle-border-color-hover:var(--toggle-border-color); - --toggle-border-color-active:var(--toggle-border-color); - --toggle-border-radius:var(--border-radius-circle); - --toggle-border-width:var(--border-width); - --toggle-height:var(--size-item-small); - --toggle-width:var(--size-item-large); - --toggle-dot-background-color:var(--toggle-border-color); - --toggle-dot-background-color-hover:var(--toggle-dot-background-color); - --toggle-dot-background-color-active:var(--toggle-dot-background-color); - --toggle-dot-background-color-on-pressed:var(--background-color-canvas); - --toggle-dot-margin:1px; - --toggle-dot-height:calc( +@media (forced-colors: active) { + .toggle-button { + --color-accent-primary: ButtonText; + --color-accent-primary-hover: SelectedItem; + --color-accent-primary-active: SelectedItem; + --button-background-color: ButtonFace; + --border-color-interactive: ButtonText; + --border-color-interactive-hover: SelectedItem; + --border-color-interactive-active: ButtonText; + --color-canvas: ButtonText; + --background-color-canvas: Canvas; + } +} + +.toggle-button { + --toggle-background-color: var(--button-background-color); + --toggle-background-color-hover: var(--button-background-color-hover); + --toggle-background-color-active: var(--button-background-color-active); + --toggle-background-color-pressed: var(--color-accent-primary); + --toggle-background-color-pressed-hover: var(--color-accent-primary-hover); + --toggle-background-color-pressed-active: var(--color-accent-primary-active); + --toggle-border-color: var(--border-color-interactive); + --toggle-border-color-hover: var(--toggle-border-color); + --toggle-border-color-active: var(--toggle-border-color); + --toggle-border-radius: var(--border-radius-circle); + --toggle-border-width: var(--border-width); + --toggle-height: var(--size-item-small); + --toggle-width: var(--size-item-large); + --toggle-dot-background-color: var(--toggle-border-color); + --toggle-dot-background-color-hover: var(--toggle-dot-background-color); + --toggle-dot-background-color-active: var(--toggle-dot-background-color); + --toggle-dot-background-color-on-pressed: var(--background-color-canvas); + --toggle-dot-margin: 1px; + --toggle-dot-height: calc( var(--toggle-height) - 2 * var(--toggle-dot-margin) - 2 * var(--toggle-border-width) ); - --toggle-dot-width:var(--toggle-dot-height); - --toggle-dot-transform-x:calc( + --toggle-dot-width: var(--toggle-dot-height); + --toggle-dot-transform-x: calc( var(--toggle-width) - 4 * var(--toggle-dot-margin) - var(--toggle-dot-width) ); - --input-width:var(--toggle-width); + --input-width: var(--toggle-width); - -webkit-appearance:none; + -webkit-appearance: none; - -moz-appearance:none; + -moz-appearance: none; - appearance:none; - padding:0; - border:var(--toggle-border-width) solid var(--toggle-border-color); - height:var(--toggle-height); - width:var(--toggle-width); - border-radius:var(--toggle-border-radius); - background-color:var(--toggle-background-color); - box-sizing:border-box; + appearance: none; + padding: 0; + border: var(--toggle-border-width) solid var(--toggle-border-color); + height: var(--toggle-height); + width: var(--toggle-width); + border-radius: var(--toggle-border-radius); + background-color: var(--toggle-background-color); + box-sizing: border-box; } -.toggle-button:focus-visible{ - outline:var(--focus-outline); - outline-offset:var(--focus-outline-offset); - } - -.toggle-button:enabled:hover{ - background-color:var(--toggle-background-color-hover); - border-color:var(--toggle-border-color); - } - -.toggle-button:enabled:hover:active{ - background-color:var(--toggle-background-color-active); - border-color:var(--toggle-border-color); - } - -.toggle-button::before{ - display:block; - content:""; - background-color:var(--toggle-dot-background-color); - height:var(--toggle-dot-height); - width:var(--toggle-dot-width); - margin:var(--toggle-dot-margin); - border-radius:var(--toggle-border-radius); - translate:0; - } - -.toggle-button[aria-pressed="true"]{ - background-color:var(--toggle-background-color-pressed); - border-color:transparent; +.toggle-button:focus-visible { + outline: var(--focus-outline); + outline-offset: var(--focus-outline-offset); } -.toggle-button[aria-pressed="true"]:enabled:hover{ - background-color:var(--toggle-background-color-pressed-hover); - border-color:transparent; - } +.toggle-button:enabled:hover { + background-color: var(--toggle-background-color-hover); + border-color: var(--toggle-border-color); +} -.toggle-button[aria-pressed="true"]:enabled:hover:active{ - background-color:var(--toggle-background-color-pressed-active); - border-color:transparent; - } +.toggle-button:enabled:hover:active { + background-color: var(--toggle-background-color-active); + border-color: var(--toggle-border-color); +} -.toggle-button[aria-pressed="true"]::before{ - translate:var(--toggle-dot-transform-x); - background-color:var(--toggle-dot-background-color-on-pressed); - } +.toggle-button::before { + display: block; + content: ''; + background-color: var(--toggle-dot-background-color); + height: var(--toggle-dot-height); + width: var(--toggle-dot-width); + margin: var(--toggle-dot-margin); + border-radius: var(--toggle-border-radius); + translate: 0; +} -.toggle-button[aria-pressed="true"]:enabled:hover::before,.toggle-button[aria-pressed="true"]:enabled:hover:active::before{ - background-color:var(--toggle-dot-background-color-on-pressed); - } +.toggle-button[aria-pressed='true'] { + background-color: var(--toggle-background-color-pressed); + border-color: transparent; +} -.toggle-button[aria-pressed="true"]:-moz-locale-dir(rtl)::before,[dir="rtl"] .toggle-button[aria-pressed="true"]::before{ - translate:calc(-1 * var(--toggle-dot-transform-x)); - } +.toggle-button[aria-pressed='true']:enabled:hover { + background-color: var(--toggle-background-color-pressed-hover); + border-color: transparent; +} -@media (prefers-reduced-motion: no-preference){ - .toggle-button::before{ - transition:translate 100ms; +.toggle-button[aria-pressed='true']:enabled:hover:active { + background-color: var(--toggle-background-color-pressed-active); + border-color: transparent; +} + +.toggle-button[aria-pressed='true']::before { + translate: var(--toggle-dot-transform-x); + background-color: var(--toggle-dot-background-color-on-pressed); +} + +.toggle-button[aria-pressed='true']:enabled:hover::before, +.toggle-button[aria-pressed='true']:enabled:hover:active::before { + background-color: var(--toggle-dot-background-color-on-pressed); +} + +.toggle-button[aria-pressed='true']:-moz-locale-dir(rtl)::before, +[dir='rtl'] .toggle-button[aria-pressed='true']::before { + translate: calc(-1 * var(--toggle-dot-transform-x)); +} + +@media (prefers-reduced-motion: no-preference) { + .toggle-button::before { + transition: translate 100ms; } } -@media (prefers-contrast){ - .toggle-button:enabled:hover{ - border-color:var(--toggle-border-color-hover); +@media (prefers-contrast) { + .toggle-button:enabled:hover { + border-color: var(--toggle-border-color-hover); } - .toggle-button:enabled:hover:active{ - border-color:var(--toggle-border-color-active); + .toggle-button:enabled:hover:active { + border-color: var(--toggle-border-color-active); } - .toggle-button[aria-pressed="true"]:enabled{ - border-color:var(--toggle-border-color); - position:relative; + .toggle-button[aria-pressed='true']:enabled { + border-color: var(--toggle-border-color); + position: relative; } - .toggle-button[aria-pressed="true"]:enabled:hover{ - border-color:var(--toggle-border-color-hover); - } + .toggle-button[aria-pressed='true']:enabled:hover { + border-color: var(--toggle-border-color-hover); + } - .toggle-button[aria-pressed="true"]:enabled:hover:active{ - background-color:var(--toggle-dot-background-color-active); - border-color:var(--toggle-dot-background-color-hover); - } + .toggle-button[aria-pressed='true']:enabled:hover:active { + background-color: var(--toggle-dot-background-color-active); + border-color: var(--toggle-dot-background-color-hover); + } .toggle-button:enabled:hover::before, - .toggle-button:enabled:hover:active::before{ - background-color:var(--toggle-dot-background-color-hover); + .toggle-button:enabled:hover:active::before { + background-color: var(--toggle-dot-background-color-hover); } } -@media (forced-colors){ - .toggle-button{ - --toggle-dot-background-color:var(--color-accent-primary); - --toggle-dot-background-color-hover:var(--color-accent-primary-hover); - --toggle-dot-background-color-active:var(--color-accent-primary-active); - --toggle-dot-background-color-on-pressed:var(--button-background-color); - --toggle-border-color-hover:var(--border-color-interactive-hover); - --toggle-border-color-active:var(--border-color-interactive-active); +@media (forced-colors) { + .toggle-button { + --toggle-dot-background-color: var(--color-accent-primary); + --toggle-dot-background-color-hover: var(--color-accent-primary-hover); + --toggle-dot-background-color-active: var(--color-accent-primary-active); + --toggle-dot-background-color-on-pressed: var(--button-background-color); + --toggle-border-color-hover: var(--border-color-interactive-hover); + --toggle-border-color-active: var(--border-color-interactive-active); } - .toggle-button[aria-pressed="true"]:enabled::after{ - border:1px solid var(--button-background-color); - content:""; - position:absolute; - height:var(--toggle-height); - width:var(--toggle-width); - display:block; - border-radius:var(--toggle-border-radius); - inset:-2px; + .toggle-button[aria-pressed='true']:enabled::after { + border: 1px solid var(--button-background-color); + content: ''; + position: absolute; + height: var(--toggle-height); + width: var(--toggle-width); + display: block; + border-radius: var(--toggle-border-radius); + inset: -2px; } - .toggle-button[aria-pressed="true"]:enabled:hover:active::after{ - border-color:var(--toggle-border-color-active); + .toggle-button[aria-pressed='true']:enabled:hover:active::after { + border-color: var(--toggle-border-color-active); } } -:root{ - --clear-signature-button-icon:url(images/editor-toolbar-delete.svg); - --csstools-light-dark-toggle--71:var(--csstools-color-scheme--light) #2b2a33; - --signature-bg:var(--csstools-light-dark-toggle--71, #f9f9fb); - --csstools-light-dark-toggle--72:var(--csstools-color-scheme--light) var(--signature-bg); - --signature-hover-bg:var(--csstools-light-dark-toggle--72, #f0f0f4); - --button-signature-bg:transparent; - --button-signature-color:var(--main-color); - --csstools-light-dark-toggle--73:var(--csstools-color-scheme--light) #5b5b66; - --button-signature-active-bg:var(--csstools-light-dark-toggle--73, #cfcfd8); - --button-signature-active-border:none; - --button-signature-active-color:var(--button-signature-color); - --button-signature-border:none; - --csstools-light-dark-toggle--74:var(--csstools-color-scheme--light) #52525e; - --button-signature-hover-bg:var(--csstools-light-dark-toggle--74, #e0e0e6); - --button-signature-hover-color:var(--button-signature-color); +:root { + --clear-signature-button-icon: url(images/editor-toolbar-delete.svg); + --csstools-light-dark-toggle--71: var(--csstools-color-scheme--light) #2b2a33; + --signature-bg: var(--csstools-light-dark-toggle--71, #f9f9fb); + --csstools-light-dark-toggle--72: var(--csstools-color-scheme--light) + var(--signature-bg); + --signature-hover-bg: var(--csstools-light-dark-toggle--72, #f0f0f4); + --button-signature-bg: transparent; + --button-signature-color: var(--main-color); + --csstools-light-dark-toggle--73: var(--csstools-color-scheme--light) #5b5b66; + --button-signature-active-bg: var(--csstools-light-dark-toggle--73, #cfcfd8); + --button-signature-active-border: none; + --button-signature-active-color: var(--button-signature-color); + --button-signature-border: none; + --csstools-light-dark-toggle--74: var(--csstools-color-scheme--light) #52525e; + --button-signature-hover-bg: var(--csstools-light-dark-toggle--74, #e0e0e6); + --button-signature-hover-color: var(--button-signature-color); } -@supports (color: light-dark(red, red)){ -:root{ - --signature-bg:light-dark(#f9f9fb, #2b2a33); - --signature-hover-bg:light-dark(#f0f0f4, var(--signature-bg)); - --button-signature-active-bg:light-dark(#cfcfd8, #5b5b66); - --button-signature-hover-bg:light-dark(#e0e0e6, #52525e); -} -} - -@supports not (color: light-dark(tan, tan)){ - -:root *{ - --csstools-light-dark-toggle--71:var(--csstools-color-scheme--light) #2b2a33; - --signature-bg:var(--csstools-light-dark-toggle--71, #f9f9fb); - --csstools-light-dark-toggle--72:var(--csstools-color-scheme--light) var(--signature-bg); - --signature-hover-bg:var(--csstools-light-dark-toggle--72, #f0f0f4); - --csstools-light-dark-toggle--73:var(--csstools-color-scheme--light) #5b5b66; - --button-signature-active-bg:var(--csstools-light-dark-toggle--73, #cfcfd8); - --csstools-light-dark-toggle--74:var(--csstools-color-scheme--light) #52525e; - --button-signature-hover-bg:var(--csstools-light-dark-toggle--74, #e0e0e6); +@supports (color: light-dark(red, red)) { + :root { + --signature-bg: light-dark(#f9f9fb, #2b2a33); + --signature-hover-bg: light-dark(#f0f0f4, var(--signature-bg)); + --button-signature-active-bg: light-dark(#cfcfd8, #5b5b66); + --button-signature-hover-bg: light-dark(#e0e0e6, #52525e); } } -@media screen and (forced-colors: active){ - -:root{ - --signature-bg:HighlightText; - --signature-hover-bg:var(--signature-bg); - --button-signature-bg:HighlightText; - --button-signature-color:ButtonText; - --button-signature-active-bg:ButtonText; - --button-signature-active-color:HighlightText; - --button-signature-border:1px solid ButtonText; - --button-signature-hover-bg:Highlight; - --button-signature-hover-color:HighlightText; -} +@supports not (color: light-dark(tan, tan)) { + :root * { + --csstools-light-dark-toggle--71: var(--csstools-color-scheme--light) + #2b2a33; + --signature-bg: var(--csstools-light-dark-toggle--71, #f9f9fb); + --csstools-light-dark-toggle--72: var(--csstools-color-scheme--light) + var(--signature-bg); + --signature-hover-bg: var(--csstools-light-dark-toggle--72, #f0f0f4); + --csstools-light-dark-toggle--73: var(--csstools-color-scheme--light) + #5b5b66; + --button-signature-active-bg: var( + --csstools-light-dark-toggle--73, + #cfcfd8 + ); + --csstools-light-dark-toggle--74: var(--csstools-color-scheme--light) + #52525e; + --button-signature-hover-bg: var(--csstools-light-dark-toggle--74, #e0e0e6); } - -.signatureDialog{ - --primary-color:var(--text-primary-color); - --border-color:#8f8f9d; - --open-link-fg:var(--link-fg-color); - --open-link-hover-fg:var(--link-hover-fg-color); } -@media screen and (forced-colors: active){ - -.signatureDialog{ - --primary-color:ButtonText; - --border-color:ButtonText; - --open-link-fg:ButtonText; - --open-link-hover-fg:ButtonText; -} +@media screen and (forced-colors: active) { + :root { + --signature-bg: HighlightText; + --signature-hover-bg: var(--signature-bg); + --button-signature-bg: HighlightText; + --button-signature-color: ButtonText; + --button-signature-active-bg: ButtonText; + --button-signature-active-color: HighlightText; + --button-signature-border: 1px solid ButtonText; + --button-signature-hover-bg: Highlight; + --button-signature-hover-color: HighlightText; } - -.signatureDialog{ - - width:570px; - max-width:100%; - min-width:300px; - padding:16px 0; } -.signatureDialog .mainContainer{ - width:100%; - display:flex; - flex-direction:column; - align-items:flex-start; - gap:12px; +.signatureDialog { + --primary-color: var(--text-primary-color); + --border-color: #8f8f9d; + --open-link-fg: var(--link-fg-color); + --open-link-hover-fg: var(--link-hover-fg-color); +} + +@media screen and (forced-colors: active) { + .signatureDialog { + --primary-color: ButtonText; + --border-color: ButtonText; + --open-link-fg: ButtonText; + --open-link-hover-fg: ButtonText; } +} -:is(.signatureDialog .mainContainer) span:not([role="sectionhead"]){ - font-size:13px; - font-style:normal; - font-weight:400; - line-height:normal; - } +.signatureDialog { + width: 570px; + max-width: 100%; + min-width: 300px; + padding: 16px 0; +} -:is(.signatureDialog .mainContainer) .title{ - margin-inline-start:16px; - } +.signatureDialog .mainContainer { + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 12px; +} -.signatureDialog .inputWithClearButton{ - --button-dimension:24px; - --clear-button-icon:url(images/messageBar_closingButton.svg); +:is(.signatureDialog .mainContainer) span:not([role='sectionhead']) { + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: normal; +} - width:100%; - position:relative; - display:flex; - align-items:center; - justify-content:center; - } +:is(.signatureDialog .mainContainer) .title { + margin-inline-start: 16px; +} -:is(.signatureDialog .inputWithClearButton) > input{ - width:100%; - height:32px; - padding-inline:8px calc(4px + var(--button-dimension)); - box-sizing:border-box; - border-radius:4px; - border:1px solid var(--border-color); - } +.signatureDialog .inputWithClearButton { + --button-dimension: 24px; + --clear-button-icon: url(images/messageBar_closingButton.svg); -:is(.signatureDialog .inputWithClearButton) .clearInputButton{ - position:absolute; - inset-block-start:4px; - inset-inline-end:4px; - display:inline-block; - width:var(--button-dimension); - height:var(--button-dimension); - background-color:var(--input-text-fg-color); - -webkit-mask-size:cover; - mask-size:cover; - -webkit-mask-image:var(--clear-button-icon); - mask-image:var(--clear-button-icon); - padding:0; - border:0; - } + width: 100%; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} -#addSignatureDialog{ - --secondary-color:var(--text-secondary-color); - --bg-hover:#e0e0e6; - --tab-top-line-active-color:#0060df; - --tab-top-line-active-hover-color:var(--tab-text-hover-color); - --tab-top-line-hover-color:#8f8f9d; - --tab-top-line-inactive-color:#cfcfd8; - --tab-bottom-line-active-color:var(--tab-top-line-inactive-color); - --tab-bottom-line-hover-color:var(--tab-top-line-inactive-color); - --tab-bottom-line-inactive-color:var(--tab-top-line-inactive-color); - --tab-bg:var(--dialog-bg-color); - --tab-bg-active-color:var(--tab-bg); - --tab-bg-active-hover-color:var(--bg-hover); - --tab-bg-hover:var(--bg-hover); - --tab-panel-border:none; - --tab-panel-border-radius:4px; - --tab-text-color:var(--primary-color); - --tab-text-active-color:var(--tab-top-line-active-color); - --tab-text-active-hover-color:var(--tab-text-hover-color); - --tab-text-hover-color:var(--tab-text-color); - --signature-placeholder-color:var(--secondary-color); - --signature-draw-placeholder-color:var(--primary-color); - --signature-color:var(--primary-color); - --clear-signature-button-border-width:0; - --clear-signature-button-border-style:solid; - --clear-signature-button-border-color:transparent; - --clear-signature-button-border-disabled-color:transparent; - --clear-signature-button-color:var(--primary-color); - --clear-signature-button-hover-color:var(--clear-signature-button-color); - --clear-signature-button-active-color:var(--clear-signature-button-color); - --clear-signature-button-disabled-color:var(--clear-signature-button-color); - --clear-signature-button-focus-color:var(--clear-signature-button-color); - --clear-signature-button-bg:var(--dialog-bg-color); - --clear-signature-button-bg-hover:var(--bg-hover); - --clear-signature-button-bg-active:#cfcfd8; - --clear-signature-button-bg-focus:#f0f0f4; - --clear-signature-button-bg-disabled:color-mix( +:is(.signatureDialog .inputWithClearButton) > input { + width: 100%; + height: 32px; + padding-inline: 8px calc(4px + var(--button-dimension)); + box-sizing: border-box; + border-radius: 4px; + border: 1px solid var(--border-color); +} + +:is(.signatureDialog .inputWithClearButton) .clearInputButton { + position: absolute; + inset-block-start: 4px; + inset-inline-end: 4px; + display: inline-block; + width: var(--button-dimension); + height: var(--button-dimension); + background-color: var(--input-text-fg-color); + -webkit-mask-size: cover; + mask-size: cover; + -webkit-mask-image: var(--clear-button-icon); + mask-image: var(--clear-button-icon); + padding: 0; + border: 0; +} + +#addSignatureDialog { + --secondary-color: var(--text-secondary-color); + --bg-hover: #e0e0e6; + --tab-top-line-active-color: #0060df; + --tab-top-line-active-hover-color: var(--tab-text-hover-color); + --tab-top-line-hover-color: #8f8f9d; + --tab-top-line-inactive-color: #cfcfd8; + --tab-bottom-line-active-color: var(--tab-top-line-inactive-color); + --tab-bottom-line-hover-color: var(--tab-top-line-inactive-color); + --tab-bottom-line-inactive-color: var(--tab-top-line-inactive-color); + --tab-bg: var(--dialog-bg-color); + --tab-bg-active-color: var(--tab-bg); + --tab-bg-active-hover-color: var(--bg-hover); + --tab-bg-hover: var(--bg-hover); + --tab-panel-border: none; + --tab-panel-border-radius: 4px; + --tab-text-color: var(--primary-color); + --tab-text-active-color: var(--tab-top-line-active-color); + --tab-text-active-hover-color: var(--tab-text-hover-color); + --tab-text-hover-color: var(--tab-text-color); + --signature-placeholder-color: var(--secondary-color); + --signature-draw-placeholder-color: var(--primary-color); + --signature-color: var(--primary-color); + --clear-signature-button-border-width: 0; + --clear-signature-button-border-style: solid; + --clear-signature-button-border-color: transparent; + --clear-signature-button-border-disabled-color: transparent; + --clear-signature-button-color: var(--primary-color); + --clear-signature-button-hover-color: var(--clear-signature-button-color); + --clear-signature-button-active-color: var(--clear-signature-button-color); + --clear-signature-button-disabled-color: var(--clear-signature-button-color); + --clear-signature-button-focus-color: var(--clear-signature-button-color); + --clear-signature-button-bg: var(--dialog-bg-color); + --clear-signature-button-bg-hover: var(--bg-hover); + --clear-signature-button-bg-active: #cfcfd8; + --clear-signature-button-bg-focus: #f0f0f4; + --clear-signature-button-bg-disabled: color-mix( in srgb, #f0f0f4, transparent 40% ); - --save-warning-color:var(--secondary-color); - --thickness-bg:var(--dialog-bg-color); - --thickness-label-color:var(--primary-color); - --thickness-slider-color:var(--primary-color); - --thickness-border:none; - --draw-cursor:url(images/cursor-editorInk.svg) 0 16, pointer; + --save-warning-color: var(--secondary-color); + --thickness-bg: var(--dialog-bg-color); + --thickness-label-color: var(--primary-color); + --thickness-slider-color: var(--primary-color); + --thickness-border: none; + --draw-cursor: url(images/cursor-editorInk.svg) 0 16, pointer; } -@media (prefers-color-scheme: dark){ - -#addSignatureDialog{ - --dialog-bg-color:#42414d; - --bg-hover:#52525e; - --primary-color:#fbfbfe; - --secondary-color:#cfcfd8; - --tab-top-line-active-color:#0df; - --tab-top-line-inactive-color:#8f8f9d; - --clear-signature-button-bg-active:#5b5b66; - --clear-signature-button-bg-focus:#2b2a33; - --clear-signature-button-bg-disabled:color-mix( +@media (prefers-color-scheme: dark) { + #addSignatureDialog { + --dialog-bg-color: #42414d; + --bg-hover: #52525e; + --primary-color: #fbfbfe; + --secondary-color: #cfcfd8; + --tab-top-line-active-color: #0df; + --tab-top-line-inactive-color: #8f8f9d; + --clear-signature-button-bg-active: #5b5b66; + --clear-signature-button-bg-focus: #2b2a33; + --clear-signature-button-bg-disabled: color-mix( in srgb, #2b2a33, transparent 40% ); + } } + +@media screen and (forced-colors: active) { + #addSignatureDialog { + --secondary-color: ButtonText; + --bg: HighlightText; + --bg-hover: var(--bg); + --tab-top-line-active-color: ButtonText; + --tab-top-line-active-hover-color: HighlightText; + --tab-top-line-hover-color: SelectedItem; + --tab-top-line-inactive-color: ButtonText; + --tab-bottom-line-active-color: var(--tab-top-line-active-color); + --tab-bottom-line-hover-color: var(--tab-top-line-hover-color); + --tab-bg: var(--bg); + --tab-bg-active-color: SelectedItem; + --tab-bg-active-hover-color: SelectedItem; + --tab-panel-border: 1px solid ButtonText; + --tab-panel-border-radius: 8px; + --tab-text-color: ButtonText; + --tab-text-active-color: HighlightText; + --tab-text-active-hover-color: HighlightText; + --tab-text-hover-color: SelectedItem; + --signature-color: ButtonText; + --clear-signature-button-border-width: 1px; + --clear-signature-button-border-style: solid; + --clear-signature-button-border-color: ButtonText; + --clear-signature-button-border-disabled-color: GrayText; + --clear-signature-button-color: ButtonText; + --clear-signature-button-hover-color: HighlightText; + --clear-signature-button-active-color: SelectedItem; + --clear-signature-button-focus-color: CanvasText; + --clear-signature-button-disabled-color: GrayText; + --clear-signature-button-bg: var(--bg); + --clear-signature-button-bg-hover: SelectedItem; + --clear-signature-button-bg-active: var(--bg); + --clear-signature-button-bg-focus: var(--bg); + --clear-signature-button-bg-disabled: var(--bg); + --thickness-bg: Canvas; + --thickness-label-color: CanvasText; + --thickness-slider-color: ButtonText; + --thickness-border: 1px solid var(--border-color); } - -@media screen and (forced-colors: active){ - -#addSignatureDialog{ - --secondary-color:ButtonText; - --bg:HighlightText; - --bg-hover:var(--bg); - --tab-top-line-active-color:ButtonText; - --tab-top-line-active-hover-color:HighlightText; - --tab-top-line-hover-color:SelectedItem; - --tab-top-line-inactive-color:ButtonText; - --tab-bottom-line-active-color:var(--tab-top-line-active-color); - --tab-bottom-line-hover-color:var(--tab-top-line-hover-color); - --tab-bg:var(--bg); - --tab-bg-active-color:SelectedItem; - --tab-bg-active-hover-color:SelectedItem; - --tab-panel-border:1px solid ButtonText; - --tab-panel-border-radius:8px; - --tab-text-color:ButtonText; - --tab-text-active-color:HighlightText; - --tab-text-active-hover-color:HighlightText; - --tab-text-hover-color:SelectedItem; - --signature-color:ButtonText; - --clear-signature-button-border-width:1px; - --clear-signature-button-border-style:solid; - --clear-signature-button-border-color:ButtonText; - --clear-signature-button-border-disabled-color:GrayText; - --clear-signature-button-color:ButtonText; - --clear-signature-button-hover-color:HighlightText; - --clear-signature-button-active-color:SelectedItem; - --clear-signature-button-focus-color:CanvasText; - --clear-signature-button-disabled-color:GrayText; - --clear-signature-button-bg:var(--bg); - --clear-signature-button-bg-hover:SelectedItem; - --clear-signature-button-bg-active:var(--bg); - --clear-signature-button-bg-focus:var(--bg); - --clear-signature-button-bg-disabled:var(--bg); - --thickness-bg:Canvas; - --thickness-label-color:CanvasText; - --thickness-slider-color:ButtonText; - --thickness-border:1px solid var(--border-color); } - } -#addSignatureDialog #addSignatureDialogLabel{ - overflow:hidden; - position:absolute; - inset:0; - width:0; - height:0; - } +#addSignatureDialog #addSignatureDialogLabel { + overflow: hidden; + position: absolute; + inset: 0; + width: 0; + height: 0; +} -#addSignatureDialog.waiting::after{ - content:""; - cursor:wait; - position:absolute; - inset:0; - width:100%; - height:100%; - } +#addSignatureDialog.waiting::after { + content: ''; + cursor: wait; + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} -:is(#addSignatureDialog .mainContainer) [role="tablist"]{ - width:100%; - display:flex; - align-items:flex-start; - gap:0; - } +:is(#addSignatureDialog .mainContainer) [role='tablist'] { + width: 100%; + display: flex; + align-items: flex-start; + gap: 0; +} -:is(:is(#addSignatureDialog .mainContainer) [role="tablist"]) > [role="tab"]{ - flex:1 0 0; - align-self:stretch; - background-color:var(--tab-bg); - padding-inline:0; - cursor:default; +:is(:is(#addSignatureDialog .mainContainer) [role='tablist']) > [role='tab'] { + flex: 1 0 0; + align-self: stretch; + background-color: var(--tab-bg); + padding-inline: 0; + cursor: default; - border-inline:0; - border-block-width:1px; - border-block-style:solid; - border-block-start-color:var(--tab-top-line-inactive-color); - border-block-end-color:var(--tab-bottom-line-inactive-color); - border-radius:0; + border-inline: 0; + border-block-width: 1px; + border-block-style: solid; + border-block-start-color: var(--tab-top-line-inactive-color); + border-block-end-color: var(--tab-bottom-line-inactive-color); + border-radius: 0; - font:menu; - font-size:13px; - font-style:normal; - line-height:normal; - font-weight:400; - color:var(--tab-text-color); - } + font: menu; + font-size: 13px; + font-style: normal; + line-height: normal; + font-weight: 400; + color: var(--tab-text-color); +} -:is(:is(:is(#addSignatureDialog .mainContainer) [role="tablist"]) > [role="tab"]):hover{ - border-block-start-width:2px; - border-block-start-color:var(--tab-top-line-hover-color); - border-block-end-color:var(--tab-bottom-line-hover-color); - background-color:var(--tab-bg-hover); - color:var(--tab-text-hover-color); - } +:is( + :is(:is(#addSignatureDialog .mainContainer) [role='tablist']) > [role='tab'] +):hover { + border-block-start-width: 2px; + border-block-start-color: var(--tab-top-line-hover-color); + border-block-end-color: var(--tab-bottom-line-hover-color); + background-color: var(--tab-bg-hover); + color: var(--tab-text-hover-color); +} -:is(:is(:is(#addSignatureDialog .mainContainer) [role="tablist"]) > [role="tab"]):focus-visible{ - outline:2px solid var(--tab-top-line-active-color); - outline-offset:-2px; - } +:is( + :is(:is(#addSignatureDialog .mainContainer) [role='tablist']) > [role='tab'] +):focus-visible { + outline: 2px solid var(--tab-top-line-active-color); + outline-offset: -2px; +} -[aria-selected="true"]:is(:is(:is(#addSignatureDialog .mainContainer) [role="tablist"]) > [role="tab"]){ - border-block-start-width:2px; - border-block-start-color:var(--tab-top-line-active-color); - border-block-end-color:var(--tab-bottom-line-active-color); - background-color:var(--tab-bg-active-color); - font-weight:590; - color:var(--tab-text-active-color); - } +[aria-selected='true']:is( + :is(:is(#addSignatureDialog .mainContainer) [role='tablist']) > [role='tab'] +) { + border-block-start-width: 2px; + border-block-start-color: var(--tab-top-line-active-color); + border-block-end-color: var(--tab-bottom-line-active-color); + background-color: var(--tab-bg-active-color); + font-weight: 590; + color: var(--tab-text-active-color); +} -[aria-selected="true"]:is(:is(:is(#addSignatureDialog .mainContainer) [role="tablist"]) > [role="tab"]):hover{ - border-block-start-color:var(--tab-top-line-active-hover-color); - background-color:var(--tab-bg-active-hover-color); - color:var(--tab-text-active-hover-color); - } +[aria-selected='true']:is( + :is(:is(#addSignatureDialog .mainContainer) [role='tablist']) > [role='tab'] + ):hover { + border-block-start-color: var(--tab-top-line-active-hover-color); + background-color: var(--tab-bg-active-hover-color); + color: var(--tab-text-active-hover-color); +} -:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer{ - width:100%; - height:auto; - display:flex; - flex-direction:column; - align-items:flex-end; - align-self:stretch; - gap:12px; - padding-inline:16px; - box-sizing:border-box; - } +:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer { + width: 100%; + height: auto; + display: flex; + flex-direction: column; + align-items: flex-end; + align-self: stretch; + gap: 12px; + padding-inline: 16px; + box-sizing: border-box; +} -:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]{ - position:relative; - width:100%; - height:220px; - background-color:var(--signature-bg); - border:var(--tab-panel-border); - border-radius:var(--tab-panel-border-radius); - } +:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] { + position: relative; + width: 100%; + height: 220px; + background-color: var(--signature-bg); + border: var(--tab-panel-border); + border-radius: var(--tab-panel-border-radius); +} -:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) > svg{ - position:absolute; - inset:0; - width:100%; - height:100%; - background-color:transparent; - } +:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + > svg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + background-color: transparent; +} -#addSignatureTypeContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]){ - display:none; - } +#addSignatureTypeContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] +) { + display: none; +} /* Custom handwriting fonts for signature type input */ @font-face { - font-family: "Kalam"; - src: url("./standard_fonts/Kalam.ttf") format("truetype"); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "Sacramento"; - src: url("./standard_fonts/Sacramento.ttf") format("truetype"); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "Alex"; - src: url("./standard_fonts/AlexBrush.ttf") format("truetype"); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "Allura"; - src: url("./standard_fonts/Allura.ttf") format("truetype"); + font-family: 'Kalam'; + src: url('./standard_fonts/Kalam.ttf') format('truetype'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { - font-family: "Handlee"; - src: url("./standard_fonts/Handlee.ttf") format("truetype"); + font-family: 'Sacramento'; + src: url('./standard_fonts/Sacramento.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Alex'; + src: url('./standard_fonts/AlexBrush.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Allura'; + src: url('./standard_fonts/Allura.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Handlee'; + src: url('./standard_fonts/Handlee.ttf') format('truetype'); font-weight: 400; font-style: normal; font-display: swap; @@ -2445,5071 +2665,7620 @@ /* Custom end */ -#addSignatureTypeContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureTypeInput{ - position:absolute; - inset:0; - width:100%; - height:100%; - border:0; - padding:0; - text-align:center; - color:var(--signature-color); - background-color:transparent; - border-radius:var(--tab-panel-border-radius); +#addSignatureTypeContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #addSignatureTypeInput { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + border: 0; + padding: 0; + text-align: center; + color: var(--signature-color); + background-color: transparent; + border-radius: var(--tab-panel-border-radius); - font-family:"Brush script", "Apple Chancery", "Segoe script", "Freestyle Script", "Palace Script MT", "Brush Script MT", TK, cursive, serif; - font-size:44px; - font-style:italic; - font-weight:400; - } - -#signatureTypeControls{ - position:absolute; - inset-inline:8px; - inset-block-start:8px; - display:flex; - align-items:center; - gap:8px; - padding:4px 8px; - background-color:rgba(0,0,0,0.4); - border-radius:4px; - z-index:1; -} -#signatureTypeControls label{ - font-size:11px; - color:var(--secondary-text-color); -} -#signatureFontSelect{ - font-size:11px; -} -#signatureColorPicker{ - width:20px; - height:20px; - padding:0; - border:none; - background:transparent; + font-family: + 'Brush script', 'Apple Chancery', 'Segoe script', 'Freestyle Script', + 'Palace Script MT', 'Brush Script MT', TK, cursive, serif; + font-size: 44px; + font-style: italic; + font-weight: 400; } -:is(#addSignatureTypeContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureTypeInput)::-moz-placeholder{ - color:var(--signature-placeholder-color); - text-align:center; - - font:menu; - font-style:normal; - font-weight:274; - font-size:44px; - line-height:normal; - } - -:is(#addSignatureTypeContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureTypeInput)::placeholder{ - color:var(--signature-placeholder-color); - text-align:center; - - font:menu; - font-style:normal; - font-weight:274; - font-size:44px; - line-height:normal; - } - -#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]){ - display:none; - } - -#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) > span{ - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - display:grid; - align-items:center; - justify-content:center; - - background-color:transparent; - color:var(--signature-placeholder-color); - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) > svg{ - stroke:var(--signature-color); - fill:none; - stroke-opacity:1; - stroke-linecap:round; - stroke-linejoin:round; - stroke-miterlimit:10; - } - -:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) > svg):hover{ - cursor:var(--draw-cursor); - } - -#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness{ - position:absolute; - width:100%; - inset-block-end:0; - display:grid; - align-items:center; - justify-content:center; - pointer-events:none; - } - -:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > span{ - color:var(--signature-draw-placeholder-color); - } - -:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div{ - width:auto; - height:auto; - display:flex; - align-items:center; - justify-content:center; - gap:8px; - padding:6px 8px 7px; - margin:0; - background-color:var(--thickness-bg); - border-radius:4px 4px 0 0; - border-inline:var(--thickness-border); - border-top:var(--thickness-border); - pointer-events:auto; - position:relative; - top:1px; - } - -:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > label{ - color:var(--thickness-label-color); - } - -:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input{ - width:100px; - height:14px; - background-color:transparent; - } - -:is(:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input)::-webkit-slider-runnable-track,:is(:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input)::-moz-range-track,:is(:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input)::-moz-range-progress{ - background-color:var(--thickness-slider-color); - } - -:is(:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input)::-webkit-slider-thumb,:is(:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input)::-moz-range-thumb{ - background-color:var(--thickness-bg); - } - -:is(:is(#addSignatureDrawContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #thickness) > div) > input{ - - border-radius:4.5px; - border:0; - color:var(--signature-color); - } - -#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]){ - display:none; - } - -#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) > svg{ - stroke:none; - stroke-width:0; - fill:var(--signature-color); - fill-opacity:1; - } - -#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureImagePlaceholder{ - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - background-color:transparent; - display:flex; - flex-direction:column; - align-items:center; - justify-content:center; - } - -:is(#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureImagePlaceholder) span{ - color:var(--signature-placeholder-color); - } - -:is(#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureImagePlaceholder) a{ - color:var(--open-link-fg); - text-decoration:underline; - cursor:pointer; - } - -:is(:is(#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureImagePlaceholder) a):hover{ - color:var(--open-link-hover-fg); - } - -#addSignatureImageContainer:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > [role="tabpanel"]) #addSignatureFilePicker{ - visibility:hidden; - position:relative; - width:0; - height:0; - } - -[data-selected="type"]:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > #addSignatureTypeContainer,[data-selected="draw"]:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > #addSignatureDrawContainer,[data-selected="image"]:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) > #addSignatureImageContainer{ - display:block; - } - -:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls{ - display:flex; - flex-direction:column; - justify-content:center; - align-items:flex-start; - gap:12px; - align-self:stretch; - } - -:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer{ - display:flex; - align-items:flex-end; - gap:16px; - align-self:stretch; - } - -:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #addSignatureDescriptionContainer{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:4px; - flex:1 0 0; - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #addSignatureDescriptionContainer):has(input:disabled) > label{ - opacity:0.4; - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #addSignatureDescriptionContainer) > label{ - width:auto; - } - -:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton{ - display:flex; - height:32px; - padding:4px 8px; - align-items:center; - background-color:var(--clear-signature-button-bg); - border-width:var(--clear-signature-button-border-width); - border-style:var(--clear-signature-button-border-style); - border-color:var(--clear-signature-button-border-color); - border-radius:4px; - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton) > span{ - display:flex; - height:24px; - align-items:center; - gap:4px; - flex-shrink:0; - - color:var(--clear-signature-button-color); - } - -:is(:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton) > span)::after{ - content:""; - display:inline-block; - width:16px; - height:16px; - -webkit-mask-image:var(--clear-signature-button-icon); - mask-image:var(--clear-signature-button-icon); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--clear-signature-button-color); - flex-shrink:0; - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):hover{ - background-color:var(--clear-signature-button-bg-hover); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):hover > span{ - color:var(--clear-signature-button-hover-color); - } - -:is(:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):hover > span)::after{ - background-color:var(--clear-signature-button-hover-color); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):active{ - background-color:var(--clear-signature-button-bg-active); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):active > span{ - color:var(--clear-signature-button-active-color); - } - -:is(:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):active > span)::after{ - background-color:var(--clear-signature-button-active-color); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):focus-visible{ - background-color:var(--clear-signature-button-bg-focus); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):focus-visible > span{ - color:var(--clear-signature-button-focus-color); - } - -:is(:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):focus-visible > span)::after{ - background-color:var(--clear-signature-button-focus-color); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):disabled{ - background-color:var(--clear-signature-button-bg-disabled); - border-color:var(--clear-signature-button-border-disabled-color); - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):disabled > span{ - color:var(--clear-signature-button-disabled-color); - } - -:is(:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #horizontalContainer) #clearSignatureButton):disabled > span)::after{ - background-color:var( - --clear-signature-button-disabled-color - ); - } - -:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer{ - display:grid; - grid-template-columns:max-content auto; - gap:4px; - width:100%; - } - -:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer) > input{ - margin:0; - } - -:is(:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer) > input):disabled + label{ - opacity:0.4; - } - -:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer) > label{ - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer):not(.fullStorage) #addSignatureSaveWarning{ - display:none; - } - -.fullStorage:is(:is(:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) #addSignatureControls) #addSignatureSaveContainer) #addSignatureSaveWarning{ - display:block; - opacity:1; - color:var(--save-warning-color); - font-size:11px; - } - -#editSignatureDescriptionDialog .mainContainer{ - padding-inline:16px; - box-sizing:border-box; - } - -:is(#editSignatureDescriptionDialog .mainContainer) .title{ - margin-inline-start:0; - } - -:is(#editSignatureDescriptionDialog .mainContainer) #editSignatureDescriptionAndView{ - width:auto; - display:flex; - justify-content:flex-end; - align-items:flex-start; - gap:12px; - align-self:stretch; - } - -:is(:is(#editSignatureDescriptionDialog .mainContainer) #editSignatureDescriptionAndView) #editSignatureDescriptionContainer{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:4px; - flex:1 1 auto; - } - -:is(:is(#editSignatureDescriptionDialog .mainContainer) #editSignatureDescriptionAndView) > svg{ - width:210px; - height:180px; - padding:8px; - background-color:var(--signature-bg); - } - -:is(:is(:is(#editSignatureDescriptionDialog .mainContainer) #editSignatureDescriptionAndView) > svg) > path{ - stroke:var(--button-signature-color); - stroke-width:1px; - stroke-linecap:round; - stroke-linejoin:round; - stroke-miterlimit:10; - vector-effect:non-scaling-stroke; - fill:none; - } - -.contours:is(:is(:is(:is(#editSignatureDescriptionDialog .mainContainer) #editSignatureDescriptionAndView) > svg) > path){ - fill:var(--button-signature-color); - stroke-width:0.5px; - } - -#editorSignatureParamsToolbar{ - padding:8px; +#signatureTypeControls { + position: absolute; + inset-inline: 8px; + inset-block-start: 8px; + display: flex; + align-items: center; + gap: 8px; + padding: 4px 8px; + background-color: rgba(0, 0, 0, 0.4); + border-radius: 4px; + z-index: 1; +} +#signatureTypeControls label { + font-size: 11px; + color: var(--secondary-text-color); +} +#signatureFontSelect { + font-size: 11px; +} +#signatureColorPicker { + width: 20px; + height: 20px; + padding: 0; + border: none; + background: transparent; } -#editorSignatureParamsToolbar #addSignatureDoorHanger{ - gap:8px; - padding:2px; - } +:is( + #addSignatureTypeContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #addSignatureTypeInput +)::-moz-placeholder { + color: var(--signature-placeholder-color); + text-align: center; -:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer{ - height:32px; - display:flex; - justify-content:space-between; - align-items:center; - align-self:stretch; - gap:8px; - } - -:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button{ - border:var(--button-signature-border); - border-radius:4px; - background-color:var(--button-signature-bg); - color:var(--button-signature-color); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button):hover{ - background-color:var(--button-signature-hover-bg); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button):active{ - border:var(--button-signature-active-border); - background-color:var(--button-signature-active-bg); - color:var(--button-signature-active-color); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button):active::before{ - background-color:var(--button-signature-active-color); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button):focus-visible{ - outline:var(--focus-ring-outline); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) button):focus-visible::before{ - background-color:var(--button-signature-color); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .deleteButton)::before{ - -webkit-mask-image:var(--clear-signature-button-icon); - mask-image:var(--clear-signature-button-icon); - } - -:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton{ - width:calc(0.8 * var(--editor-toolbar-min-width)); - height:100%; - min-height:var(--menuitem-height); - aspect-ratio:unset; - display:flex; - align-items:center; - justify-content:flex-start; - outline:none; - border-radius:4px; - box-sizing:border-box; - font:message-box; - position:relative; - flex:1 1 auto; - padding:0; - gap:8px; - text-align:start; - white-space:normal; - cursor:default; - overflow:hidden; - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton) > svg{ - display:inline-block; - height:100%; - aspect-ratio:1; - background-color:var(--signature-bg); - flex:none; - padding:4px; - box-sizing:border-box; - border:none; - border-radius:4px; - } - -:is(:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton) > svg) > path{ - stroke:var(--button-signature-color); - stroke-width:1px; - stroke-linecap:round; - stroke-linejoin:round; - stroke-miterlimit:10; - vector-effect:non-scaling-stroke; - fill:none; - } - -.contours:is(:is(:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton) > svg) > path){ - fill:var(--button-signature-color); - stroke-width:0.5px; - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton):is(:hover,:active) > svg{ - border-radius:4px 0 0 4px; - background-color:var(--signature-hover-bg); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton):hover > span{ - color:var(--button-signature-hover-color); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton):active{ - background-color:var(--button-signature-active-bg); - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton):is([disabled="disabled"],[disabled]){ - opacity:0.5; - pointer-events:none; - } - -:is(:is(:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) .toolbarAddSignatureButtonContainer) .toolbarAddSignatureButton) > span{ - height:auto; - text-overflow:ellipsis; - white-space:nowrap; - flex:1 1 auto; - font:menu; - font-size:13px; - font-style:normal; - font-weight:400; - line-height:normal; - overflow:hidden; - } - -.editDescription.altText{ - --alt-text-add-image:url(images/editor-toolbar-edit.svg) !important; + font: menu; + font-style: normal; + font-weight: 274; + font-size: 44px; + line-height: normal; } -.editDescription.altText::before{ - width:16px !important; - height:16px !important; - } +:is( + #addSignatureTypeContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #addSignatureTypeInput +)::placeholder { + color: var(--signature-placeholder-color); + text-align: center; + + font: menu; + font-style: normal; + font-weight: 274; + font-size: 44px; + line-height: normal; +} + +#addSignatureDrawContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] +) { + display: none; +} + +#addSignatureDrawContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + > span { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: grid; + align-items: center; + justify-content: center; + + background-color: transparent; + color: var(--signature-placeholder-color); + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + touch-action: none; +} + +#addSignatureDrawContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + > svg { + stroke: var(--signature-color); + fill: none; + stroke-opacity: 1; + stroke-linecap: round; + stroke-linejoin: round; + stroke-miterlimit: 10; + touch-action: none; +} + +:is( + #addSignatureDrawContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + > svg +):hover { + cursor: var(--draw-cursor); +} + +#addSignatureDrawContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #thickness { + position: absolute; + width: 100%; + inset-block-end: 0; + display: grid; + align-items: center; + justify-content: center; + pointer-events: none; +} + +:is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > span { + color: var(--signature-draw-placeholder-color); +} + +:is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div { + width: auto; + height: auto; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 6px 8px 7px; + margin: 0; + background-color: var(--thickness-bg); + border-radius: 4px 4px 0 0; + border-inline: var(--thickness-border); + border-top: var(--thickness-border); + pointer-events: auto; + position: relative; + top: 1px; +} + +:is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > label { + color: var(--thickness-label-color); +} + +:is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input { + width: 100px; + height: 14px; + background-color: transparent; +} + +:is( + :is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input +)::-webkit-slider-runnable-track, +:is( + :is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input +)::-moz-range-track, +:is( + :is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input +)::-moz-range-progress { + background-color: var(--thickness-slider-color); +} + +:is( + :is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input +)::-webkit-slider-thumb, +:is( + :is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input +)::-moz-range-thumb { + background-color: var(--thickness-bg); +} + +:is( + :is( + #addSignatureDrawContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #thickness + ) + > div + ) + > input { + border-radius: 4.5px; + border: 0; + color: var(--signature-color); +} + +#addSignatureImageContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] +) { + display: none; +} + +#addSignatureImageContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + > svg { + stroke: none; + stroke-width: 0; + fill: var(--signature-color); + fill-opacity: 1; +} + +#addSignatureImageContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #addSignatureImagePlaceholder { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: transparent; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +:is( + #addSignatureImageContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #addSignatureImagePlaceholder + ) + span { + color: var(--signature-placeholder-color); +} + +:is( + #addSignatureImageContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #addSignatureImagePlaceholder + ) + a { + color: var(--open-link-fg); + text-decoration: underline; + cursor: pointer; +} + +:is( + :is( + #addSignatureImageContainer:is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + > [role='tabpanel'] + ) + #addSignatureImagePlaceholder + ) + a +):hover { + color: var(--open-link-hover-fg); +} + +#addSignatureImageContainer:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + > [role='tabpanel'] + ) + #addSignatureFilePicker { + visibility: hidden; + position: relative; + width: 0; + height: 0; +} + +[data-selected='type']:is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > #addSignatureTypeContainer, +[data-selected='draw']:is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > #addSignatureDrawContainer, +[data-selected='image']:is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + > #addSignatureImageContainer { + display: block; +} + +:is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + #addSignatureControls { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + gap: 12px; + align-self: stretch; +} + +:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + #addSignatureControls + ) + #horizontalContainer { + display: flex; + align-items: flex-end; + gap: 16px; + align-self: stretch; +} + +:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #addSignatureDescriptionContainer { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; + flex: 1 0 0; +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #addSignatureDescriptionContainer + ):has(input:disabled) + > label { + opacity: 0.4; +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #addSignatureDescriptionContainer + ) + > label { + width: auto; +} + +:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton { + display: flex; + height: 32px; + padding: 4px 8px; + align-items: center; + background-color: var(--clear-signature-button-bg); + border-width: var(--clear-signature-button-border-width); + border-style: var(--clear-signature-button-border-style); + border-color: var(--clear-signature-button-border-color); + border-radius: 4px; +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ) + > span { + display: flex; + height: 24px; + align-items: center; + gap: 4px; + flex-shrink: 0; + + color: var(--clear-signature-button-color); +} + +:is( + :is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ) + > span +)::after { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + -webkit-mask-image: var(--clear-signature-button-icon); + mask-image: var(--clear-signature-button-icon); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--clear-signature-button-color); + flex-shrink: 0; +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton +):hover { + background-color: var(--clear-signature-button-bg-hover); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):hover + > span { + color: var(--clear-signature-button-hover-color); +} + +:is( + :is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):hover + > span +)::after { + background-color: var(--clear-signature-button-hover-color); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton +):active { + background-color: var(--clear-signature-button-bg-active); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):active + > span { + color: var(--clear-signature-button-active-color); +} + +:is( + :is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):active + > span +)::after { + background-color: var(--clear-signature-button-active-color); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton +):focus-visible { + background-color: var(--clear-signature-button-bg-focus); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):focus-visible + > span { + color: var(--clear-signature-button-focus-color); +} + +:is( + :is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):focus-visible + > span +)::after { + background-color: var(--clear-signature-button-focus-color); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton +):disabled { + background-color: var(--clear-signature-button-bg-disabled); + border-color: var(--clear-signature-button-border-disabled-color); +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):disabled + > span { + color: var(--clear-signature-button-disabled-color); +} + +:is( + :is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #horizontalContainer + ) + #clearSignatureButton + ):disabled + > span +)::after { + background-color: var(--clear-signature-button-disabled-color); +} + +:is( + :is(:is(#addSignatureDialog .mainContainer) #addSignatureActionContainer) + #addSignatureControls + ) + #addSignatureSaveContainer { + display: grid; + grid-template-columns: max-content auto; + gap: 4px; + width: 100%; +} + +:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #addSignatureSaveContainer + ) + > input { + margin: 0; +} + +:is( + :is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) + #addSignatureActionContainer + ) + #addSignatureControls + ) + #addSignatureSaveContainer + ) + > input + ):disabled + + label { + opacity: 0.4; +} + +:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #addSignatureSaveContainer + ) + > label { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #addSignatureSaveContainer + ):not(.fullStorage) + #addSignatureSaveWarning { + display: none; +} + +.fullStorage:is( + :is( + :is( + :is(#addSignatureDialog .mainContainer) #addSignatureActionContainer + ) + #addSignatureControls + ) + #addSignatureSaveContainer + ) + #addSignatureSaveWarning { + display: block; + opacity: 1; + color: var(--save-warning-color); + font-size: 11px; +} + +#editSignatureDescriptionDialog .mainContainer { + padding-inline: 16px; + box-sizing: border-box; +} + +:is(#editSignatureDescriptionDialog .mainContainer) .title { + margin-inline-start: 0; +} + +:is(#editSignatureDescriptionDialog .mainContainer) + #editSignatureDescriptionAndView { + width: auto; + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 12px; + align-self: stretch; +} + +:is( + :is(#editSignatureDescriptionDialog .mainContainer) + #editSignatureDescriptionAndView + ) + #editSignatureDescriptionContainer { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; + flex: 1 1 auto; +} + +:is( + :is(#editSignatureDescriptionDialog .mainContainer) + #editSignatureDescriptionAndView + ) + > svg { + width: 210px; + height: 180px; + padding: 8px; + background-color: var(--signature-bg); +} + +:is( + :is( + :is(#editSignatureDescriptionDialog .mainContainer) + #editSignatureDescriptionAndView + ) + > svg + ) + > path { + stroke: var(--button-signature-color); + stroke-width: 1px; + stroke-linecap: round; + stroke-linejoin: round; + stroke-miterlimit: 10; + vector-effect: non-scaling-stroke; + fill: none; +} + +.contours:is( + :is( + :is( + :is(#editSignatureDescriptionDialog .mainContainer) + #editSignatureDescriptionAndView + ) + > svg + ) + > path +) { + fill: var(--button-signature-color); + stroke-width: 0.5px; +} + +#editorSignatureParamsToolbar { + padding: 8px; +} + +#editorSignatureParamsToolbar #addSignatureDoorHanger { + gap: 8px; + padding: 2px; +} + +:is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer { + height: 32px; + display: flex; + justify-content: space-between; + align-items: center; + align-self: stretch; + gap: 8px; +} + +:is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button { + border: var(--button-signature-border); + border-radius: 4px; + background-color: var(--button-signature-bg); + color: var(--button-signature-color); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button +):hover { + background-color: var(--button-signature-hover-bg); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button +):active { + border: var(--button-signature-active-border); + background-color: var(--button-signature-active-bg); + color: var(--button-signature-active-color); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button + ):active::before { + background-color: var(--button-signature-active-color); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button +):focus-visible { + outline: var(--focus-ring-outline); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + button + ):focus-visible::before { + background-color: var(--button-signature-color); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .deleteButton +)::before { + -webkit-mask-image: var(--clear-signature-button-icon); + mask-image: var(--clear-signature-button-icon); +} + +:is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton { + width: calc(0.8 * var(--editor-toolbar-min-width)); + height: 100%; + min-height: var(--menuitem-height); + aspect-ratio: unset; + display: flex; + align-items: center; + justify-content: flex-start; + outline: none; + border-radius: 4px; + box-sizing: border-box; + font: message-box; + position: relative; + flex: 1 1 auto; + padding: 0; + gap: 8px; + text-align: start; + white-space: normal; + cursor: default; + overflow: hidden; +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ) + > svg { + display: inline-block; + height: 100%; + aspect-ratio: 1; + background-color: var(--signature-bg); + flex: none; + padding: 4px; + box-sizing: border-box; + border: none; + border-radius: 4px; +} + +:is( + :is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ) + > svg + ) + > path { + stroke: var(--button-signature-color); + stroke-width: 1px; + stroke-linecap: round; + stroke-linejoin: round; + stroke-miterlimit: 10; + vector-effect: non-scaling-stroke; + fill: none; +} + +.contours:is( + :is( + :is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ) + > svg + ) + > path +) { + fill: var(--button-signature-color); + stroke-width: 0.5px; +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ):is(:hover, :active) + > svg { + border-radius: 4px 0 0 4px; + background-color: var(--signature-hover-bg); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ):hover + > span { + color: var(--button-signature-hover-color); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton +):active { + background-color: var(--button-signature-active-bg); +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton +):is([disabled='disabled'], [disabled]) { + opacity: 0.5; + pointer-events: none; +} + +:is( + :is( + :is(#editorSignatureParamsToolbar #addSignatureDoorHanger) + .toolbarAddSignatureButtonContainer + ) + .toolbarAddSignatureButton + ) + > span { + height: auto; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1 1 auto; + font: menu; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: normal; + overflow: hidden; +} + +.editDescription.altText { + --alt-text-add-image: url(images/editor-toolbar-edit.svg) !important; +} + +.editDescription.altText::before { + width: 16px !important; + height: 16px !important; +} .commentPopup, -#commentManagerDialog{ - width:360px; - max-width:100%; - min-width:200px; - position:absolute; - padding:8px 16px 16px; - margin-left:0; - margin-top:0; - box-sizing:border-box; +#commentManagerDialog { + width: 360px; + max-width: 100%; + min-width: 200px; + position: absolute; + padding: 8px 16px 16px; + margin-left: 0; + margin-top: 0; + box-sizing: border-box; - border-radius:8px; + border-radius: 8px; } -#commentManagerDialog{ - --comment-close-button-icon:url(images/comment-closeButton.svg); +#commentManagerDialog { + --comment-close-button-icon: url(images/comment-closeButton.svg); } -#commentManagerDialog .mainContainer{ - width:100%; - height:auto; - display:flex; - flex-direction:column; - align-items:flex-start; - gap:4px; - } - -:is(#commentManagerDialog .mainContainer) #commentManagerToolbar{ - width:100%; - height:32px; - display:flex; - justify-content:flex-start; - align-items:flex-start; - gap:8px; - align-self:stretch; - - cursor:move; - } - -:is(#commentManagerDialog .mainContainer) #commentManagerTextInput{ - width:100%; - min-height:132px; - margin-bottom:12px; - } - -.annotationLayer.disabled :is(.annotationCommentButton){ - display:none; +#commentManagerDialog .mainContainer { + width: 100%; + height: auto; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; } -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ - --csstools-color-scheme--light:initial; - color-scheme:light dark; - --csstools-light-dark-toggle--75:var(--csstools-color-scheme--light) #1c1b22; - --comment-button-bg:var(--csstools-light-dark-toggle--75, white); - --csstools-light-dark-toggle--76:var(--csstools-color-scheme--light) #fbfbfe; - --comment-button-fg:var(--csstools-light-dark-toggle--76, #5b5b66); - --csstools-light-dark-toggle--77:var(--csstools-color-scheme--light) #a6ecf4; - --comment-button-active-bg:var(--csstools-light-dark-toggle--77, #0041a4); - --csstools-light-dark-toggle--78:var(--csstools-color-scheme--light) #15141a; - --comment-button-active-fg:var(--csstools-light-dark-toggle--78, white); - --csstools-light-dark-toggle--79:var(--csstools-color-scheme--light) #61dce9; - --comment-button-hover-bg:var(--csstools-light-dark-toggle--79, #0053cb); - --csstools-light-dark-toggle--80:var(--csstools-color-scheme--light) #15141a; - --comment-button-hover-fg:var(--csstools-light-dark-toggle--80, white); - --csstools-light-dark-toggle--81:var(--csstools-color-scheme--light) #00cadb; - --comment-button-selected-bg:var(--csstools-light-dark-toggle--81, #0062fa); - --csstools-light-dark-toggle--82:var(--csstools-color-scheme--light) #bfbfc9; - --comment-button-border-color:var(--csstools-light-dark-toggle--82, #8f8f9d); - --comment-button-active-border-color:var(--comment-button-active-bg); - --csstools-light-dark-toggle--83:var(--csstools-color-scheme--light) #3a3944; - --comment-button-focus-border-color:var(--csstools-light-dark-toggle--83, #cfcfd8); - --comment-button-hover-border-color:var(--comment-button-hover-bg); - --comment-button-selected-border-color:var(--comment-button-selected-bg); - --csstools-light-dark-toggle--84:var(--csstools-color-scheme--light) #15141a; - --comment-button-selected-fg:var(--csstools-light-dark-toggle--84, white); - --comment-button-dim:24px; - --csstools-light-dark-toggle--85:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--86:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --comment-button-box-shadow:0 0.25px 0.75px 0 var(--csstools-light-dark-toggle--85, rgb(0 0 0 / 0.05)), 0 2px 6px 0 var(--csstools-light-dark-toggle--86, rgb(0 0 0 / 0.1)); - --csstools-light-dark-toggle--87:var(--csstools-color-scheme--light) #00cadb; - --comment-button-focus-outline-color:var(--csstools-light-dark-toggle--87, #0062fa); - } +:is(#commentManagerDialog .mainContainer) #commentManagerToolbar { + width: 100%; + height: 32px; + display: flex; + justify-content: flex-start; + align-items: flex-start; + gap: 8px; + align-self: stretch; -@supports (color: light-dark(red, red)){ -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ - --comment-button-bg:light-dark(white, #1c1b22); - --comment-button-fg:light-dark(#5b5b66, #fbfbfe); - --comment-button-active-bg:light-dark(#0041a4, #a6ecf4); - --comment-button-active-fg:light-dark(white, #15141a); - --comment-button-hover-bg:light-dark(#0053cb, #61dce9); - --comment-button-hover-fg:light-dark(white, #15141a); - --comment-button-selected-bg:light-dark(#0062fa, #00cadb); - --comment-button-border-color:light-dark(#8f8f9d, #bfbfc9); - --comment-button-focus-border-color:light-dark(#cfcfd8, #3a3944); - --comment-button-selected-fg:light-dark(white, #15141a); + cursor: move; +} + +:is(#commentManagerDialog .mainContainer) #commentManagerTextInput { + width: 100%; + min-height: 132px; + margin-bottom: 12px; +} + +.annotationLayer.disabled :is(.annotationCommentButton) { + display: none; +} + +:is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + --csstools-color-scheme--light: initial; + color-scheme: light dark; + --csstools-light-dark-toggle--75: var(--csstools-color-scheme--light) #1c1b22; + --comment-button-bg: var(--csstools-light-dark-toggle--75, white); + --csstools-light-dark-toggle--76: var(--csstools-color-scheme--light) #fbfbfe; + --comment-button-fg: var(--csstools-light-dark-toggle--76, #5b5b66); + --csstools-light-dark-toggle--77: var(--csstools-color-scheme--light) #a6ecf4; + --comment-button-active-bg: var(--csstools-light-dark-toggle--77, #0041a4); + --csstools-light-dark-toggle--78: var(--csstools-color-scheme--light) #15141a; + --comment-button-active-fg: var(--csstools-light-dark-toggle--78, white); + --csstools-light-dark-toggle--79: var(--csstools-color-scheme--light) #61dce9; + --comment-button-hover-bg: var(--csstools-light-dark-toggle--79, #0053cb); + --csstools-light-dark-toggle--80: var(--csstools-color-scheme--light) #15141a; + --comment-button-hover-fg: var(--csstools-light-dark-toggle--80, white); + --csstools-light-dark-toggle--81: var(--csstools-color-scheme--light) #00cadb; + --comment-button-selected-bg: var(--csstools-light-dark-toggle--81, #0062fa); + --csstools-light-dark-toggle--82: var(--csstools-color-scheme--light) #bfbfc9; + --comment-button-border-color: var(--csstools-light-dark-toggle--82, #8f8f9d); + --comment-button-active-border-color: var(--comment-button-active-bg); + --csstools-light-dark-toggle--83: var(--csstools-color-scheme--light) #3a3944; + --comment-button-focus-border-color: var( + --csstools-light-dark-toggle--83, + #cfcfd8 + ); + --comment-button-hover-border-color: var(--comment-button-hover-bg); + --comment-button-selected-border-color: var(--comment-button-selected-bg); + --csstools-light-dark-toggle--84: var(--csstools-color-scheme--light) #15141a; + --comment-button-selected-fg: var(--csstools-light-dark-toggle--84, white); + --comment-button-dim: 24px; + --csstools-light-dark-toggle--85: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--86: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --comment-button-box-shadow: + 0 0.25px 0.75px 0 var(--csstools-light-dark-toggle--85, rgb(0 0 0 / 0.05)), + 0 2px 6px 0 var(--csstools-light-dark-toggle--86, rgb(0 0 0 / 0.1)); + --csstools-light-dark-toggle--87: var(--csstools-color-scheme--light) #00cadb; + --comment-button-focus-outline-color: var( + --csstools-light-dark-toggle--87, + #0062fa + ); +} + +@supports (color: light-dark(red, red)) { + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + --comment-button-bg: light-dark(white, #1c1b22); + --comment-button-fg: light-dark(#5b5b66, #fbfbfe); + --comment-button-active-bg: light-dark(#0041a4, #a6ecf4); + --comment-button-active-fg: light-dark(white, #15141a); + --comment-button-hover-bg: light-dark(#0053cb, #61dce9); + --comment-button-hover-fg: light-dark(white, #15141a); + --comment-button-selected-bg: light-dark(#0062fa, #00cadb); + --comment-button-border-color: light-dark(#8f8f9d, #bfbfc9); + --comment-button-focus-border-color: light-dark(#cfcfd8, #3a3944); + --comment-button-selected-fg: light-dark(white, #15141a); } } -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ - --comment-button-box-shadow:0 0.25px 0.75px 0 light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), 0 2px 6px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + --comment-button-box-shadow: + 0 0.25px 0.75px 0 light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), + 0 2px 6px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); } } -@supports (color: light-dark(red, red)){ -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ - --comment-button-focus-outline-color:light-dark(#0062fa, #00cadb); +@supports (color: light-dark(red, red)) { + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + --comment-button-focus-outline-color: light-dark(#0062fa, #00cadb); } } -@supports not (color: light-dark(tan, tan)){ - -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton) *{ - --csstools-light-dark-toggle--75:var(--csstools-color-scheme--light) #1c1b22; - --comment-button-bg:var(--csstools-light-dark-toggle--75, white); - --csstools-light-dark-toggle--76:var(--csstools-color-scheme--light) #fbfbfe; - --comment-button-fg:var(--csstools-light-dark-toggle--76, #5b5b66); - --csstools-light-dark-toggle--77:var(--csstools-color-scheme--light) #a6ecf4; - --comment-button-active-bg:var(--csstools-light-dark-toggle--77, #0041a4); - --csstools-light-dark-toggle--78:var(--csstools-color-scheme--light) #15141a; - --comment-button-active-fg:var(--csstools-light-dark-toggle--78, white); - --csstools-light-dark-toggle--79:var(--csstools-color-scheme--light) #61dce9; - --comment-button-hover-bg:var(--csstools-light-dark-toggle--79, #0053cb); - --csstools-light-dark-toggle--80:var(--csstools-color-scheme--light) #15141a; - --comment-button-hover-fg:var(--csstools-light-dark-toggle--80, white); - --csstools-light-dark-toggle--81:var(--csstools-color-scheme--light) #00cadb; - --comment-button-selected-bg:var(--csstools-light-dark-toggle--81, #0062fa); - --csstools-light-dark-toggle--82:var(--csstools-color-scheme--light) #bfbfc9; - --comment-button-border-color:var(--csstools-light-dark-toggle--82, #8f8f9d); - --csstools-light-dark-toggle--83:var(--csstools-color-scheme--light) #3a3944; - --comment-button-focus-border-color:var(--csstools-light-dark-toggle--83, #cfcfd8); - --csstools-light-dark-toggle--84:var(--csstools-color-scheme--light) #15141a; - --comment-button-selected-fg:var(--csstools-light-dark-toggle--84, white); - --csstools-light-dark-toggle--85:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--86:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --comment-button-box-shadow:0 0.25px 0.75px 0 var(--csstools-light-dark-toggle--85, rgb(0 0 0 / 0.05)), 0 2px 6px 0 var(--csstools-light-dark-toggle--86, rgb(0 0 0 / 0.1)); - --csstools-light-dark-toggle--87:var(--csstools-color-scheme--light) #00cadb; - --comment-button-focus-outline-color:var(--csstools-light-dark-toggle--87, #0062fa); +@supports not (color: light-dark(tan, tan)) { + :is(:is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton) + * { + --csstools-light-dark-toggle--75: var(--csstools-color-scheme--light) + #1c1b22; + --comment-button-bg: var(--csstools-light-dark-toggle--75, white); + --csstools-light-dark-toggle--76: var(--csstools-color-scheme--light) + #fbfbfe; + --comment-button-fg: var(--csstools-light-dark-toggle--76, #5b5b66); + --csstools-light-dark-toggle--77: var(--csstools-color-scheme--light) + #a6ecf4; + --comment-button-active-bg: var(--csstools-light-dark-toggle--77, #0041a4); + --csstools-light-dark-toggle--78: var(--csstools-color-scheme--light) + #15141a; + --comment-button-active-fg: var(--csstools-light-dark-toggle--78, white); + --csstools-light-dark-toggle--79: var(--csstools-color-scheme--light) + #61dce9; + --comment-button-hover-bg: var(--csstools-light-dark-toggle--79, #0053cb); + --csstools-light-dark-toggle--80: var(--csstools-color-scheme--light) + #15141a; + --comment-button-hover-fg: var(--csstools-light-dark-toggle--80, white); + --csstools-light-dark-toggle--81: var(--csstools-color-scheme--light) + #00cadb; + --comment-button-selected-bg: var( + --csstools-light-dark-toggle--81, + #0062fa + ); + --csstools-light-dark-toggle--82: var(--csstools-color-scheme--light) + #bfbfc9; + --comment-button-border-color: var( + --csstools-light-dark-toggle--82, + #8f8f9d + ); + --csstools-light-dark-toggle--83: var(--csstools-color-scheme--light) + #3a3944; + --comment-button-focus-border-color: var( + --csstools-light-dark-toggle--83, + #cfcfd8 + ); + --csstools-light-dark-toggle--84: var(--csstools-color-scheme--light) + #15141a; + --comment-button-selected-fg: var(--csstools-light-dark-toggle--84, white); + --csstools-light-dark-toggle--85: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--86: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --comment-button-box-shadow: + 0 0.25px 0.75px 0 var(--csstools-light-dark-toggle--85, rgb(0 0 0 / 0.05)), + 0 2px 6px 0 var(--csstools-light-dark-toggle--86, rgb(0 0 0 / 0.1)); + --csstools-light-dark-toggle--87: var(--csstools-color-scheme--light) + #00cadb; + --comment-button-focus-outline-color: var( + --csstools-light-dark-toggle--87, + #0062fa + ); } } -@media (prefers-color-scheme: dark){ - -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ +@media (prefers-color-scheme: dark) { + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { --csstools-color-scheme--light: light; } } -@media screen and (forced-colors: active){ - -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ - --comment-button-bg:ButtonFace; - --comment-button-fg:ButtonText; - --comment-button-hover-bg:SelectedItemText; - --comment-button-hover-fg:SelectedItem; - --comment-button-active-bg:SelectedItemText; - --comment-button-active-fg:SelectedItem; - --comment-button-border-color:ButtonBorder; - --comment-button-active-border-color:ButtonBorder; - --comment-button-hover-border-color:SelectedItem; - --comment-button-box-shadow:none; - --comment-button-focus-outline-color:CanvasText; - --comment-button-selected-bg:ButtonBorder; - --comment-button-selected-fg:ButtonFace; +@media screen and (forced-colors: active) { + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + --comment-button-bg: ButtonFace; + --comment-button-fg: ButtonText; + --comment-button-hover-bg: SelectedItemText; + --comment-button-hover-fg: SelectedItem; + --comment-button-active-bg: SelectedItemText; + --comment-button-active-fg: SelectedItem; + --comment-button-border-color: ButtonBorder; + --comment-button-active-border-color: ButtonBorder; + --comment-button-hover-border-color: SelectedItem; + --comment-button-box-shadow: none; + --comment-button-focus-outline-color: CanvasText; + --comment-button-selected-bg: ButtonBorder; + --comment-button-selected-fg: ButtonFace; } - } +} -:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton{ +:is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton { + position: absolute; + width: var(--comment-button-dim); + height: var(--comment-button-dim); + background-color: var(--comment-button-bg); + border-radius: 6px 6px 6px 0; + border: 1px solid var(--comment-button-border-color); + box-shadow: var(--comment-button-box-shadow); + cursor: auto; + z-index: 1; + padding: 4px; + margin: 0; + box-sizing: border-box; + pointer-events: auto; +} - position:absolute; - width:var(--comment-button-dim); - height:var(--comment-button-dim); - background-color:var(--comment-button-bg); - border-radius:6px 6px 6px 0; - border:1px solid var(--comment-button-border-color); - box-shadow:var(--comment-button-box-shadow); - cursor:auto; - z-index:1; - padding:4px; - margin:0; - box-sizing:border-box; - pointer-events:auto; - } +[dir='rtl'] + :is(:is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton) { + border-radius: 6px 6px 0; +} -[dir="rtl"] :is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton){ - border-radius:6px 6px 0; - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton +)::before { + content: ''; + display: inline-block; + width: 100%; + height: 100%; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: cover; + mask-size: cover; + -webkit-mask-image: var(--comment-edit-button-icon); + mask-image: var(--comment-edit-button-icon); + background-color: var(--comment-button-fg); + margin: 0; + padding: 0; + transform: scaleX(var(--dir-factor)); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton)::before{ - content:""; - display:inline-block; - width:100%; - height:100%; - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-size:cover; - mask-size:cover; - -webkit-mask-image:var(--comment-edit-button-icon); - mask-image:var(--comment-edit-button-icon); - background-color:var(--comment-button-fg); - margin:0; - padding:0; - transform:scaleX(var(--dir-factor)); - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton +):focus-visible { + outline: 2px solid var(--comment-button-focus-outline-color); + outline-offset: 1px; + border-color: var(--comment-button-focus-border-color); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton):focus-visible{ - outline:2px solid var(--comment-button-focus-outline-color); - outline-offset:1px; - border-color:var(--comment-button-focus-border-color); - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton +):hover { + background-color: var(--comment-button-hover-bg) !important; + border-color: var(--comment-button-hover-border-color); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton):hover{ - background-color:var(--comment-button-hover-bg) !important; - border-color:var(--comment-button-hover-border-color); - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton + ):hover::before { + background-color: var(--comment-button-hover-fg); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton):hover::before{ - background-color:var(--comment-button-hover-fg); - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton +):active { + background-color: var(--comment-button-active-bg) !important; + border-color: var(--comment-button-active-border-color); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton):active{ - background-color:var(--comment-button-active-bg) !important; - border-color:var(--comment-button-active-border-color); - } +:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton + ):active::before { + background-color: var(--comment-button-active-fg); +} -:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton):active::before{ - background-color:var(--comment-button-active-fg); - } +.selected:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton +) { + background-color: var(--comment-button-selected-bg) !important; + border-color: var(--comment-button-selected-border-color); +} -.selected:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton){ - background-color:var(--comment-button-selected-bg) !important; - border-color:var(--comment-button-selected-border-color); - } - -.selected:is(:is(.annotationLayer,.annotationEditorLayer) .annotationCommentButton)::before{ - background-color:var(--comment-button-selected-fg); - } +.selected:is( + :is(.annotationLayer, .annotationEditorLayer) .annotationCommentButton + )::before { + background-color: var(--comment-button-selected-fg); +} #editorCommentsSidebar, -.commentPopup{ - --comment-close-button-icon:url(images/comment-closeButton.svg); - --comment-popup-edit-button-icon:url(images/comment-popup-editButton.svg); - --comment-popup-delete-button-icon:url(images/editor-toolbar-delete.svg); +.commentPopup { + --comment-close-button-icon: url(images/comment-closeButton.svg); + --comment-popup-edit-button-icon: url(images/comment-popup-editButton.svg); + --comment-popup-delete-button-icon: url(images/editor-toolbar-delete.svg); - --csstools-light-dark-toggle--88:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.69); + --csstools-light-dark-toggle--88: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.69); - --comment-date-fg-color:var(--csstools-light-dark-toggle--88, rgb(21 20 26 / 0.69)); - --csstools-light-dark-toggle--89:var(--csstools-color-scheme--light) #1c1b22; - --comment-bg-color:var(--csstools-light-dark-toggle--89, #f9f9fb); - --csstools-light-dark-toggle--90:var(--csstools-color-scheme--light) #2c2b33; - --comment-hover-bg-color:var(--csstools-light-dark-toggle--90, #e0e0e6); - --csstools-light-dark-toggle--91:var(--csstools-color-scheme--light) #3a3944; - --comment-active-bg-color:var(--csstools-light-dark-toggle--91, #d1d1d9); - --comment-hover-brightness:0.89; - --comment-hover-filter:brightness(var(--comment-hover-brightness)); - --comment-active-brightness:0.825; - --comment-active-filter:brightness(var(--comment-active-brightness)); - --csstools-light-dark-toggle--92:var(--csstools-color-scheme--light) #52525e; - --comment-border-color:var(--csstools-light-dark-toggle--92, #f0f0f4); - --csstools-light-dark-toggle--93:var(--csstools-color-scheme--light) #00cadb; - --comment-focus-outline-color:var(--csstools-light-dark-toggle--93, #0062fa); - --csstools-light-dark-toggle--94:var(--csstools-color-scheme--light) #fbfbfe; - --comment-fg-color:var(--csstools-light-dark-toggle--94, #15141a); - --csstools-light-dark-toggle--95:var(--csstools-color-scheme--light) #00317e; - --comment-count-bg-color:var(--csstools-light-dark-toggle--95, #e2f7ff); - --csstools-light-dark-toggle--96:var(--csstools-color-scheme--light) #a6ecf4; - --comment-indicator-active-fg-color:var(--csstools-light-dark-toggle--96, #0041a4); - --comment-indicator-active-filter:brightness( + --comment-date-fg-color: var( + --csstools-light-dark-toggle--88, + rgb(21 20 26 / 0.69) + ); + --csstools-light-dark-toggle--89: var(--csstools-color-scheme--light) #1c1b22; + --comment-bg-color: var(--csstools-light-dark-toggle--89, #f9f9fb); + --csstools-light-dark-toggle--90: var(--csstools-color-scheme--light) #2c2b33; + --comment-hover-bg-color: var(--csstools-light-dark-toggle--90, #e0e0e6); + --csstools-light-dark-toggle--91: var(--csstools-color-scheme--light) #3a3944; + --comment-active-bg-color: var(--csstools-light-dark-toggle--91, #d1d1d9); + --comment-hover-brightness: 0.89; + --comment-hover-filter: brightness(var(--comment-hover-brightness)); + --comment-active-brightness: 0.825; + --comment-active-filter: brightness(var(--comment-active-brightness)); + --csstools-light-dark-toggle--92: var(--csstools-color-scheme--light) #52525e; + --comment-border-color: var(--csstools-light-dark-toggle--92, #f0f0f4); + --csstools-light-dark-toggle--93: var(--csstools-color-scheme--light) #00cadb; + --comment-focus-outline-color: var(--csstools-light-dark-toggle--93, #0062fa); + --csstools-light-dark-toggle--94: var(--csstools-color-scheme--light) #fbfbfe; + --comment-fg-color: var(--csstools-light-dark-toggle--94, #15141a); + --csstools-light-dark-toggle--95: var(--csstools-color-scheme--light) #00317e; + --comment-count-bg-color: var(--csstools-light-dark-toggle--95, #e2f7ff); + --csstools-light-dark-toggle--96: var(--csstools-color-scheme--light) #a6ecf4; + --comment-indicator-active-fg-color: var( + --csstools-light-dark-toggle--96, + #0041a4 + ); + --comment-indicator-active-filter: brightness( calc(1 / var(--comment-active-brightness)) ); - --csstools-light-dark-toggle--97:var(--csstools-color-scheme--light) #fbfbfe; - --comment-indicator-focus-fg-color:var(--csstools-light-dark-toggle--97, #5b5b66); - --csstools-light-dark-toggle--98:var(--csstools-color-scheme--light) #61dce9; - --comment-indicator-hover-fg-color:var(--csstools-light-dark-toggle--98, #0053cb); - --comment-indicator-hover-filter:brightness( + --csstools-light-dark-toggle--97: var(--csstools-color-scheme--light) #fbfbfe; + --comment-indicator-focus-fg-color: var( + --csstools-light-dark-toggle--97, + #5b5b66 + ); + --csstools-light-dark-toggle--98: var(--csstools-color-scheme--light) #61dce9; + --comment-indicator-hover-fg-color: var( + --csstools-light-dark-toggle--98, + #0053cb + ); + --comment-indicator-hover-filter: brightness( calc(1 / var(--comment-hover-brightness)) ); - --csstools-light-dark-toggle--99:var(--csstools-color-scheme--light) #00cadb; - --comment-indicator-selected-fg-color:var(--csstools-light-dark-toggle--99, #0062fa); - - --button-comment-bg:transparent; - --button-comment-color:var(--main-color); - --csstools-light-dark-toggle--100:var(--csstools-color-scheme--light) #5b5b66; - --button-comment-active-bg:var(--csstools-light-dark-toggle--100, #cfcfd8); - --button-comment-active-border:none; - --button-comment-active-color:var(--button-comment-color); - --button-comment-border:none; - --csstools-light-dark-toggle--101:var(--csstools-color-scheme--light) #52525e; - --button-comment-hover-bg:var(--csstools-light-dark-toggle--101, #e0e0e6); - --button-comment-hover-color:var(--button-comment-color); -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -#editorCommentsSidebar, -.commentPopup{ - - --comment-date-fg-color:light-dark( - rgb(21 20 26 / 0.69), - rgb(251 251 254 / 0.69) + --csstools-light-dark-toggle--99: var(--csstools-color-scheme--light) #00cadb; + --comment-indicator-selected-fg-color: var( + --csstools-light-dark-toggle--99, + #0062fa ); -} + + --button-comment-bg: transparent; + --button-comment-color: var(--main-color); + --csstools-light-dark-toggle--100: var(--csstools-color-scheme--light) #5b5b66; + --button-comment-active-bg: var(--csstools-light-dark-toggle--100, #cfcfd8); + --button-comment-active-border: none; + --button-comment-active-color: var(--button-comment-color); + --button-comment-border: none; + --csstools-light-dark-toggle--101: var(--csstools-color-scheme--light) #52525e; + --button-comment-hover-bg: var(--csstools-light-dark-toggle--101, #e0e0e6); + --button-comment-hover-color: var(--button-comment-color); } -@supports (color: light-dark(red, red)){ -#editorCommentsSidebar, -.commentPopup{ - --comment-bg-color:light-dark(#f9f9fb, #1c1b22); - --comment-hover-bg-color:light-dark(#e0e0e6, #2c2b33); - --comment-active-bg-color:light-dark(#d1d1d9, #3a3944); - --comment-border-color:light-dark(#f0f0f4, #52525e); - --comment-focus-outline-color:light-dark(#0062fa, #00cadb); - --comment-fg-color:light-dark(#15141a, #fbfbfe); - --comment-count-bg-color:light-dark(#e2f7ff, #00317e); - --comment-indicator-active-fg-color:light-dark(#0041a4, #a6ecf4); - --comment-indicator-focus-fg-color:light-dark(#5b5b66, #fbfbfe); - --comment-indicator-hover-fg-color:light-dark(#0053cb, #61dce9); - --comment-indicator-selected-fg-color:light-dark(#0062fa, #00cadb); - --button-comment-active-bg:light-dark(#cfcfd8, #5b5b66); - --button-comment-hover-bg:light-dark(#e0e0e6, #52525e); -} -} - -@supports not (color: light-dark(tan, tan)){ - -:is(#editorCommentsSidebar,.commentPopup) *{ - - --csstools-light-dark-toggle--88:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.69); - - --comment-date-fg-color:var(--csstools-light-dark-toggle--88, rgb(21 20 26 / 0.69)); - --csstools-light-dark-toggle--89:var(--csstools-color-scheme--light) #1c1b22; - --comment-bg-color:var(--csstools-light-dark-toggle--89, #f9f9fb); - --csstools-light-dark-toggle--90:var(--csstools-color-scheme--light) #2c2b33; - --comment-hover-bg-color:var(--csstools-light-dark-toggle--90, #e0e0e6); - --csstools-light-dark-toggle--91:var(--csstools-color-scheme--light) #3a3944; - --comment-active-bg-color:var(--csstools-light-dark-toggle--91, #d1d1d9); - --csstools-light-dark-toggle--92:var(--csstools-color-scheme--light) #52525e; - --comment-border-color:var(--csstools-light-dark-toggle--92, #f0f0f4); - --csstools-light-dark-toggle--93:var(--csstools-color-scheme--light) #00cadb; - --comment-focus-outline-color:var(--csstools-light-dark-toggle--93, #0062fa); - --csstools-light-dark-toggle--94:var(--csstools-color-scheme--light) #fbfbfe; - --comment-fg-color:var(--csstools-light-dark-toggle--94, #15141a); - --csstools-light-dark-toggle--95:var(--csstools-color-scheme--light) #00317e; - --comment-count-bg-color:var(--csstools-light-dark-toggle--95, #e2f7ff); - --csstools-light-dark-toggle--96:var(--csstools-color-scheme--light) #a6ecf4; - --comment-indicator-active-fg-color:var(--csstools-light-dark-toggle--96, #0041a4); - --csstools-light-dark-toggle--97:var(--csstools-color-scheme--light) #fbfbfe; - --comment-indicator-focus-fg-color:var(--csstools-light-dark-toggle--97, #5b5b66); - --csstools-light-dark-toggle--98:var(--csstools-color-scheme--light) #61dce9; - --comment-indicator-hover-fg-color:var(--csstools-light-dark-toggle--98, #0053cb); - --csstools-light-dark-toggle--99:var(--csstools-color-scheme--light) #00cadb; - --comment-indicator-selected-fg-color:var(--csstools-light-dark-toggle--99, #0062fa); - --csstools-light-dark-toggle--100:var(--csstools-color-scheme--light) #5b5b66; - --button-comment-active-bg:var(--csstools-light-dark-toggle--100, #cfcfd8); - --csstools-light-dark-toggle--101:var(--csstools-color-scheme--light) #52525e; - --button-comment-hover-bg:var(--csstools-light-dark-toggle--101, #e0e0e6); +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + #editorCommentsSidebar, + .commentPopup { + --comment-date-fg-color: light-dark( + rgb(21 20 26 / 0.69), + rgb(251 251 254 / 0.69) + ); } } -@media screen and (forced-colors: active){ - -#editorCommentsSidebar, -.commentPopup{ - --comment-date-fg-color:CanvasText; - --comment-bg-color:Canvas; - --comment-hover-bg-color:Canvas; - --comment-hover-filter:none; - --comment-active-bg-color:Canvas; - --comment-active-filter:none; - --comment-border-color:CanvasText; - --comment-fg-color:CanvasText; - --comment-count-bg-color:Canvas; - --comment-indicator-active-fg-color:SelectedItem; - --comment-indicator-focus-fg-color:CanvasText; - --comment-indicator-hover-fg-color:CanvasText; - --comment-indicator-selected-fg-color:SelectedItem; - --button-comment-bg:ButtonFace; - --button-comment-color:ButtonText; - --button-comment-active-bg:ButtonText; - --button-comment-active-color:HighlightText; - --button-comment-border:1px solid ButtonText; - --button-comment-hover-bg:Highlight; - --button-comment-hover-color:HighlightText; -} - } - -#editorCommentsSidebar{ - display:flex; - height:auto; - padding-bottom:16px; - flex-direction:column; - align-items:flex-start; -} - -#editorCommentsSidebar #editorCommentsSidebarHeader{ - width:100%; - box-sizing:border-box; - padding:16px; - display:flex; - align-items:center; - justify-content:space-between; - } - -:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount{ - display:flex; - align-items:baseline; - gap:6px; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount) #editorCommentsSidebarTitle{ - font:menu; - font-style:normal; - font-weight:590; - line-height:normal; - font-size:17px; - color:var(--comment-fg-color); - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount) #editorCommentsSidebarCount{ - padding:0 4px; - border-radius:4px; - background-color:var(--comment-count-bg-color); - - color:var(--comment-fg-color); - text-align:center; - - font:menu; - font-size:13px; - font-style:normal; - font-weight:400; - line-height:normal; - } - -:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton{ - width:32px; - height:32px; - padding:8px; - border-radius:4px; - border:none; - background:none; - cursor:pointer; - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton)::before{ - content:""; - display:inline-block; - width:100%; - height:100%; - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - -webkit-mask-image:var(--comment-close-button-icon); - mask-image:var(--comment-close-button-icon); - background-color:var(--comment-fg-color); - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton):hover{ - background-color:var(--comment-hover-bg-color); - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton):active{ - background-color:var(--comment-active-bg-color); - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton):focus-visible{ - outline:var(--focus-ring-outline); - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) #editorCommentsSidebarCloseButton) > span{ - display:inline-block; - width:0; - height:0; - overflow:hidden; - } - -#editorCommentsSidebar #editorCommentsSidebarListContainer{ - overflow:auto; - width:100%; - } - -:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList{ - display:flex; - width:auto; - padding:4px 16px; - gap:10px; - align-items:flex-start; - flex-direction:column; - list-style-type:none; - } - -:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment{ - display:flex; - width:auto; - padding:8px 16px 16px; - flex-direction:column; - align-items:flex-start; - align-self:stretch; - gap:4px; - - border-radius:8px; - border:0.5px solid var(--comment-border-color); - background-color:var(--comment-bg-color); - } - -@media screen and (forced-colors: active){ - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):hover{ - background-color:var(--comment-hover-bg-color); - } - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):hover{ - filter:var(--comment-hover-filter); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):hover time::after{ - display:inline-block; - background-color:var(--comment-indicator-hover-fg-color); - filter:var(--comment-indicator-hover-filter); - } - -@media screen and (forced-colors: active){ - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):active{ - background-color:var(--comment-active-bg-color); - } - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):active{ - filter:var(--comment-active-filter); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):active time::after{ - display:inline-block; - background-color:var(--comment-indicator-active-fg-color); - filter:var(--comment-indicator-active-filter); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):is(:focus,:focus-visible) time::after{ - display:inline-block; - background-color:var(--comment-indicator-focus-fg-color); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments):focus-visible{ - outline:2px solid var(--comment-focus-outline-color); - outline-offset:2px; - } - -.selected:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments) .sidebarCommentText{ - max-height:-moz-fit-content; - max-height:fit-content; - -webkit-line-clamp:unset; - } - -.selected:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment):not(.noComments) time::after{ - display:inline-block; - background-color:var(--comment-indicator-selected-fg-color); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) .sidebarCommentText{ - font:menu; - font-style:normal; - font-weight:400; - line-height:normal; - font-size:15px; - width:100%; - height:-moz-fit-content; - height:fit-content; - max-height:80px; - display:-webkit-box; - -webkit-box-orient:vertical; - -webkit-line-clamp:2; - overflow:hidden; - overflow-wrap:break-word; - } - -:is(:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) .sidebarCommentText) .richText{ - --total-scale-factor:1.5; - } - -.noComments:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) .sidebarCommentText{ - max-height:-moz-fit-content; - max-height:fit-content; - -webkit-line-clamp:unset; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -.noComments:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) a{ - font:menu; - font-style:normal; - font-weight:400; - line-height:normal; - font-size:15px; - width:100%; - height:auto; - overflow-wrap:break-word; - margin-block-start:15px; - } - -:is(.noComments:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) a):focus-visible{ - outline:var(--focus-ring-outline); - } - -:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) time{ - width:100%; - display:inline-flex; - align-items:center; - justify-content:space-between; - - font:menu; - font-style:normal; - font-weight:400; - line-height:normal; - font-size:13px; - } - -:is(:is(:is(:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) #editorCommentsSidebarList) .sidebarComment) time)::after{ - content:""; - display:none; - width:16px; - height:16px; - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - -webkit-mask-image:var(--comment-edit-button-icon); - mask-image:var(--comment-edit-button-icon); - transform:scaleX(var(--dir-factor)); - } - -.commentPopup{ - --csstools-color-scheme--light:initial; - color-scheme:light dark; - - --csstools-light-dark-toggle--102:var(--csstools-color-scheme--light) #3a3944; - - --divider-color:var(--csstools-light-dark-toggle--102, #cfcfd8); - --csstools-light-dark-toggle--103:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--104:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --comment-shadow:0 0.5px 2px 0 var(--csstools-light-dark-toggle--103, rgb(0 0 0 / 0.05)), 0 4px 16px 0 var(--csstools-light-dark-toggle--104, rgb(0 0 0 / 0.1)); -} - -@supports (color: light-dark(red, red)){ -.commentPopup{ - - --divider-color:light-dark(#cfcfd8, #3a3944); -} -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.commentPopup{ - --comment-shadow:0 0.5px 2px 0 light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), 0 4px 16px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.commentPopup *{ - - --csstools-light-dark-toggle--102:var(--csstools-color-scheme--light) #3a3944; - - --divider-color:var(--csstools-light-dark-toggle--102, #cfcfd8); - --csstools-light-dark-toggle--103:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--104:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --comment-shadow:0 0.5px 2px 0 var(--csstools-light-dark-toggle--103, rgb(0 0 0 / 0.05)), 0 4px 16px 0 var(--csstools-light-dark-toggle--104, rgb(0 0 0 / 0.1)); +@supports (color: light-dark(red, red)) { + #editorCommentsSidebar, + .commentPopup { + --comment-bg-color: light-dark(#f9f9fb, #1c1b22); + --comment-hover-bg-color: light-dark(#e0e0e6, #2c2b33); + --comment-active-bg-color: light-dark(#d1d1d9, #3a3944); + --comment-border-color: light-dark(#f0f0f4, #52525e); + --comment-focus-outline-color: light-dark(#0062fa, #00cadb); + --comment-fg-color: light-dark(#15141a, #fbfbfe); + --comment-count-bg-color: light-dark(#e2f7ff, #00317e); + --comment-indicator-active-fg-color: light-dark(#0041a4, #a6ecf4); + --comment-indicator-focus-fg-color: light-dark(#5b5b66, #fbfbfe); + --comment-indicator-hover-fg-color: light-dark(#0053cb, #61dce9); + --comment-indicator-selected-fg-color: light-dark(#0062fa, #00cadb); + --button-comment-active-bg: light-dark(#cfcfd8, #5b5b66); + --button-comment-hover-bg: light-dark(#e0e0e6, #52525e); } } -@media (prefers-color-scheme: dark){ +@supports not (color: light-dark(tan, tan)) { + :is(#editorCommentsSidebar, .commentPopup) * { + --csstools-light-dark-toggle--88: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.69); -.commentPopup{ - --csstools-color-scheme--light: light; -} + --comment-date-fg-color: var( + --csstools-light-dark-toggle--88, + rgb(21 20 26 / 0.69) + ); + --csstools-light-dark-toggle--89: var(--csstools-color-scheme--light) + #1c1b22; + --comment-bg-color: var(--csstools-light-dark-toggle--89, #f9f9fb); + --csstools-light-dark-toggle--90: var(--csstools-color-scheme--light) + #2c2b33; + --comment-hover-bg-color: var(--csstools-light-dark-toggle--90, #e0e0e6); + --csstools-light-dark-toggle--91: var(--csstools-color-scheme--light) + #3a3944; + --comment-active-bg-color: var(--csstools-light-dark-toggle--91, #d1d1d9); + --csstools-light-dark-toggle--92: var(--csstools-color-scheme--light) + #52525e; + --comment-border-color: var(--csstools-light-dark-toggle--92, #f0f0f4); + --csstools-light-dark-toggle--93: var(--csstools-color-scheme--light) + #00cadb; + --comment-focus-outline-color: var( + --csstools-light-dark-toggle--93, + #0062fa + ); + --csstools-light-dark-toggle--94: var(--csstools-color-scheme--light) + #fbfbfe; + --comment-fg-color: var(--csstools-light-dark-toggle--94, #15141a); + --csstools-light-dark-toggle--95: var(--csstools-color-scheme--light) + #00317e; + --comment-count-bg-color: var(--csstools-light-dark-toggle--95, #e2f7ff); + --csstools-light-dark-toggle--96: var(--csstools-color-scheme--light) + #a6ecf4; + --comment-indicator-active-fg-color: var( + --csstools-light-dark-toggle--96, + #0041a4 + ); + --csstools-light-dark-toggle--97: var(--csstools-color-scheme--light) + #fbfbfe; + --comment-indicator-focus-fg-color: var( + --csstools-light-dark-toggle--97, + #5b5b66 + ); + --csstools-light-dark-toggle--98: var(--csstools-color-scheme--light) + #61dce9; + --comment-indicator-hover-fg-color: var( + --csstools-light-dark-toggle--98, + #0053cb + ); + --csstools-light-dark-toggle--99: var(--csstools-color-scheme--light) + #00cadb; + --comment-indicator-selected-fg-color: var( + --csstools-light-dark-toggle--99, + #0062fa + ); + --csstools-light-dark-toggle--100: var(--csstools-color-scheme--light) + #5b5b66; + --button-comment-active-bg: var(--csstools-light-dark-toggle--100, #cfcfd8); + --csstools-light-dark-toggle--101: var(--csstools-color-scheme--light) + #52525e; + --button-comment-hover-bg: var(--csstools-light-dark-toggle--101, #e0e0e6); + } } -@media screen and (forced-colors: active){ - -.commentPopup{ - --divider-color:CanvasText; - --comment-shadow:none; -} +@media screen and (forced-colors: active) { + #editorCommentsSidebar, + .commentPopup { + --comment-date-fg-color: CanvasText; + --comment-bg-color: Canvas; + --comment-hover-bg-color: Canvas; + --comment-hover-filter: none; + --comment-active-bg-color: Canvas; + --comment-active-filter: none; + --comment-border-color: CanvasText; + --comment-fg-color: CanvasText; + --comment-count-bg-color: Canvas; + --comment-indicator-active-fg-color: SelectedItem; + --comment-indicator-focus-fg-color: CanvasText; + --comment-indicator-hover-fg-color: CanvasText; + --comment-indicator-selected-fg-color: SelectedItem; + --button-comment-bg: ButtonFace; + --button-comment-color: ButtonText; + --button-comment-active-bg: ButtonText; + --button-comment-active-color: HighlightText; + --button-comment-border: 1px solid ButtonText; + --button-comment-hover-bg: Highlight; + --button-comment-hover-color: HighlightText; } - -.commentPopup{ - - display:flex; - flex-direction:column; - align-items:flex-start; - gap:12px; - z-index:100001; - pointer-events:auto; - margin-top:2px; - - border:0.5px solid var(--comment-border-color); - background:var(--comment-bg-color); - box-shadow:var(--comment-shadow); } -.commentPopup:focus-visible{ - outline:none; +#editorCommentsSidebar { + display: flex; + height: auto; + padding-bottom: 16px; + flex-direction: column; + align-items: flex-start; +} + +#editorCommentsSidebar #editorCommentsSidebarHeader { + width: 100%; + box-sizing: border-box; + padding: 16px; + display: flex; + align-items: center; + justify-content: space-between; +} + +:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount { + display: flex; + align-items: baseline; + gap: 6px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount) + #editorCommentsSidebarTitle { + font: menu; + font-style: normal; + font-weight: 590; + line-height: normal; + font-size: 17px; + color: var(--comment-fg-color); +} + +:is(:is(#editorCommentsSidebar #editorCommentsSidebarHeader) .commentCount) + #editorCommentsSidebarCount { + padding: 0 4px; + border-radius: 4px; + background-color: var(--comment-count-bg-color); + + color: var(--comment-fg-color); + text-align: center; + + font: menu; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +:is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton { + width: 32px; + height: 32px; + padding: 8px; + border-radius: 4px; + border: none; + background: none; + cursor: pointer; +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton +)::before { + content: ''; + display: inline-block; + width: 100%; + height: 100%; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-image: var(--comment-close-button-icon); + mask-image: var(--comment-close-button-icon); + background-color: var(--comment-fg-color); +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton +):hover { + background-color: var(--comment-hover-bg-color); +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton +):active { + background-color: var(--comment-active-bg-color); +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton +):focus-visible { + outline: var(--focus-ring-outline); +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarHeader) + #editorCommentsSidebarCloseButton + ) + > span { + display: inline-block; + width: 0; + height: 0; + overflow: hidden; +} + +#editorCommentsSidebar #editorCommentsSidebarListContainer { + overflow: auto; + width: 100%; +} + +:is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList { + display: flex; + width: auto; + padding: 4px 16px; + gap: 10px; + align-items: flex-start; + flex-direction: column; + list-style-type: none; +} + +:is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment { + display: flex; + width: auto; + padding: 8px 16px 16px; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + gap: 4px; + + border-radius: 8px; + border: 0.5px solid var(--comment-border-color); + background-color: var(--comment-bg-color); +} + +@media screen and (forced-colors: active) { + :is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):hover { + background-color: var(--comment-hover-bg-color); } +} -.commentPopup.dragging{ - cursor:move !important; +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):hover { + filter: var(--comment-hover-filter); +} + +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):hover + time::after { + display: inline-block; + background-color: var(--comment-indicator-hover-fg-color); + filter: var(--comment-indicator-hover-filter); +} + +@media screen and (forced-colors: active) { + :is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):active { + background-color: var(--comment-active-bg-color); } +} -.commentPopup.dragging *{ - cursor:move !important; - } +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):active { + filter: var(--comment-active-filter); +} -.commentPopup.dragging button{ - pointer-events:none !important; - } +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):active + time::after { + display: inline-block; + background-color: var(--comment-indicator-active-fg-color); + filter: var(--comment-indicator-active-filter); +} -.commentPopup:not(.selected) .commentPopupButtons{ - visibility:hidden !important; +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):is(:focus, :focus-visible) + time::after { + display: inline-block; + background-color: var(--comment-indicator-focus-fg-color); +} + +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments):focus-visible { + outline: 2px solid var(--comment-focus-outline-color); + outline-offset: 2px; +} + +.selected:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments) + .sidebarCommentText { + max-height: -moz-fit-content; + max-height: fit-content; + -webkit-line-clamp: unset; +} + +.selected:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ):not(.noComments) + time::after { + display: inline-block; + background-color: var(--comment-indicator-selected-fg-color); +} + +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + .sidebarCommentText { + font: menu; + font-style: normal; + font-weight: 400; + line-height: normal; + font-size: 15px; + width: 100%; + height: -moz-fit-content; + height: fit-content; + max-height: 80px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + overflow-wrap: break-word; +} + +:is( + :is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + .sidebarCommentText + ) + .richText { + --total-scale-factor: 1.5; +} + +.noComments:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + .sidebarCommentText { + max-height: -moz-fit-content; + max-height: fit-content; + -webkit-line-clamp: unset; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.noComments:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + a { + font: menu; + font-style: normal; + font-weight: 400; + line-height: normal; + font-size: 15px; + width: 100%; + height: auto; + overflow-wrap: break-word; + margin-block-start: 15px; +} + +:is( + .noComments:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + a +):focus-visible { + outline: var(--focus-ring-outline); +} + +:is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + time { + width: 100%; + display: inline-flex; + align-items: center; + justify-content: space-between; + + font: menu; + font-style: normal; + font-weight: 400; + line-height: normal; + font-size: 13px; +} + +:is( + :is( + :is( + :is(#editorCommentsSidebar #editorCommentsSidebarListContainer) + #editorCommentsSidebarList + ) + .sidebarComment + ) + time +)::after { + content: ''; + display: none; + width: 16px; + height: 16px; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-image: var(--comment-edit-button-icon); + mask-image: var(--comment-edit-button-icon); + transform: scaleX(var(--dir-factor)); +} + +.commentPopup { + --csstools-color-scheme--light: initial; + color-scheme: light dark; + + --csstools-light-dark-toggle--102: var(--csstools-color-scheme--light) #3a3944; + + --divider-color: var(--csstools-light-dark-toggle--102, #cfcfd8); + --csstools-light-dark-toggle--103: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--104: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --comment-shadow: + 0 0.5px 2px 0 var(--csstools-light-dark-toggle--103, rgb(0 0 0 / 0.05)), + 0 4px 16px 0 var(--csstools-light-dark-toggle--104, rgb(0 0 0 / 0.1)); +} + +@supports (color: light-dark(red, red)) { + .commentPopup { + --divider-color: light-dark(#cfcfd8, #3a3944); } +} -.commentPopup hr{ - width:100%; - height:1px; - border:none; - border-top:1px solid var(--divider-color); - margin:0; - padding:0; +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .commentPopup { + --comment-shadow: + 0 0.5px 2px 0 light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), + 0 4px 16px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); } +} -.commentPopup .commentPopupTop{ - display:flex; - width:100%; - height:auto; - padding-bottom:4px; - justify-content:space-between; - align-items:center; - align-self:stretch; - cursor:move; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; +@supports not (color: light-dark(tan, tan)) { + .commentPopup * { + --csstools-light-dark-toggle--102: var(--csstools-color-scheme--light) + #3a3944; + + --divider-color: var(--csstools-light-dark-toggle--102, #cfcfd8); + --csstools-light-dark-toggle--103: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--104: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --comment-shadow: + 0 0.5px 2px 0 var(--csstools-light-dark-toggle--103, rgb(0 0 0 / 0.05)), + 0 4px 16px 0 var(--csstools-light-dark-toggle--104, rgb(0 0 0 / 0.1)); } +} -:is(.commentPopup .commentPopupTop) .commentPopupTime{ - font:menu; - font-style:normal; - font-weight:400; - line-height:normal; - font-size:13px; - color:var(--comment-date-fg-color); - } - -:is(.commentPopup .commentPopupTop) .commentPopupButtons{ - display:flex; - align-items:center; - gap:2px; - cursor:default; - } - -:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button{ - width:32px; - height:32px; - padding:8px; - border:var(--button-comment-border); - border-radius:4px; - background-color:var(--button-comment-bg); - color:var(--button-comment-color); - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button):hover{ - background-color:var(--button-comment-hover-bg); - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button):hover::before{ - background-color:var(--button-comment-hover-color); - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button):active{ - border:var(--button-comment-active-border); - background-color:var(--button-comment-active-bg); - color:var(--button-comment-active-color); - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button):active::before{ - background-color:var(--button-comment-active-color); - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button):focus-visible{ - background-color:var(--button-comment-hover-bg); - outline:2px solid var(--comment-focus-outline-color); - outline-offset:0; - } - -:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button)::before{ - content:""; - display:inline-block; - width:100%; - height:100%; - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - } - -.commentPopupEdit:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button)::before{ - -webkit-mask-image:var(--comment-popup-edit-button-icon); - mask-image:var(--comment-popup-edit-button-icon); - } - -.commentPopupDelete:is(:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button)::before{ - -webkit-mask-image:var(--comment-popup-delete-button-icon); - mask-image:var(--comment-popup-delete-button-icon); - } - -.commentPopup .commentPopupText{ - width:100%; - height:auto; - - font:menu; - font-style:normal; - font-weight:400; - line-height:normal; - font-size:15px; - color:var(--comment-fg-color); +@media (prefers-color-scheme: dark) { + .commentPopup { + --csstools-color-scheme--light: light; } +} + +@media screen and (forced-colors: active) { + .commentPopup { + --divider-color: CanvasText; + --comment-shadow: none; + } +} + +.commentPopup { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 12px; + z-index: 100001; + pointer-events: auto; + margin-top: 2px; + + border: 0.5px solid var(--comment-border-color); + background: var(--comment-bg-color); + box-shadow: var(--comment-shadow); +} + +.commentPopup:focus-visible { + outline: none; +} + +.commentPopup.dragging { + cursor: move !important; +} + +.commentPopup.dragging * { + cursor: move !important; +} + +.commentPopup.dragging button { + pointer-events: none !important; +} + +.commentPopup:not(.selected) .commentPopupButtons { + visibility: hidden !important; +} + +.commentPopup hr { + width: 100%; + height: 1px; + border: none; + border-top: 1px solid var(--divider-color); + margin: 0; + padding: 0; +} + +.commentPopup .commentPopupTop { + display: flex; + width: 100%; + height: auto; + padding-bottom: 4px; + justify-content: space-between; + align-items: center; + align-self: stretch; + cursor: move; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +:is(.commentPopup .commentPopupTop) .commentPopupTime { + font: menu; + font-style: normal; + font-weight: 400; + line-height: normal; + font-size: 13px; + color: var(--comment-date-fg-color); +} + +:is(.commentPopup .commentPopupTop) .commentPopupButtons { + display: flex; + align-items: center; + gap: 2px; + cursor: default; +} + +:is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button { + width: 32px; + height: 32px; + padding: 8px; + border: var(--button-comment-border); + border-radius: 4px; + background-color: var(--button-comment-bg); + color: var(--button-comment-color); +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button +):hover { + background-color: var(--button-comment-hover-bg); +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button + ):hover::before { + background-color: var(--button-comment-hover-color); +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button +):active { + border: var(--button-comment-active-border); + background-color: var(--button-comment-active-bg); + color: var(--button-comment-active-color); +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button + ):active::before { + background-color: var(--button-comment-active-color); +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button +):focus-visible { + background-color: var(--button-comment-hover-bg); + outline: 2px solid var(--comment-focus-outline-color); + outline-offset: 0; +} + +:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button +)::before { + content: ''; + display: inline-block; + width: 100%; + height: 100%; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; +} + +.commentPopupEdit:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button + )::before { + -webkit-mask-image: var(--comment-popup-edit-button-icon); + mask-image: var(--comment-popup-edit-button-icon); +} + +.commentPopupDelete:is( + :is(:is(.commentPopup .commentPopupTop) .commentPopupButtons) > button + )::before { + -webkit-mask-image: var(--comment-popup-delete-button-icon); + mask-image: var(--comment-popup-delete-button-icon); +} + +.commentPopup .commentPopupText { + width: 100%; + height: auto; + + font: menu; + font-style: normal; + font-weight: 400; + line-height: normal; + font-size: 15px; + color: var(--comment-fg-color); +} .commentPopupText, -.sidebarCommentText .richText{ - margin-block:0; +.sidebarCommentText .richText { + margin-block: 0; } -:is(.commentPopupText,.sidebarCommentText .richText) p:first-of-type{ - margin-block:0; - } +:is(.commentPopupText, .sidebarCommentText .richText) p:first-of-type { + margin-block: 0; +} -:is(.commentPopupText,.sidebarCommentText .richText) > *{ - white-space:pre-wrap; - font-size:max(15px, calc(10px * var(--total-scale-factor))); - overflow-wrap:break-word; - } +:is(.commentPopupText, .sidebarCommentText .richText) > * { + white-space: pre-wrap; + font-size: max(15px, calc(10px * var(--total-scale-factor))); + overflow-wrap: break-word; +} -:is(.commentPopupText,.sidebarCommentText .richText) span{ - color:var(--comment-fg-color) !important; - } +:is(.commentPopupText, .sidebarCommentText .richText) span { + color: var(--comment-fg-color) !important; +} -:root{ - --editor-toolbar-vert-offset:6px; - --outline-width:2px; - --outline-color:#0060df; - --outline-around-width:1px; - --outline-around-color:#f0f0f4; - --hover-outline-around-color:var(--outline-around-color); - --focus-outline:solid var(--outline-width) var(--outline-color); - --unfocus-outline:solid var(--outline-width) transparent; - --focus-outline-around:solid var(--outline-around-width) var(--outline-around-color); - --hover-outline-color:#8f8f9d; - --hover-outline:solid var(--outline-width) var(--hover-outline-color); - --hover-outline-around:solid var(--outline-around-width) var(--hover-outline-around-color); - --freetext-line-height:1.35; - --freetext-padding:2px; - --resizer-bg-color:var(--outline-color); - --resizer-size:6px; - --resizer-shift:calc( +:root { + --editor-toolbar-vert-offset: 6px; + --outline-width: 2px; + --outline-color: #0060df; + --outline-around-width: 1px; + --outline-around-color: #f0f0f4; + --hover-outline-around-color: var(--outline-around-color); + --focus-outline: solid var(--outline-width) var(--outline-color); + --unfocus-outline: solid var(--outline-width) transparent; + --focus-outline-around: solid var(--outline-around-width) + var(--outline-around-color); + --hover-outline-color: #8f8f9d; + --hover-outline: solid var(--outline-width) var(--hover-outline-color); + --hover-outline-around: solid var(--outline-around-width) + var(--hover-outline-around-color); + --freetext-line-height: 1.35; + --freetext-padding: 2px; + --resizer-bg-color: var(--outline-color); + --resizer-size: 6px; + --resizer-shift: calc( 0px - (var(--outline-width) + var(--resizer-size)) / 2 - var(--outline-around-width) ); - --editorFreeText-editing-cursor:text; - --editorInk-editing-cursor:url(images/cursor-editorInk.svg) 0 16, pointer; - --editorHighlight-editing-cursor:url(images/cursor-editorTextHighlight.svg) 24 24, text; - --editorFreeHighlight-editing-cursor:url(images/cursor-editorFreeHighlight.svg) 1 18, pointer; + --editorFreeText-editing-cursor: text; + --editorInk-editing-cursor: url(images/cursor-editorInk.svg) 0 16, pointer; + --editorHighlight-editing-cursor: + url(images/cursor-editorTextHighlight.svg) 24 24, text; + --editorFreeHighlight-editing-cursor: + url(images/cursor-editorFreeHighlight.svg) 1 18, pointer; - --new-alt-text-warning-image:url(images/altText_warning.svg); + --new-alt-text-warning-image: url(images/altText_warning.svg); } -.textLayer.highlighting{ - cursor:var(--editorFreeHighlight-editing-cursor); - } +.textLayer.highlighting { + cursor: var(--editorFreeHighlight-editing-cursor); +} -.textLayer.highlighting:not(.free) span{ - cursor:var(--editorHighlight-editing-cursor); - } +.textLayer.highlighting:not(.free) span { + cursor: var(--editorHighlight-editing-cursor); +} -[role="img"]:is(.textLayer.highlighting:not(.free) span){ - cursor:var(--editorFreeHighlight-editing-cursor); - } +[role='img']:is(.textLayer.highlighting:not(.free) span) { + cursor: var(--editorFreeHighlight-editing-cursor); +} -.textLayer.highlighting.free span{ - cursor:var(--editorFreeHighlight-editing-cursor); - } +.textLayer.highlighting.free span { + cursor: var(--editorFreeHighlight-editing-cursor); +} .page:has(.annotationEditorLayer.nonEditing) .annotationLayer - .editorAnnotation{ - position:absolute; - pointer-events:none; + .editorAnnotation { + position: absolute; + pointer-events: none; } -:is(#viewerContainer.pdfPresentationMode:fullscreen,.annotationEditorLayer.disabled) .noAltTextBadge{ - display:none !important; - } +:is( + #viewerContainer.pdfPresentationMode:fullscreen, + .annotationEditorLayer.disabled + ) + .noAltTextBadge { + display: none !important; +} -@media (min-resolution: 1.1dppx){ - :root{ - --editorFreeText-editing-cursor:url(images/cursor-editorFreeText.svg) 0 16, text; +@media (min-resolution: 1.1dppx) { + :root { + --editorFreeText-editing-cursor: + url(images/cursor-editorFreeText.svg) 0 16, text; } } -@media screen and (forced-colors: active){ - :root{ - --outline-color:CanvasText; - --outline-around-color:ButtonFace; - --resizer-bg-color:ButtonText; - --hover-outline-color:Highlight; - --hover-outline-around-color:SelectedItemText; +@media screen and (forced-colors: active) { + :root { + --outline-color: CanvasText; + --outline-around-color: ButtonFace; + --resizer-bg-color: ButtonText; + --hover-outline-color: Highlight; + --hover-outline-around-color: SelectedItemText; } } -[data-editor-rotation="90"]{ - transform:rotate(90deg); +[data-editor-rotation='90'] { + transform: rotate(90deg); } -[data-editor-rotation="180"]{ - transform:rotate(180deg); +[data-editor-rotation='180'] { + transform: rotate(180deg); } -[data-editor-rotation="270"]{ - transform:rotate(270deg); +[data-editor-rotation='270'] { + transform: rotate(270deg); } -.annotationEditorLayer{ - background:transparent; - position:absolute; - inset:0; - font-size:calc(100px * var(--total-scale-factor)); - transform-origin:0 0; - cursor:auto; +.annotationEditorLayer { + background: transparent; + position: absolute; + inset: 0; + font-size: calc(100px * var(--total-scale-factor)); + transform-origin: 0 0; + cursor: auto; } -.annotationEditorLayer .selectedEditor{ - z-index:100000 !important; - } - -.annotationEditorLayer.drawing *{ - pointer-events:none !important; - } - -.annotationEditorLayer.getElements{ - pointer-events:auto !important; - } - -.annotationEditorLayer.getElements > div{ - pointer-events:auto !important; - } - -.annotationEditorLayer.waiting{ - content:""; - cursor:wait; - position:absolute; - inset:0; - width:100%; - height:100%; +.annotationEditorLayer .selectedEditor { + z-index: 100000 !important; } -.annotationEditorLayer.disabled{ - pointer-events:none; +.annotationEditorLayer.drawing * { + pointer-events: none !important; } -.annotationEditorLayer.disabled.highlightEditing :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor,.commentPopup){ - pointer-events:auto; - } - -.annotationEditorLayer.freetextEditing{ - cursor:var(--editorFreeText-editing-cursor); +.annotationEditorLayer.getElements { + pointer-events: auto !important; } -.annotationEditorLayer.inkEditing{ - cursor:var(--editorInk-editing-cursor); +.annotationEditorLayer.getElements > div { + pointer-events: auto !important; } -.annotationEditorLayer .draw{ - box-sizing:border-box; +.annotationEditorLayer.waiting { + content: ''; + cursor: wait; + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} + +.annotationEditorLayer.disabled { + pointer-events: none; +} + +.annotationEditorLayer.disabled.highlightEditing + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .signatureEditor, + .commentPopup + ) { + pointer-events: auto; +} + +.annotationEditorLayer.freetextEditing { + cursor: var(--editorFreeText-editing-cursor); +} + +.annotationEditorLayer.inkEditing { + cursor: var(--editorInk-editing-cursor); +} + +.annotationEditorLayer .draw { + box-sizing: border-box; } .annotationEditorLayer - :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor){ - position:absolute; - background:transparent; - z-index:1; - transform-origin:0 0; - cursor:auto; - max-width:100%; - max-height:100%; - border:var(--unfocus-outline); + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) { + position: absolute; + background: transparent; + z-index: 1; + transform-origin: 0 0; + cursor: auto; + max-width: 100%; + max-height: 100%; + border: var(--unfocus-outline); } -.draggable.selectedEditor:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)){ - cursor:move; - } - -.selectedEditor:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)){ - border:var(--focus-outline); - outline:var(--focus-outline-around); - } - -.selectedEditor:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor))::before{ - content:""; - position:absolute; - inset:0; - border:var(--focus-outline-around); - pointer-events:none; - } - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)):hover:not(.selectedEditor){ - border:var(--hover-outline); - outline:var(--hover-outline-around); - } - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)):hover:not(.selectedEditor)::before{ - content:""; - position:absolute; - inset:0; - border:var(--focus-outline-around); - } - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar{ - --editor-toolbar-delete-image:url(images/editor-toolbar-delete.svg); - --csstools-light-dark-toggle--105:var(--csstools-color-scheme--light) #2b2a33; - --editor-toolbar-bg-color:var(--csstools-light-dark-toggle--105, #f0f0f4); - --editor-toolbar-highlight-image:url(images/toolbarButton-editorHighlight.svg); - --csstools-light-dark-toggle--106:var(--csstools-color-scheme--light) #fbfbfe; - --editor-toolbar-fg-color:var(--csstools-light-dark-toggle--106, #2e2e56); - --editor-toolbar-border-color:#8f8f9d; - --editor-toolbar-hover-border-color:var(--editor-toolbar-border-color); - --csstools-light-dark-toggle--107:var(--csstools-color-scheme--light) #52525e; - --editor-toolbar-hover-bg-color:var(--csstools-light-dark-toggle--107, #e0e0e6); - --editor-toolbar-hover-fg-color:var(--editor-toolbar-fg-color); - --editor-toolbar-hover-outline:none; - --csstools-light-dark-toggle--108:var(--csstools-color-scheme--light) #0df; - --editor-toolbar-focus-outline-color:var(--csstools-light-dark-toggle--108, #0060df); - --editor-toolbar-shadow:0 2px 6px 0 rgb(58 57 68 / 0.2); - --editor-toolbar-height:28px; - --editor-toolbar-padding:2px; - --csstools-light-dark-toggle--109:var(--csstools-color-scheme--light) #54ffbd; - --alt-text-done-color:var(--csstools-light-dark-toggle--109, #2ac3a2); - --csstools-light-dark-toggle--110:var(--csstools-color-scheme--light) #80ebff; - --alt-text-warning-color:var(--csstools-light-dark-toggle--110, #0090ed); - --alt-text-hover-done-color:var(--alt-text-done-color); - --alt-text-hover-warning-color:var(--alt-text-warning-color); - } - -@supports (color: light-dark(red, red)){ -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar{ - --editor-toolbar-bg-color:light-dark(#f0f0f4, #2b2a33); - --editor-toolbar-fg-color:light-dark(#2e2e56, #fbfbfe); - --editor-toolbar-hover-bg-color:light-dark(#e0e0e6, #52525e); - --editor-toolbar-focus-outline-color:light-dark(#0060df, #0df); - --alt-text-done-color:light-dark(#2ac3a2, #54ffbd); - --alt-text-warning-color:light-dark(#0090ed, #80ebff); - } +.draggable.selectedEditor:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) { + cursor: move; } -@supports not (color: light-dark(tan, tan)){ - -:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) *{ - --csstools-light-dark-toggle--105:var(--csstools-color-scheme--light) #2b2a33; - --editor-toolbar-bg-color:var(--csstools-light-dark-toggle--105, #f0f0f4); - --csstools-light-dark-toggle--106:var(--csstools-color-scheme--light) #fbfbfe; - --editor-toolbar-fg-color:var(--csstools-light-dark-toggle--106, #2e2e56); - --csstools-light-dark-toggle--107:var(--csstools-color-scheme--light) #52525e; - --editor-toolbar-hover-bg-color:var(--csstools-light-dark-toggle--107, #e0e0e6); - --csstools-light-dark-toggle--108:var(--csstools-color-scheme--light) #0df; - --editor-toolbar-focus-outline-color:var(--csstools-light-dark-toggle--108, #0060df); - --csstools-light-dark-toggle--109:var(--csstools-color-scheme--light) #54ffbd; - --alt-text-done-color:var(--csstools-light-dark-toggle--109, #2ac3a2); - --csstools-light-dark-toggle--110:var(--csstools-color-scheme--light) #80ebff; - --alt-text-warning-color:var(--csstools-light-dark-toggle--110, #0090ed); - } +.selectedEditor:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) +) { + border: var(--focus-outline); + outline: var(--focus-outline-around); } -@media screen and (forced-colors: active){ - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar{ - --editor-toolbar-bg-color:ButtonFace; - --editor-toolbar-fg-color:ButtonText; - --editor-toolbar-border-color:ButtonText; - --editor-toolbar-hover-border-color:AccentColor; - --editor-toolbar-hover-bg-color:ButtonFace; - --editor-toolbar-hover-fg-color:AccentColor; - --editor-toolbar-hover-outline:2px solid var(--editor-toolbar-hover-border-color); - --editor-toolbar-focus-outline-color:ButtonBorder; - --editor-toolbar-shadow:none; - --alt-text-done-color:var(--editor-toolbar-fg-color); - --alt-text-warning-color:var(--editor-toolbar-fg-color); - --alt-text-hover-done-color:var(--editor-toolbar-hover-fg-color); - --alt-text-hover-warning-color:var(--editor-toolbar-hover-fg-color); - } - } - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar{ - - display:flex; - width:-moz-fit-content; - width:fit-content; - height:var(--editor-toolbar-height); - flex-direction:column; - justify-content:center; - align-items:center; - cursor:default; - pointer-events:auto; - box-sizing:content-box; - padding:var(--editor-toolbar-padding); - - position:absolute; - inset-inline-end:0; - inset-block-start:calc(100% + var(--editor-toolbar-vert-offset)); - - border-radius:6px; - background-color:var(--editor-toolbar-bg-color); - border:1px solid var(--editor-toolbar-border-color); - box-shadow:var(--editor-toolbar-shadow); - } - -.hidden:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar){ - display:none; - } - -:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar):has(:focus-visible){ - border-color:transparent; - } - -[dir="ltr"] :is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar){ - transform-origin:100% 0; - } - -[dir="rtl"] :is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar){ - transform-origin:0 0; - } - -:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons{ - display:flex; - justify-content:center; - align-items:center; - gap:0; - height:100%; - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) button{ - padding:0; - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .divider{ - width:0; - height:calc( - 2 * var(--editor-toolbar-padding) + var(--editor-toolbar-height) - ); - border-left:1px solid var(--editor-toolbar-border-color); - border-right:none; - display:inline-block; - margin-inline:2px; - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic{ - width:var(--editor-toolbar-height); - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic)::before{ - content:""; - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - display:inline-block; - background-color:var(--editor-toolbar-fg-color); - width:100%; - height:100%; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic):hover::before{ - background-color:var(--editor-toolbar-hover-fg-color); - } - -.highlightButton:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic)::before{ - -webkit-mask-image:var(--editor-toolbar-highlight-image); - mask-image:var(--editor-toolbar-highlight-image); - } - -.commentButton:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic)::before{ - -webkit-mask-image:var(--comment-edit-button-icon); - mask-image:var(--comment-edit-button-icon); - } - -.deleteButton:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .basic)::before{ - -webkit-mask-image:var(--editor-toolbar-delete-image); - mask-image:var(--editor-toolbar-delete-image); - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) > *{ - height:var(--editor-toolbar-height); - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) > :not(.divider){ - border:none; - background-color:transparent; - cursor:pointer; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) > :not(.divider)):hover{ - border-radius:2px; - background-color:var(--editor-toolbar-hover-bg-color); - color:var(--editor-toolbar-hover-fg-color); - outline:var(--editor-toolbar-hover-outline); - outline-offset:1px; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) > :not(.divider)):hover:active{ - outline:none; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) > :not(.divider)):focus-visible{ - border-radius:2px; - outline:2px solid var(--editor-toolbar-focus-outline-color); - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText{ - --alt-text-add-image:url(images/altText_add.svg); - --alt-text-done-image:url(images/altText_done.svg); - - display:flex; - align-items:center; - justify-content:center; - width:-moz-max-content; - width:max-content; - padding-inline:8px; - pointer-events:all; - font:menu; - font-weight:590; - font-size:12px; - color:var(--editor-toolbar-fg-color); - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText):disabled{ - pointer-events:none; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText)::before{ - content:""; - -webkit-mask-image:var(--alt-text-add-image); - mask-image:var(--alt-text-add-image); - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - display:inline-block; - width:12px; - height:13px; - background-color:var(--editor-toolbar-fg-color); - margin-inline-end:4px; - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText):hover::before{ - background-color:var(--editor-toolbar-hover-fg-color); - } - -.done:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText)::before{ - -webkit-mask-image:var(--alt-text-done-image); - mask-image:var(--alt-text-done-image); - } - -.new:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText)::before{ - width:16px; - height:16px; - -webkit-mask-image:var(--new-alt-text-warning-image); - mask-image:var(--new-alt-text-warning-image); - background-color:var(--alt-text-warning-color); - -webkit-mask-size:cover; - mask-size:cover; - } - -.new:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText):hover::before{ - background-color:var(--alt-text-hover-warning-color); - } - -.new.done:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText)::before{ - -webkit-mask-image:var(--alt-text-done-image); - mask-image:var(--alt-text-done-image); - background-color:var(--alt-text-done-color); - } - -.new.done:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText):hover::before{ - background-color:var(--alt-text-hover-done-color); - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip{ - display:none; - word-wrap:anywhere; - } - -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip){ - --csstools-light-dark-toggle--111:var(--csstools-color-scheme--light) #1c1b22; - --alt-text-tooltip-bg:var(--csstools-light-dark-toggle--111, #f0f0f4); - --csstools-light-dark-toggle--112:var(--csstools-color-scheme--light) #fbfbfe; - --alt-text-tooltip-fg:var(--csstools-light-dark-toggle--112, #15141a); - --alt-text-tooltip-border:#8f8f9d; - --csstools-light-dark-toggle--113:var(--csstools-color-scheme--light) #15141a; - --alt-text-tooltip-shadow:0 2px 6px 0 var(--csstools-light-dark-toggle--113, rgb(58 57 68 / 0.2)); - } - -@supports (color: light-dark(red, red)){ -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip){ - --alt-text-tooltip-bg:light-dark(#f0f0f4, #1c1b22); - --alt-text-tooltip-fg:light-dark(#15141a, #fbfbfe); - } +.selectedEditor:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + )::before { + content: ''; + position: absolute; + inset: 0; + border: var(--focus-outline-around); + pointer-events: none; } -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip){ - --alt-text-tooltip-shadow:0 2px 6px 0 light-dark(rgb(58 57 68 / 0.2), #15141a); - } +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ):hover:not(.selectedEditor) { + border: var(--hover-outline); + outline: var(--hover-outline-around); } -@supports not (color: light-dark(tan, tan)){ - -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip) *{ - --csstools-light-dark-toggle--111:var(--csstools-color-scheme--light) #1c1b22; - --alt-text-tooltip-bg:var(--csstools-light-dark-toggle--111, #f0f0f4); - --csstools-light-dark-toggle--112:var(--csstools-color-scheme--light) #fbfbfe; - --alt-text-tooltip-fg:var(--csstools-light-dark-toggle--112, #15141a); - --csstools-light-dark-toggle--113:var(--csstools-color-scheme--light) #15141a; - --alt-text-tooltip-shadow:0 2px 6px 0 var(--csstools-light-dark-toggle--113, rgb(58 57 68 / 0.2)); - } +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ):hover:not(.selectedEditor)::before { + content: ''; + position: absolute; + inset: 0; + border: var(--focus-outline-around); } -@media screen and (forced-colors: active){ - -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip){ - --alt-text-tooltip-bg:Canvas; - --alt-text-tooltip-fg:CanvasText; - --alt-text-tooltip-border:CanvasText; - --alt-text-tooltip-shadow:none; - } - } - -.show:is(:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .altText) .tooltip){ - - display:inline-flex; - flex-direction:column; - align-items:center; - justify-content:center; - position:absolute; - top:calc(100% + 2px); - inset-inline-start:0; - padding-block:2px 3px; - padding-inline:3px; - max-width:300px; - width:-moz-max-content; - width:max-content; - height:auto; - font-size:12px; - - border:0.5px solid var(--alt-text-tooltip-border); - background:var(--alt-text-tooltip-bg); - box-shadow:var(--alt-text-tooltip-shadow); - color:var(--alt-text-tooltip-fg); - - pointer-events:none; - } - -:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .comment{ - width:var(--editor-toolbar-height); - } - -:is(:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.highlightEditor,.signatureEditor),.textLayer) .editToolbar) .buttons) .comment)::before{ - content:""; - -webkit-mask-image:var(--comment-edit-button-icon); - mask-image:var(--comment-edit-button-icon); - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - display:inline-block; - background-color:var(--editor-toolbar-fg-color); - width:100%; - height:100%; - } - -.annotationEditorLayer .freeTextEditor{ - padding:calc(var(--freetext-padding) * var(--total-scale-factor)); - width:auto; - height:auto; - touch-action:none; -} - -.annotationEditorLayer .freeTextEditor .internal{ - background:transparent; - border:none; - inset:0; - overflow:visible; - white-space:nowrap; - font:10px sans-serif; - line-height:var(--freetext-line-height); - text-align:start; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; -} - -.annotationEditorLayer .freeTextEditor .overlay{ - position:absolute; - display:none; - background:transparent; - inset:0; - width:100%; - height:100%; -} - -.annotationEditorLayer freeTextEditor .overlay.enabled{ - display:block; -} - -.annotationEditorLayer .freeTextEditor .internal:empty::before{ - content:attr(default-content); - color:gray; -} - -.annotationEditorLayer .freeTextEditor .internal:focus{ - outline:none; - -webkit-user-select:auto; - -moz-user-select:auto; - user-select:auto; -} - -.annotationEditorLayer .inkEditor{ - width:100%; - height:100%; -} - -.annotationEditorLayer .inkEditor.editing{ - cursor:inherit; -} - -.annotationEditorLayer .inkEditor .inkEditorCanvas{ - position:absolute; - inset:0; - width:100%; - height:100%; - touch-action:none; -} - -.annotationEditorLayer .stampEditor{ - width:auto; - height:auto; -} - -:is(.annotationEditorLayer .stampEditor) canvas{ - position:absolute; - width:100%; - height:100%; - margin:0; - top:0; - left:0; - } - -:is(.annotationEditorLayer .stampEditor) .noAltTextBadge{ - --csstools-light-dark-toggle--114:var(--csstools-color-scheme--light) #52525e; - --no-alt-text-badge-border-color:var(--csstools-light-dark-toggle--114, #f0f0f4); - --csstools-light-dark-toggle--115:var(--csstools-color-scheme--light) #fbfbfe; - --no-alt-text-badge-bg-color:var(--csstools-light-dark-toggle--115, #cfcfd8); - --csstools-light-dark-toggle--116:var(--csstools-color-scheme--light) #15141a; - --no-alt-text-badge-fg-color:var(--csstools-light-dark-toggle--116, #5b5b66); - } - -@supports (color: light-dark(red, red)){ -:is(.annotationEditorLayer .stampEditor) .noAltTextBadge{ - --no-alt-text-badge-border-color:light-dark(#f0f0f4, #52525e); - --no-alt-text-badge-bg-color:light-dark(#cfcfd8, #fbfbfe); - --no-alt-text-badge-fg-color:light-dark(#5b5b66, #15141a); - } -} - -@supports not (color: light-dark(tan, tan)){ - -:is(:is(.annotationEditorLayer .stampEditor) .noAltTextBadge) *{ - --csstools-light-dark-toggle--114:var(--csstools-color-scheme--light) #52525e; - --no-alt-text-badge-border-color:var(--csstools-light-dark-toggle--114, #f0f0f4); - --csstools-light-dark-toggle--115:var(--csstools-color-scheme--light) #fbfbfe; - --no-alt-text-badge-bg-color:var(--csstools-light-dark-toggle--115, #cfcfd8); - --csstools-light-dark-toggle--116:var(--csstools-color-scheme--light) #15141a; - --no-alt-text-badge-fg-color:var(--csstools-light-dark-toggle--116, #5b5b66); - } -} - -@media screen and (forced-colors: active){ - -:is(.annotationEditorLayer .stampEditor) .noAltTextBadge{ - --no-alt-text-badge-border-color:ButtonText; - --no-alt-text-badge-bg-color:ButtonFace; - --no-alt-text-badge-fg-color:ButtonText; - } - } - -:is(.annotationEditorLayer .stampEditor) .noAltTextBadge{ - - position:absolute; - inset-inline-end:5px; - inset-block-end:5px; - display:inline-flex; - width:32px; - height:32px; - padding:3px; - justify-content:center; - align-items:center; - pointer-events:none; - z-index:1; - - border-radius:2px; - border:1px solid var(--no-alt-text-badge-border-color); - background:var(--no-alt-text-badge-bg-color); - } - -:is(:is(.annotationEditorLayer .stampEditor) .noAltTextBadge)::before{ - content:""; - display:inline-block; - width:16px; - height:16px; - -webkit-mask-image:var(--new-alt-text-warning-image); - mask-image:var(--new-alt-text-warning-image); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--no-alt-text-badge-fg-color); - } - -:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers{ - position:absolute; - inset:0; - z-index:1; - } - -.hidden:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers){ - display:none; - } - -:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer{ - width:var(--resizer-size); - height:var(--resizer-size); - background:content-box var(--resizer-bg-color); - border:var(--focus-outline-around); - border-radius:2px; - position:absolute; - } - -.topLeft:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - top:var(--resizer-shift); - left:var(--resizer-shift); - } - -.topMiddle:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - top:var(--resizer-shift); - left:calc(50% + var(--resizer-shift)); - } - -.topRight:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - top:var(--resizer-shift); - right:var(--resizer-shift); - } - -.middleRight:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - top:calc(50% + var(--resizer-shift)); - right:var(--resizer-shift); - } - -.bottomRight:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - bottom:var(--resizer-shift); - right:var(--resizer-shift); - } - -.bottomMiddle:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - bottom:var(--resizer-shift); - left:calc(50% + var(--resizer-shift)); - } - -.bottomLeft:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - bottom:var(--resizer-shift); - left:var(--resizer-shift); - } - -.middleLeft:is(:is(:is(.annotationEditorLayer :is(.freeTextEditor,.inkEditor,.stampEditor,.signatureEditor)) > .resizers) > .resizer){ - top:calc(50% + var(--resizer-shift)); - left:var(--resizer-shift); - } - -.topLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer),.bottomRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer){ - cursor:nwse-resize; - } - -.topMiddle:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer),.bottomMiddle:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer){ - cursor:ns-resize; - } - -.topRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer),.bottomLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer){ - cursor:nesw-resize; - } - -.middleRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer),.middleLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="180"],[data-editor-rotation="0"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="90"],[data-editor-rotation="270"])) > .resizers > .resizer){ - cursor:ew-resize; - } - -.topLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer),.bottomRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer){ - cursor:nesw-resize; - } - -.topMiddle:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer),.bottomMiddle:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer){ - cursor:ew-resize; - } - -.topRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer),.bottomLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer){ - cursor:nwse-resize; - } - -.middleRight:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer),.middleLeft:is(:is(.annotationEditorLayer[data-main-rotation="0"] :is([data-editor-rotation="90"],[data-editor-rotation="270"]),.annotationEditorLayer[data-main-rotation="90"] :is([data-editor-rotation="0"],[data-editor-rotation="180"]),.annotationEditorLayer[data-main-rotation="180"] :is([data-editor-rotation="270"],[data-editor-rotation="90"]),.annotationEditorLayer[data-main-rotation="270"] :is([data-editor-rotation="180"],[data-editor-rotation="0"])) > .resizers > .resizer){ - cursor:ns-resize; - } - -:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="90"],[data-main-rotation="90"] [data-editor-rotation="0"],[data-main-rotation="180"] [data-editor-rotation="270"],[data-main-rotation="270"] [data-editor-rotation="180"])) .editToolbar{ - rotate:270deg; - } - -[dir="ltr"] :is(:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="90"],[data-main-rotation="90"] [data-editor-rotation="0"],[data-main-rotation="180"] [data-editor-rotation="270"],[data-main-rotation="270"] [data-editor-rotation="180"])) .editToolbar){ - inset-inline-end:calc(0px - var(--editor-toolbar-vert-offset)); - inset-block-start:0; - } - -[dir="rtl"] :is(:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="90"],[data-main-rotation="90"] [data-editor-rotation="0"],[data-main-rotation="180"] [data-editor-rotation="270"],[data-main-rotation="270"] [data-editor-rotation="180"])) .editToolbar){ - inset-inline-end:calc(100% + var(--editor-toolbar-vert-offset)); - inset-block-start:0; - } - -:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="180"],[data-main-rotation="90"] [data-editor-rotation="90"],[data-main-rotation="180"] [data-editor-rotation="0"],[data-main-rotation="270"] [data-editor-rotation="270"])) .editToolbar{ - rotate:180deg; - inset-inline-end:100%; - inset-block-start:calc(0px - var(--editor-toolbar-vert-offset)); - } - -:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="270"],[data-main-rotation="90"] [data-editor-rotation="180"],[data-main-rotation="180"] [data-editor-rotation="90"],[data-main-rotation="270"] [data-editor-rotation="0"])) .editToolbar{ - rotate:90deg; - } - -[dir="ltr"] :is(:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="270"],[data-main-rotation="90"] [data-editor-rotation="180"],[data-main-rotation="180"] [data-editor-rotation="90"],[data-main-rotation="270"] [data-editor-rotation="0"])) .editToolbar){ - inset-inline-end:calc(100% + var(--editor-toolbar-vert-offset)); - inset-block-start:100%; - } - -[dir="rtl"] :is(:is(.annotationEditorLayer :is([data-main-rotation="0"] [data-editor-rotation="270"],[data-main-rotation="90"] [data-editor-rotation="180"],[data-main-rotation="180"] [data-editor-rotation="90"],[data-main-rotation="270"] [data-editor-rotation="0"])) .editToolbar){ - inset-inline-start:calc(0px - var(--editor-toolbar-vert-offset)); - inset-block-start:0; - } - -.dialog.altText::backdrop{ - -webkit-mask:url(#alttext-manager-mask); - mask:url(#alttext-manager-mask); - } - -.dialog.altText.positioned{ - margin:0; - } - -.dialog.altText #altTextContainer{ - width:300px; - height:-moz-fit-content; - height:fit-content; - display:inline-flex; - flex-direction:column; - align-items:flex-start; - gap:16px; - } - -:is(.dialog.altText #altTextContainer) #overallDescription{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:4px; - align-self:stretch; - } - -:is(:is(.dialog.altText #altTextContainer) #overallDescription) span{ - align-self:stretch; - } - -:is(:is(.dialog.altText #altTextContainer) #overallDescription) .title{ - font-size:13px; - font-style:normal; - font-weight:590; - } - -:is(.dialog.altText #altTextContainer) #addDescription{ - display:flex; - flex-direction:column; - align-items:stretch; - gap:8px; - } - -:is(:is(.dialog.altText #altTextContainer) #addDescription) .descriptionArea{ - flex:1; - padding-inline:24px 10px; - } - -:is(:is(:is(.dialog.altText #altTextContainer) #addDescription) .descriptionArea) textarea{ - width:100%; - min-height:75px; - } - -:is(.dialog.altText #altTextContainer) #buttons{ - display:flex; - justify-content:flex-end; - align-items:flex-start; - gap:8px; - align-self:stretch; - } - -.dialog.newAltText{ - --new-alt-text-ai-disclaimer-icon:url(images/altText_disclaimer.svg); - --new-alt-text-spinner-icon:url(images/altText_spinner.svg); - --csstools-light-dark-toggle--117:var(--csstools-color-scheme--light) #2b2a33; - --preview-image-bg-color:var(--csstools-light-dark-toggle--117, #f0f0f4); - --preview-image-border:none; -} - -@supports (color: light-dark(red, red)){ -.dialog.newAltText{ - --preview-image-bg-color:light-dark(#f0f0f4, #2b2a33); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.dialog.newAltText *{ - --csstools-light-dark-toggle--117:var(--csstools-color-scheme--light) #2b2a33; - --preview-image-bg-color:var(--csstools-light-dark-toggle--117, #f0f0f4); - } -} - -@media screen and (forced-colors: active){ - -.dialog.newAltText{ - --preview-image-bg-color:ButtonFace; - --preview-image-border:1px solid ButtonText; -} - } - -.dialog.newAltText{ - - width:80%; - max-width:570px; - min-width:300px; - padding:0; -} - -.dialog.newAltText.noAi #newAltTextDisclaimer,.dialog.newAltText.noAi #newAltTextCreateAutomatically{ - display:none !important; - } - -.dialog.newAltText.aiInstalling #newAltTextCreateAutomatically{ - display:none !important; - } - -.dialog.newAltText.aiInstalling #newAltTextDownloadModel{ - display:flex !important; - } - -.dialog.newAltText.error #newAltTextNotNow{ - display:none !important; - } - -.dialog.newAltText.error #newAltTextCancel{ - display:inline-block !important; - } - -.dialog.newAltText:not(.error) #newAltTextError{ - display:none !important; - } - -.dialog.newAltText #newAltTextContainer{ - display:flex; - width:auto; - padding:16px; - flex-direction:column; - justify-content:flex-end; - align-items:flex-start; - gap:12px; - flex:0 1 auto; - line-height:normal; - } - -:is(.dialog.newAltText #newAltTextContainer) #mainContent{ - display:flex; - justify-content:flex-end; - align-items:flex-start; - gap:12px; - align-self:stretch; - flex:1 1 auto; - } - -:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionAndSettings{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:16px; - flex:1 0 0; - align-self:stretch; - } - -:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:8px; - align-self:stretch; - flex:1 1 auto; - } - -:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer{ - width:100%; - height:70px; - position:relative; - } - -:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) textarea{ - width:100%; - height:100%; - padding:8px; - } - -:is(:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) textarea)::-moz-placeholder{ - color:var(--text-secondary-color); - } - -:is(:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) textarea)::placeholder{ - color:var(--text-secondary-color); - } - -:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) .altTextSpinner{ - display:none; - position:absolute; - width:16px; - height:16px; - inset-inline-start:8px; - inset-block-start:8px; - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--text-secondary-color); - pointer-events:none; - } - -.loading:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) textarea::-moz-placeholder{ - color:transparent; - } - -.loading:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) textarea::placeholder{ - color:transparent; - } - -.loading:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescriptionContainer) .altTextSpinner{ - display:inline-block; - -webkit-mask-image:var(--new-alt-text-spinner-icon); - mask-image:var(--new-alt-text-spinner-icon); - } - -:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDescription{ - font-size:11px; - } - -:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDisclaimer{ - display:flex; - flex-direction:row; - align-items:flex-start; - gap:4px; - font-size:11px; - } - -:is(:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #descriptionInstruction) #newAltTextDisclaimer)::before{ - content:""; - display:inline-block; - width:17px; - height:16px; - -webkit-mask-image:var(--new-alt-text-ai-disclaimer-icon); - mask-image:var(--new-alt-text-ai-disclaimer-icon); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--text-secondary-color); - flex:1 0 auto; - } - -:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #newAltTextDownloadModel{ - display:flex; - align-items:center; - gap:4px; - align-self:stretch; - } - -:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #newAltTextDownloadModel)::before{ - content:""; - display:inline-block; - width:16px; - height:16px; - -webkit-mask-image:var(--new-alt-text-spinner-icon); - mask-image:var(--new-alt-text-spinner-icon); - -webkit-mask-size:cover; - mask-size:cover; - background-color:var(--text-secondary-color); - } - -:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #newAltTextImagePreview{ - width:180px; - aspect-ratio:1; - display:flex; - justify-content:center; - align-items:center; - flex:0 0 auto; - background-color:var(--preview-image-bg-color); - border:var(--preview-image-border); - } - -:is(:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) #newAltTextImagePreview) > canvas{ - max-width:100%; - max-height:100%; - } - -.colorPicker{ - --csstools-light-dark-toggle--118:var(--csstools-color-scheme--light) #80ebff; - --hover-outline-color:var(--csstools-light-dark-toggle--118, #0250bb); - --csstools-light-dark-toggle--119:var(--csstools-color-scheme--light) #aaf2ff; - --selected-outline-color:var(--csstools-light-dark-toggle--119, #0060df); - --csstools-light-dark-toggle--120:var(--csstools-color-scheme--light) #52525e; - --swatch-border-color:var(--csstools-light-dark-toggle--120, #cfcfd8); -} - -@supports (color: light-dark(red, red)){ -.colorPicker{ - --hover-outline-color:light-dark(#0250bb, #80ebff); - --selected-outline-color:light-dark(#0060df, #aaf2ff); - --swatch-border-color:light-dark(#cfcfd8, #52525e); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.colorPicker *{ - --csstools-light-dark-toggle--118:var(--csstools-color-scheme--light) #80ebff; - --hover-outline-color:var(--csstools-light-dark-toggle--118, #0250bb); - --csstools-light-dark-toggle--119:var(--csstools-color-scheme--light) #aaf2ff; - --selected-outline-color:var(--csstools-light-dark-toggle--119, #0060df); - --csstools-light-dark-toggle--120:var(--csstools-color-scheme--light) #52525e; - --swatch-border-color:var(--csstools-light-dark-toggle--120, #cfcfd8); - } -} - -@media screen and (forced-colors: active){ - -.colorPicker{ - --hover-outline-color:Highlight; - --selected-outline-color:var(--hover-outline-color); - --swatch-border-color:ButtonText; -} - } - -.colorPicker .swatch{ - width:16px; - height:16px; - border:1px solid var(--swatch-border-color); - border-radius:100%; - outline-offset:2px; - box-sizing:border-box; - forced-color-adjust:none; - } - -.colorPicker button:is(:hover,.selected) > .swatch{ - border:none; - } - -.basicColorPicker{ - width:28px; -} - -.basicColorPicker::-moz-color-swatch{ - border-radius:100%; - } - -.basicColorPicker::-webkit-color-swatch{ - border-radius:100%; - } - -.annotationEditorLayer[data-main-rotation="0"] .highlightEditor:not(.free) > .editToolbar{ - rotate:0deg; - } - -.annotationEditorLayer[data-main-rotation="90"] .highlightEditor:not(.free) > .editToolbar{ - rotate:270deg; - } - -.annotationEditorLayer[data-main-rotation="180"] .highlightEditor:not(.free) > .editToolbar{ - rotate:180deg; - } - -.annotationEditorLayer[data-main-rotation="270"] .highlightEditor:not(.free) > .editToolbar{ - rotate:90deg; - } - -.annotationEditorLayer .highlightEditor{ - position:absolute; - background:transparent; - z-index:1; - cursor:auto; - max-width:100%; - max-height:100%; - border:none; - outline:none; - pointer-events:none; - transform-origin:0 0; - } - -:is(.annotationEditorLayer .highlightEditor):not(.free){ - transform:none; - } - -:is(.annotationEditorLayer .highlightEditor) .internal{ - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - pointer-events:auto; - } - -.disabled:is(.annotationEditorLayer .highlightEditor) .internal{ - pointer-events:none; - } - -.selectedEditor:is(.annotationEditorLayer .highlightEditor) .internal{ - cursor:pointer; - } - -:is(.annotationEditorLayer .highlightEditor) .editToolbar{ - --editor-toolbar-colorpicker-arrow-image:url(images/toolbarButton-menuArrow.svg); - - transform-origin:center !important; - } - -:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker{ - position:relative; - width:auto; - display:flex; - justify-content:center; - align-items:center; - gap:4px; - padding:4px; - } - -:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker)::after{ - content:""; - -webkit-mask-image:var(--editor-toolbar-colorpicker-arrow-image); - mask-image:var(--editor-toolbar-colorpicker-arrow-image); - -webkit-mask-repeat:no-repeat; - mask-repeat:no-repeat; - -webkit-mask-position:center; - mask-position:center; - display:inline-block; - background-color:var(--editor-toolbar-fg-color); - width:12px; - height:12px; - } - -:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker):hover::after{ - background-color:var(--editor-toolbar-hover-fg-color); - } - -:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker):has(.dropdown:not(.hidden)){ - background-color:var(--editor-toolbar-hover-bg-color); - } - -:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker):has(.dropdown:not(.hidden))::after{ - scale:-1; - } - -:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown{ - position:absolute; - display:flex; - justify-content:center; - align-items:center; - flex-direction:column; - gap:11px; - padding-block:8px; - border-radius:6px; - background-color:var(--editor-toolbar-bg-color); - border:1px solid var(--editor-toolbar-border-color); - box-shadow:var(--editor-toolbar-shadow); - inset-block-start:calc(100% + 4px); - width:calc(100% + 2 * var(--editor-toolbar-padding)); - } - -:is(:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown) button{ - width:100%; - height:auto; - border:none; - cursor:pointer; - display:flex; - justify-content:center; - align-items:center; - background:none; - } - -:is(:is(:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown) button):is(:active,:focus-visible){ - outline:none; - } - -:is(:is(:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown) button) > .swatch{ - outline-offset:2px; - } - -[aria-selected="true"]:is(:is(:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown) button) > .swatch{ - outline:2px solid var(--selected-outline-color); - } - -:is(:is(:is(:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) .colorPicker) .dropdown) button):is(:hover,:active,:focus-visible) > .swatch{ - outline:2px solid var(--hover-outline-color); - } - -.editorParamsToolbar:has(#highlightParamsToolbarContainer){ - padding:unset; -} - -#highlightParamsToolbarContainer{ - gap:16px; - padding-inline:10px; - padding-block-end:12px; -} - -#highlightParamsToolbarContainer .colorPicker{ - display:flex; - flex-direction:column; - gap:8px; - } - -:is(#highlightParamsToolbarContainer .colorPicker) .dropdown{ - display:flex; - justify-content:space-between; - align-items:center; - flex-direction:row; - height:auto; - } - -:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button{ - width:auto; - height:auto; - border:none; - cursor:pointer; - display:flex; - justify-content:center; - align-items:center; - background:none; - flex:0 0 auto; - padding:0; - } - -:is(:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button) .swatch{ - width:24px; - height:24px; - } - -:is(:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button):is(:active,:focus-visible){ - outline:none; - } - -[aria-selected="true"]:is(:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button) > .swatch{ - outline:2px solid var(--selected-outline-color); - } - -:is(:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button):is(:hover,:active,:focus-visible) > .swatch{ - outline:2px solid var(--hover-outline-color); - } - -#highlightParamsToolbarContainer #editorHighlightThickness{ - display:flex; - flex-direction:column; - align-items:center; - gap:4px; - align-self:stretch; - } - -:is(#highlightParamsToolbarContainer #editorHighlightThickness) .editorParamsLabel{ - height:auto; - align-self:stretch; - } - -:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker{ - display:flex; - justify-content:space-between; - align-items:center; - align-self:stretch; - - --csstools-light-dark-toggle--121:var(--csstools-color-scheme--light) #80808e; - - --example-color:var(--csstools-light-dark-toggle--121, #bfbfc9); - } - -@supports (color: light-dark(red, red)){ -:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker{ - - --example-color:light-dark(#bfbfc9, #80808e); - } -} - -@supports not (color: light-dark(tan, tan)){ - -:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker) *{ - - --csstools-light-dark-toggle--121:var(--csstools-color-scheme--light) #80808e; - - --example-color:var(--csstools-light-dark-toggle--121, #bfbfc9); - } -} - -@media screen and (forced-colors: active){ - -:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker{ - --example-color:CanvasText; - } - } - -:is(:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker) > .editorParamsSlider[disabled]){ - opacity:0.4; - } - -:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker)::before,:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker)::after{ - content:""; - width:8px; - aspect-ratio:1; - display:block; - border-radius:100%; - background-color:var(--example-color); - } - -:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker)::after{ - width:24px; - } - -:is(:is(#highlightParamsToolbarContainer #editorHighlightThickness) .thicknessPicker) .editorParamsSlider{ - width:unset; - height:14px; - } - -#highlightParamsToolbarContainer #editorHighlightVisibility{ - display:flex; - flex-direction:column; - align-items:flex-start; - gap:8px; - align-self:stretch; - } - -:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider{ - --csstools-light-dark-toggle--122:var(--csstools-color-scheme--light) #8f8f9d; - --divider-color:var(--csstools-light-dark-toggle--122, #d7d7db); - } - -@supports (color: light-dark(red, red)){ -:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider{ - --divider-color:light-dark(#d7d7db, #8f8f9d); - } -} - -@supports not (color: light-dark(tan, tan)){ - -:is(:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider) *{ - --csstools-light-dark-toggle--122:var(--csstools-color-scheme--light) #8f8f9d; - --divider-color:var(--csstools-light-dark-toggle--122, #d7d7db); - } -} - -@media screen and (forced-colors: active){ - -:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider{ - --divider-color:CanvasText; - } - } - -:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider{ - - margin-block:4px; - width:100%; - height:1px; - background-color:var(--divider-color); - } - -:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .toggler{ - display:flex; - justify-content:space-between; - align-items:center; - align-self:stretch; - } - -#altTextSettingsDialog{ - padding:16px; -} - -#altTextSettingsDialog #altTextSettingsContainer{ - display:flex; - width:573px; - flex-direction:column; - gap:16px; - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) .mainContainer{ - gap:16px; - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) .description{ - color:var(--text-secondary-color); - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings{ - display:flex; - flex-direction:column; - gap:12px; - } - -:is(:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings) button{ - width:-moz-fit-content; - width:fit-content; - } - -.download:is(:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings) #deleteModelButton{ - display:none; - } - -:is(:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings):not(.download) #downloadModelButton{ - display:none; - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) #automaticAltText,:is(#altTextSettingsDialog #altTextSettingsContainer) #altTextEditor{ - display:flex; - flex-direction:column; - gap:8px; - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) #createModelDescription,:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings,:is(#altTextSettingsDialog #altTextSettingsContainer) #showAltTextDialogDescription{ - padding-inline-start:40px; - } - -:is(#altTextSettingsDialog #altTextSettingsContainer) #automaticSettings{ - display:flex; - flex-direction:column; - gap:16px; - } - -.sidebar{ - --csstools-light-dark-toggle--123:var(--csstools-color-scheme--light) #23222b; - --sidebar-bg-color:var(--csstools-light-dark-toggle--123, #fff); - --csstools-light-dark-toggle--124:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.1); - --sidebar-border-color:var(--csstools-light-dark-toggle--124, rgb(21 20 26 / 0.1)); - --csstools-light-dark-toggle--125:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--126:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --sidebar-box-shadow:0 0.25px 0.75px var(--csstools-light-dark-toggle--125, rgb(0 0 0 / 0.05)), 0 2px 6px 0 var(--csstools-light-dark-toggle--126, rgb(0 0 0 / 0.1)); - --sidebar-border-radius:8px; - --sidebar-padding:5px; - --sidebar-min-width:180px; - --sidebar-max-width:632px; - --sidebar-width:239px; - --resizer-width:4px; - --csstools-light-dark-toggle--127:var(--csstools-color-scheme--light) #00cadb; - --resizer-hover-bg-color:var(--csstools-light-dark-toggle--127, #0062fa); -} - -@supports (color: light-dark(red, red)){ -.sidebar{ - --sidebar-bg-color:light-dark(#fff, #23222b); -} -} - -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -.sidebar{ - --sidebar-border-color:light-dark( - rgb(21 20 26 / 0.1), - rgb(251 251 254 / 0.1) +:is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar { + --editor-toolbar-delete-image: url(images/editor-toolbar-delete.svg); + --csstools-light-dark-toggle--105: var(--csstools-color-scheme--light) #2b2a33; + --editor-toolbar-bg-color: var(--csstools-light-dark-toggle--105, #f0f0f4); + --editor-toolbar-highlight-image: url(images/toolbarButton-editorHighlight.svg); + --csstools-light-dark-toggle--106: var(--csstools-color-scheme--light) #fbfbfe; + --editor-toolbar-fg-color: var(--csstools-light-dark-toggle--106, #2e2e56); + --editor-toolbar-border-color: #8f8f9d; + --editor-toolbar-hover-border-color: var(--editor-toolbar-border-color); + --csstools-light-dark-toggle--107: var(--csstools-color-scheme--light) #52525e; + --editor-toolbar-hover-bg-color: var( + --csstools-light-dark-toggle--107, + #e0e0e6 ); - --sidebar-box-shadow:0 0.25px 0.75px light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), 0 2px 6px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); -} + --editor-toolbar-hover-fg-color: var(--editor-toolbar-fg-color); + --editor-toolbar-hover-outline: none; + --csstools-light-dark-toggle--108: var(--csstools-color-scheme--light) #0df; + --editor-toolbar-focus-outline-color: var( + --csstools-light-dark-toggle--108, + #0060df + ); + --editor-toolbar-shadow: 0 2px 6px 0 rgb(58 57 68 / 0.2); + --editor-toolbar-height: 28px; + --editor-toolbar-padding: 2px; + --csstools-light-dark-toggle--109: var(--csstools-color-scheme--light) #54ffbd; + --alt-text-done-color: var(--csstools-light-dark-toggle--109, #2ac3a2); + --csstools-light-dark-toggle--110: var(--csstools-color-scheme--light) #80ebff; + --alt-text-warning-color: var(--csstools-light-dark-toggle--110, #0090ed); + --alt-text-hover-done-color: var(--alt-text-done-color); + --alt-text-hover-warning-color: var(--alt-text-warning-color); } -@supports (color: light-dark(red, red)){ -.sidebar{ - --resizer-hover-bg-color:light-dark(#0062fa, #00cadb); -} -} - -@supports not (color: light-dark(tan, tan)){ - -.sidebar *{ - --csstools-light-dark-toggle--123:var(--csstools-color-scheme--light) #23222b; - --sidebar-bg-color:var(--csstools-light-dark-toggle--123, #fff); - --csstools-light-dark-toggle--124:var(--csstools-color-scheme--light) rgb(251 251 254 / 0.1); - --sidebar-border-color:var(--csstools-light-dark-toggle--124, rgb(21 20 26 / 0.1)); - --csstools-light-dark-toggle--125:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.2); - --csstools-light-dark-toggle--126:var(--csstools-color-scheme--light) rgb(0 0 0 / 0.4); - --sidebar-box-shadow:0 0.25px 0.75px var(--csstools-light-dark-toggle--125, rgb(0 0 0 / 0.05)), 0 2px 6px 0 var(--csstools-light-dark-toggle--126, rgb(0 0 0 / 0.1)); - --csstools-light-dark-toggle--127:var(--csstools-color-scheme--light) #00cadb; - --resizer-hover-bg-color:var(--csstools-light-dark-toggle--127, #0062fa); +@supports (color: light-dark(red, red)) { + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar { + --editor-toolbar-bg-color: light-dark(#f0f0f4, #2b2a33); + --editor-toolbar-fg-color: light-dark(#2e2e56, #fbfbfe); + --editor-toolbar-hover-bg-color: light-dark(#e0e0e6, #52525e); + --editor-toolbar-focus-outline-color: light-dark(#0060df, #0df); + --alt-text-done-color: light-dark(#2ac3a2, #54ffbd); + --alt-text-warning-color: light-dark(#0090ed, #80ebff); } } -@media screen and (forced-colors: active){ - -.sidebar{ - --sidebar-bg-color:Canvas; - --sidebar-border-color:CanvasText; - --sidebar-box-shadow:none; - --resizer-hover-bg-color:CanvasText; -} - } - -.sidebar{ - - border-radius:var(--sidebar-border-radius); - box-shadow:var(--sidebar-box-shadow); - border:1px solid var(--sidebar-border-color); - background-color:var(--sidebar-bg-color); - inset-block-start:calc(100% + var(--doorhanger-height) - 2px); - padding-block:var(--sidebar-padding); - width:var(--sidebar-width); - min-width:var(--sidebar-min-width); - max-width:var(--sidebar-max-width); -} - -.sidebar .sidebarResizer{ - width:var(--resizer-width); - background-color:transparent; - forced-color-adjust:none; - cursor:ew-resize; - position:absolute; - inset-block:calc(var(--sidebar-padding) + var(--sidebar-border-radius)); - inset-inline-start:calc(0px - var(--resizer-width) / 2); - transition:background-color 0.5s ease-in-out; - box-sizing:border-box; - border:1px solid transparent; - border-block-width:0; - background-clip:content-box; - } - -:is(.sidebar .sidebarResizer):hover{ - background-color:var(--resizer-hover-bg-color); - } - -.sidebar.resizing{ - cursor:ew-resize; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - } - -.sidebar.resizing :not(.sidebarResizer){ - pointer-events:none; - } - -:root{ - --csstools-color-scheme--light:initial; - color-scheme:light dark; - - --viewer-container-height:0; - --pdfViewer-padding-bottom:0; - --page-margin:1px auto -8px; - --page-border:9px solid transparent; - --spreadHorizontalWrapped-margin-LR:-3.5px; - --loading-icon-delay:400ms; - --csstools-light-dark-toggle--128:var(--csstools-color-scheme--light) #0df; - --focus-ring-color:var(--csstools-light-dark-toggle--128, #0060df); - --focus-ring-outline:2px solid var(--focus-ring-color); -} - -@supports (color: light-dark(red, red)){ -:root{ - --focus-ring-color:light-dark(#0060df, #0df); -} -} - -@supports not (color: light-dark(tan, tan)){ - -:root *{ - --csstools-light-dark-toggle--128:var(--csstools-color-scheme--light) #0df; - --focus-ring-color:var(--csstools-light-dark-toggle--128, #0060df); +@supports not (color: light-dark(tan, tan)) { + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + * { + --csstools-light-dark-toggle--105: var(--csstools-color-scheme--light) + #2b2a33; + --editor-toolbar-bg-color: var(--csstools-light-dark-toggle--105, #f0f0f4); + --csstools-light-dark-toggle--106: var(--csstools-color-scheme--light) + #fbfbfe; + --editor-toolbar-fg-color: var(--csstools-light-dark-toggle--106, #2e2e56); + --csstools-light-dark-toggle--107: var(--csstools-color-scheme--light) + #52525e; + --editor-toolbar-hover-bg-color: var( + --csstools-light-dark-toggle--107, + #e0e0e6 + ); + --csstools-light-dark-toggle--108: var(--csstools-color-scheme--light) #0df; + --editor-toolbar-focus-outline-color: var( + --csstools-light-dark-toggle--108, + #0060df + ); + --csstools-light-dark-toggle--109: var(--csstools-color-scheme--light) + #54ffbd; + --alt-text-done-color: var(--csstools-light-dark-toggle--109, #2ac3a2); + --csstools-light-dark-toggle--110: var(--csstools-color-scheme--light) + #80ebff; + --alt-text-warning-color: var(--csstools-light-dark-toggle--110, #0090ed); } } -@media (prefers-color-scheme: dark){ - -:root{ - --csstools-color-scheme--light: light; -} -} - -@media screen and (forced-colors: active){ - -:root{ - --pdfViewer-padding-bottom:9px; - --page-margin:8px auto -1px; - --page-border:1px solid CanvasText; - --spreadHorizontalWrapped-margin-LR:3.5px; - --focus-ring-color:CanvasText; -} +@media screen and (forced-colors: active) { + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar { + --editor-toolbar-bg-color: ButtonFace; + --editor-toolbar-fg-color: ButtonText; + --editor-toolbar-border-color: ButtonText; + --editor-toolbar-hover-border-color: AccentColor; + --editor-toolbar-hover-bg-color: ButtonFace; + --editor-toolbar-hover-fg-color: AccentColor; + --editor-toolbar-hover-outline: 2px solid + var(--editor-toolbar-hover-border-color); + --editor-toolbar-focus-outline-color: ButtonBorder; + --editor-toolbar-shadow: none; + --alt-text-done-color: var(--editor-toolbar-fg-color); + --alt-text-warning-color: var(--editor-toolbar-fg-color); + --alt-text-hover-done-color: var(--editor-toolbar-hover-fg-color); + --alt-text-hover-warning-color: var(--editor-toolbar-hover-fg-color); } +} -[data-main-rotation="90"]{ - transform:rotate(90deg) translateY(-100%); +:is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar { + display: flex; + width: -moz-fit-content; + width: fit-content; + height: var(--editor-toolbar-height); + flex-direction: column; + justify-content: center; + align-items: center; + cursor: default; + pointer-events: auto; + box-sizing: content-box; + padding: var(--editor-toolbar-padding); + + position: absolute; + inset-inline-end: 0; + inset-block-start: calc(100% + var(--editor-toolbar-vert-offset)); + + border-radius: 6px; + background-color: var(--editor-toolbar-bg-color); + border: 1px solid var(--editor-toolbar-border-color); + box-shadow: var(--editor-toolbar-shadow); } -[data-main-rotation="180"]{ - transform:rotate(180deg) translate(-100%, -100%); + +.hidden:is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar +) { + display: none; } -[data-main-rotation="270"]{ - transform:rotate(270deg) translateX(-100%); + +:is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar +):has(:focus-visible) { + border-color: transparent; +} + +[dir='ltr'] + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) { + transform-origin: 100% 0; +} + +[dir='rtl'] + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) { + transform-origin: 0 0; +} + +:is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons { + display: flex; + justify-content: center; + align-items: center; + gap: 0; + height: 100%; +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + button { + padding: 0; +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .divider { + width: 0; + height: calc( + 2 * var(--editor-toolbar-padding) + var(--editor-toolbar-height) + ); + border-left: 1px solid var(--editor-toolbar-border-color); + border-right: none; + display: inline-block; + margin-inline: 2px; +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic { + width: var(--editor-toolbar-height); +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic +)::before { + content: ''; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 100%; + height: 100%; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic + ):hover::before { + background-color: var(--editor-toolbar-hover-fg-color); +} + +.highlightButton:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic + )::before { + -webkit-mask-image: var(--editor-toolbar-highlight-image); + mask-image: var(--editor-toolbar-highlight-image); +} + +.commentButton:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic + )::before { + -webkit-mask-image: var(--comment-edit-button-icon); + mask-image: var(--comment-edit-button-icon); +} + +.deleteButton:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .basic + )::before { + -webkit-mask-image: var(--editor-toolbar-delete-image); + mask-image: var(--editor-toolbar-delete-image); +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + > * { + height: var(--editor-toolbar-height); +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + > :not(.divider) { + border: none; + background-color: transparent; + cursor: pointer; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + > :not(.divider) +):hover { + border-radius: 2px; + background-color: var(--editor-toolbar-hover-bg-color); + color: var(--editor-toolbar-hover-fg-color); + outline: var(--editor-toolbar-hover-outline); + outline-offset: 1px; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + > :not(.divider) + ):hover:active { + outline: none; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + > :not(.divider) +):focus-visible { + border-radius: 2px; + outline: 2px solid var(--editor-toolbar-focus-outline-color); +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText { + --alt-text-add-image: url(images/altText_add.svg); + --alt-text-done-image: url(images/altText_done.svg); + + display: flex; + align-items: center; + justify-content: center; + width: -moz-max-content; + width: max-content; + padding-inline: 8px; + pointer-events: all; + font: menu; + font-weight: 590; + font-size: 12px; + color: var(--editor-toolbar-fg-color); +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText +):disabled { + pointer-events: none; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText +)::before { + content: ''; + -webkit-mask-image: var(--alt-text-add-image); + mask-image: var(--alt-text-add-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + width: 12px; + height: 13px; + background-color: var(--editor-toolbar-fg-color); + margin-inline-end: 4px; +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ):hover::before { + background-color: var(--editor-toolbar-hover-fg-color); +} + +.done:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + )::before { + -webkit-mask-image: var(--alt-text-done-image); + mask-image: var(--alt-text-done-image); +} + +.new:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + )::before { + width: 16px; + height: 16px; + -webkit-mask-image: var(--new-alt-text-warning-image); + mask-image: var(--new-alt-text-warning-image); + background-color: var(--alt-text-warning-color); + -webkit-mask-size: cover; + mask-size: cover; +} + +.new:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ):hover::before { + background-color: var(--alt-text-hover-warning-color); +} + +.new.done:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + )::before { + -webkit-mask-image: var(--alt-text-done-image); + mask-image: var(--alt-text-done-image); + background-color: var(--alt-text-done-color); +} + +.new.done:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ):hover::before { + background-color: var(--alt-text-hover-done-color); +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip { + display: none; + word-wrap: anywhere; +} + +.show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip +) { + --csstools-light-dark-toggle--111: var(--csstools-color-scheme--light) #1c1b22; + --alt-text-tooltip-bg: var(--csstools-light-dark-toggle--111, #f0f0f4); + --csstools-light-dark-toggle--112: var(--csstools-color-scheme--light) #fbfbfe; + --alt-text-tooltip-fg: var(--csstools-light-dark-toggle--112, #15141a); + --alt-text-tooltip-border: #8f8f9d; + --csstools-light-dark-toggle--113: var(--csstools-color-scheme--light) #15141a; + --alt-text-tooltip-shadow: 0 2px 6px 0 + var(--csstools-light-dark-toggle--113, rgb(58 57 68 / 0.2)); +} + +@supports (color: light-dark(red, red)) { + .show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip + ) { + --alt-text-tooltip-bg: light-dark(#f0f0f4, #1c1b22); + --alt-text-tooltip-fg: light-dark(#15141a, #fbfbfe); + } +} + +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip + ) { + --alt-text-tooltip-shadow: 0 2px 6px 0 + light-dark(rgb(58 57 68 / 0.2), #15141a); + } +} + +@supports not (color: light-dark(tan, tan)) { + .show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip + ) + * { + --csstools-light-dark-toggle--111: var(--csstools-color-scheme--light) + #1c1b22; + --alt-text-tooltip-bg: var(--csstools-light-dark-toggle--111, #f0f0f4); + --csstools-light-dark-toggle--112: var(--csstools-color-scheme--light) + #fbfbfe; + --alt-text-tooltip-fg: var(--csstools-light-dark-toggle--112, #15141a); + --csstools-light-dark-toggle--113: var(--csstools-color-scheme--light) + #15141a; + --alt-text-tooltip-shadow: 0 2px 6px 0 + var(--csstools-light-dark-toggle--113, rgb(58 57 68 / 0.2)); + } +} + +@media screen and (forced-colors: active) { + .show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip + ) { + --alt-text-tooltip-bg: Canvas; + --alt-text-tooltip-fg: CanvasText; + --alt-text-tooltip-border: CanvasText; + --alt-text-tooltip-shadow: none; + } +} + +.show:is( + :is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .altText + ) + .tooltip +) { + display: inline-flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: absolute; + top: calc(100% + 2px); + inset-inline-start: 0; + padding-block: 2px 3px; + padding-inline: 3px; + max-width: 300px; + width: -moz-max-content; + width: max-content; + height: auto; + font-size: 12px; + + border: 0.5px solid var(--alt-text-tooltip-border); + background: var(--alt-text-tooltip-bg); + box-shadow: var(--alt-text-tooltip-shadow); + color: var(--alt-text-tooltip-fg); + + pointer-events: none; +} + +:is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .comment { + width: var(--editor-toolbar-height); +} + +:is( + :is( + :is( + :is( + .annotationEditorLayer + :is( + .freeTextEditor, + .inkEditor, + .stampEditor, + .highlightEditor, + .signatureEditor + ), + .textLayer + ) + .editToolbar + ) + .buttons + ) + .comment +)::before { + content: ''; + -webkit-mask-image: var(--comment-edit-button-icon); + mask-image: var(--comment-edit-button-icon); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 100%; + height: 100%; +} + +.annotationEditorLayer .freeTextEditor { + padding: calc(var(--freetext-padding) * var(--total-scale-factor)); + width: auto; + height: auto; + touch-action: none; +} + +.annotationEditorLayer .freeTextEditor .internal { + background: transparent; + border: none; + inset: 0; + overflow: visible; + white-space: nowrap; + font: 10px sans-serif; + line-height: var(--freetext-line-height); + text-align: start; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.annotationEditorLayer .freeTextEditor .overlay { + position: absolute; + display: none; + background: transparent; + inset: 0; + width: 100%; + height: 100%; +} + +.annotationEditorLayer freeTextEditor .overlay.enabled { + display: block; +} + +.annotationEditorLayer .freeTextEditor .internal:empty::before { + content: attr(default-content); + color: gray; +} + +.annotationEditorLayer .freeTextEditor .internal:focus { + outline: none; + -webkit-user-select: auto; + -moz-user-select: auto; + user-select: auto; +} + +.annotationEditorLayer .inkEditor { + width: 100%; + height: 100%; +} + +.annotationEditorLayer .inkEditor.editing { + cursor: inherit; +} + +.annotationEditorLayer .inkEditor .inkEditorCanvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + touch-action: none; +} + +.annotationEditorLayer .stampEditor { + width: auto; + height: auto; +} + +:is(.annotationEditorLayer .stampEditor) canvas { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + top: 0; + left: 0; +} + +:is(.annotationEditorLayer .stampEditor) .noAltTextBadge { + --csstools-light-dark-toggle--114: var(--csstools-color-scheme--light) #52525e; + --no-alt-text-badge-border-color: var( + --csstools-light-dark-toggle--114, + #f0f0f4 + ); + --csstools-light-dark-toggle--115: var(--csstools-color-scheme--light) #fbfbfe; + --no-alt-text-badge-bg-color: var(--csstools-light-dark-toggle--115, #cfcfd8); + --csstools-light-dark-toggle--116: var(--csstools-color-scheme--light) #15141a; + --no-alt-text-badge-fg-color: var(--csstools-light-dark-toggle--116, #5b5b66); +} + +@supports (color: light-dark(red, red)) { + :is(.annotationEditorLayer .stampEditor) .noAltTextBadge { + --no-alt-text-badge-border-color: light-dark(#f0f0f4, #52525e); + --no-alt-text-badge-bg-color: light-dark(#cfcfd8, #fbfbfe); + --no-alt-text-badge-fg-color: light-dark(#5b5b66, #15141a); + } +} + +@supports not (color: light-dark(tan, tan)) { + :is(:is(.annotationEditorLayer .stampEditor) .noAltTextBadge) * { + --csstools-light-dark-toggle--114: var(--csstools-color-scheme--light) + #52525e; + --no-alt-text-badge-border-color: var( + --csstools-light-dark-toggle--114, + #f0f0f4 + ); + --csstools-light-dark-toggle--115: var(--csstools-color-scheme--light) + #fbfbfe; + --no-alt-text-badge-bg-color: var( + --csstools-light-dark-toggle--115, + #cfcfd8 + ); + --csstools-light-dark-toggle--116: var(--csstools-color-scheme--light) + #15141a; + --no-alt-text-badge-fg-color: var( + --csstools-light-dark-toggle--116, + #5b5b66 + ); + } +} + +@media screen and (forced-colors: active) { + :is(.annotationEditorLayer .stampEditor) .noAltTextBadge { + --no-alt-text-badge-border-color: ButtonText; + --no-alt-text-badge-bg-color: ButtonFace; + --no-alt-text-badge-fg-color: ButtonText; + } +} + +:is(.annotationEditorLayer .stampEditor) .noAltTextBadge { + position: absolute; + inset-inline-end: 5px; + inset-block-end: 5px; + display: inline-flex; + width: 32px; + height: 32px; + padding: 3px; + justify-content: center; + align-items: center; + pointer-events: none; + z-index: 1; + + border-radius: 2px; + border: 1px solid var(--no-alt-text-badge-border-color); + background: var(--no-alt-text-badge-bg-color); +} + +:is(:is(.annotationEditorLayer .stampEditor) .noAltTextBadge)::before { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + -webkit-mask-image: var(--new-alt-text-warning-image); + mask-image: var(--new-alt-text-warning-image); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--no-alt-text-badge-fg-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers { + position: absolute; + inset: 0; + z-index: 1; +} + +.hidden:is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers +) { + display: none; +} + +:is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer { + width: var(--resizer-size); + height: var(--resizer-size); + background: content-box var(--resizer-bg-color); + border: var(--focus-outline-around); + border-radius: 2px; + position: absolute; +} + +.topLeft:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + top: var(--resizer-shift); + left: var(--resizer-shift); +} + +.topMiddle:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + top: var(--resizer-shift); + left: calc(50% + var(--resizer-shift)); +} + +.topRight:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + top: var(--resizer-shift); + right: var(--resizer-shift); +} + +.middleRight:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + top: calc(50% + var(--resizer-shift)); + right: var(--resizer-shift); +} + +.bottomRight:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + bottom: var(--resizer-shift); + right: var(--resizer-shift); +} + +.bottomMiddle:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + bottom: var(--resizer-shift); + left: calc(50% + var(--resizer-shift)); +} + +.bottomLeft:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + bottom: var(--resizer-shift); + left: var(--resizer-shift); +} + +.middleLeft:is( + :is( + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) + ) + > .resizers + ) + > .resizer +) { + top: calc(50% + var(--resizer-shift)); + left: var(--resizer-shift); +} + +.topLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +), +.bottomRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +) { + cursor: nwse-resize; +} + +.topMiddle:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +), +.bottomMiddle:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +) { + cursor: ns-resize; +} + +.topRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +), +.bottomLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +) { + cursor: nesw-resize; +} + +.middleRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +), +.middleLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']) + ) + > .resizers + > .resizer +) { + cursor: ew-resize; +} + +.topLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +), +.bottomRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +) { + cursor: nesw-resize; +} + +.topMiddle:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +), +.bottomMiddle:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +) { + cursor: ew-resize; +} + +.topRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +), +.bottomLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +) { + cursor: nwse-resize; +} + +.middleRight:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +), +.middleLeft:is( + :is( + .annotationEditorLayer[data-main-rotation='0'] + :is([data-editor-rotation='90'], [data-editor-rotation='270']), + .annotationEditorLayer[data-main-rotation='90'] + :is([data-editor-rotation='0'], [data-editor-rotation='180']), + .annotationEditorLayer[data-main-rotation='180'] + :is([data-editor-rotation='270'], [data-editor-rotation='90']), + .annotationEditorLayer[data-main-rotation='270'] + :is([data-editor-rotation='180'], [data-editor-rotation='0']) + ) + > .resizers + > .resizer +) { + cursor: ns-resize; +} + +:is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='90'], + [data-main-rotation='90'] [data-editor-rotation='0'], + [data-main-rotation='180'] [data-editor-rotation='270'], + [data-main-rotation='270'] [data-editor-rotation='180'] + ) + ) + .editToolbar { + rotate: 270deg; +} + +[dir='ltr'] + :is( + :is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='90'], + [data-main-rotation='90'] [data-editor-rotation='0'], + [data-main-rotation='180'] [data-editor-rotation='270'], + [data-main-rotation='270'] [data-editor-rotation='180'] + ) + ) + .editToolbar + ) { + inset-inline-end: calc(0px - var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +[dir='rtl'] + :is( + :is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='90'], + [data-main-rotation='90'] [data-editor-rotation='0'], + [data-main-rotation='180'] [data-editor-rotation='270'], + [data-main-rotation='270'] [data-editor-rotation='180'] + ) + ) + .editToolbar + ) { + inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +:is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='180'], + [data-main-rotation='90'] [data-editor-rotation='90'], + [data-main-rotation='180'] [data-editor-rotation='0'], + [data-main-rotation='270'] [data-editor-rotation='270'] + ) + ) + .editToolbar { + rotate: 180deg; + inset-inline-end: 100%; + inset-block-start: calc(0px - var(--editor-toolbar-vert-offset)); +} + +:is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='270'], + [data-main-rotation='90'] [data-editor-rotation='180'], + [data-main-rotation='180'] [data-editor-rotation='90'], + [data-main-rotation='270'] [data-editor-rotation='0'] + ) + ) + .editToolbar { + rotate: 90deg; +} + +[dir='ltr'] + :is( + :is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='270'], + [data-main-rotation='90'] [data-editor-rotation='180'], + [data-main-rotation='180'] [data-editor-rotation='90'], + [data-main-rotation='270'] [data-editor-rotation='0'] + ) + ) + .editToolbar + ) { + inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset)); + inset-block-start: 100%; +} + +[dir='rtl'] + :is( + :is( + .annotationEditorLayer + :is( + [data-main-rotation='0'] [data-editor-rotation='270'], + [data-main-rotation='90'] [data-editor-rotation='180'], + [data-main-rotation='180'] [data-editor-rotation='90'], + [data-main-rotation='270'] [data-editor-rotation='0'] + ) + ) + .editToolbar + ) { + inset-inline-start: calc(0px - var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +.dialog.altText::backdrop { + -webkit-mask: url(#alttext-manager-mask); + mask: url(#alttext-manager-mask); +} + +.dialog.altText.positioned { + margin: 0; +} + +.dialog.altText #altTextContainer { + width: 300px; + height: -moz-fit-content; + height: fit-content; + display: inline-flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; +} + +:is(.dialog.altText #altTextContainer) #overallDescription { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; +} + +:is(:is(.dialog.altText #altTextContainer) #overallDescription) span { + align-self: stretch; +} + +:is(:is(.dialog.altText #altTextContainer) #overallDescription) .title { + font-size: 13px; + font-style: normal; + font-weight: 590; +} + +:is(.dialog.altText #altTextContainer) #addDescription { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 8px; +} + +:is(:is(.dialog.altText #altTextContainer) #addDescription) .descriptionArea { + flex: 1; + padding-inline: 24px 10px; +} + +:is( + :is(:is(.dialog.altText #altTextContainer) #addDescription) .descriptionArea + ) + textarea { + width: 100%; + min-height: 75px; +} + +:is(.dialog.altText #altTextContainer) #buttons { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 8px; + align-self: stretch; +} + +.dialog.newAltText { + --new-alt-text-ai-disclaimer-icon: url(images/altText_disclaimer.svg); + --new-alt-text-spinner-icon: url(images/altText_spinner.svg); + --csstools-light-dark-toggle--117: var(--csstools-color-scheme--light) #2b2a33; + --preview-image-bg-color: var(--csstools-light-dark-toggle--117, #f0f0f4); + --preview-image-border: none; +} + +@supports (color: light-dark(red, red)) { + .dialog.newAltText { + --preview-image-bg-color: light-dark(#f0f0f4, #2b2a33); + } +} + +@supports not (color: light-dark(tan, tan)) { + .dialog.newAltText * { + --csstools-light-dark-toggle--117: var(--csstools-color-scheme--light) + #2b2a33; + --preview-image-bg-color: var(--csstools-light-dark-toggle--117, #f0f0f4); + } +} + +@media screen and (forced-colors: active) { + .dialog.newAltText { + --preview-image-bg-color: ButtonFace; + --preview-image-border: 1px solid ButtonText; + } +} + +.dialog.newAltText { + width: 80%; + max-width: 570px; + min-width: 300px; + padding: 0; +} + +.dialog.newAltText.noAi #newAltTextDisclaimer, +.dialog.newAltText.noAi #newAltTextCreateAutomatically { + display: none !important; +} + +.dialog.newAltText.aiInstalling #newAltTextCreateAutomatically { + display: none !important; +} + +.dialog.newAltText.aiInstalling #newAltTextDownloadModel { + display: flex !important; +} + +.dialog.newAltText.error #newAltTextNotNow { + display: none !important; +} + +.dialog.newAltText.error #newAltTextCancel { + display: inline-block !important; +} + +.dialog.newAltText:not(.error) #newAltTextError { + display: none !important; +} + +.dialog.newAltText #newAltTextContainer { + display: flex; + width: auto; + padding: 16px; + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + gap: 12px; + flex: 0 1 auto; + line-height: normal; +} + +:is(.dialog.newAltText #newAltTextContainer) #mainContent { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 12px; + align-self: stretch; + flex: 1 1 auto; +} + +:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionAndSettings { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; + flex: 1 0 0; + align-self: stretch; +} + +:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; + flex: 1 1 auto; +} + +:is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer { + width: 100%; + height: 70px; + position: relative; +} + +:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + textarea { + width: 100%; + height: 100%; + padding: 8px; +} + +:is( + :is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + textarea +)::-moz-placeholder { + color: var(--text-secondary-color); +} + +:is( + :is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + textarea +)::placeholder { + color: var(--text-secondary-color); +} + +:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + .altTextSpinner { + display: none; + position: absolute; + width: 16px; + height: 16px; + inset-inline-start: 8px; + inset-block-start: 8px; + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--text-secondary-color); + pointer-events: none; +} + +.loading:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + textarea::-moz-placeholder { + color: transparent; +} + +.loading:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + textarea::placeholder { + color: transparent; +} + +.loading:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescriptionContainer + ) + .altTextSpinner { + display: inline-block; + -webkit-mask-image: var(--new-alt-text-spinner-icon); + mask-image: var(--new-alt-text-spinner-icon); +} + +:is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDescription { + font-size: 11px; +} + +:is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDisclaimer { + display: flex; + flex-direction: row; + align-items: flex-start; + gap: 4px; + font-size: 11px; +} + +:is( + :is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #descriptionInstruction + ) + #newAltTextDisclaimer +)::before { + content: ''; + display: inline-block; + width: 17px; + height: 16px; + -webkit-mask-image: var(--new-alt-text-ai-disclaimer-icon); + mask-image: var(--new-alt-text-ai-disclaimer-icon); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--text-secondary-color); + flex: 1 0 auto; +} + +:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #newAltTextDownloadModel { + display: flex; + align-items: center; + gap: 4px; + align-self: stretch; +} + +:is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #newAltTextDownloadModel +)::before { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + -webkit-mask-image: var(--new-alt-text-spinner-icon); + mask-image: var(--new-alt-text-spinner-icon); + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--text-secondary-color); +} + +:is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #newAltTextImagePreview { + width: 180px; + aspect-ratio: 1; + display: flex; + justify-content: center; + align-items: center; + flex: 0 0 auto; + background-color: var(--preview-image-bg-color); + border: var(--preview-image-border); +} + +:is( + :is(:is(.dialog.newAltText #newAltTextContainer) #mainContent) + #newAltTextImagePreview + ) + > canvas { + max-width: 100%; + max-height: 100%; +} + +.colorPicker { + --csstools-light-dark-toggle--118: var(--csstools-color-scheme--light) #80ebff; + --hover-outline-color: var(--csstools-light-dark-toggle--118, #0250bb); + --csstools-light-dark-toggle--119: var(--csstools-color-scheme--light) #aaf2ff; + --selected-outline-color: var(--csstools-light-dark-toggle--119, #0060df); + --csstools-light-dark-toggle--120: var(--csstools-color-scheme--light) #52525e; + --swatch-border-color: var(--csstools-light-dark-toggle--120, #cfcfd8); +} + +@supports (color: light-dark(red, red)) { + .colorPicker { + --hover-outline-color: light-dark(#0250bb, #80ebff); + --selected-outline-color: light-dark(#0060df, #aaf2ff); + --swatch-border-color: light-dark(#cfcfd8, #52525e); + } +} + +@supports not (color: light-dark(tan, tan)) { + .colorPicker * { + --csstools-light-dark-toggle--118: var(--csstools-color-scheme--light) + #80ebff; + --hover-outline-color: var(--csstools-light-dark-toggle--118, #0250bb); + --csstools-light-dark-toggle--119: var(--csstools-color-scheme--light) + #aaf2ff; + --selected-outline-color: var(--csstools-light-dark-toggle--119, #0060df); + --csstools-light-dark-toggle--120: var(--csstools-color-scheme--light) + #52525e; + --swatch-border-color: var(--csstools-light-dark-toggle--120, #cfcfd8); + } +} + +@media screen and (forced-colors: active) { + .colorPicker { + --hover-outline-color: Highlight; + --selected-outline-color: var(--hover-outline-color); + --swatch-border-color: ButtonText; + } +} + +.colorPicker .swatch { + width: 16px; + height: 16px; + border: 1px solid var(--swatch-border-color); + border-radius: 100%; + outline-offset: 2px; + box-sizing: border-box; + forced-color-adjust: none; +} + +.colorPicker button:is(:hover, .selected) > .swatch { + border: none; +} + +.basicColorPicker { + width: 28px; +} + +.basicColorPicker::-moz-color-swatch { + border-radius: 100%; +} + +.basicColorPicker::-webkit-color-swatch { + border-radius: 100%; +} + +.annotationEditorLayer[data-main-rotation='0'] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 0deg; +} + +.annotationEditorLayer[data-main-rotation='90'] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 270deg; +} + +.annotationEditorLayer[data-main-rotation='180'] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 180deg; +} + +.annotationEditorLayer[data-main-rotation='270'] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 90deg; +} + +.annotationEditorLayer .highlightEditor { + position: absolute; + background: transparent; + z-index: 1; + cursor: auto; + max-width: 100%; + max-height: 100%; + border: none; + outline: none; + pointer-events: none; + transform-origin: 0 0; +} + +:is(.annotationEditorLayer .highlightEditor):not(.free) { + transform: none; +} + +:is(.annotationEditorLayer .highlightEditor) .internal { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: auto; +} + +.disabled:is(.annotationEditorLayer .highlightEditor) .internal { + pointer-events: none; +} + +.selectedEditor:is(.annotationEditorLayer .highlightEditor) .internal { + cursor: pointer; +} + +:is(.annotationEditorLayer .highlightEditor) .editToolbar { + --editor-toolbar-colorpicker-arrow-image: url(images/toolbarButton-menuArrow.svg); + + transform-origin: center !important; +} + +:is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker { + position: relative; + width: auto; + display: flex; + justify-content: center; + align-items: center; + gap: 4px; + padding: 4px; +} + +:is( + :is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker +)::after { + content: ''; + -webkit-mask-image: var(--editor-toolbar-colorpicker-arrow-image); + mask-image: var(--editor-toolbar-colorpicker-arrow-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 12px; + height: 12px; +} + +:is( + :is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker + ):hover::after { + background-color: var(--editor-toolbar-hover-fg-color); +} + +:is( + :is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker +):has(.dropdown:not(.hidden)) { + background-color: var(--editor-toolbar-hover-bg-color); +} + +:is( + :is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker + ):has(.dropdown:not(.hidden))::after { + scale: -1; +} + +:is( + :is(:is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) .buttons) + .colorPicker + ) + .dropdown { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 11px; + padding-block: 8px; + border-radius: 6px; + background-color: var(--editor-toolbar-bg-color); + border: 1px solid var(--editor-toolbar-border-color); + box-shadow: var(--editor-toolbar-shadow); + inset-block-start: calc(100% + 4px); + width: calc(100% + 2 * var(--editor-toolbar-padding)); +} + +:is( + :is( + :is( + :is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) + .buttons + ) + .colorPicker + ) + .dropdown + ) + button { + width: 100%; + height: auto; + border: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + background: none; +} + +:is( + :is( + :is( + :is( + :is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) + .buttons + ) + .colorPicker + ) + .dropdown + ) + button +):is(:active, :focus-visible) { + outline: none; +} + +:is( + :is( + :is( + :is( + :is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) + .buttons + ) + .colorPicker + ) + .dropdown + ) + button + ) + > .swatch { + outline-offset: 2px; +} + +[aria-selected='true']:is( + :is( + :is( + :is( + :is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) + .buttons + ) + .colorPicker + ) + .dropdown + ) + button + ) + > .swatch { + outline: 2px solid var(--selected-outline-color); +} + +:is( + :is( + :is( + :is( + :is(:is(.annotationEditorLayer .highlightEditor) .editToolbar) + .buttons + ) + .colorPicker + ) + .dropdown + ) + button + ):is(:hover, :active, :focus-visible) + > .swatch { + outline: 2px solid var(--hover-outline-color); +} + +.editorParamsToolbar:has(#highlightParamsToolbarContainer) { + padding: unset; +} + +#highlightParamsToolbarContainer { + gap: 16px; + padding-inline: 10px; + padding-block-end: 12px; +} + +#highlightParamsToolbarContainer .colorPicker { + display: flex; + flex-direction: column; + gap: 8px; +} + +:is(#highlightParamsToolbarContainer .colorPicker) .dropdown { + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + height: auto; +} + +:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button { + width: auto; + height: auto; + border: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + background: none; + flex: 0 0 auto; + padding: 0; +} + +:is(:is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button) + .swatch { + width: 24px; + height: 24px; +} + +:is( + :is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button +):is(:active, :focus-visible) { + outline: none; +} + +[aria-selected='true']:is( + :is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button + ) + > .swatch { + outline: 2px solid var(--selected-outline-color); +} + +:is( + :is(:is(#highlightParamsToolbarContainer .colorPicker) .dropdown) button + ):is(:hover, :active, :focus-visible) + > .swatch { + outline: 2px solid var(--hover-outline-color); +} + +#highlightParamsToolbarContainer #editorHighlightThickness { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + align-self: stretch; +} + +:is(#highlightParamsToolbarContainer #editorHighlightThickness) + .editorParamsLabel { + height: auto; + align-self: stretch; +} + +:is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker { + display: flex; + justify-content: space-between; + align-items: center; + align-self: stretch; + + --csstools-light-dark-toggle--121: var(--csstools-color-scheme--light) #80808e; + + --example-color: var(--csstools-light-dark-toggle--121, #bfbfc9); +} + +@supports (color: light-dark(red, red)) { + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker { + --example-color: light-dark(#bfbfc9, #80808e); + } +} + +@supports not (color: light-dark(tan, tan)) { + :is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker + ) + * { + --csstools-light-dark-toggle--121: var(--csstools-color-scheme--light) + #80808e; + + --example-color: var(--csstools-light-dark-toggle--121, #bfbfc9); + } +} + +@media screen and (forced-colors: active) { + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker { + --example-color: CanvasText; + } +} + +:is( + :is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker + ) + > .editorParamsSlider[disabled] +) { + opacity: 0.4; +} + +:is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker +)::before, +:is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker +)::after { + content: ''; + width: 8px; + aspect-ratio: 1; + display: block; + border-radius: 100%; + background-color: var(--example-color); +} + +:is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker +)::after { + width: 24px; +} + +:is( + :is(#highlightParamsToolbarContainer #editorHighlightThickness) + .thicknessPicker + ) + .editorParamsSlider { + width: unset; + height: 14px; +} + +#highlightParamsToolbarContainer #editorHighlightVisibility { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; +} + +:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider { + --csstools-light-dark-toggle--122: var(--csstools-color-scheme--light) #8f8f9d; + --divider-color: var(--csstools-light-dark-toggle--122, #d7d7db); +} + +@supports (color: light-dark(red, red)) { + :is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider { + --divider-color: light-dark(#d7d7db, #8f8f9d); + } +} + +@supports not (color: light-dark(tan, tan)) { + :is(:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider) + * { + --csstools-light-dark-toggle--122: var(--csstools-color-scheme--light) + #8f8f9d; + --divider-color: var(--csstools-light-dark-toggle--122, #d7d7db); + } +} + +@media screen and (forced-colors: active) { + :is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider { + --divider-color: CanvasText; + } +} + +:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .divider { + margin-block: 4px; + width: 100%; + height: 1px; + background-color: var(--divider-color); +} + +:is(#highlightParamsToolbarContainer #editorHighlightVisibility) .toggler { + display: flex; + justify-content: space-between; + align-items: center; + align-self: stretch; +} + +#altTextSettingsDialog { + padding: 16px; +} + +#altTextSettingsDialog #altTextSettingsContainer { + display: flex; + width: 573px; + flex-direction: column; + gap: 16px; +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) .mainContainer { + gap: 16px; +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) .description { + color: var(--text-secondary-color); +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings { + display: flex; + flex-direction: column; + gap: 12px; +} + +:is(:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings) + button { + width: -moz-fit-content; + width: fit-content; +} + +.download:is( + :is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings + ) + #deleteModelButton { + display: none; +} + +:is(:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings):not( + .download + ) + #downloadModelButton { + display: none; +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) #automaticAltText, +:is(#altTextSettingsDialog #altTextSettingsContainer) #altTextEditor { + display: flex; + flex-direction: column; + gap: 8px; +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) #createModelDescription, +:is(#altTextSettingsDialog #altTextSettingsContainer) #aiModelSettings, +:is(#altTextSettingsDialog #altTextSettingsContainer) + #showAltTextDialogDescription { + padding-inline-start: 40px; +} + +:is(#altTextSettingsDialog #altTextSettingsContainer) #automaticSettings { + display: flex; + flex-direction: column; + gap: 16px; +} + +.sidebar { + --csstools-light-dark-toggle--123: var(--csstools-color-scheme--light) #23222b; + --sidebar-bg-color: var(--csstools-light-dark-toggle--123, #fff); + --csstools-light-dark-toggle--124: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.1); + --sidebar-border-color: var( + --csstools-light-dark-toggle--124, + rgb(21 20 26 / 0.1) + ); + --csstools-light-dark-toggle--125: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--126: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --sidebar-box-shadow: + 0 0.25px 0.75px var(--csstools-light-dark-toggle--125, rgb(0 0 0 / 0.05)), + 0 2px 6px 0 var(--csstools-light-dark-toggle--126, rgb(0 0 0 / 0.1)); + --sidebar-border-radius: 8px; + --sidebar-padding: 5px; + --sidebar-min-width: 180px; + --sidebar-max-width: 632px; + --sidebar-width: 239px; + --resizer-width: 4px; + --csstools-light-dark-toggle--127: var(--csstools-color-scheme--light) #00cadb; + --resizer-hover-bg-color: var(--csstools-light-dark-toggle--127, #0062fa); +} + +@supports (color: light-dark(red, red)) { + .sidebar { + --sidebar-bg-color: light-dark(#fff, #23222b); + } +} + +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + .sidebar { + --sidebar-border-color: light-dark( + rgb(21 20 26 / 0.1), + rgb(251 251 254 / 0.1) + ); + --sidebar-box-shadow: + 0 0.25px 0.75px light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)), + 0 2px 6px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4)); + } +} + +@supports (color: light-dark(red, red)) { + .sidebar { + --resizer-hover-bg-color: light-dark(#0062fa, #00cadb); + } +} + +@supports not (color: light-dark(tan, tan)) { + .sidebar * { + --csstools-light-dark-toggle--123: var(--csstools-color-scheme--light) + #23222b; + --sidebar-bg-color: var(--csstools-light-dark-toggle--123, #fff); + --csstools-light-dark-toggle--124: var(--csstools-color-scheme--light) + rgb(251 251 254 / 0.1); + --sidebar-border-color: var( + --csstools-light-dark-toggle--124, + rgb(21 20 26 / 0.1) + ); + --csstools-light-dark-toggle--125: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.2); + --csstools-light-dark-toggle--126: var(--csstools-color-scheme--light) + rgb(0 0 0 / 0.4); + --sidebar-box-shadow: + 0 0.25px 0.75px var(--csstools-light-dark-toggle--125, rgb(0 0 0 / 0.05)), + 0 2px 6px 0 var(--csstools-light-dark-toggle--126, rgb(0 0 0 / 0.1)); + --csstools-light-dark-toggle--127: var(--csstools-color-scheme--light) + #00cadb; + --resizer-hover-bg-color: var(--csstools-light-dark-toggle--127, #0062fa); + } +} + +@media screen and (forced-colors: active) { + .sidebar { + --sidebar-bg-color: Canvas; + --sidebar-border-color: CanvasText; + --sidebar-box-shadow: none; + --resizer-hover-bg-color: CanvasText; + } +} + +.sidebar { + border-radius: var(--sidebar-border-radius); + box-shadow: var(--sidebar-box-shadow); + border: 1px solid var(--sidebar-border-color); + background-color: var(--sidebar-bg-color); + inset-block-start: calc(100% + var(--doorhanger-height) - 2px); + padding-block: var(--sidebar-padding); + width: var(--sidebar-width); + min-width: var(--sidebar-min-width); + max-width: var(--sidebar-max-width); +} + +.sidebar .sidebarResizer { + width: var(--resizer-width); + background-color: transparent; + forced-color-adjust: none; + cursor: ew-resize; + position: absolute; + inset-block: calc(var(--sidebar-padding) + var(--sidebar-border-radius)); + inset-inline-start: calc(0px - var(--resizer-width) / 2); + transition: background-color 0.5s ease-in-out; + box-sizing: border-box; + border: 1px solid transparent; + border-block-width: 0; + background-clip: content-box; +} + +:is(.sidebar .sidebarResizer):hover { + background-color: var(--resizer-hover-bg-color); +} + +.sidebar.resizing { + cursor: ew-resize; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.sidebar.resizing :not(.sidebarResizer) { + pointer-events: none; +} + +:root { + --csstools-color-scheme--light: initial; + color-scheme: light dark; + + --viewer-container-height: 0; + --pdfViewer-padding-bottom: 0; + --page-margin: 1px auto -8px; + --page-border: 9px solid transparent; + --spreadHorizontalWrapped-margin-LR: -3.5px; + --loading-icon-delay: 400ms; + --csstools-light-dark-toggle--128: var(--csstools-color-scheme--light) #0df; + --focus-ring-color: var(--csstools-light-dark-toggle--128, #0060df); + --focus-ring-outline: 2px solid var(--focus-ring-color); +} + +@supports (color: light-dark(red, red)) { + :root { + --focus-ring-color: light-dark(#0060df, #0df); + } +} + +@supports not (color: light-dark(tan, tan)) { + :root * { + --csstools-light-dark-toggle--128: var(--csstools-color-scheme--light) #0df; + --focus-ring-color: var(--csstools-light-dark-toggle--128, #0060df); + } +} + +@media (prefers-color-scheme: dark) { + :root { + --csstools-color-scheme--light: light; + } +} + +@media screen and (forced-colors: active) { + :root { + --pdfViewer-padding-bottom: 9px; + --page-margin: 8px auto -1px; + --page-border: 1px solid CanvasText; + --spreadHorizontalWrapped-margin-LR: 3.5px; + --focus-ring-color: CanvasText; + } +} + +[data-main-rotation='90'] { + transform: rotate(90deg) translateY(-100%); +} +[data-main-rotation='180'] { + transform: rotate(180deg) translate(-100%, -100%); +} +[data-main-rotation='270'] { + transform: rotate(270deg) translateX(-100%); } #hiddenCopyElement, -.hiddenCanvasElement{ - position:absolute; - top:0; - left:0; - width:0; - height:0; - display:none; +.hiddenCanvasElement { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + display: none; } -.pdfViewer{ - --scale-factor:1; - --page-bg-color:unset; +.pdfViewer { + --scale-factor: 1; + --page-bg-color: unset; - padding-bottom:var(--pdfViewer-padding-bottom); + padding-bottom: var(--pdfViewer-padding-bottom); - --hcm-highlight-filter:none; - --hcm-highlight-selected-filter:none; + --hcm-highlight-filter: none; + --hcm-highlight-selected-filter: none; } -@media screen and (forced-colors: active){ - -.pdfViewer{ - --hcm-highlight-filter:invert(100%); -} +@media screen and (forced-colors: active) { + .pdfViewer { + --hcm-highlight-filter: invert(100%); } - -.pdfViewer.copyAll{ - cursor:wait; - } - -.pdfViewer .canvasWrapper{ - overflow:hidden; - width:100%; - height:100%; - } - -:is(.pdfViewer .canvasWrapper) canvas{ - position:absolute; - top:0; - left:0; - margin:0; - display:block; - width:100%; - height:100%; - contain:content; - } - -:is(:is(.pdfViewer .canvasWrapper) canvas) .structTree{ - contain:strict; - } - -.detailView:is(:is(.pdfViewer .canvasWrapper) canvas){ - image-rendering:pixelated; - } - -.pdfViewer .page{ - --user-unit:1; - --total-scale-factor:calc(var(--scale-factor) * var(--user-unit)); - --scale-round-x:1px; - --scale-round-y:1px; - - direction:ltr; - width:816px; - height:1056px; - margin:var(--page-margin); - position:relative; - overflow:visible; - border:var(--page-border); - background-clip:content-box; - background-color:var(--page-bg-color, rgb(255 255 255)); } -.pdfViewer .dummyPage{ - position:relative; - width:0; - height:var(--viewer-container-height); +.pdfViewer.copyAll { + cursor: wait; } -.pdfViewer.noUserSelect{ - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; +.pdfViewer .canvasWrapper { + overflow: hidden; + width: 100%; + height: 100%; } -.pdfViewer.removePageBorders .page{ - margin:0 auto 10px; - border:none; +:is(.pdfViewer .canvasWrapper) canvas { + position: absolute; + top: 0; + left: 0; + margin: 0; + display: block; + width: 100%; + height: 100%; + contain: content; +} + +:is(:is(.pdfViewer .canvasWrapper) canvas) .structTree { + contain: strict; +} + +.detailView:is(:is(.pdfViewer .canvasWrapper) canvas) { + image-rendering: pixelated; +} + +.pdfViewer .page { + --user-unit: 1; + --total-scale-factor: calc(var(--scale-factor) * var(--user-unit)); + --scale-round-x: 1px; + --scale-round-y: 1px; + + direction: ltr; + width: 816px; + height: 1056px; + margin: var(--page-margin); + position: relative; + overflow: visible; + border: var(--page-border); + background-clip: content-box; + background-color: var(--page-bg-color, rgb(255 255 255)); +} + +.pdfViewer .dummyPage { + position: relative; + width: 0; + height: var(--viewer-container-height); +} + +.pdfViewer.noUserSelect { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pdfViewer.removePageBorders .page { + margin: 0 auto 10px; + border: none; } .pdfViewer:is(.scrollHorizontal, .scrollWrapped), -.spread{ - margin-inline:3.5px; - text-align:center; +.spread { + margin-inline: 3.5px; + text-align: center; } .pdfViewer.scrollHorizontal, -.spread{ - white-space:nowrap; +.spread { + white-space: nowrap; } .pdfViewer.removePageBorders, -.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .spread{ - margin-inline:0; +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .spread { + margin-inline: 0; } .spread :is(.page, .dummyPage), -.pdfViewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread){ - display:inline-block; - vertical-align:middle; +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread) { + display: inline-block; + vertical-align: middle; } .spread .page, -.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .page{ - margin-inline:var(--spreadHorizontalWrapped-margin-LR); +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .page { + margin-inline: var(--spreadHorizontalWrapped-margin-LR); } .pdfViewer.removePageBorders .spread .page, -.pdfViewer.removePageBorders:is(.scrollHorizontal, .scrollWrapped) .page{ - margin-inline:5px; +.pdfViewer.removePageBorders:is(.scrollHorizontal, .scrollWrapped) .page { + margin-inline: 5px; } -.pdfViewer .page.loadingIcon::after{ - position:absolute; - top:0; - left:0; - content:""; - width:100%; - height:100%; - background:url("images/loading-icon.gif") center no-repeat; - display:none; - transition-property:display; - transition-delay:var(--loading-icon-delay); - z-index:5; - contain:strict; +.pdfViewer .page.loadingIcon::after { + position: absolute; + top: 0; + left: 0; + content: ''; + width: 100%; + height: 100%; + background: url('images/loading-icon.gif') center no-repeat; + display: none; + transition-property: display; + transition-delay: var(--loading-icon-delay); + z-index: 5; + contain: strict; } -.pdfViewer .page.loading::after{ - display:block; +.pdfViewer .page.loading::after { + display: block; } -.pdfViewer .page:not(.loading)::after{ - transition-property:none; - display:none; +.pdfViewer .page:not(.loading)::after { + transition-property: none; + display: none; } -.pdfPresentationMode .pdfViewer{ - padding-bottom:0; +.pdfPresentationMode .pdfViewer { + padding-bottom: 0; } -.pdfPresentationMode .spread{ - margin:0; +.pdfPresentationMode .spread { + margin: 0; } -.pdfPresentationMode .pdfViewer .page{ - margin:0 auto; - border:2px solid transparent; +.pdfPresentationMode .pdfViewer .page { + margin: 0 auto; + border: 2px solid transparent; } -:root{ - --dir-factor:1; - --inline-start:left; - --inline-end:right; +:root { + --dir-factor: 1; + --inline-start: left; + --inline-end: right; - --sidebar-width:200px; - --sidebar-transition-duration:200ms; - --sidebar-transition-timing-function:ease; + --sidebar-width: 200px; + --sidebar-transition-duration: 200ms; + --sidebar-transition-timing-function: ease; - --toolbar-height:32px; - --toolbar-horizontal-padding:1px; - --toolbar-vertical-padding:2px; - --icon-size:16px; + --toolbar-height: 32px; + --toolbar-horizontal-padding: 1px; + --toolbar-vertical-padding: 2px; + --icon-size: 16px; - --toolbar-icon-opacity:0.7; - --doorhanger-icon-opacity:0.9; - --doorhanger-height:8px; + --toolbar-icon-opacity: 0.7; + --doorhanger-icon-opacity: 0.9; + --doorhanger-height: 8px; - --csstools-light-dark-toggle--0:var(--csstools-color-scheme--light) rgb(249 249 250); + --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) + rgb(249 249 250); - --main-color:var(--csstools-light-dark-toggle--0, rgb(12 12 13)); - --csstools-light-dark-toggle--1:var(--csstools-color-scheme--light) rgb(42 42 46); - --body-bg-color:var(--csstools-light-dark-toggle--1, rgb(212 212 215)); - --csstools-light-dark-toggle--2:var(--csstools-color-scheme--light) rgb(0 96 223); - --progressBar-color:var(--csstools-light-dark-toggle--2, rgb(10 132 255)); - --csstools-light-dark-toggle--3:var(--csstools-color-scheme--light) rgb(40 40 43); - --progressBar-bg-color:var(--csstools-light-dark-toggle--3, rgb(221 221 222)); - --csstools-light-dark-toggle--4:var(--csstools-color-scheme--light) rgb(20 68 133); - --progressBar-blend-color:var(--csstools-light-dark-toggle--4, rgb(116 177 239)); - --csstools-light-dark-toggle--5:var(--csstools-color-scheme--light) rgb(121 121 123); - --scrollbar-color:var(--csstools-light-dark-toggle--5, auto); - --csstools-light-dark-toggle--6:var(--csstools-color-scheme--light) rgb(35 35 39); - --scrollbar-bg-color:var(--csstools-light-dark-toggle--6, auto); - --csstools-light-dark-toggle--7:var(--csstools-color-scheme--light) rgb(255 255 255); - --toolbar-icon-bg-color:var(--csstools-light-dark-toggle--7, rgb(0 0 0)); - --csstools-light-dark-toggle--8:var(--csstools-color-scheme--light) rgb(255 255 255); - --toolbar-icon-hover-bg-color:var(--csstools-light-dark-toggle--8, rgb(0 0 0)); + --main-color: var(--csstools-light-dark-toggle--0, rgb(12 12 13)); + --csstools-light-dark-toggle--1: var(--csstools-color-scheme--light) + rgb(42 42 46); + --body-bg-color: var(--csstools-light-dark-toggle--1, rgb(212 212 215)); + --csstools-light-dark-toggle--2: var(--csstools-color-scheme--light) + rgb(0 96 223); + --progressBar-color: var(--csstools-light-dark-toggle--2, rgb(10 132 255)); + --csstools-light-dark-toggle--3: var(--csstools-color-scheme--light) + rgb(40 40 43); + --progressBar-bg-color: var( + --csstools-light-dark-toggle--3, + rgb(221 221 222) + ); + --csstools-light-dark-toggle--4: var(--csstools-color-scheme--light) + rgb(20 68 133); + --progressBar-blend-color: var( + --csstools-light-dark-toggle--4, + rgb(116 177 239) + ); + --csstools-light-dark-toggle--5: var(--csstools-color-scheme--light) + rgb(121 121 123); + --scrollbar-color: var(--csstools-light-dark-toggle--5, auto); + --csstools-light-dark-toggle--6: var(--csstools-color-scheme--light) + rgb(35 35 39); + --scrollbar-bg-color: var(--csstools-light-dark-toggle--6, auto); + --csstools-light-dark-toggle--7: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toolbar-icon-bg-color: var(--csstools-light-dark-toggle--7, rgb(0 0 0)); + --csstools-light-dark-toggle--8: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toolbar-icon-hover-bg-color: var( + --csstools-light-dark-toggle--8, + rgb(0 0 0) + ); - --csstools-light-dark-toggle--9:var(--csstools-color-scheme--light) rgb(42 42 46 / 0.9); + --csstools-light-dark-toggle--9: var(--csstools-color-scheme--light) + rgb(42 42 46 / 0.9); - --sidebar-narrow-bg-color:var(--csstools-light-dark-toggle--9, rgb(212 212 215 / 0.9)); - --csstools-light-dark-toggle--10:var(--csstools-color-scheme--light) rgb(50 50 52); - --sidebar-toolbar-bg-color:var(--csstools-light-dark-toggle--10, rgb(245 246 247)); - --csstools-light-dark-toggle--11:var(--csstools-color-scheme--light) rgb(56 56 61); - --toolbar-bg-color:var(--csstools-light-dark-toggle--11, rgb(249 249 250)); - --csstools-light-dark-toggle--12:var(--csstools-color-scheme--light) rgb(12 12 13); - --toolbar-border-color:var(--csstools-light-dark-toggle--12, rgb(184 184 184)); - --toolbar-box-shadow:0 1px 0 var(--toolbar-border-color); - --toolbar-border-bottom:none; - --toolbarSidebar-box-shadow:inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25), 0 1px 0 rgb(0 0 0 / 0.15), 0 0 1px rgb(0 0 0 / 0.1); - --toolbarSidebar-border-bottom:none; - --button-hover-color:color-mix(in srgb, currentColor 17%, transparent); - --csstools-light-dark-toggle--13:var(--csstools-color-scheme--light) rgb(255 255 255); - --toggled-btn-color:var(--csstools-light-dark-toggle--13, rgb(0 0 0)); - --toggled-btn-bg-color:rgb(0 0 0 / 0.3); - --toggled-hover-active-btn-color:rgb(0 0 0 / 0.4); - --toggled-hover-btn-outline:none; - --csstools-light-dark-toggle--14:var(--csstools-color-scheme--light) rgb(74 74 79); - --dropdown-btn-bg-color:var(--csstools-light-dark-toggle--14, rgb(215 215 219)); - --dropdown-btn-border:none; - --separator-color:rgb(0 0 0 / 0.3); - --csstools-light-dark-toggle--15:var(--csstools-color-scheme--light) rgb(250 250 250); - --field-color:var(--csstools-light-dark-toggle--15, rgb(6 6 6)); - --csstools-light-dark-toggle--16:var(--csstools-color-scheme--light) rgb(64 64 68); - --field-bg-color:var(--csstools-light-dark-toggle--16, rgb(255 255 255)); - --csstools-light-dark-toggle--17:var(--csstools-color-scheme--light) rgb(115 115 115); - --field-border-color:var(--csstools-light-dark-toggle--17, rgb(187 187 188)); - --csstools-light-dark-toggle--18:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.8); - --treeitem-color:var(--csstools-light-dark-toggle--18, rgb(0 0 0 / 0.8)); - --csstools-light-dark-toggle--19:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.15); - --treeitem-bg-color:var(--csstools-light-dark-toggle--19, rgb(0 0 0 / 0.15)); - --csstools-light-dark-toggle--20:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.9); - --treeitem-hover-color:var(--csstools-light-dark-toggle--20, rgb(0 0 0 / 0.9)); - --csstools-light-dark-toggle--21:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.9); - --treeitem-selected-color:var(--csstools-light-dark-toggle--21, rgb(0 0 0 / 0.9)); - --csstools-light-dark-toggle--22:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.25); - --treeitem-selected-bg-color:var(--csstools-light-dark-toggle--22, rgb(0 0 0 / 0.25)); - --csstools-light-dark-toggle--23:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.1); - --thumbnail-hover-color:var(--csstools-light-dark-toggle--23, rgb(0 0 0 / 0.1)); - --csstools-light-dark-toggle--24:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.2); - --thumbnail-selected-color:var(--csstools-light-dark-toggle--24, rgb(0 0 0 / 0.2)); - --csstools-light-dark-toggle--25:var(--csstools-color-scheme--light) #42414d; - --doorhanger-bg-color:var(--csstools-light-dark-toggle--25, rgb(255 255 255)); - --csstools-light-dark-toggle--26:var(--csstools-color-scheme--light) rgb(39 39 43); - --doorhanger-border-color:var(--csstools-light-dark-toggle--26, rgb(12 12 13 / 0.2)); - --csstools-light-dark-toggle--27:var(--csstools-color-scheme--light) rgb(249 249 250); - --doorhanger-hover-color:var(--csstools-light-dark-toggle--27, rgb(12 12 13)); - --csstools-light-dark-toggle--28:var(--csstools-color-scheme--light) rgb(92 92 97); - --doorhanger-separator-color:var(--csstools-light-dark-toggle--28, rgb(222 222 222)); - --dialog-button-border:none; - --csstools-light-dark-toggle--29:var(--csstools-color-scheme--light) rgb(92 92 97); - --dialog-button-bg-color:var(--csstools-light-dark-toggle--29, rgb(12 12 13 / 0.1)); - --csstools-light-dark-toggle--30:var(--csstools-color-scheme--light) rgb(115 115 115); - --dialog-button-hover-bg-color:var(--csstools-light-dark-toggle--30, rgb(12 12 13 / 0.3)); + --sidebar-narrow-bg-color: var( + --csstools-light-dark-toggle--9, + rgb(212 212 215 / 0.9) + ); + --csstools-light-dark-toggle--10: var(--csstools-color-scheme--light) + rgb(50 50 52); + --sidebar-toolbar-bg-color: var( + --csstools-light-dark-toggle--10, + rgb(245 246 247) + ); + --csstools-light-dark-toggle--11: var(--csstools-color-scheme--light) + rgb(56 56 61); + --toolbar-bg-color: var(--csstools-light-dark-toggle--11, rgb(249 249 250)); + --csstools-light-dark-toggle--12: var(--csstools-color-scheme--light) + rgb(12 12 13); + --toolbar-border-color: var( + --csstools-light-dark-toggle--12, + rgb(184 184 184) + ); + --toolbar-box-shadow: 0 1px 0 var(--toolbar-border-color); + --toolbar-border-bottom: none; + --toolbarSidebar-box-shadow: + inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25), + 0 1px 0 rgb(0 0 0 / 0.15), 0 0 1px rgb(0 0 0 / 0.1); + --toolbarSidebar-border-bottom: none; + --button-hover-color: color-mix(in srgb, currentColor 17%, transparent); + --csstools-light-dark-toggle--13: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toggled-btn-color: var(--csstools-light-dark-toggle--13, rgb(0 0 0)); + --toggled-btn-bg-color: rgb(0 0 0 / 0.3); + --toggled-hover-active-btn-color: rgb(0 0 0 / 0.4); + --toggled-hover-btn-outline: none; + --csstools-light-dark-toggle--14: var(--csstools-color-scheme--light) + rgb(74 74 79); + --dropdown-btn-bg-color: var( + --csstools-light-dark-toggle--14, + rgb(215 215 219) + ); + --dropdown-btn-border: none; + --separator-color: rgb(0 0 0 / 0.3); + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) + rgb(250 250 250); + --field-color: var(--csstools-light-dark-toggle--15, rgb(6 6 6)); + --csstools-light-dark-toggle--16: var(--csstools-color-scheme--light) + rgb(64 64 68); + --field-bg-color: var(--csstools-light-dark-toggle--16, rgb(255 255 255)); + --csstools-light-dark-toggle--17: var(--csstools-color-scheme--light) + rgb(115 115 115); + --field-border-color: var(--csstools-light-dark-toggle--17, rgb(187 187 188)); + --csstools-light-dark-toggle--18: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.8); + --treeitem-color: var(--csstools-light-dark-toggle--18, rgb(0 0 0 / 0.8)); + --csstools-light-dark-toggle--19: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.15); + --treeitem-bg-color: var(--csstools-light-dark-toggle--19, rgb(0 0 0 / 0.15)); + --csstools-light-dark-toggle--20: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.9); + --treeitem-hover-color: var( + --csstools-light-dark-toggle--20, + rgb(0 0 0 / 0.9) + ); + --csstools-light-dark-toggle--21: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.9); + --treeitem-selected-color: var( + --csstools-light-dark-toggle--21, + rgb(0 0 0 / 0.9) + ); + --csstools-light-dark-toggle--22: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.25); + --treeitem-selected-bg-color: var( + --csstools-light-dark-toggle--22, + rgb(0 0 0 / 0.25) + ); + --csstools-light-dark-toggle--23: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.1); + --thumbnail-hover-color: var( + --csstools-light-dark-toggle--23, + rgb(0 0 0 / 0.1) + ); + --csstools-light-dark-toggle--24: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.2); + --thumbnail-selected-color: var( + --csstools-light-dark-toggle--24, + rgb(0 0 0 / 0.2) + ); + --csstools-light-dark-toggle--25: var(--csstools-color-scheme--light) #42414d; + --doorhanger-bg-color: var( + --csstools-light-dark-toggle--25, + rgb(255 255 255) + ); + --csstools-light-dark-toggle--26: var(--csstools-color-scheme--light) + rgb(39 39 43); + --doorhanger-border-color: var( + --csstools-light-dark-toggle--26, + rgb(12 12 13 / 0.2) + ); + --csstools-light-dark-toggle--27: var(--csstools-color-scheme--light) + rgb(249 249 250); + --doorhanger-hover-color: var( + --csstools-light-dark-toggle--27, + rgb(12 12 13) + ); + --csstools-light-dark-toggle--28: var(--csstools-color-scheme--light) + rgb(92 92 97); + --doorhanger-separator-color: var( + --csstools-light-dark-toggle--28, + rgb(222 222 222) + ); + --dialog-button-border: none; + --csstools-light-dark-toggle--29: var(--csstools-color-scheme--light) + rgb(92 92 97); + --dialog-button-bg-color: var( + --csstools-light-dark-toggle--29, + rgb(12 12 13 / 0.1) + ); + --csstools-light-dark-toggle--30: var(--csstools-color-scheme--light) + rgb(115 115 115); + --dialog-button-hover-bg-color: var( + --csstools-light-dark-toggle--30, + rgb(12 12 13 / 0.3) + ); - --loading-icon:url(images/loading.svg); - --treeitem-expanded-icon:url(images/treeitem-expanded.svg); - --treeitem-collapsed-icon:url(images/treeitem-collapsed.svg); - --toolbarButton-editorComment-icon:url(images/comment-editButton.svg); - --toolbarButton-editorFreeText-icon:url(images/toolbarButton-editorFreeText.svg); - --toolbarButton-editorHighlight-icon:url(images/toolbarButton-editorHighlight.svg); - --toolbarButton-editorInk-icon:url(images/toolbarButton-editorInk.svg); - --toolbarButton-editorStamp-icon:url(images/toolbarButton-editorStamp.svg); - --toolbarButton-editorSignature-icon:url(images/toolbarButton-editorSignature.svg); - --toolbarButton-menuArrow-icon:url(images/toolbarButton-menuArrow.svg); - --toolbarButton-sidebarToggle-icon:url(images/toolbarButton-sidebarToggle.svg); - --toolbarButton-secondaryToolbarToggle-icon:url(images/toolbarButton-secondaryToolbarToggle.svg); - --toolbarButton-pageUp-icon:url(images/toolbarButton-pageUp.svg); - --toolbarButton-pageDown-icon:url(images/toolbarButton-pageDown.svg); - --toolbarButton-zoomOut-icon:url(images/toolbarButton-zoomOut.svg); - --toolbarButton-zoomIn-icon:url(images/toolbarButton-zoomIn.svg); - --toolbarButton-presentationMode-icon:url(images/toolbarButton-presentationMode.svg); - --toolbarButton-print-icon:url(images/toolbarButton-print.svg); - --toolbarButton-openFile-icon:url(images/toolbarButton-openFile.svg); - --toolbarButton-download-icon:url(images/toolbarButton-download.svg); - --toolbarButton-bookmark-icon:url(images/toolbarButton-bookmark.svg); - --toolbarButton-viewThumbnail-icon:url(images/toolbarButton-viewThumbnail.svg); - --toolbarButton-viewOutline-icon:url(images/toolbarButton-viewOutline.svg); - --toolbarButton-viewAttachments-icon:url(images/toolbarButton-viewAttachments.svg); - --toolbarButton-viewLayers-icon:url(images/toolbarButton-viewLayers.svg); - --toolbarButton-currentOutlineItem-icon:url(images/toolbarButton-currentOutlineItem.svg); - --toolbarButton-search-icon:url(images/toolbarButton-search.svg); - --findbarButton-previous-icon:url(images/findbarButton-previous.svg); - --findbarButton-next-icon:url(images/findbarButton-next.svg); - --secondaryToolbarButton-firstPage-icon:url(images/secondaryToolbarButton-firstPage.svg); - --secondaryToolbarButton-lastPage-icon:url(images/secondaryToolbarButton-lastPage.svg); - --secondaryToolbarButton-rotateCcw-icon:url(images/secondaryToolbarButton-rotateCcw.svg); - --secondaryToolbarButton-rotateCw-icon:url(images/secondaryToolbarButton-rotateCw.svg); - --secondaryToolbarButton-selectTool-icon:url(images/secondaryToolbarButton-selectTool.svg); - --secondaryToolbarButton-handTool-icon:url(images/secondaryToolbarButton-handTool.svg); - --secondaryToolbarButton-scrollPage-icon:url(images/secondaryToolbarButton-scrollPage.svg); - --secondaryToolbarButton-scrollVertical-icon:url(images/secondaryToolbarButton-scrollVertical.svg); - --secondaryToolbarButton-scrollHorizontal-icon:url(images/secondaryToolbarButton-scrollHorizontal.svg); - --secondaryToolbarButton-scrollWrapped-icon:url(images/secondaryToolbarButton-scrollWrapped.svg); - --secondaryToolbarButton-spreadNone-icon:url(images/secondaryToolbarButton-spreadNone.svg); - --secondaryToolbarButton-spreadOdd-icon:url(images/secondaryToolbarButton-spreadOdd.svg); - --secondaryToolbarButton-spreadEven-icon:url(images/secondaryToolbarButton-spreadEven.svg); - --secondaryToolbarButton-imageAltTextSettings-icon:var( + --loading-icon: url(images/loading.svg); + --treeitem-expanded-icon: url(images/treeitem-expanded.svg); + --treeitem-collapsed-icon: url(images/treeitem-collapsed.svg); + --toolbarButton-editorComment-icon: url(images/comment-editButton.svg); + --toolbarButton-editorFreeText-icon: url(images/toolbarButton-editorFreeText.svg); + --toolbarButton-editorHighlight-icon: url(images/toolbarButton-editorHighlight.svg); + --toolbarButton-editorInk-icon: url(images/toolbarButton-editorInk.svg); + --toolbarButton-editorStamp-icon: url(images/toolbarButton-editorStamp.svg); + --toolbarButton-editorSignature-icon: url(images/toolbarButton-editorSignature.svg); + --toolbarButton-menuArrow-icon: url(images/toolbarButton-menuArrow.svg); + --toolbarButton-sidebarToggle-icon: url(images/toolbarButton-sidebarToggle.svg); + --toolbarButton-secondaryToolbarToggle-icon: url(images/toolbarButton-secondaryToolbarToggle.svg); + --toolbarButton-pageUp-icon: url(images/toolbarButton-pageUp.svg); + --toolbarButton-pageDown-icon: url(images/toolbarButton-pageDown.svg); + --toolbarButton-zoomOut-icon: url(images/toolbarButton-zoomOut.svg); + --toolbarButton-zoomIn-icon: url(images/toolbarButton-zoomIn.svg); + --toolbarButton-presentationMode-icon: url(images/toolbarButton-presentationMode.svg); + --toolbarButton-print-icon: url(images/toolbarButton-print.svg); + --toolbarButton-openFile-icon: url(images/toolbarButton-openFile.svg); + --toolbarButton-download-icon: url(images/toolbarButton-download.svg); + --toolbarButton-bookmark-icon: url(images/toolbarButton-bookmark.svg); + --toolbarButton-viewThumbnail-icon: url(images/toolbarButton-viewThumbnail.svg); + --toolbarButton-viewOutline-icon: url(images/toolbarButton-viewOutline.svg); + --toolbarButton-viewAttachments-icon: url(images/toolbarButton-viewAttachments.svg); + --toolbarButton-viewLayers-icon: url(images/toolbarButton-viewLayers.svg); + --toolbarButton-currentOutlineItem-icon: url(images/toolbarButton-currentOutlineItem.svg); + --toolbarButton-search-icon: url(images/toolbarButton-search.svg); + --findbarButton-previous-icon: url(images/findbarButton-previous.svg); + --findbarButton-next-icon: url(images/findbarButton-next.svg); + --secondaryToolbarButton-firstPage-icon: url(images/secondaryToolbarButton-firstPage.svg); + --secondaryToolbarButton-lastPage-icon: url(images/secondaryToolbarButton-lastPage.svg); + --secondaryToolbarButton-rotateCcw-icon: url(images/secondaryToolbarButton-rotateCcw.svg); + --secondaryToolbarButton-rotateCw-icon: url(images/secondaryToolbarButton-rotateCw.svg); + --secondaryToolbarButton-selectTool-icon: url(images/secondaryToolbarButton-selectTool.svg); + --secondaryToolbarButton-handTool-icon: url(images/secondaryToolbarButton-handTool.svg); + --secondaryToolbarButton-scrollPage-icon: url(images/secondaryToolbarButton-scrollPage.svg); + --secondaryToolbarButton-scrollVertical-icon: url(images/secondaryToolbarButton-scrollVertical.svg); + --secondaryToolbarButton-scrollHorizontal-icon: url(images/secondaryToolbarButton-scrollHorizontal.svg); + --secondaryToolbarButton-scrollWrapped-icon: url(images/secondaryToolbarButton-scrollWrapped.svg); + --secondaryToolbarButton-spreadNone-icon: url(images/secondaryToolbarButton-spreadNone.svg); + --secondaryToolbarButton-spreadOdd-icon: url(images/secondaryToolbarButton-spreadOdd.svg); + --secondaryToolbarButton-spreadEven-icon: url(images/secondaryToolbarButton-spreadEven.svg); + --secondaryToolbarButton-imageAltTextSettings-icon: var( --toolbarButton-editorStamp-icon ); - --secondaryToolbarButton-documentProperties-icon:url(images/secondaryToolbarButton-documentProperties.svg); - --editorParams-stampAddImage-icon:url(images/toolbarButton-zoomIn.svg); - --comment-edit-button-icon:url(images/comment-editButton.svg); + --secondaryToolbarButton-documentProperties-icon: url(images/secondaryToolbarButton-documentProperties.svg); + --editorParams-stampAddImage-icon: url(images/toolbarButton-zoomIn.svg); + --comment-edit-button-icon: url(images/comment-editButton.svg); } -@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)){ -:root{ +@supports (color: light-dark(red, red)) and (color: rgb(0 0 0 / 0)) { + :root { + --main-color: light-dark(rgb(12 12 13), rgb(249 249 250)); + --body-bg-color: light-dark(rgb(212 212 215), rgb(42 42 46)); + --progressBar-color: light-dark(rgb(10 132 255), rgb(0 96 223)); + --progressBar-bg-color: light-dark(rgb(221 221 222), rgb(40 40 43)); + --progressBar-blend-color: light-dark(rgb(116 177 239), rgb(20 68 133)); + --scrollbar-color: light-dark(auto, rgb(121 121 123)); + --scrollbar-bg-color: light-dark(auto, rgb(35 35 39)); + --toolbar-icon-bg-color: light-dark(rgb(0 0 0), rgb(255 255 255)); + --toolbar-icon-hover-bg-color: light-dark(rgb(0 0 0), rgb(255 255 255)); - --main-color:light-dark(rgb(12 12 13), rgb(249 249 250)); - --body-bg-color:light-dark(rgb(212 212 215), rgb(42 42 46)); - --progressBar-color:light-dark(rgb(10 132 255), rgb(0 96 223)); - --progressBar-bg-color:light-dark(rgb(221 221 222), rgb(40 40 43)); - --progressBar-blend-color:light-dark(rgb(116 177 239), rgb(20 68 133)); - --scrollbar-color:light-dark(auto, rgb(121 121 123)); - --scrollbar-bg-color:light-dark(auto, rgb(35 35 39)); - --toolbar-icon-bg-color:light-dark(rgb(0 0 0), rgb(255 255 255)); - --toolbar-icon-hover-bg-color:light-dark(rgb(0 0 0), rgb(255 255 255)); - - --sidebar-narrow-bg-color:light-dark( - rgb(212 212 215 / 0.9), - rgb(42 42 46 / 0.9) - ); - --sidebar-toolbar-bg-color:light-dark(rgb(245 246 247), rgb(50 50 52)); - --toolbar-bg-color:light-dark(rgb(249 249 250), rgb(56 56 61)); - --toolbar-border-color:light-dark(rgb(184 184 184), rgb(12 12 13)); - --toggled-btn-color:light-dark(rgb(0 0 0), rgb(255 255 255)); - --dropdown-btn-bg-color:light-dark(rgb(215 215 219), rgb(74 74 79)); - --field-color:light-dark(rgb(6 6 6), rgb(250 250 250)); - --field-bg-color:light-dark(rgb(255 255 255), rgb(64 64 68)); - --field-border-color:light-dark(rgb(187 187 188), rgb(115 115 115)); - --treeitem-color:light-dark(rgb(0 0 0 / 0.8), rgb(255 255 255 / 0.8)); - --treeitem-bg-color:light-dark(rgb(0 0 0 / 0.15), rgb(255 255 255 / 0.15)); - --treeitem-hover-color:light-dark(rgb(0 0 0 / 0.9), rgb(255 255 255 / 0.9)); - --treeitem-selected-color:light-dark( - rgb(0 0 0 / 0.9), - rgb(255 255 255 / 0.9) - ); - --treeitem-selected-bg-color:light-dark( - rgb(0 0 0 / 0.25), - rgb(255 255 255 / 0.25) - ); - --thumbnail-hover-color:light-dark(rgb(0 0 0 / 0.1), rgb(255 255 255 / 0.1)); - --thumbnail-selected-color:light-dark( - rgb(0 0 0 / 0.2), - rgb(255 255 255 / 0.2) - ); - --doorhanger-bg-color:light-dark(rgb(255 255 255), #42414d); - --doorhanger-border-color:light-dark(rgb(12 12 13 / 0.2), rgb(39 39 43)); - --doorhanger-hover-color:light-dark(rgb(12 12 13), rgb(249 249 250)); - --doorhanger-separator-color:light-dark(rgb(222 222 222), rgb(92 92 97)); - --dialog-button-bg-color:light-dark(rgb(12 12 13 / 0.1), rgb(92 92 97)); - --dialog-button-hover-bg-color:light-dark( - rgb(12 12 13 / 0.3), - rgb(115 115 115) - ); -} -} - -@supports not (color: light-dark(tan, tan)){ - -:root *{ - - --csstools-light-dark-toggle--0:var(--csstools-color-scheme--light) rgb(249 249 250); - - --main-color:var(--csstools-light-dark-toggle--0, rgb(12 12 13)); - --csstools-light-dark-toggle--1:var(--csstools-color-scheme--light) rgb(42 42 46); - --body-bg-color:var(--csstools-light-dark-toggle--1, rgb(212 212 215)); - --csstools-light-dark-toggle--2:var(--csstools-color-scheme--light) rgb(0 96 223); - --progressBar-color:var(--csstools-light-dark-toggle--2, rgb(10 132 255)); - --csstools-light-dark-toggle--3:var(--csstools-color-scheme--light) rgb(40 40 43); - --progressBar-bg-color:var(--csstools-light-dark-toggle--3, rgb(221 221 222)); - --csstools-light-dark-toggle--4:var(--csstools-color-scheme--light) rgb(20 68 133); - --progressBar-blend-color:var(--csstools-light-dark-toggle--4, rgb(116 177 239)); - --csstools-light-dark-toggle--5:var(--csstools-color-scheme--light) rgb(121 121 123); - --scrollbar-color:var(--csstools-light-dark-toggle--5, auto); - --csstools-light-dark-toggle--6:var(--csstools-color-scheme--light) rgb(35 35 39); - --scrollbar-bg-color:var(--csstools-light-dark-toggle--6, auto); - --csstools-light-dark-toggle--7:var(--csstools-color-scheme--light) rgb(255 255 255); - --toolbar-icon-bg-color:var(--csstools-light-dark-toggle--7, rgb(0 0 0)); - --csstools-light-dark-toggle--8:var(--csstools-color-scheme--light) rgb(255 255 255); - --toolbar-icon-hover-bg-color:var(--csstools-light-dark-toggle--8, rgb(0 0 0)); - - --csstools-light-dark-toggle--9:var(--csstools-color-scheme--light) rgb(42 42 46 / 0.9); - - --sidebar-narrow-bg-color:var(--csstools-light-dark-toggle--9, rgb(212 212 215 / 0.9)); - --csstools-light-dark-toggle--10:var(--csstools-color-scheme--light) rgb(50 50 52); - --sidebar-toolbar-bg-color:var(--csstools-light-dark-toggle--10, rgb(245 246 247)); - --csstools-light-dark-toggle--11:var(--csstools-color-scheme--light) rgb(56 56 61); - --toolbar-bg-color:var(--csstools-light-dark-toggle--11, rgb(249 249 250)); - --csstools-light-dark-toggle--12:var(--csstools-color-scheme--light) rgb(12 12 13); - --toolbar-border-color:var(--csstools-light-dark-toggle--12, rgb(184 184 184)); - --csstools-light-dark-toggle--13:var(--csstools-color-scheme--light) rgb(255 255 255); - --toggled-btn-color:var(--csstools-light-dark-toggle--13, rgb(0 0 0)); - --csstools-light-dark-toggle--14:var(--csstools-color-scheme--light) rgb(74 74 79); - --dropdown-btn-bg-color:var(--csstools-light-dark-toggle--14, rgb(215 215 219)); - --csstools-light-dark-toggle--15:var(--csstools-color-scheme--light) rgb(250 250 250); - --field-color:var(--csstools-light-dark-toggle--15, rgb(6 6 6)); - --csstools-light-dark-toggle--16:var(--csstools-color-scheme--light) rgb(64 64 68); - --field-bg-color:var(--csstools-light-dark-toggle--16, rgb(255 255 255)); - --csstools-light-dark-toggle--17:var(--csstools-color-scheme--light) rgb(115 115 115); - --field-border-color:var(--csstools-light-dark-toggle--17, rgb(187 187 188)); - --csstools-light-dark-toggle--18:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.8); - --treeitem-color:var(--csstools-light-dark-toggle--18, rgb(0 0 0 / 0.8)); - --csstools-light-dark-toggle--19:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.15); - --treeitem-bg-color:var(--csstools-light-dark-toggle--19, rgb(0 0 0 / 0.15)); - --csstools-light-dark-toggle--20:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.9); - --treeitem-hover-color:var(--csstools-light-dark-toggle--20, rgb(0 0 0 / 0.9)); - --csstools-light-dark-toggle--21:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.9); - --treeitem-selected-color:var(--csstools-light-dark-toggle--21, rgb(0 0 0 / 0.9)); - --csstools-light-dark-toggle--22:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.25); - --treeitem-selected-bg-color:var(--csstools-light-dark-toggle--22, rgb(0 0 0 / 0.25)); - --csstools-light-dark-toggle--23:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.1); - --thumbnail-hover-color:var(--csstools-light-dark-toggle--23, rgb(0 0 0 / 0.1)); - --csstools-light-dark-toggle--24:var(--csstools-color-scheme--light) rgb(255 255 255 / 0.2); - --thumbnail-selected-color:var(--csstools-light-dark-toggle--24, rgb(0 0 0 / 0.2)); - --csstools-light-dark-toggle--25:var(--csstools-color-scheme--light) #42414d; - --doorhanger-bg-color:var(--csstools-light-dark-toggle--25, rgb(255 255 255)); - --csstools-light-dark-toggle--26:var(--csstools-color-scheme--light) rgb(39 39 43); - --doorhanger-border-color:var(--csstools-light-dark-toggle--26, rgb(12 12 13 / 0.2)); - --csstools-light-dark-toggle--27:var(--csstools-color-scheme--light) rgb(249 249 250); - --doorhanger-hover-color:var(--csstools-light-dark-toggle--27, rgb(12 12 13)); - --csstools-light-dark-toggle--28:var(--csstools-color-scheme--light) rgb(92 92 97); - --doorhanger-separator-color:var(--csstools-light-dark-toggle--28, rgb(222 222 222)); - --csstools-light-dark-toggle--29:var(--csstools-color-scheme--light) rgb(92 92 97); - --dialog-button-bg-color:var(--csstools-light-dark-toggle--29, rgb(12 12 13 / 0.1)); - --csstools-light-dark-toggle--30:var(--csstools-color-scheme--light) rgb(115 115 115); - --dialog-button-hover-bg-color:var(--csstools-light-dark-toggle--30, rgb(12 12 13 / 0.3)); + --sidebar-narrow-bg-color: light-dark( + rgb(212 212 215 / 0.9), + rgb(42 42 46 / 0.9) + ); + --sidebar-toolbar-bg-color: light-dark(rgb(245 246 247), rgb(50 50 52)); + --toolbar-bg-color: light-dark(rgb(249 249 250), rgb(56 56 61)); + --toolbar-border-color: light-dark(rgb(184 184 184), rgb(12 12 13)); + --toggled-btn-color: light-dark(rgb(0 0 0), rgb(255 255 255)); + --dropdown-btn-bg-color: light-dark(rgb(215 215 219), rgb(74 74 79)); + --field-color: light-dark(rgb(6 6 6), rgb(250 250 250)); + --field-bg-color: light-dark(rgb(255 255 255), rgb(64 64 68)); + --field-border-color: light-dark(rgb(187 187 188), rgb(115 115 115)); + --treeitem-color: light-dark(rgb(0 0 0 / 0.8), rgb(255 255 255 / 0.8)); + --treeitem-bg-color: light-dark(rgb(0 0 0 / 0.15), rgb(255 255 255 / 0.15)); + --treeitem-hover-color: light-dark( + rgb(0 0 0 / 0.9), + rgb(255 255 255 / 0.9) + ); + --treeitem-selected-color: light-dark( + rgb(0 0 0 / 0.9), + rgb(255 255 255 / 0.9) + ); + --treeitem-selected-bg-color: light-dark( + rgb(0 0 0 / 0.25), + rgb(255 255 255 / 0.25) + ); + --thumbnail-hover-color: light-dark( + rgb(0 0 0 / 0.1), + rgb(255 255 255 / 0.1) + ); + --thumbnail-selected-color: light-dark( + rgb(0 0 0 / 0.2), + rgb(255 255 255 / 0.2) + ); + --doorhanger-bg-color: light-dark(rgb(255 255 255), #42414d); + --doorhanger-border-color: light-dark(rgb(12 12 13 / 0.2), rgb(39 39 43)); + --doorhanger-hover-color: light-dark(rgb(12 12 13), rgb(249 249 250)); + --doorhanger-separator-color: light-dark(rgb(222 222 222), rgb(92 92 97)); + --dialog-button-bg-color: light-dark(rgb(12 12 13 / 0.1), rgb(92 92 97)); + --dialog-button-hover-bg-color: light-dark( + rgb(12 12 13 / 0.3), + rgb(115 115 115) + ); } } -[dir="rtl"]:root{ - --dir-factor:-1; - --inline-start:right; - --inline-end:left; -} +@supports not (color: light-dark(tan, tan)) { + :root * { + --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) + rgb(249 249 250); -@media screen and (forced-colors: active){ - :root{ - --button-hover-color:Highlight; - --toolbar-icon-opacity:1; - --toolbar-icon-bg-color:ButtonText; - --toolbar-icon-hover-bg-color:ButtonFace; - --toggled-hover-active-btn-color:ButtonText; - --toggled-hover-btn-outline:2px solid ButtonBorder; - --toolbar-border-color:CanvasText; - --toolbar-border-bottom:1px solid var(--toolbar-border-color); - --toolbar-box-shadow:none; - --toggled-btn-color:HighlightText; - --toggled-btn-bg-color:LinkText; - --doorhanger-hover-color:ButtonFace; - --doorhanger-border-color-whcm:1px solid ButtonText; - --doorhanger-triangle-opacity-whcm:0; - --dialog-button-border:1px solid Highlight; - --dialog-button-hover-bg-color:Highlight; - --dialog-button-hover-color:ButtonFace; - --dropdown-btn-border:1px solid ButtonText; - --field-border-color:ButtonText; - --main-color:CanvasText; - --separator-color:GrayText; - --doorhanger-separator-color:GrayText; - --toolbarSidebar-box-shadow:none; - --toolbarSidebar-border-bottom:1px solid var(--toolbar-border-color); + --main-color: var(--csstools-light-dark-toggle--0, rgb(12 12 13)); + --csstools-light-dark-toggle--1: var(--csstools-color-scheme--light) + rgb(42 42 46); + --body-bg-color: var(--csstools-light-dark-toggle--1, rgb(212 212 215)); + --csstools-light-dark-toggle--2: var(--csstools-color-scheme--light) + rgb(0 96 223); + --progressBar-color: var(--csstools-light-dark-toggle--2, rgb(10 132 255)); + --csstools-light-dark-toggle--3: var(--csstools-color-scheme--light) + rgb(40 40 43); + --progressBar-bg-color: var( + --csstools-light-dark-toggle--3, + rgb(221 221 222) + ); + --csstools-light-dark-toggle--4: var(--csstools-color-scheme--light) + rgb(20 68 133); + --progressBar-blend-color: var( + --csstools-light-dark-toggle--4, + rgb(116 177 239) + ); + --csstools-light-dark-toggle--5: var(--csstools-color-scheme--light) + rgb(121 121 123); + --scrollbar-color: var(--csstools-light-dark-toggle--5, auto); + --csstools-light-dark-toggle--6: var(--csstools-color-scheme--light) + rgb(35 35 39); + --scrollbar-bg-color: var(--csstools-light-dark-toggle--6, auto); + --csstools-light-dark-toggle--7: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toolbar-icon-bg-color: var(--csstools-light-dark-toggle--7, rgb(0 0 0)); + --csstools-light-dark-toggle--8: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toolbar-icon-hover-bg-color: var( + --csstools-light-dark-toggle--8, + rgb(0 0 0) + ); + + --csstools-light-dark-toggle--9: var(--csstools-color-scheme--light) + rgb(42 42 46 / 0.9); + + --sidebar-narrow-bg-color: var( + --csstools-light-dark-toggle--9, + rgb(212 212 215 / 0.9) + ); + --csstools-light-dark-toggle--10: var(--csstools-color-scheme--light) + rgb(50 50 52); + --sidebar-toolbar-bg-color: var( + --csstools-light-dark-toggle--10, + rgb(245 246 247) + ); + --csstools-light-dark-toggle--11: var(--csstools-color-scheme--light) + rgb(56 56 61); + --toolbar-bg-color: var(--csstools-light-dark-toggle--11, rgb(249 249 250)); + --csstools-light-dark-toggle--12: var(--csstools-color-scheme--light) + rgb(12 12 13); + --toolbar-border-color: var( + --csstools-light-dark-toggle--12, + rgb(184 184 184) + ); + --csstools-light-dark-toggle--13: var(--csstools-color-scheme--light) + rgb(255 255 255); + --toggled-btn-color: var(--csstools-light-dark-toggle--13, rgb(0 0 0)); + --csstools-light-dark-toggle--14: var(--csstools-color-scheme--light) + rgb(74 74 79); + --dropdown-btn-bg-color: var( + --csstools-light-dark-toggle--14, + rgb(215 215 219) + ); + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) + rgb(250 250 250); + --field-color: var(--csstools-light-dark-toggle--15, rgb(6 6 6)); + --csstools-light-dark-toggle--16: var(--csstools-color-scheme--light) + rgb(64 64 68); + --field-bg-color: var(--csstools-light-dark-toggle--16, rgb(255 255 255)); + --csstools-light-dark-toggle--17: var(--csstools-color-scheme--light) + rgb(115 115 115); + --field-border-color: var( + --csstools-light-dark-toggle--17, + rgb(187 187 188) + ); + --csstools-light-dark-toggle--18: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.8); + --treeitem-color: var(--csstools-light-dark-toggle--18, rgb(0 0 0 / 0.8)); + --csstools-light-dark-toggle--19: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.15); + --treeitem-bg-color: var( + --csstools-light-dark-toggle--19, + rgb(0 0 0 / 0.15) + ); + --csstools-light-dark-toggle--20: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.9); + --treeitem-hover-color: var( + --csstools-light-dark-toggle--20, + rgb(0 0 0 / 0.9) + ); + --csstools-light-dark-toggle--21: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.9); + --treeitem-selected-color: var( + --csstools-light-dark-toggle--21, + rgb(0 0 0 / 0.9) + ); + --csstools-light-dark-toggle--22: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.25); + --treeitem-selected-bg-color: var( + --csstools-light-dark-toggle--22, + rgb(0 0 0 / 0.25) + ); + --csstools-light-dark-toggle--23: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.1); + --thumbnail-hover-color: var( + --csstools-light-dark-toggle--23, + rgb(0 0 0 / 0.1) + ); + --csstools-light-dark-toggle--24: var(--csstools-color-scheme--light) + rgb(255 255 255 / 0.2); + --thumbnail-selected-color: var( + --csstools-light-dark-toggle--24, + rgb(0 0 0 / 0.2) + ); + --csstools-light-dark-toggle--25: var(--csstools-color-scheme--light) + #42414d; + --doorhanger-bg-color: var( + --csstools-light-dark-toggle--25, + rgb(255 255 255) + ); + --csstools-light-dark-toggle--26: var(--csstools-color-scheme--light) + rgb(39 39 43); + --doorhanger-border-color: var( + --csstools-light-dark-toggle--26, + rgb(12 12 13 / 0.2) + ); + --csstools-light-dark-toggle--27: var(--csstools-color-scheme--light) + rgb(249 249 250); + --doorhanger-hover-color: var( + --csstools-light-dark-toggle--27, + rgb(12 12 13) + ); + --csstools-light-dark-toggle--28: var(--csstools-color-scheme--light) + rgb(92 92 97); + --doorhanger-separator-color: var( + --csstools-light-dark-toggle--28, + rgb(222 222 222) + ); + --csstools-light-dark-toggle--29: var(--csstools-color-scheme--light) + rgb(92 92 97); + --dialog-button-bg-color: var( + --csstools-light-dark-toggle--29, + rgb(12 12 13 / 0.1) + ); + --csstools-light-dark-toggle--30: var(--csstools-color-scheme--light) + rgb(115 115 115); + --dialog-button-hover-bg-color: var( + --csstools-light-dark-toggle--30, + rgb(12 12 13 / 0.3) + ); } } -@media screen and (prefers-reduced-motion: reduce){ - :root{ - --sidebar-transition-duration:0; +[dir='rtl']:root { + --dir-factor: -1; + --inline-start: right; + --inline-end: left; +} + +@media screen and (forced-colors: active) { + :root { + --button-hover-color: Highlight; + --toolbar-icon-opacity: 1; + --toolbar-icon-bg-color: ButtonText; + --toolbar-icon-hover-bg-color: ButtonFace; + --toggled-hover-active-btn-color: ButtonText; + --toggled-hover-btn-outline: 2px solid ButtonBorder; + --toolbar-border-color: CanvasText; + --toolbar-border-bottom: 1px solid var(--toolbar-border-color); + --toolbar-box-shadow: none; + --toggled-btn-color: HighlightText; + --toggled-btn-bg-color: LinkText; + --doorhanger-hover-color: ButtonFace; + --doorhanger-border-color-whcm: 1px solid ButtonText; + --doorhanger-triangle-opacity-whcm: 0; + --dialog-button-border: 1px solid Highlight; + --dialog-button-hover-bg-color: Highlight; + --dialog-button-hover-color: ButtonFace; + --dropdown-btn-border: 1px solid ButtonText; + --field-border-color: ButtonText; + --main-color: CanvasText; + --separator-color: GrayText; + --doorhanger-separator-color: GrayText; + --toolbarSidebar-box-shadow: none; + --toolbarSidebar-border-bottom: 1px solid var(--toolbar-border-color); } } -@keyframes progressIndeterminate{ - 0%{ - transform:translateX(calc(-142px * var(--dir-factor))); - } - - 100%{ - transform:translateX(0); +@media screen and (prefers-reduced-motion: reduce) { + :root { + --sidebar-transition-duration: 0; } } -html[data-toolbar-density="compact"]{ - --toolbar-height:30px; +@keyframes progressIndeterminate { + 0% { + transform: translateX(calc(-142px * var(--dir-factor))); } -html[data-toolbar-density="touch"]{ - --toolbar-height:44px; + 100% { + transform: translateX(0); } +} + +html[data-toolbar-density='compact'] { + --toolbar-height: 30px; +} + +html[data-toolbar-density='touch'] { + --toolbar-height: 44px; +} html, -body{ - height:100%; - width:100%; +body { + height: 100%; + width: 100%; } -body{ - margin:0; - background-color:var(--body-bg-color); - scrollbar-color:var(--scrollbar-color) var(--scrollbar-bg-color); +body { + margin: 0; + background-color: var(--body-bg-color); + scrollbar-color: var(--scrollbar-color) var(--scrollbar-bg-color); } -body.wait::before{ - content:""; - position:fixed; - width:100%; - height:100%; - z-index:100000; - cursor:wait; - } -.visuallyHidden{ - position:absolute; - top:0; - left:0; - border:0; - margin:0; - padding:0; - width:0; - height:0; - overflow:hidden; - white-space:nowrap; - font-size:0; +body.wait::before { + content: ''; + position: fixed; + width: 100%; + height: 100%; + z-index: 100000; + cursor: wait; +} +.visuallyHidden { + position: absolute; + top: 0; + left: 0; + border: 0; + margin: 0; + padding: 0; + width: 0; + height: 0; + overflow: hidden; + white-space: nowrap; + font-size: 0; } .hidden, -[hidden]{ - display:none !important; +[hidden] { + display: none !important; } -#viewerContainer.pdfPresentationMode:fullscreen{ - top:0; - background-color:rgb(0 0 0); - width:100%; - height:100%; - overflow:hidden; - cursor:none; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; +#viewerContainer.pdfPresentationMode:fullscreen { + top: 0; + background-color: rgb(0 0 0); + width: 100%; + height: 100%; + overflow: hidden; + cursor: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; } -.pdfPresentationMode:fullscreen section:not([data-internal-link]){ - pointer-events:none; +.pdfPresentationMode:fullscreen section:not([data-internal-link]) { + pointer-events: none; } -.pdfPresentationMode:fullscreen .textLayer span{ - cursor:none; +.pdfPresentationMode:fullscreen .textLayer span { + cursor: none; } .pdfPresentationMode.pdfPresentationModeControls > *, -.pdfPresentationMode.pdfPresentationModeControls .textLayer span{ - cursor:default; +.pdfPresentationMode.pdfPresentationModeControls .textLayer span { + cursor: default; } -#outerContainer{ - width:100%; - height:100%; - position:relative; - margin:0; +#outerContainer { + width: 100%; + height: 100%; + position: relative; + margin: 0; } -#sidebarContainer{ - position:absolute; - inset-block:var(--toolbar-height) 0; - inset-inline-start:calc(-1 * var(--sidebar-width)); - width:var(--sidebar-width); - visibility:hidden; - z-index:1; - font:message-box; - border-top:1px solid transparent; - border-inline-end:var(--doorhanger-border-color-whcm); - transition-property:inset-inline-start; - transition-duration:var(--sidebar-transition-duration); - transition-timing-function:var(--sidebar-transition-timing-function); +#sidebarContainer { + position: absolute; + inset-block: var(--toolbar-height) 0; + inset-inline-start: calc(-1 * var(--sidebar-width)); + width: var(--sidebar-width); + visibility: hidden; + z-index: 1; + font: message-box; + border-top: 1px solid transparent; + border-inline-end: var(--doorhanger-border-color-whcm); + transition-property: inset-inline-start; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); } -#outerContainer:is(.sidebarMoving, .sidebarOpen) #sidebarContainer{ - visibility:visible; +#outerContainer:is(.sidebarMoving, .sidebarOpen) #sidebarContainer { + visibility: visible; } -#outerContainer.sidebarOpen #sidebarContainer{ - inset-inline-start:0; +#outerContainer.sidebarOpen #sidebarContainer { + inset-inline-start: 0; } -#mainContainer{ - position:absolute; - inset:0; - min-width:350px; - margin:0; - display:flex; - flex-direction:column; +#mainContainer { + position: absolute; + inset: 0; + min-width: 350px; + margin: 0; + display: flex; + flex-direction: column; } -#sidebarContent{ - inset-block:var(--toolbar-height) 0; - inset-inline-start:0; - overflow:auto; - position:absolute; - width:100%; - box-shadow:inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25); +#sidebarContent { + inset-block: var(--toolbar-height) 0; + inset-inline-start: 0; + overflow: auto; + position: absolute; + width: 100%; + box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25); } -#viewerContainer{ - overflow:auto; - position:absolute; - inset:var(--toolbar-height) 0 0; - outline:none; - z-index:0; +#viewerContainer { + overflow: auto; + position: absolute; + inset: var(--toolbar-height) 0 0; + outline: none; + z-index: 0; } -#viewerContainer:not(.pdfPresentationMode){ - transition-duration:var(--sidebar-transition-duration); - transition-timing-function:var(--sidebar-transition-timing-function); +#viewerContainer:not(.pdfPresentationMode) { + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); } -#outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode){ - inset-inline-start:var(--sidebar-width); - transition-property:inset-inline-start; +#outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode) { + inset-inline-start: var(--sidebar-width); + transition-property: inset-inline-start; } -#sidebarContainer :is(input, button, select){ - font:message-box; +#sidebarContainer :is(input, button, select) { + font: message-box; } -.toolbar{ - z-index:2; +.toolbar { + z-index: 2; } -#toolbarSidebar{ - width:100%; - height:var(--toolbar-height); - background-color:var(--sidebar-toolbar-bg-color); - box-shadow:var(--toolbarSidebar-box-shadow); - border-bottom:var(--toolbarSidebar-border-bottom); - padding:var(--toolbar-vertical-padding) var(--toolbar-horizontal-padding); - justify-content:space-between; +#toolbarSidebar { + width: 100%; + height: var(--toolbar-height); + background-color: var(--sidebar-toolbar-bg-color); + box-shadow: var(--toolbarSidebar-box-shadow); + border-bottom: var(--toolbarSidebar-border-bottom); + padding: var(--toolbar-vertical-padding) var(--toolbar-horizontal-padding); + justify-content: space-between; } -#toolbarSidebar #toolbarSidebarLeft{ - width:auto; - height:100%; - } - -:is(#toolbarSidebar #toolbarSidebarLeft) #viewThumbnail::before{ - -webkit-mask-image:var(--toolbarButton-viewThumbnail-icon); - mask-image:var(--toolbarButton-viewThumbnail-icon); - } - -:is(#toolbarSidebar #toolbarSidebarLeft) #viewOutline::before{ - -webkit-mask-image:var(--toolbarButton-viewOutline-icon); - mask-image:var(--toolbarButton-viewOutline-icon); - transform:scaleX(var(--dir-factor)); - } - -:is(#toolbarSidebar #toolbarSidebarLeft) #viewAttachments::before{ - -webkit-mask-image:var(--toolbarButton-viewAttachments-icon); - mask-image:var(--toolbarButton-viewAttachments-icon); - } - -:is(#toolbarSidebar #toolbarSidebarLeft) #viewLayers::before{ - -webkit-mask-image:var(--toolbarButton-viewLayers-icon); - mask-image:var(--toolbarButton-viewLayers-icon); - } - -#toolbarSidebar #toolbarSidebarRight{ - width:auto; - height:100%; - padding-inline-end:2px; - } - -#sidebarResizer{ - position:absolute; - inset-block:0; - inset-inline-end:-6px; - width:6px; - z-index:200; - cursor:ew-resize; +#toolbarSidebar #toolbarSidebarLeft { + width: auto; + height: 100%; } -#outerContainer.sidebarOpen #loadingBar{ - inset-inline-start:var(--sidebar-width); +:is(#toolbarSidebar #toolbarSidebarLeft) #viewThumbnail::before { + -webkit-mask-image: var(--toolbarButton-viewThumbnail-icon); + mask-image: var(--toolbarButton-viewThumbnail-icon); +} + +:is(#toolbarSidebar #toolbarSidebarLeft) #viewOutline::before { + -webkit-mask-image: var(--toolbarButton-viewOutline-icon); + mask-image: var(--toolbarButton-viewOutline-icon); + transform: scaleX(var(--dir-factor)); +} + +:is(#toolbarSidebar #toolbarSidebarLeft) #viewAttachments::before { + -webkit-mask-image: var(--toolbarButton-viewAttachments-icon); + mask-image: var(--toolbarButton-viewAttachments-icon); +} + +:is(#toolbarSidebar #toolbarSidebarLeft) #viewLayers::before { + -webkit-mask-image: var(--toolbarButton-viewLayers-icon); + mask-image: var(--toolbarButton-viewLayers-icon); +} + +#toolbarSidebar #toolbarSidebarRight { + width: auto; + height: 100%; + padding-inline-end: 2px; +} + +#sidebarResizer { + position: absolute; + inset-block: 0; + inset-inline-end: -6px; + width: 6px; + z-index: 200; + cursor: ew-resize; +} + +#outerContainer.sidebarOpen #loadingBar { + inset-inline-start: var(--sidebar-width); } #outerContainer.sidebarResizing - :is(#sidebarContainer, #viewerContainer, #loadingBar){ - transition-duration:0s; + :is(#sidebarContainer, #viewerContainer, #loadingBar) { + transition-duration: 0s; } .doorHanger, -.doorHangerRight{ - border-radius:2px; - box-shadow:0 1px 5px var(--doorhanger-border-color), 0 0 0 1px var(--doorhanger-border-color); - border:var(--doorhanger-border-color-whcm); - background-color:var(--doorhanger-bg-color); - inset-block-start:calc(100% + var(--doorhanger-height) - 2px); +.doorHangerRight { + border-radius: 2px; + box-shadow: + 0 1px 5px var(--doorhanger-border-color), + 0 0 0 1px var(--doorhanger-border-color); + border: var(--doorhanger-border-color-whcm); + background-color: var(--doorhanger-bg-color); + inset-block-start: calc(100% + var(--doorhanger-height) - 2px); } -:is(.doorHanger,.doorHangerRight)::after,:is(.doorHanger,.doorHangerRight)::before{ - bottom:100%; - border-style:solid; - border-color:transparent; - content:""; - height:0; - width:0; - position:absolute; - pointer-events:none; - opacity:var(--doorhanger-triangle-opacity-whcm); - } - -:is(.doorHanger,.doorHangerRight)::before{ - border-width:calc(var(--doorhanger-height) + 2px); - border-bottom-color:var(--doorhanger-border-color); - } - -:is(.doorHanger,.doorHangerRight)::after{ - border-width:var(--doorhanger-height); - } - -.doorHangerRight{ - inset-inline-end:calc(50% - var(--doorhanger-height) - 1px); +:is(.doorHanger, .doorHangerRight)::after, +:is(.doorHanger, .doorHangerRight)::before { + bottom: 100%; + border-style: solid; + border-color: transparent; + content: ''; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + opacity: var(--doorhanger-triangle-opacity-whcm); } -.doorHangerRight::before{ - inset-inline-end:-1px; - } - -.doorHangerRight::after{ - border-bottom-color:var(--doorhanger-bg-color); - inset-inline-end:1px; - } - -.doorHanger{ - inset-inline-start:calc(50% - var(--doorhanger-height) - 1px); +:is(.doorHanger, .doorHangerRight)::before { + border-width: calc(var(--doorhanger-height) + 2px); + border-bottom-color: var(--doorhanger-border-color); } -.doorHanger::before{ - inset-inline-start:-1px; - } - -.doorHanger::after{ - border-bottom-color:var(--toolbar-bg-color); - inset-inline-start:1px; - } - -.dialogButton{ - border:none; - background:none; - width:28px; - height:28px; - outline:none; +:is(.doorHanger, .doorHangerRight)::after { + border-width: var(--doorhanger-height); } -.dialogButton:is(:hover, :focus-visible){ - background-color:var(--dialog-button-hover-bg-color); +.doorHangerRight { + inset-inline-end: calc(50% - var(--doorhanger-height) - 1px); } -.dialogButton:is(:hover, :focus-visible) > span{ - color:var(--dialog-button-hover-color); +.doorHangerRight::before { + inset-inline-end: -1px; } -.splitToolbarButtonSeparator{ - float:var(--inline-start); - width:0; - height:62%; - border-left:1px solid var(--separator-color); - border-right:none; +.doorHangerRight::after { + border-bottom-color: var(--doorhanger-bg-color); + inset-inline-end: 1px; } -.dialogButton{ - min-width:16px; - margin:2px 1px; - padding:2px 6px 0; - border:none; - border-radius:2px; - color:var(--main-color); - font-size:12px; - line-height:14px; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - cursor:default; - box-sizing:border-box; +.doorHanger { + inset-inline-start: calc(50% - var(--doorhanger-height) - 1px); } -.treeItemToggler::before{ - position:absolute; - display:inline-block; - width:16px; - height:16px; - - content:""; - background-color:var(--toolbar-icon-bg-color); - -webkit-mask-size:cover; - mask-size:cover; +.doorHanger::before { + inset-inline-start: -1px; } -#sidebarToggleButton::before{ - -webkit-mask-image:var(--toolbarButton-sidebarToggle-icon); - mask-image:var(--toolbarButton-sidebarToggle-icon); - transform:scaleX(var(--dir-factor)); +.doorHanger::after { + border-bottom-color: var(--toolbar-bg-color); + inset-inline-start: 1px; } -#secondaryToolbarToggleButton::before{ - -webkit-mask-image:var(--toolbarButton-secondaryToolbarToggle-icon); - mask-image:var(--toolbarButton-secondaryToolbarToggle-icon); - transform:scaleX(var(--dir-factor)); +.dialogButton { + border: none; + background: none; + width: 28px; + height: 28px; + outline: none; } -#previous::before{ - -webkit-mask-image:var(--toolbarButton-pageUp-icon); - mask-image:var(--toolbarButton-pageUp-icon); +.dialogButton:is(:hover, :focus-visible) { + background-color: var(--dialog-button-hover-bg-color); } -#next::before{ - -webkit-mask-image:var(--toolbarButton-pageDown-icon); - mask-image:var(--toolbarButton-pageDown-icon); +.dialogButton:is(:hover, :focus-visible) > span { + color: var(--dialog-button-hover-color); } -#zoomOutButton::before{ - -webkit-mask-image:var(--toolbarButton-zoomOut-icon); - mask-image:var(--toolbarButton-zoomOut-icon); +.splitToolbarButtonSeparator { + float: var(--inline-start); + width: 0; + height: 62%; + border-left: 1px solid var(--separator-color); + border-right: none; } -#zoomInButton::before{ - -webkit-mask-image:var(--toolbarButton-zoomIn-icon); - mask-image:var(--toolbarButton-zoomIn-icon); +.dialogButton { + min-width: 16px; + margin: 2px 1px; + padding: 2px 6px 0; + border: none; + border-radius: 2px; + color: var(--main-color); + font-size: 12px; + line-height: 14px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; + box-sizing: border-box; } -#editorCommentButton::before{ - -webkit-mask-image:var(--toolbarButton-editorComment-icon); - mask-image:var(--toolbarButton-editorComment-icon); - transform:scaleX(var(--dir-factor)); +.treeItemToggler::before { + position: absolute; + display: inline-block; + width: 16px; + height: 16px; + + content: ''; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; } -#editorFreeTextButton::before{ - -webkit-mask-image:var(--toolbarButton-editorFreeText-icon); - mask-image:var(--toolbarButton-editorFreeText-icon); +#sidebarToggleButton::before { + -webkit-mask-image: var(--toolbarButton-sidebarToggle-icon); + mask-image: var(--toolbarButton-sidebarToggle-icon); + transform: scaleX(var(--dir-factor)); } -#editorHighlightButton::before{ - -webkit-mask-image:var(--toolbarButton-editorHighlight-icon); - mask-image:var(--toolbarButton-editorHighlight-icon); +#secondaryToolbarToggleButton::before { + -webkit-mask-image: var(--toolbarButton-secondaryToolbarToggle-icon); + mask-image: var(--toolbarButton-secondaryToolbarToggle-icon); + transform: scaleX(var(--dir-factor)); } -#editorInkButton::before{ - -webkit-mask-image:var(--toolbarButton-editorInk-icon); - mask-image:var(--toolbarButton-editorInk-icon); +#previous::before { + -webkit-mask-image: var(--toolbarButton-pageUp-icon); + mask-image: var(--toolbarButton-pageUp-icon); } -#editorStampButton::before{ - -webkit-mask-image:var(--toolbarButton-editorStamp-icon); - mask-image:var(--toolbarButton-editorStamp-icon); +#next::before { + -webkit-mask-image: var(--toolbarButton-pageDown-icon); + mask-image: var(--toolbarButton-pageDown-icon); } -#editorSignatureButton::before{ - -webkit-mask-image:var(--toolbarButton-editorSignature-icon); - mask-image:var(--toolbarButton-editorSignature-icon); +#zoomOutButton::before { + -webkit-mask-image: var(--toolbarButton-zoomOut-icon); + mask-image: var(--toolbarButton-zoomOut-icon); } -#printButton::before{ - -webkit-mask-image:var(--toolbarButton-print-icon); - mask-image:var(--toolbarButton-print-icon); +#zoomInButton::before { + -webkit-mask-image: var(--toolbarButton-zoomIn-icon); + mask-image: var(--toolbarButton-zoomIn-icon); } -#downloadButton::before{ - -webkit-mask-image:var(--toolbarButton-download-icon); - mask-image:var(--toolbarButton-download-icon); +#editorCommentButton::before { + -webkit-mask-image: var(--toolbarButton-editorComment-icon); + mask-image: var(--toolbarButton-editorComment-icon); + transform: scaleX(var(--dir-factor)); } -#currentOutlineItem::before{ - -webkit-mask-image:var(--toolbarButton-currentOutlineItem-icon); - mask-image:var(--toolbarButton-currentOutlineItem-icon); - transform:scaleX(var(--dir-factor)); +#editorFreeTextButton::before { + -webkit-mask-image: var(--toolbarButton-editorFreeText-icon); + mask-image: var(--toolbarButton-editorFreeText-icon); } -#viewFindButton::before{ - -webkit-mask-image:var(--toolbarButton-search-icon); - mask-image:var(--toolbarButton-search-icon); +#editorHighlightButton::before { + -webkit-mask-image: var(--toolbarButton-editorHighlight-icon); + mask-image: var(--toolbarButton-editorHighlight-icon); } -.pdfSidebarNotification::after{ - position:absolute; - display:inline-block; - top:2px; - inset-inline-end:2px; - content:""; - background-color:rgb(112 219 85); - height:9px; - width:9px; - border-radius:50%; +#editorInkButton::before { + -webkit-mask-image: var(--toolbarButton-editorInk-icon); + mask-image: var(--toolbarButton-editorInk-icon); } -.verticalToolbarSeparator{ - display:block; - margin-inline:2px; - width:0; - height:80%; - border-left:1px solid var(--separator-color); - border-right:none; - box-sizing:border-box; +#editorStampButton::before { + -webkit-mask-image: var(--toolbarButton-editorStamp-icon); + mask-image: var(--toolbarButton-editorStamp-icon); } -.horizontalToolbarSeparator{ - display:block; - margin:6px 0; - border-top:1px solid var(--doorhanger-separator-color); - border-bottom:none; - height:0; - width:100%; +#editorSignatureButton::before { + -webkit-mask-image: var(--toolbarButton-editorSignature-icon); + mask-image: var(--toolbarButton-editorSignature-icon); } -.toggleButton{ - display:inline; +#printButton::before { + -webkit-mask-image: var(--toolbarButton-print-icon); + mask-image: var(--toolbarButton-print-icon); } -.toggleButton:has( > input:checked){ - color:var(--toggled-btn-color); - background-color:var(--toggled-btn-bg-color); - } - -.toggleButton:is(:hover,:has( > input:focus-visible)){ - color:var(--toggled-btn-color); - background-color:var(--button-hover-color); - } - -.toggleButton > input{ - position:absolute; - top:50%; - left:50%; - opacity:0; - width:0; - height:0; - } - -.toolbarField{ - padding:4px 7px; - margin:3px 0; - border-radius:2px; - background-color:var(--field-bg-color); - background-clip:padding-box; - border:1px solid var(--field-border-color); - box-shadow:none; - color:var(--field-color); - font-size:12px; - line-height:16px; - outline:none; +#downloadButton::before { + -webkit-mask-image: var(--toolbarButton-download-icon); + mask-image: var(--toolbarButton-download-icon); } -.toolbarField:focus{ - border-color:#0a84ff; - } - -#pageNumber{ - -moz-appearance:textfield; - text-align:end; - width:40px; - background-size:0 0; - transition-property:none; +#currentOutlineItem::before { + -webkit-mask-image: var(--toolbarButton-currentOutlineItem-icon); + mask-image: var(--toolbarButton-currentOutlineItem-icon); + transform: scaleX(var(--dir-factor)); } -#pageNumber::-webkit-inner-spin-button{ - -webkit-appearance:none; - } - -.loadingInput:has( > .loading:is(#pageNumber))::after{ - display:inline; - visibility:visible; - - transition-property:visibility; - transition-delay:var(--loading-icon-delay); - } - -.loadingInput{ - position:relative; +#viewFindButton::before { + -webkit-mask-image: var(--toolbarButton-search-icon); + mask-image: var(--toolbarButton-search-icon); } -.loadingInput::after{ - position:absolute; - visibility:hidden; - display:none; - width:var(--icon-size); - height:var(--icon-size); +.pdfSidebarNotification::after { + position: absolute; + display: inline-block; + top: 2px; + inset-inline-end: 2px; + content: ''; + background-color: rgb(112 219 85); + height: 9px; + width: 9px; + border-radius: 50%; +} - content:""; - background-color:var(--toolbar-icon-bg-color); - -webkit-mask-size:cover; - mask-size:cover; - -webkit-mask-image:var(--loading-icon); - mask-image:var(--loading-icon); - } +.verticalToolbarSeparator { + display: block; + margin-inline: 2px; + width: 0; + height: 80%; + border-left: 1px solid var(--separator-color); + border-right: none; + box-sizing: border-box; +} -.loadingInput.start::after{ - inset-inline-start:4px; - } +.horizontalToolbarSeparator { + display: block; + margin: 6px 0; + border-top: 1px solid var(--doorhanger-separator-color); + border-bottom: none; + height: 0; + width: 100%; +} -.loadingInput.end::after{ - inset-inline-end:4px; - } +.toggleButton { + display: inline; +} + +.toggleButton:has(> input:checked) { + color: var(--toggled-btn-color); + background-color: var(--toggled-btn-bg-color); +} + +.toggleButton:is(:hover, :has(> input:focus-visible)) { + color: var(--toggled-btn-color); + background-color: var(--button-hover-color); +} + +.toggleButton > input { + position: absolute; + top: 50%; + left: 50%; + opacity: 0; + width: 0; + height: 0; +} + +.toolbarField { + padding: 4px 7px; + margin: 3px 0; + border-radius: 2px; + background-color: var(--field-bg-color); + background-clip: padding-box; + border: 1px solid var(--field-border-color); + box-shadow: none; + color: var(--field-color); + font-size: 12px; + line-height: 16px; + outline: none; +} + +.toolbarField:focus { + border-color: #0a84ff; +} + +#pageNumber { + -moz-appearance: textfield; + text-align: end; + width: 40px; + background-size: 0 0; + transition-property: none; +} + +#pageNumber::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +.loadingInput:has(> .loading:is(#pageNumber))::after { + display: inline; + visibility: visible; + + transition-property: visibility; + transition-delay: var(--loading-icon-delay); +} + +.loadingInput { + position: relative; +} + +.loadingInput::after { + position: absolute; + visibility: hidden; + display: none; + width: var(--icon-size); + height: var(--icon-size); + + content: ''; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; + -webkit-mask-image: var(--loading-icon); + mask-image: var(--loading-icon); +} + +.loadingInput.start::after { + inset-inline-start: 4px; +} + +.loadingInput.end::after { + inset-inline-end: 4px; +} #thumbnailView, #outlineView, #attachmentsView, -#layersView{ - position:absolute; - width:calc(100% - 8px); - inset-block:0; - padding:4px 4px 0; - overflow:auto; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; +#layersView { + position: absolute; + width: calc(100% - 8px); + inset-block: 0; + padding: 4px 4px 0; + overflow: auto; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; } -#thumbnailView{ - width:calc(100% - 60px); - padding:10px 30px 0; +#thumbnailView { + width: calc(100% - 60px); + padding: 10px 30px 0; } -#thumbnailView > a:is(:active, :focus){ - outline:0; +#thumbnailView > a:is(:active, :focus) { + outline: 0; } -.thumbnail{ - --thumbnail-width:0; - --thumbnail-height:0; +.thumbnail { + --thumbnail-width: 0; + --thumbnail-height: 0; - float:var(--inline-start); - width:var(--thumbnail-width); - height:var(--thumbnail-height); - margin:0 10px 5px; - padding:1px; - border:7px solid transparent; - border-radius:2px; + float: var(--inline-start); + width: var(--thumbnail-width); + height: var(--thumbnail-height); + margin: 0 10px 5px; + padding: 1px; + border: 7px solid transparent; + border-radius: 2px; } -#thumbnailView > a:last-of-type > .thumbnail{ - margin-bottom:10px; +#thumbnailView > a:last-of-type > .thumbnail { + margin-bottom: 10px; } a:focus > .thumbnail, -.thumbnail:hover{ - border-color:var(--thumbnail-hover-color); +.thumbnail:hover { + border-color: var(--thumbnail-hover-color); } -.thumbnail.selected{ - border-color:var(--thumbnail-selected-color) !important; +.thumbnail.selected { + border-color: var(--thumbnail-selected-color) !important; } -.thumbnailImage{ - width:var(--thumbnail-width); - height:var(--thumbnail-height); - opacity:0.9; +.thumbnailImage { + width: var(--thumbnail-width); + height: var(--thumbnail-height); + opacity: 0.9; } a:focus > .thumbnail > .thumbnailImage, -.thumbnail:hover > .thumbnailImage{ - opacity:0.95; +.thumbnail:hover > .thumbnailImage { + opacity: 0.95; } -.thumbnail.selected > .thumbnailImage{ - opacity:1 !important; +.thumbnail.selected > .thumbnailImage { + opacity: 1 !important; } -.thumbnail:not([data-loaded]) > .thumbnailImage{ - width:calc(var(--thumbnail-width) - 2px); - height:calc(var(--thumbnail-height) - 2px); - border:1px dashed rgb(132 132 132); +.thumbnail:not([data-loaded]) > .thumbnailImage { + width: calc(var(--thumbnail-width) - 2px); + height: calc(var(--thumbnail-height) - 2px); + border: 1px dashed rgb(132 132 132); } .treeWithDeepNesting > .treeItem, -.treeItem > .treeItems{ - margin-inline-start:20px; +.treeItem > .treeItems { + margin-inline-start: 20px; } -.treeItem > a{ - text-decoration:none; - display:inline-block; - min-width:calc(100% - 4px); - height:auto; - margin-bottom:1px; - padding:2px 0 5px; - padding-inline-start:4px; - border-radius:2px; - color:var(--treeitem-color); - font-size:13px; - line-height:15px; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - white-space:normal; - cursor:pointer; +.treeItem > a { + text-decoration: none; + display: inline-block; + min-width: calc(100% - 4px); + height: auto; + margin-bottom: 1px; + padding: 2px 0 5px; + padding-inline-start: 4px; + border-radius: 2px; + color: var(--treeitem-color); + font-size: 13px; + line-height: 15px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + white-space: normal; + cursor: pointer; } -#layersView .treeItem > a *{ - cursor:pointer; +#layersView .treeItem > a * { + cursor: pointer; } -#layersView .treeItem > a > label{ - padding-inline-start:4px; +#layersView .treeItem > a > label { + padding-inline-start: 4px; } -#layersView .treeItem > a > label > input{ - float:var(--inline-start); - margin-top:1px; +#layersView .treeItem > a > label > input { + float: var(--inline-start); + margin-top: 1px; } -.treeItemToggler{ - position:relative; - float:var(--inline-start); - height:0; - width:0; - color:rgb(255 255 255 / 0.5); +.treeItemToggler { + position: relative; + float: var(--inline-start); + height: 0; + width: 0; + color: rgb(255 255 255 / 0.5); } -.treeItemToggler::before{ - inset-inline-end:4px; - -webkit-mask-image:var(--treeitem-expanded-icon); - mask-image:var(--treeitem-expanded-icon); +.treeItemToggler::before { + inset-inline-end: 4px; + -webkit-mask-image: var(--treeitem-expanded-icon); + mask-image: var(--treeitem-expanded-icon); } -.treeItemToggler.treeItemsHidden::before{ - -webkit-mask-image:var(--treeitem-collapsed-icon); - mask-image:var(--treeitem-collapsed-icon); - transform:scaleX(var(--dir-factor)); +.treeItemToggler.treeItemsHidden::before { + -webkit-mask-image: var(--treeitem-collapsed-icon); + mask-image: var(--treeitem-collapsed-icon); + transform: scaleX(var(--dir-factor)); } -.treeItemToggler.treeItemsHidden ~ .treeItems{ - display:none; +.treeItemToggler.treeItemsHidden ~ .treeItems { + display: none; } -.treeItem.selected > a{ - background-color:var(--treeitem-selected-bg-color); - color:var(--treeitem-selected-color); +.treeItem.selected > a { + background-color: var(--treeitem-selected-bg-color); + color: var(--treeitem-selected-color); } .treeItemToggler:hover, .treeItemToggler:hover + a, .treeItemToggler:hover ~ .treeItems, -.treeItem > a:hover{ - background-color:var(--treeitem-bg-color); - background-clip:padding-box; - border-radius:2px; - color:var(--treeitem-hover-color); +.treeItem > a:hover { + background-color: var(--treeitem-bg-color); + background-clip: padding-box; + border-radius: 2px; + color: var(--treeitem-hover-color); } -#outlineOptionsContainer{ - display:none; +#outlineOptionsContainer { + display: none; } -#sidebarContainer:has(#outlineView:not(.hidden)) #outlineOptionsContainer{ - display:inline flex; - } - -.dialogButton{ - width:auto; - margin:3px 4px 2px !important; - padding:2px 11px; - color:var(--main-color); - background-color:var(--dialog-button-bg-color); - border:var(--dialog-button-border) !important; +#sidebarContainer:has(#outlineView:not(.hidden)) #outlineOptionsContainer { + display: inline flex; } -dialog{ - margin:auto; - padding:15px; - border-spacing:4px; - color:var(--main-color); - font:message-box; - font-size:12px; - line-height:14px; - background-color:var(--doorhanger-bg-color); - border:1px solid rgb(0 0 0 / 0.5); - border-radius:4px; - box-shadow:0 1px 4px rgb(0 0 0 / 0.3); +.dialogButton { + width: auto; + margin: 3px 4px 2px !important; + padding: 2px 11px; + color: var(--main-color); + background-color: var(--dialog-button-bg-color); + border: var(--dialog-button-border) !important; } -dialog::backdrop{ - background-color:rgb(0 0 0 / 0.2); +dialog { + margin: auto; + padding: 15px; + border-spacing: 4px; + color: var(--main-color); + font: message-box; + font-size: 12px; + line-height: 14px; + background-color: var(--doorhanger-bg-color); + border: 1px solid rgb(0 0 0 / 0.5); + border-radius: 4px; + box-shadow: 0 1px 4px rgb(0 0 0 / 0.3); } -dialog > .row{ - display:table-row; +dialog::backdrop { + background-color: rgb(0 0 0 / 0.2); } -dialog > .row > *{ - display:table-cell; +dialog > .row { + display: table-row; } -dialog .toolbarField{ - margin:5px 0; +dialog > .row > * { + display: table-cell; } -dialog .separator{ - display:block; - margin:4px 0; - height:0; - width:100%; - border-top:1px solid var(--separator-color); - border-bottom:none; +dialog .toolbarField { + margin: 5px 0; } -dialog .buttonRow{ - text-align:center; - vertical-align:middle; +dialog .separator { + display: block; + margin: 4px 0; + height: 0; + width: 100%; + border-top: 1px solid var(--separator-color); + border-bottom: none; } -dialog :link{ - color:rgb(255 255 255); +dialog .buttonRow { + text-align: center; + vertical-align: middle; } -#passwordDialog{ - text-align:center; +dialog :link { + color: rgb(255 255 255); } -#passwordDialog .toolbarField{ - width:200px; +#passwordDialog { + text-align: center; } -#documentPropertiesDialog{ - text-align:left; +#passwordDialog .toolbarField { + width: 200px; } -#documentPropertiesDialog .row > *{ - min-width:100px; - text-align:start; +#documentPropertiesDialog { + text-align: left; } -#documentPropertiesDialog .row > span{ - width:125px; - word-wrap:break-word; +#documentPropertiesDialog .row > * { + min-width: 100px; + text-align: start; } -#documentPropertiesDialog .row > p{ - max-width:225px; - word-wrap:break-word; +#documentPropertiesDialog .row > span { + width: 125px; + word-wrap: break-word; } -#documentPropertiesDialog .buttonRow{ - margin-top:10px; +#documentPropertiesDialog .row > p { + max-width: 225px; + word-wrap: break-word; } -.grab-to-pan-grab{ - cursor:grab !important; +#documentPropertiesDialog .buttonRow { + margin-top: 10px; +} + +.grab-to-pan-grab { + cursor: grab !important; } .grab-to-pan-grab - *:not(input):not(textarea):not(button):not(select):not(:link){ - cursor:inherit !important; + *:not(input):not(textarea):not(button):not(select):not(:link) { + cursor: inherit !important; } .grab-to-pan-grab:active, -.grab-to-pan-grabbing{ - cursor:grabbing !important; +.grab-to-pan-grabbing { + cursor: grabbing !important; } -.grab-to-pan-grabbing{ - position:fixed; - background:rgb(0 0 0 / 0); - display:block; - inset:0; - overflow:hidden; - z-index:50000; +.grab-to-pan-grabbing { + position: fixed; + background: rgb(0 0 0 / 0); + display: block; + inset: 0; + overflow: hidden; + z-index: 50000; } -.toolbarButton{ - height:100%; - aspect-ratio:1; - display:flex; - align-items:center; - justify-content:center; - background:none; - border:none; - color:var(--main-color); - outline:none; - border-radius:2px; - box-sizing:border-box; - font:message-box; - flex:none; - position:relative; - padding:0; +.toolbarButton { + height: 100%; + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + color: var(--main-color); + outline: none; + border-radius: 2px; + box-sizing: border-box; + font: message-box; + flex: none; + position: relative; + padding: 0; } -.toolbarButton > span{ - display:inline-block; - width:0; - height:0; - overflow:hidden; - } - -.toolbarButton::before{ - opacity:var(--toolbar-icon-opacity); - display:inline-block; - width:var(--icon-size); - height:var(--icon-size); - content:""; - background-color:var(--toolbar-icon-bg-color); - -webkit-mask-size:cover; - mask-size:cover; - -webkit-mask-position:center; - mask-position:center; - } - -.toolbarButton.toggled{ - background-color:var(--toggled-btn-bg-color); - color:var(--toggled-btn-color); - } - -.toolbarButton.toggled::before{ - background-color:var(--toggled-btn-color); - } - -.toolbarButton.toggled:hover{ - outline:var(--toggled-hover-btn-outline) !important; - } - -.toolbarButton.toggled:hover:active{ - background-color:var(--toggled-hover-active-btn-color); - } - -.toolbarButton:is(:hover,:focus-visible){ - background-color:var(--button-hover-color); - } - -.toolbarButton:is(:hover,:focus-visible)::before{ - background-color:var(--toolbar-icon-hover-bg-color); - } - -.toolbarButton:is([disabled="disabled"],[disabled]){ - opacity:0.5; - pointer-events:none; - } - -.toolbarButton.labeled{ - width:100%; - min-height:var(--menuitem-height); - justify-content:flex-start; - gap:8px; - padding-inline-start:12px; - aspect-ratio:unset; - text-align:start; - white-space:normal; - cursor:default; - } - -.toolbarButton.labeled:is(a){ - text-decoration:none; - } - -.toolbarButton.labeled[href="#"]:is(a){ - opacity:0.5; - pointer-events:none; - } - -.toolbarButton.labeled::before{ - opacity:var(--doorhanger-icon-opacity); - } - -.toolbarButton.labeled:is(:hover,:focus-visible){ - color:var(--doorhanger-hover-color); - } - -.toolbarButton.labeled > span{ - display:inline-block; - width:-moz-max-content; - width:max-content; - height:auto; - } - -.toolbarButtonWithContainer{ - height:100%; - aspect-ratio:1; - display:inline-block; - position:relative; - flex:none; +.toolbarButton > span { + display: inline-block; + width: 0; + height: 0; + overflow: hidden; } -.toolbarButtonWithContainer > .toolbarButton{ - width:100%; - height:100%; - } - -.toolbarButtonWithContainer .menu{ - padding-block:5px; - } - -.toolbarButtonWithContainer .menuContainer{ - height:auto; - max-height:calc( - var(--viewer-container-height) - var(--toolbar-height) - - var(--doorhanger-height) - ); - display:flex; - flex-direction:column; - box-sizing:border-box; - overflow-y:auto; - } - -.toolbarButtonWithContainer .editorParamsToolbar{ - --editor-toolbar-min-width:220px; - - height:auto; - min-width:var(--editor-toolbar-min-width); - width:-moz-max-content; - width:max-content; - position:absolute; - z-index:30000; - cursor:default; - } - -:is(.toolbarButtonWithContainer .editorParamsToolbar) :is(#editorStampAddImage,#editorSignatureAddSignature)::before{ - -webkit-mask-image:var(--editorParams-stampAddImage-icon); - mask-image:var(--editorParams-stampAddImage-icon); - } - -:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsLabel{ - flex:none; - font:menu; - font-size:13px; - font-style:normal; - font-weight:400; - line-height:150%; - width:-moz-fit-content; - width:fit-content; - inset-inline-start:0; - color:var(--main-color); - } - -:is(.toolbarButtonWithContainer .editorParamsToolbar) button:is(:hover,:focus-visible) .editorParamsLabel{ - color:var(--doorhanger-hover-color); - } - -:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer{ - width:100%; - height:auto; - display:flex; - flex-direction:column; - box-sizing:border-box; - padding-inline:10px; - padding-block:10px; - } - -:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) > .editorParamsSetter{ - min-height:26px; - display:flex; - align-items:center; - justify-content:space-between; - } - -:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsColor{ - width:32px; - height:32px; - flex:none; - padding:0; - } - -:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider{ - background-color:transparent; - width:90px; - flex:0 1 0; - font:message-box; - } - -:is(:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider)::-moz-range-progress{ - background-color:black; - } - -:is(:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider)::-webkit-slider-runnable-track,:is(:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider)::-moz-range-track{ - background-color:black; - } - -:is(:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider)::-webkit-slider-thumb,:is(:is(:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsToolbarContainer) .editorParamsSlider)::-moz-range-thumb{ - background-color:white; - } - -#secondaryToolbar{ - height:auto; - width:220px; - position:absolute; - z-index:30000; - cursor:default; - min-height:26px; - max-height:calc(var(--viewer-container-height) - 40px); +.toolbarButton::before { + opacity: var(--toolbar-icon-opacity); + display: inline-block; + width: var(--icon-size); + height: var(--icon-size); + content: ''; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; + -webkit-mask-position: center; + mask-position: center; } -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #secondaryOpenFile::before{ - -webkit-mask-image:var(--toolbarButton-openFile-icon); - mask-image:var(--toolbarButton-openFile-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #secondaryPrint::before{ - -webkit-mask-image:var(--toolbarButton-print-icon); - mask-image:var(--toolbarButton-print-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #secondaryDownload::before{ - -webkit-mask-image:var(--toolbarButton-download-icon); - mask-image:var(--toolbarButton-download-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #presentationMode::before{ - -webkit-mask-image:var(--toolbarButton-presentationMode-icon); - mask-image:var(--toolbarButton-presentationMode-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #viewBookmark::before{ - -webkit-mask-image:var(--toolbarButton-bookmark-icon); - mask-image:var(--toolbarButton-bookmark-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #firstPage::before{ - -webkit-mask-image:var(--secondaryToolbarButton-firstPage-icon); - mask-image:var(--secondaryToolbarButton-firstPage-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #lastPage::before{ - -webkit-mask-image:var(--secondaryToolbarButton-lastPage-icon); - mask-image:var(--secondaryToolbarButton-lastPage-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #pageRotateCcw::before{ - -webkit-mask-image:var(--secondaryToolbarButton-rotateCcw-icon); - mask-image:var(--secondaryToolbarButton-rotateCcw-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #pageRotateCw::before{ - -webkit-mask-image:var(--secondaryToolbarButton-rotateCw-icon); - mask-image:var(--secondaryToolbarButton-rotateCw-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #cursorSelectTool::before{ - -webkit-mask-image:var(--secondaryToolbarButton-selectTool-icon); - mask-image:var(--secondaryToolbarButton-selectTool-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #cursorHandTool::before{ - -webkit-mask-image:var(--secondaryToolbarButton-handTool-icon); - mask-image:var(--secondaryToolbarButton-handTool-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollPage::before{ - -webkit-mask-image:var(--secondaryToolbarButton-scrollPage-icon); - mask-image:var(--secondaryToolbarButton-scrollPage-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollVertical::before{ - -webkit-mask-image:var(--secondaryToolbarButton-scrollVertical-icon); - mask-image:var(--secondaryToolbarButton-scrollVertical-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollHorizontal::before{ - -webkit-mask-image:var(--secondaryToolbarButton-scrollHorizontal-icon); - mask-image:var(--secondaryToolbarButton-scrollHorizontal-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollWrapped::before{ - -webkit-mask-image:var(--secondaryToolbarButton-scrollWrapped-icon); - mask-image:var(--secondaryToolbarButton-scrollWrapped-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadNone::before{ - -webkit-mask-image:var(--secondaryToolbarButton-spreadNone-icon); - mask-image:var(--secondaryToolbarButton-spreadNone-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadOdd::before{ - -webkit-mask-image:var(--secondaryToolbarButton-spreadOdd-icon); - mask-image:var(--secondaryToolbarButton-spreadOdd-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadEven::before{ - -webkit-mask-image:var(--secondaryToolbarButton-spreadEven-icon); - mask-image:var(--secondaryToolbarButton-spreadEven-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #imageAltTextSettings::before{ - -webkit-mask-image:var(--secondaryToolbarButton-imageAltTextSettings-icon); - mask-image:var(--secondaryToolbarButton-imageAltTextSettings-icon); - } - -:is(#secondaryToolbar #secondaryToolbarButtonContainer) #documentProperties::before{ - -webkit-mask-image:var(--secondaryToolbarButton-documentProperties-icon); - mask-image:var(--secondaryToolbarButton-documentProperties-icon); - } - -#findbar{ - --input-horizontal-padding:4px; - --findbar-padding:2px; - - width:-moz-max-content; - - width:max-content; - max-width:90vw; - min-height:var(--toolbar-height); - height:auto; - position:absolute; - z-index:30000; - cursor:default; - padding:0; - min-width:300px; - background-color:var(--toolbar-bg-color); - box-sizing:border-box; - flex-wrap:wrap; - justify-content:flex-start; +.toolbarButton.toggled { + background-color: var(--toggled-btn-bg-color); + color: var(--toggled-btn-color); } -#findbar > *{ - height:var(--toolbar-height); - padding:var(--findbar-padding); - } - -#findbar #findInputContainer{ - margin-inline-start:2px; - } - -:is(#findbar #findInputContainer) #findPreviousButton::before{ - -webkit-mask-image:var(--findbarButton-previous-icon); - mask-image:var(--findbarButton-previous-icon); - } - -:is(#findbar #findInputContainer) #findNextButton::before{ - -webkit-mask-image:var(--findbarButton-next-icon); - mask-image:var(--findbarButton-next-icon); - } - -:is(#findbar #findInputContainer) #findInput{ - width:200px; - padding:5px var(--input-horizontal-padding); - } - -:is(:is(#findbar #findInputContainer) #findInput)::-moz-placeholder{ - font-style:normal; - } - -:is(:is(#findbar #findInputContainer) #findInput)::placeholder{ - font-style:normal; - } - -.loadingInput:has( > [data-status="pending"]:is(:is(#findbar #findInputContainer) #findInput))::after{ - display:inline; - visibility:visible; - inset-inline-end:calc(var(--input-horizontal-padding) + 1px); - } - -[data-status="notFound"]:is(:is(#findbar #findInputContainer) #findInput){ - background-color:rgb(255 102 102); - } - -#findbar #findbarMessageContainer{ - display:none; - gap:4px; - } - -:is(#findbar #findbarMessageContainer):has( > :is(#findResultsCount,#findMsg):not(:empty)){ - display:inline flex; - } - -:is(#findbar #findbarMessageContainer) #findResultsCount{ - background-color:rgb(217 217 217); - color:rgb(82 82 82); - padding-block:4px; - } - -:is(:is(#findbar #findbarMessageContainer) #findResultsCount):empty{ - display:none; - } - -[data-status="notFound"]:is(:is(#findbar #findbarMessageContainer) #findMsg){ - font-weight:bold; - } - -:is(:is(#findbar #findbarMessageContainer) #findMsg):empty{ - display:none; - } - -#findbar.wrapContainers{ - flex-direction:column; - align-items:flex-start; - height:-moz-max-content; - height:max-content; - } - -#findbar.wrapContainers .toolbarLabel{ - margin:0 4px; - } - -#findbar.wrapContainers #findbarMessageContainer{ - flex-wrap:wrap; - flex-flow:column nowrap; - align-items:flex-start; - height:-moz-max-content; - height:max-content; - } - -:is(#findbar.wrapContainers #findbarMessageContainer) #findResultsCount{ - height:calc(var(--toolbar-height) - 2 * var(--findbar-padding)); - } - -:is(#findbar.wrapContainers #findbarMessageContainer) #findMsg{ - min-height:var(--toolbar-height); - } - -@page{ - margin:0; +.toolbarButton.toggled::before { + background-color: var(--toggled-btn-color); } -#printContainer{ - display:none; +.toolbarButton.toggled:hover { + outline: var(--toggled-hover-btn-outline) !important; } -@media print{ - body{ - background:rgb(0 0 0 / 0) none; +.toolbarButton.toggled:hover:active { + background-color: var(--toggled-hover-active-btn-color); +} + +.toolbarButton:is(:hover, :focus-visible) { + background-color: var(--button-hover-color); +} + +.toolbarButton:is(:hover, :focus-visible)::before { + background-color: var(--toolbar-icon-hover-bg-color); +} + +.toolbarButton:is([disabled='disabled'], [disabled]) { + opacity: 0.5; + pointer-events: none; +} + +.toolbarButton.labeled { + width: 100%; + min-height: var(--menuitem-height); + justify-content: flex-start; + gap: 8px; + padding-inline-start: 12px; + aspect-ratio: unset; + text-align: start; + white-space: normal; + cursor: default; +} + +.toolbarButton.labeled:is(a) { + text-decoration: none; +} + +.toolbarButton.labeled[href='#']:is(a) { + opacity: 0.5; + pointer-events: none; +} + +.toolbarButton.labeled::before { + opacity: var(--doorhanger-icon-opacity); +} + +.toolbarButton.labeled:is(:hover, :focus-visible) { + color: var(--doorhanger-hover-color); +} + +.toolbarButton.labeled > span { + display: inline-block; + width: -moz-max-content; + width: max-content; + height: auto; +} + +.toolbarButtonWithContainer { + height: 100%; + aspect-ratio: 1; + display: inline-block; + position: relative; + flex: none; +} + +.toolbarButtonWithContainer > .toolbarButton { + width: 100%; + height: 100%; +} + +.toolbarButtonWithContainer .menu { + padding-block: 5px; +} + +.toolbarButtonWithContainer .menuContainer { + height: auto; + max-height: calc( + var(--viewer-container-height) - var(--toolbar-height) - + var(--doorhanger-height) + ); + display: flex; + flex-direction: column; + box-sizing: border-box; + overflow-y: auto; +} + +.toolbarButtonWithContainer .editorParamsToolbar { + --editor-toolbar-min-width: 220px; + + height: auto; + min-width: var(--editor-toolbar-min-width); + width: -moz-max-content; + width: max-content; + position: absolute; + z-index: 30000; + cursor: default; +} + +:is(.toolbarButtonWithContainer .editorParamsToolbar) + :is(#editorStampAddImage, #editorSignatureAddSignature)::before { + -webkit-mask-image: var(--editorParams-stampAddImage-icon); + mask-image: var(--editorParams-stampAddImage-icon); +} + +:is(.toolbarButtonWithContainer .editorParamsToolbar) .editorParamsLabel { + flex: none; + font: menu; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 150%; + width: -moz-fit-content; + width: fit-content; + inset-inline-start: 0; + color: var(--main-color); +} + +:is(.toolbarButtonWithContainer .editorParamsToolbar) + button:is(:hover, :focus-visible) + .editorParamsLabel { + color: var(--doorhanger-hover-color); +} + +:is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer { + width: 100%; + height: auto; + display: flex; + flex-direction: column; + box-sizing: border-box; + padding-inline: 10px; + padding-block: 10px; +} + +:is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + > .editorParamsSetter { + min-height: 26px; + display: flex; + align-items: center; + justify-content: space-between; +} + +:is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsColor { + width: 32px; + height: 32px; + flex: none; + padding: 0; +} + +:is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider { + background-color: transparent; + width: 90px; + flex: 0 1 0; + font: message-box; +} + +:is( + :is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider +)::-moz-range-progress { + background-color: black; +} + +:is( + :is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider +)::-webkit-slider-runnable-track, +:is( + :is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider +)::-moz-range-track { + background-color: black; +} + +:is( + :is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider +)::-webkit-slider-thumb, +:is( + :is( + :is(.toolbarButtonWithContainer .editorParamsToolbar) + .editorParamsToolbarContainer + ) + .editorParamsSlider +)::-moz-range-thumb { + background-color: white; +} + +#secondaryToolbar { + height: auto; + width: 220px; + position: absolute; + z-index: 30000; + cursor: default; + min-height: 26px; + max-height: calc(var(--viewer-container-height) - 40px); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #secondaryOpenFile::before { + -webkit-mask-image: var(--toolbarButton-openFile-icon); + mask-image: var(--toolbarButton-openFile-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #secondaryPrint::before { + -webkit-mask-image: var(--toolbarButton-print-icon); + mask-image: var(--toolbarButton-print-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #secondaryDownload::before { + -webkit-mask-image: var(--toolbarButton-download-icon); + mask-image: var(--toolbarButton-download-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #presentationMode::before { + -webkit-mask-image: var(--toolbarButton-presentationMode-icon); + mask-image: var(--toolbarButton-presentationMode-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #viewBookmark::before { + -webkit-mask-image: var(--toolbarButton-bookmark-icon); + mask-image: var(--toolbarButton-bookmark-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #firstPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-firstPage-icon); + mask-image: var(--secondaryToolbarButton-firstPage-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #lastPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-lastPage-icon); + mask-image: var(--secondaryToolbarButton-lastPage-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #pageRotateCcw::before { + -webkit-mask-image: var(--secondaryToolbarButton-rotateCcw-icon); + mask-image: var(--secondaryToolbarButton-rotateCcw-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #pageRotateCw::before { + -webkit-mask-image: var(--secondaryToolbarButton-rotateCw-icon); + mask-image: var(--secondaryToolbarButton-rotateCw-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #cursorSelectTool::before { + -webkit-mask-image: var(--secondaryToolbarButton-selectTool-icon); + mask-image: var(--secondaryToolbarButton-selectTool-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #cursorHandTool::before { + -webkit-mask-image: var(--secondaryToolbarButton-handTool-icon); + mask-image: var(--secondaryToolbarButton-handTool-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollPage-icon); + mask-image: var(--secondaryToolbarButton-scrollPage-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #scrollVertical::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollVertical-icon); + mask-image: var(--secondaryToolbarButton-scrollVertical-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #scrollHorizontal::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollHorizontal-icon); + mask-image: var(--secondaryToolbarButton-scrollHorizontal-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #scrollWrapped::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollWrapped-icon); + mask-image: var(--secondaryToolbarButton-scrollWrapped-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadNone::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadNone-icon); + mask-image: var(--secondaryToolbarButton-spreadNone-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadOdd::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadOdd-icon); + mask-image: var(--secondaryToolbarButton-spreadOdd-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) #spreadEven::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadEven-icon); + mask-image: var(--secondaryToolbarButton-spreadEven-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #imageAltTextSettings::before { + -webkit-mask-image: var(--secondaryToolbarButton-imageAltTextSettings-icon); + mask-image: var(--secondaryToolbarButton-imageAltTextSettings-icon); +} + +:is(#secondaryToolbar #secondaryToolbarButtonContainer) + #documentProperties::before { + -webkit-mask-image: var(--secondaryToolbarButton-documentProperties-icon); + mask-image: var(--secondaryToolbarButton-documentProperties-icon); +} + +#findbar { + --input-horizontal-padding: 4px; + --findbar-padding: 2px; + + width: -moz-max-content; + + width: max-content; + max-width: 90vw; + min-height: var(--toolbar-height); + height: auto; + position: absolute; + z-index: 30000; + cursor: default; + padding: 0; + min-width: 300px; + background-color: var(--toolbar-bg-color); + box-sizing: border-box; + flex-wrap: wrap; + justify-content: flex-start; +} + +#findbar > * { + height: var(--toolbar-height); + padding: var(--findbar-padding); +} + +#findbar #findInputContainer { + margin-inline-start: 2px; +} + +:is(#findbar #findInputContainer) #findPreviousButton::before { + -webkit-mask-image: var(--findbarButton-previous-icon); + mask-image: var(--findbarButton-previous-icon); +} + +:is(#findbar #findInputContainer) #findNextButton::before { + -webkit-mask-image: var(--findbarButton-next-icon); + mask-image: var(--findbarButton-next-icon); +} + +:is(#findbar #findInputContainer) #findInput { + width: 200px; + padding: 5px var(--input-horizontal-padding); +} + +:is(:is(#findbar #findInputContainer) #findInput)::-moz-placeholder { + font-style: normal; +} + +:is(:is(#findbar #findInputContainer) #findInput)::placeholder { + font-style: normal; +} + +.loadingInput:has( + > [data-status='pending']:is(:is(#findbar #findInputContainer) #findInput) + )::after { + display: inline; + visibility: visible; + inset-inline-end: calc(var(--input-horizontal-padding) + 1px); +} + +[data-status='notFound']:is(:is(#findbar #findInputContainer) #findInput) { + background-color: rgb(255 102 102); +} + +#findbar #findbarMessageContainer { + display: none; + gap: 4px; +} + +:is(#findbar #findbarMessageContainer):has( + > :is(#findResultsCount, #findMsg):not(:empty) +) { + display: inline flex; +} + +:is(#findbar #findbarMessageContainer) #findResultsCount { + background-color: rgb(217 217 217); + color: rgb(82 82 82); + padding-block: 4px; +} + +:is(:is(#findbar #findbarMessageContainer) #findResultsCount):empty { + display: none; +} + +[data-status='notFound']:is(:is(#findbar #findbarMessageContainer) #findMsg) { + font-weight: bold; +} + +:is(:is(#findbar #findbarMessageContainer) #findMsg):empty { + display: none; +} + +#findbar.wrapContainers { + flex-direction: column; + align-items: flex-start; + height: -moz-max-content; + height: max-content; +} + +#findbar.wrapContainers .toolbarLabel { + margin: 0 4px; +} + +#findbar.wrapContainers #findbarMessageContainer { + flex-wrap: wrap; + flex-flow: column nowrap; + align-items: flex-start; + height: -moz-max-content; + height: max-content; +} + +:is(#findbar.wrapContainers #findbarMessageContainer) #findResultsCount { + height: calc(var(--toolbar-height) - 2 * var(--findbar-padding)); +} + +:is(#findbar.wrapContainers #findbarMessageContainer) #findMsg { + min-height: var(--toolbar-height); +} + +@page { + margin: 0; +} + +#printContainer { + display: none; +} + +@media print { + body { + background: rgb(0 0 0 / 0) none; } - body[data-pdfjsprinting] #outerContainer{ - display:none; + body[data-pdfjsprinting] #outerContainer { + display: none; } - body[data-pdfjsprinting] #printContainer{ - display:block; + body[data-pdfjsprinting] #printContainer { + display: block; } - #printContainer{ - height:100%; + #printContainer { + height: 100%; } - #printContainer > .printedPage{ - page-break-after:always; - page-break-inside:avoid; - height:100%; - width:100%; + #printContainer > .printedPage { + page-break-after: always; + page-break-inside: avoid; + height: 100%; + width: 100%; - display:flex; - flex-direction:column; - justify-content:center; - align-items:center; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; } - #printContainer > .xfaPrintedPage .xfaPage{ - position:absolute; + #printContainer > .xfaPrintedPage .xfaPage { + position: absolute; } - #printContainer > .xfaPrintedPage{ - page-break-after:always; - page-break-inside:avoid; - width:100%; - height:100%; - position:relative; + #printContainer > .xfaPrintedPage { + page-break-after: always; + page-break-inside: avoid; + width: 100%; + height: 100%; + position: relative; } - #printContainer > .printedPage :is(canvas, img){ - max-width:100%; - max-height:100%; + #printContainer > .printedPage :is(canvas, img) { + max-width: 100%; + max-height: 100%; - direction:ltr; - display:block; + direction: ltr; + display: block; } } -.visibleMediumView{ - display:none !important; +.visibleMediumView { + display: none !important; } -.toolbarLabel{ - width:-moz-max-content; - width:max-content; - min-width:16px; - height:100%; - padding-inline:4px; - margin:2px; - border-radius:2px; - color:var(--main-color); - font-size:12px; - line-height:14px; - text-align:left; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - cursor:default; - box-sizing:border-box; +.toolbarLabel { + width: -moz-max-content; + width: max-content; + min-width: 16px; + height: 100%; + padding-inline: 4px; + margin: 2px; + border-radius: 2px; + color: var(--main-color); + font-size: 12px; + line-height: 14px; + text-align: left; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; + box-sizing: border-box; - display:inline flex; - flex-direction:column; - align-items:center; - justify-content:center; + display: inline flex; + flex-direction: column; + align-items: center; + justify-content: center; } -.toolbarLabel > label{ - width:100%; - } - -.toolbarHorizontalGroup{ - height:100%; - display:inline flex; - flex-direction:row; - align-items:center; - justify-content:space-between; - gap:1px; - box-sizing:border-box; +.toolbarLabel > label { + width: 100%; } -.dropdownToolbarButton{ - display:inline flex; - flex-direction:row; - align-items:center; - justify-content:center; - position:relative; - - width:-moz-fit-content; - - width:fit-content; - min-width:140px; - padding:0; - background-color:var(--dropdown-btn-bg-color); - border:var(--dropdown-btn-border); - border-radius:2px; - color:var(--main-color); - font-size:12px; - line-height:14px; - -webkit-user-select:none; - -moz-user-select:none; - user-select:none; - cursor:default; - box-sizing:border-box; - outline:none; +.toolbarHorizontalGroup { + height: 100%; + display: inline flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 1px; + box-sizing: border-box; } -.dropdownToolbarButton:hover{ - background-color:var(--button-hover-color); - } +.dropdownToolbarButton { + display: inline flex; + flex-direction: row; + align-items: center; + justify-content: center; + position: relative; -.dropdownToolbarButton > select{ - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - width:inherit; - min-width:inherit; - height:28px; - font:message-box; - font-size:12px; - color:var(--main-color); - margin:0; - padding-block:1px 2px; - padding-inline:6px 38px; - border:none; - outline:none; - background-color:var(--dropdown-btn-bg-color); - } + width: -moz-fit-content; -:is(.dropdownToolbarButton > select) > option{ - background:var(--doorhanger-bg-color); - color:var(--main-color); - } - -:is(.dropdownToolbarButton > select):is(:hover,:focus-visible){ - background-color:var(--button-hover-color); - color:var(--toggled-btn-color); - } - -.dropdownToolbarButton::after{ - position:absolute; - display:inline; - width:var(--icon-size); - height:var(--icon-size); - - content:""; - background-color:var(--toolbar-icon-bg-color); - -webkit-mask-size:cover; - mask-size:cover; - - inset-inline-end:4px; - pointer-events:none; - -webkit-mask-image:var(--toolbarButton-menuArrow-icon); - mask-image:var(--toolbarButton-menuArrow-icon); - } - -.dropdownToolbarButton:is(:hover,:focus-visible,:active)::after{ - background-color:var(--toolbar-icon-hover-bg-color); - } - -#toolbarContainer{ - --menuitem-height:calc(var(--toolbar-height) - 6px); - - width:100%; - height:var(--toolbar-height); - padding:var(--toolbar-vertical-padding) var(--toolbar-horizontal-padding); - position:relative; - box-sizing:border-box; - font:message-box; - background-color:var(--toolbar-bg-color); - box-shadow:var(--toolbar-box-shadow); - border-bottom:var(--toolbar-border-bottom); + width: fit-content; + min-width: 140px; + padding: 0; + background-color: var(--dropdown-btn-bg-color); + border: var(--dropdown-btn-border); + border-radius: 2px; + color: var(--main-color); + font-size: 12px; + line-height: 14px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; + box-sizing: border-box; + outline: none; } -#toolbarContainer #toolbarViewer{ - width:100%; - height:100%; - justify-content:space-between; +.dropdownToolbarButton:hover { + background-color: var(--button-hover-color); +} + +.dropdownToolbarButton > select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: inherit; + min-width: inherit; + height: 28px; + font: message-box; + font-size: 12px; + color: var(--main-color); + margin: 0; + padding-block: 1px 2px; + padding-inline: 6px 38px; + border: none; + outline: none; + background-color: var(--dropdown-btn-bg-color); +} + +:is(.dropdownToolbarButton > select) > option { + background: var(--doorhanger-bg-color); + color: var(--main-color); +} + +:is(.dropdownToolbarButton > select):is(:hover, :focus-visible) { + background-color: var(--button-hover-color); + color: var(--toggled-btn-color); +} + +.dropdownToolbarButton::after { + position: absolute; + display: inline; + width: var(--icon-size); + height: var(--icon-size); + + content: ''; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; + + inset-inline-end: 4px; + pointer-events: none; + -webkit-mask-image: var(--toolbarButton-menuArrow-icon); + mask-image: var(--toolbarButton-menuArrow-icon); +} + +.dropdownToolbarButton:is(:hover, :focus-visible, :active)::after { + background-color: var(--toolbar-icon-hover-bg-color); +} + +#toolbarContainer { + --menuitem-height: calc(var(--toolbar-height) - 6px); + + width: 100%; + height: var(--toolbar-height); + padding: var(--toolbar-vertical-padding) var(--toolbar-horizontal-padding); + position: relative; + box-sizing: border-box; + font: message-box; + background-color: var(--toolbar-bg-color); + box-shadow: var(--toolbar-box-shadow); + border-bottom: var(--toolbar-border-bottom); +} + +#toolbarContainer #toolbarViewer { + width: 100%; + height: 100%; + justify-content: space-between; +} + +:is(#toolbarContainer #toolbarViewer) > * { + flex: none; +} + +:is(#toolbarContainer #toolbarViewer) input { + font: message-box; +} + +:is(#toolbarContainer #toolbarViewer) .toolbarButtonSpacer { + width: 30px; + display: block; + height: 1px; +} + +:is(#toolbarContainer #toolbarViewer) + #toolbarViewerLeft + #numPages.toolbarLabel { + padding-inline-start: 3px; + flex: none; +} + +#toolbarContainer #loadingBar { + --progressBar-percent: 0%; + --progressBar-end-offset: 0; + + position: absolute; + top: var(--toolbar-height); + inset-inline: 0 var(--progressBar-end-offset); + height: 4px; + background-color: var(--progressBar-bg-color); + border-bottom: 1px solid var(--toolbar-border-color); + transition-property: inset-inline-start; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); +} + +:is(#toolbarContainer #loadingBar) .progress { + position: absolute; + top: 0; + inset-inline-start: 0; + width: 100%; + transform: scaleX(var(--progressBar-percent)); + transform-origin: calc(50% - 50% * var(--dir-factor)) 0; + height: 100%; + background-color: var(--progressBar-color); + overflow: hidden; + transition: transform 200ms; +} + +.indeterminate:is(#toolbarContainer #loadingBar) .progress { + transform: none; + background-color: var(--progressBar-bg-color); + transition: none; +} + +:is(.indeterminate:is(#toolbarContainer #loadingBar) .progress) .glimmer { + position: absolute; + top: 0; + inset-inline-start: 0; + height: 100%; + width: calc(100% + 150px); + background: repeating-linear-gradient( + 135deg, + var(--progressBar-blend-color) 0, + var(--progressBar-bg-color) 5px, + var(--progressBar-bg-color) 45px, + var(--progressBar-color) 55px, + var(--progressBar-color) 95px, + var(--progressBar-blend-color) 100px + ); + animation: progressIndeterminate 1s linear infinite; +} + +@media all and (max-width: 840px) { + #sidebarContainer { + background-color: var(--sidebar-narrow-bg-color); } - -:is(#toolbarContainer #toolbarViewer) > *{ - flex:none; - } - -:is(#toolbarContainer #toolbarViewer) input{ - font:message-box; - } - -:is(#toolbarContainer #toolbarViewer) .toolbarButtonSpacer{ - width:30px; - display:block; - height:1px; - } - -:is(#toolbarContainer #toolbarViewer) #toolbarViewerLeft #numPages.toolbarLabel{ - padding-inline-start:3px; - flex:none; - } - -#toolbarContainer #loadingBar{ - --progressBar-percent:0%; - --progressBar-end-offset:0; - - position:absolute; - top:var(--toolbar-height); - inset-inline:0 var(--progressBar-end-offset); - height:4px; - background-color:var(--progressBar-bg-color); - border-bottom:1px solid var(--toolbar-border-color); - transition-property:inset-inline-start; - transition-duration:var(--sidebar-transition-duration); - transition-timing-function:var(--sidebar-transition-timing-function); - } - -:is(#toolbarContainer #loadingBar) .progress{ - position:absolute; - top:0; - inset-inline-start:0; - width:100%; - transform:scaleX(var(--progressBar-percent)); - transform-origin:calc(50% - 50% * var(--dir-factor)) 0; - height:100%; - background-color:var(--progressBar-color); - overflow:hidden; - transition:transform 200ms; - } - -.indeterminate:is(#toolbarContainer #loadingBar) .progress{ - transform:none; - background-color:var(--progressBar-bg-color); - transition:none; - } - -:is(.indeterminate:is(#toolbarContainer #loadingBar) .progress) .glimmer{ - position:absolute; - top:0; - inset-inline-start:0; - height:100%; - width:calc(100% + 150px); - background:repeating-linear-gradient( - 135deg, - var(--progressBar-blend-color) 0, - var(--progressBar-bg-color) 5px, - var(--progressBar-bg-color) 45px, - var(--progressBar-color) 55px, - var(--progressBar-color) 95px, - var(--progressBar-blend-color) 100px - ); - animation:progressIndeterminate 1s linear infinite; - } - -@media all and (max-width: 840px){ - #sidebarContainer{ - background-color:var(--sidebar-narrow-bg-color); - } - #outerContainer.sidebarOpen #viewerContainer{ - inset-inline-start:0 !important; + #outerContainer.sidebarOpen #viewerContainer { + inset-inline-start: 0 !important; } } -@media all and (max-width: 750px){ - #outerContainer .hiddenMediumView{ - display:none !important; +@media all and (max-width: 750px) { + #outerContainer .hiddenMediumView { + display: none !important; } - #outerContainer .visibleMediumView:not(.hidden, [hidden]){ - display:inline-block !important; + #outerContainer .visibleMediumView:not(.hidden, [hidden]) { + display: inline-block !important; } } -@media all and (max-width: 690px){ +@media all and (max-width: 690px) { .hiddenSmallView, - .hiddenSmallView *{ - display:none !important; + .hiddenSmallView * { + display: none !important; } - #toolbarContainer #toolbarViewer .toolbarButtonSpacer{ - width:0; + #toolbarContainer #toolbarViewer .toolbarButtonSpacer { + width: 0; } } -@media all and (max-width: 560px){ - #scaleSelectContainer{ - display:none; +@media all and (max-width: 560px) { + #scaleSelectContainer { + display: none; } } diff --git a/public/ghostscript-wasm/sRGB_IEC61966-2-1_no_black_scaling.icc b/public/sRGB_IEC61966-2-1_no_black_scaling.icc similarity index 100% rename from public/ghostscript-wasm/sRGB_IEC61966-2-1_no_black_scaling.icc rename to public/sRGB_IEC61966-2-1_no_black_scaling.icc diff --git a/public/sitemap.xml b/public/sitemap.xml index 7613a80..28fa343 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,716 +1,23962 @@ - - + - https://www.bentopdf.com/ - 2024-12-28 + https://www.bentopdf.com/de/404 + 2026-01-14 weekly - 1.0 + 0.1 + + + + + + + + + + + + - - - https://www.bentopdf.com/docs/ - 2024-12-28 + https://www.bentopdf.com/404 + 2026-01-14 weekly - 0.9 + 0.1 + + + + + + + + + + + + - - - https://www.bentopdf.com/pdf-converter - 2024-12-29 + https://www.bentopdf.com/es/404 + 2026-01-14 weekly - 0.9 + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-editor - 2024-12-29 + https://www.bentopdf.com/fr/404 + 2026-01-14 weekly - 0.9 + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-security - 2024-12-29 + https://www.bentopdf.com/id/404 + 2026-01-14 weekly - 0.9 + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-merge-split - 2024-12-29 + https://www.bentopdf.com/it/404 + 2026-01-14 weekly - 0.9 + 0.1 + + + + + + + + + + + + - - - https://www.bentopdf.com/tools - 2024-12-29 + https://www.bentopdf.com/pt/404 + 2026-01-14 weekly - 0.9 - - - - - https://www.bentopdf.com/merge-pdf - 2024-12-28 - monthly - 0.9 + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/alternate-merge - 2024-12-28 - monthly - 0.7 + https://www.bentopdf.com/tr/404 + 2026-01-14 + weekly + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/combine-single-page - 2024-12-28 - monthly - 0.7 - - - - - https://www.bentopdf.com/split-pdf - 2024-12-28 - monthly - 0.9 + https://www.bentopdf.com/vi/404 + 2026-01-14 + weekly + 0.1 + + + + + + + + + + + + - https://www.bentopdf.com/extract-pages - 2024-12-28 - monthly + https://www.bentopdf.com/zh/404 + 2026-01-14 + weekly + 0.1 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/404 + 2026-01-14 + weekly + 0.1 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/divide-pages - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/delete-pages - 2024-12-28 - monthly - 0.7 - - - - - https://www.bentopdf.com/compress-pdf - 2024-12-28 - monthly - 0.9 - - - - - https://www.bentopdf.com/edit-pdf - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/organize-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/rotate-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/es/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/rotate-custom - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/crop-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/reverse-pages - 2024-12-28 - monthly - 0.6 - - - - - https://www.bentopdf.com/word-to-pdf - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/excel-to-pdf - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/powerpoint-to-pdf - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/jpg-to-pdf - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/png-to-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/fr/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/image-to-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/id/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/webp-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/bmp-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/tiff-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/heic-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/svg-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/psd-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/txt-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/rtf-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/odt-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/ods-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/odp-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/odg-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/pages-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/epub-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/mobi-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/fb2-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/cbz-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/email-to-pdf - 2026-01-08 - monthly - 0.7 - - - https://www.bentopdf.com/xps-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/vsd-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/pub-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/wpd-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/wps-to-pdf - 2024-12-28 - monthly - 0.5 - - - https://www.bentopdf.com/markdown-to-pdf - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/json-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/xml-to-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/csv-to-pdf - 2024-12-28 - monthly - 0.6 - - - - - https://www.bentopdf.com/pdf-to-docx - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/pdf-to-excel - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/pdf-to-jpg - 2024-12-28 - monthly - 0.9 - - - https://www.bentopdf.com/pdf-to-png - 2024-12-28 - monthly + https://www.bentopdf.com/it/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-to-webp - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/pdf-to-bmp - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/pdf-to-tiff - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/pdf-to-svg - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/pdf-to-text - 2024-12-28 - monthly + https://www.bentopdf.com/pt/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-to-markdown - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/pdf-to-json - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/pdf-to-csv - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/pdf-to-zip - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/pdf-to-pdfa - 2024-12-28 - monthly + https://www.bentopdf.com/tr/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-to-greyscale - 2024-12-28 - monthly - 0.6 - - - - - https://www.bentopdf.com/encrypt-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/vi/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/decrypt-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/zh/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/change-permissions - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/remove-restrictions - 2024-12-28 - monthly - 0.7 - - - https://www.bentopdf.com/sign-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/zh-TW/about + 2026-01-14 + weekly 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/digital-sign-pdf - 2026-01-06 - monthly - 0.8 - - - https://www.bentopdf.com/validate-signature-pdf - 2026-01-06 - monthly + https://www.bentopdf.com/de/add-attachments + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/sanitize-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/add-attachments + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/flatten-pdf - 2024-12-28 - monthly + https://www.bentopdf.com/es/add-attachments + 2026-01-14 + weekly 0.7 - - - - - https://www.bentopdf.com/form-filler - 2024-12-28 - monthly - 0.8 + + + + + + + + + + + + - https://www.bentopdf.com/form-creator - 2024-12-28 - monthly + https://www.bentopdf.com/fr/add-attachments + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - - - https://www.bentopdf.com/add-watermark - 2024-12-28 - monthly - 0.8 + https://www.bentopdf.com/id/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/add-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/add-blank-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + https://www.bentopdf.com/add-stamps - 2024-12-28 - monthly + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/header-footer - 2024-12-28 - monthly + https://www.bentopdf.com/es/add-stamps + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/page-numbers - 2024-12-28 - monthly + https://www.bentopdf.com/fr/add-stamps + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/remove-annotations - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/id/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/add-stamps + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/add-watermark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/alternate-merge + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + https://www.bentopdf.com/background-color - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/text-color - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/invert-colors - 2024-12-28 - monthly - 0.5 - - - - - https://www.bentopdf.com/edit-metadata - 2024-12-28 - monthly + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/view-metadata - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/es/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/remove-metadata - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/fr/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/background-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/bmp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + https://www.bentopdf.com/bookmark - 2024-12-28 - monthly + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/table-of-contents - 2024-12-28 - monthly + https://www.bentopdf.com/es/bookmark + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-layers - 2024-12-28 - monthly - 0.5 - - - - - https://www.bentopdf.com/add-attachments - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/fr/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/edit-attachments - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/id/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/extract-attachments - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/it/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - - - https://www.bentopdf.com/ocr-pdf - 2024-12-28 - monthly - 0.8 + https://www.bentopdf.com/pt/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/bookmark + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/cbz-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/change-permissions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/combine-single-page + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + https://www.bentopdf.com/compare-pdfs - 2024-12-28 - monthly + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/repair-pdf - 2024-12-28 - monthly - 0.8 - - - https://www.bentopdf.com/linearize-pdf - 2024-12-28 - monthly - 0.6 - - - https://www.bentopdf.com/pdf-multi-tool - 2024-12-28 - monthly + https://www.bentopdf.com/es/compare-pdfs + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/prepare-pdf-for-ai - 2024-12-28 - monthly + https://www.bentopdf.com/fr/compare-pdfs + 2026-01-14 + weekly 0.7 - - - - - https://www.bentopdf.com/add-blank-page - 2024-12-28 - monthly - 0.6 + + + + + + + + + + + + - https://www.bentopdf.com/remove-blank-pages - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/id/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/fix-page-size - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/it/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/page-dimensions - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/pt/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/n-up-pdf - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/tr/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/pdf-booklet - 2024-12-28 - monthly - 0.6 + https://www.bentopdf.com/vi/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/posterize-pdf - 2024-12-28 - monthly - 0.5 + https://www.bentopdf.com/zh/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - https://www.bentopdf.com/rasterize-pdf - 2024-12-28 - monthly - 0.5 + https://www.bentopdf.com/zh-TW/compare-pdfs + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/compress-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/contact + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/crop-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/csv-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/decrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/delete-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/deskew-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/digital-sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/divide-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/edit-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/edit-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/edit-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/email-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/encrypt-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/epub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/excel-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/extract-attachments + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + - - https://www.bentopdf.com/extract-images - 2024-12-28 - monthly - 0.8 + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/extract-images + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/extract-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + https://www.bentopdf.com/extract-tables - 2024-12-28 - monthly + 2026-01-14 + weekly 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/extract-tables + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/faq + 2026-01-14 + weekly + 0.8 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/fb2-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/fix-page-size + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/flatten-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/font-to-outline + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/form-creator + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/form-filler + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/header-footer + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/heic-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/image-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/es + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/id + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/it + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW + 2026-01-14 + weekly + 1 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/invert-colors + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/jpg-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/json-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/licensing + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/linearize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/markdown-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/merge-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/mobi-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/n-up-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/ocr-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/odg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/odp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/ods-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/odt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/organize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/page-dimensions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/page-numbers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pages-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-booklet + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-converter + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-editor + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-layers + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-merge-split + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-multi-tool + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-security + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-bmp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-csv + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-docx + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-excel + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-greyscale + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-jpg + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-json + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-markdown + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-pdfa + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-png + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-svg + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-text + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-tiff + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-webp + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pdf-to-zip + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/png-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/posterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/powerpoint-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/prepare-pdf-for-ai + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/privacy + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/psd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/pub-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/rasterize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/remove-annotations + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/remove-blank-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/remove-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/remove-restrictions + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/repair-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/reverse-pages + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/rotate-custom + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/rotate-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/rtf-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/sanitize-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/sign-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/split-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/svg-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/table-of-contents + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/terms + 2026-01-14 + weekly + 0.5 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/text-color + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/tiff-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/tools + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/txt-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/validate-signature-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/view-metadata + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/vsd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/webp-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/word-to-pdf + 2026-01-14 + weekly + 0.9 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/wpd-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/wps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/xml-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/de/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/es/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/fr/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/id/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/it/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/pt/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/tr/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/vi/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + + + + https://www.bentopdf.com/zh-TW/xps-to-pdf + 2026-01-14 + weekly + 0.7 + + + + + + + + + + + + diff --git a/public/sw.js b/public/sw.js index bfb6c83..7991eb4 100644 --- a/public/sw.js +++ b/public/sw.js @@ -5,107 +5,105 @@ * Version: 1.1.0 */ -const CACHE_VERSION = 'bentopdf-v7'; +const CACHE_VERSION = 'bentopdf-v10'; const CACHE_NAME = `${CACHE_VERSION}-static`; - const getBasePath = () => { - const scope = self.registration?.scope || self.location.href; - const url = new URL(scope); - return url.pathname.replace(/\/$/, '') || ''; + const scope = self.registration?.scope || self.location.href; + const url = new URL(scope); + return url.pathname.replace(/\/$/, '') || ''; }; -const buildCriticalAssets = (basePath) => [ - `${basePath}/pymupdf-wasm/pyodide.js`, - `${basePath}/pymupdf-wasm/pyodide.asm.js`, - `${basePath}/pymupdf-wasm/pyodide.asm.wasm`, - `${basePath}/pymupdf-wasm/python_stdlib.zip`, - `${basePath}/pymupdf-wasm/pyodide-lock.json`, - - `${basePath}/pymupdf-wasm/pymupdf-1.26.3-cp313-none-pyodide_2025_0_wasm32.whl`, - `${basePath}/pymupdf-wasm/numpy-2.2.5-cp313-cp313-pyodide_2025_0_wasm32.whl`, - `${basePath}/pymupdf-wasm/opencv_python-4.11.0.86-cp313-cp313-pyodide_2025_0_wasm32.whl`, - `${basePath}/pymupdf-wasm/lxml-5.4.0-cp313-cp313-pyodide_2025_0_wasm32.whl`, - `${basePath}/pymupdf-wasm/python_docx-1.2.0-py3-none-any.whl`, - `${basePath}/pymupdf-wasm/pdf2docx-0.5.8-py3-none-any.whl`, - `${basePath}/pymupdf-wasm/fonttools-4.56.0-py3-none-any.whl`, - `${basePath}/pymupdf-wasm/typing_extensions-4.12.2-py3-none-any.whl`, - `${basePath}/pymupdf-wasm/pymupdf4llm-0.0.27-py3-none-any.whl`, - - `${basePath}/ghostscript-wasm/gs.js`, - `${basePath}/ghostscript-wasm/gs.wasm`, -]; +const buildCriticalAssets = () => []; self.addEventListener('install', (event) => { - const basePath = getBasePath(); - const CRITICAL_ASSETS = buildCriticalAssets(basePath); - // console.log('๐Ÿš€ [ServiceWorker] Installing version:', CACHE_VERSION); - // console.log('๐Ÿ“ [ServiceWorker] Base path detected:', basePath || '/'); - // console.log('๐Ÿ“ฆ [ServiceWorker] Will cache', CRITICAL_ASSETS.length, 'critical assets'); + const CRITICAL_ASSETS = buildCriticalAssets(); + // console.log('๐Ÿš€ [ServiceWorker] Installing version:', CACHE_VERSION); + // console.log('๐Ÿ“ [ServiceWorker] Base path detected:', basePath || '/'); + // console.log('๐Ÿ“ฆ [ServiceWorker] Will cache', CRITICAL_ASSETS.length, 'critical assets'); - event.waitUntil( - caches.open(CACHE_NAME) - .then((cache) => { - // console.log('[ServiceWorker] Caching critical assets...'); - return cacheInBatches(cache, CRITICAL_ASSETS, 5); - }) - .then(() => { - // console.log('โœ… [ServiceWorker] All critical assets cached successfully!'); - // console.log('โญ๏ธ [ServiceWorker] Skipping waiting, activating immediately...'); - return self.skipWaiting(); - }) - .catch((error) => { - console.error('[ServiceWorker] Cache installation failed:', error); - }) - ); + event.waitUntil( + caches + .open(CACHE_NAME) + .then((cache) => { + // console.log('[ServiceWorker] Caching critical assets...'); + return cacheInBatches(cache, CRITICAL_ASSETS, 5); + }) + .then(() => { + // console.log('โœ… [ServiceWorker] All critical assets cached successfully!'); + // console.log('โญ๏ธ [ServiceWorker] Skipping waiting, activating immediately...'); + return self.skipWaiting(); + }) + .catch((error) => { + console.error('[ServiceWorker] Cache installation failed:', error); + }) + ); }); self.addEventListener('activate', (event) => { - // console.log('๐Ÿ”„ [ServiceWorker] Activating version:', CACHE_VERSION); + // console.log('๐Ÿ”„ [ServiceWorker] Activating version:', CACHE_VERSION); - event.waitUntil( - caches.keys() - .then((cacheNames) => { - return Promise.all( - cacheNames.map((cacheName) => { - if (cacheName.startsWith('bentopdf-') && cacheName !== CACHE_NAME) { - // console.log('[ServiceWorker] Deleting old cache:', cacheName); - return caches.delete(cacheName); - } - }) - ); - }) - .then(() => { - // console.log('โœ… [ServiceWorker] Activated successfully!'); - // console.log('๐ŸŽฏ [ServiceWorker] Taking control of all pages...'); - return self.clients.claim(); - }) - ); + event.waitUntil( + caches + .keys() + .then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => { + if (cacheName.startsWith('bentopdf-') && cacheName !== CACHE_NAME) { + // console.log('[ServiceWorker] Deleting old cache:', cacheName); + return caches.delete(cacheName); + } + }) + ); + }) + .then(() => { + // console.log('โœ… [ServiceWorker] Activated successfully!'); + // console.log('๐ŸŽฏ [ServiceWorker] Taking control of all pages...'); + return self.clients.claim(); + }) + ); }); self.addEventListener('fetch', (event) => { - const url = new URL(event.request.url); + const url = new URL(event.request.url); - const isCDN = url.hostname === 'cdn.jsdelivr.net'; - const isLocal = url.origin === location.origin; + const isCDN = url.hostname === 'cdn.jsdelivr.net'; + const isLocal = url.origin === location.origin; - if (!isLocal && !isCDN) { - return; - } - if (isLocal && (url.searchParams.has('t') || url.searchParams.has('import') || url.searchParams.has('direct'))) { - // console.log('๐Ÿ”ง [Dev Mode] Skipping Vite HMR request:', url.pathname); - return; - } + if (!isLocal && !isCDN) { + return; + } + if ( + isLocal && + (url.searchParams.has('t') || + url.searchParams.has('import') || + url.searchParams.has('direct')) + ) { + // console.log('๐Ÿ”ง [Dev Mode] Skipping Vite HMR request:', url.pathname); + return; + } - if (isLocal && (url.pathname.includes('/@vite') || url.pathname.includes('/@id') || url.pathname.includes('/@fs'))) { - return; - } + if ( + isLocal && + (url.pathname.includes('/@vite') || + url.pathname.includes('/@id') || + url.pathname.includes('/@fs')) + ) { + return; + } - if (shouldCache(url.pathname, isCDN)) { - event.respondWith(cacheFirstStrategyWithDedup(event.request, isCDN)); - } else if (isLocal && (url.pathname.endsWith('.html') || url.pathname === '/')) { - event.respondWith(networkFirstStrategy(event.request)); - } + if (isLocal && url.pathname.includes('/locales/')) { + event.respondWith(networkFirstStrategy(event.request)); + } else if (shouldCache(url.pathname, isCDN)) { + event.respondWith(cacheFirstStrategyWithDedup(event.request, isCDN)); + } else if ( + isLocal && + (url.pathname.endsWith('.html') || + url.pathname === '/' || + /^\/(en|fr|es|de|zh|zh-TW|vi|tr|id|it|pt|nl)(\/|$)/.test(url.pathname)) + ) { + event.respondWith(networkFirstStrategy(event.request)); + } }); /** @@ -113,82 +111,121 @@ self.addEventListener('fetch', (event) => { * Ensures we only cache CDN OR local version, never both */ async function cacheFirstStrategyWithDedup(request, isCDN) { - const url = new URL(request.url); - const fileName = url.pathname.split('/').pop(); + const url = new URL(request.url); + const fileName = url.pathname.split('/').pop(); - try { - const cachedResponse = await findCachedFile(fileName); - if (cachedResponse) { - // console.log('โšก [Cache HIT] Instant load:', fileName); - return cachedResponse; - } - - // console.log(`๐Ÿ“ฅ [Cache MISS] Downloading from ${isCDN ? 'CDN' : 'local'}:`, fileName); - - const networkResponse = await fetch(request); - - if (networkResponse && networkResponse.status === 200) { - const cache = await caches.open(CACHE_NAME); - - await removeDuplicateCache(cache, fileName, isCDN); - - await cache.put(request, networkResponse.clone()); - // console.log(`๐Ÿ’พ [Cached from ${isCDN ? 'CDN' : 'local'}] Saved:`, fileName); - } - - return networkResponse; - } catch (error) { - if (isCDN) { - console.warn(`โš ๏ธ [CDN Failed] Trying local fallback for: ${fileName}`); - const basePath = getBasePath(); - const localPath = getLocalPathForCDNUrl(url.pathname); - - if (localPath) { - const localUrl = `${basePath}${localPath}${fileName}`; - try { - const fallbackResponse = await fetch(localUrl); - if (fallbackResponse && fallbackResponse.status === 200) { - const cache = await caches.open(CACHE_NAME); - await cache.put(localUrl, fallbackResponse.clone()); - // console.log('โœ… [Fallback Success] Cached local version:', fileName); - return fallbackResponse; - } - } catch (fallbackError) { - console.error('[ServiceWorker] Both CDN and local failed for:', fileName); - } - } - } - throw error; + try { + const cachedResponse = await findCachedFile(fileName, request.url); + if (cachedResponse) { + // console.log('โšก [Cache HIT] Instant load:', fileName); + return cachedResponse; } + + // console.log(`๐Ÿ“ฅ [Cache MISS] Downloading from ${isCDN ? 'CDN' : 'local'}:`, fileName); + + const networkResponse = await fetch(request); + + if (networkResponse && networkResponse.status === 200) { + const clone = networkResponse.clone(); + const buffer = await clone.arrayBuffer(); + if (buffer.byteLength > 0) { + const cache = await caches.open(CACHE_NAME); + await removeDuplicateCache(cache, fileName, isCDN); + await cache.put( + request, + new Response(buffer, { + status: networkResponse.status, + statusText: networkResponse.statusText, + headers: networkResponse.headers, + }) + ); + } + } + + return networkResponse; + } catch (error) { + if (isCDN) { + console.warn(`โš ๏ธ [CDN Failed] Trying local fallback for: ${fileName}`); + const basePath = getBasePath(); + const localPath = getLocalPathForCDNUrl(url.pathname); + + if (localPath) { + const localUrl = `${basePath}${localPath}${fileName}`; + try { + const fallbackResponse = await fetch(localUrl); + if (fallbackResponse && fallbackResponse.status === 200) { + const fbClone = fallbackResponse.clone(); + const fbBuffer = await fbClone.arrayBuffer(); + if (fbBuffer.byteLength > 0) { + const cache = await caches.open(CACHE_NAME); + await cache.put( + localUrl, + new Response(fbBuffer, { + status: fallbackResponse.status, + statusText: fallbackResponse.statusText, + headers: fallbackResponse.headers, + }) + ); + } + return fallbackResponse; + } + } catch (fallbackError) { + console.error( + '[ServiceWorker] Both CDN and local failed for:', + fileName + ); + } + } + } + throw error; + } } -async function findCachedFile(fileName) { - const cache = await caches.open(CACHE_NAME); - const requests = await cache.keys(); +async function findCachedFile(fileName, requestUrl) { + const cache = await caches.open(CACHE_NAME); - for (const req of requests) { - const reqUrl = new URL(req.url); - if (reqUrl.pathname.endsWith(fileName)) { - return await cache.match(req); - } + const exactMatch = await cache.match(requestUrl); + if (exactMatch) { + const clone = exactMatch.clone(); + const buffer = await clone.arrayBuffer(); + if (buffer.byteLength > 0) { + return exactMatch; } - return null; + await cache.delete(requestUrl); + } + + const requests = await cache.keys(); + for (const req of requests) { + const reqUrl = new URL(req.url); + if (reqUrl.pathname.endsWith(fileName)) { + const response = await cache.match(req); + if (response) { + const clone = response.clone(); + const buffer = await clone.arrayBuffer(); + if (buffer.byteLength > 0) { + return response; + } + await cache.delete(req); + } + } + } + return null; } async function removeDuplicateCache(cache, fileName, isCDN) { - const requests = await cache.keys(); + const requests = await cache.keys(); - for (const req of requests) { - const reqUrl = new URL(req.url); - if (reqUrl.pathname.endsWith(fileName)) { - // If caching CDN version, remove local version (and vice versa) - const reqIsCDN = reqUrl.hostname === 'cdn.jsdelivr.net'; - if (reqIsCDN !== isCDN) { - await cache.delete(req); - // console.log(`[Dedup] Removed ${reqIsCDN ? 'CDN' : 'local'} version of:`, fileName); - } - } + for (const req of requests) { + const reqUrl = new URL(req.url); + if (reqUrl.pathname.endsWith(fileName)) { + // If caching CDN version, remove local version (and vice versa) + const reqIsCDN = reqUrl.hostname === 'cdn.jsdelivr.net'; + if (reqIsCDN !== isCDN) { + await cache.delete(req); + // console.log(`[Dedup] Removed ${reqIsCDN ? 'CDN' : 'local'} version of:`, fileName); + } } + } } /** @@ -196,23 +233,34 @@ async function removeDuplicateCache(cache, fileName, isCDN) { * Perfect for HTML files that might update */ async function networkFirstStrategy(request) { - try { - const networkResponse = await fetch(request); + try { + const networkResponse = await fetch(request); - if (networkResponse && networkResponse.status === 200) { - const cache = await caches.open(CACHE_NAME); - cache.put(request, networkResponse.clone()); - } - - return networkResponse; - } catch (error) { - const cachedResponse = await caches.match(request); - if (cachedResponse) { - // console.log('[Offline Mode] Serving from cache:', request.url.split('/').pop()); - return cachedResponse; - } - throw error; + if (networkResponse && networkResponse.status === 200) { + const clone = networkResponse.clone(); + const buffer = await clone.arrayBuffer(); + if (buffer.byteLength > 0) { + const cache = await caches.open(CACHE_NAME); + cache.put( + request, + new Response(buffer, { + status: networkResponse.status, + statusText: networkResponse.statusText, + headers: networkResponse.headers, + }) + ); + } } + + return networkResponse; + } catch (error) { + const cachedResponse = await caches.match(request); + if (cachedResponse) { + // console.log('[Offline Mode] Serving from cache:', request.url.split('/').pop()); + return cachedResponse; + } + throw error; + } } /** @@ -220,16 +268,10 @@ async function networkFirstStrategy(request) { * Returns the local directory path for a given CDN package */ function getLocalPathForCDNUrl(pathname) { - if (pathname.includes('/@bentopdf/pymupdf-wasm')) { - return '/pymupdf-wasm/'; - } - if (pathname.includes('/@bentopdf/gs-wasm')) { - return '/ghostscript-wasm/'; - } - if (pathname.includes('/@matbee/libreoffice-converter')) { - return '/libreoffice-wasm/'; - } - return null; + if (pathname.includes('/@matbee/libreoffice-converter')) { + return '/libreoffice-wasm/'; + } + return null; } /** @@ -237,60 +279,63 @@ function getLocalPathForCDNUrl(pathname) { * Handles both local and CDN URLs */ function shouldCache(pathname, isCDN = false) { - if (isCDN) { - return ( - pathname.includes('/@bentopdf/pymupdf-wasm') || - pathname.includes('/@bentopdf/gs-wasm') || - pathname.includes('/@matbee/libreoffice-converter') || - pathname.match(/\.(wasm|whl|zip|json|js|gz)$/) - ); - } - + if (isCDN) { return ( - pathname.includes('/libreoffice-wasm/') || - pathname.includes('/pymupdf-wasm/') || - pathname.includes('/ghostscript-wasm/') || - pathname.includes('/embedpdf/') || - pathname.includes('/assets/') || - pathname.match(/\.(js|mjs|css|wasm|whl|zip|json|png|jpg|jpeg|gif|svg|woff|woff2|ttf|gz|br)$/) + pathname.includes('/@bentopdf/pymupdf-wasm') || + pathname.includes('/@bentopdf/gs-wasm') || + pathname.includes('/@matbee/libreoffice-converter') || + pathname.match(/\.(wasm|whl|zip|json|js|gz)$/) ); + } + + return ( + pathname.includes('/libreoffice-wasm/') || + pathname.includes('/embedpdf/') || + pathname.includes('/assets/') || + pathname.match( + /\.(js|mjs|css|wasm|whl|zip|json|png|jpg|jpeg|gif|svg|woff|woff2|ttf|gz|br)$/ + ) + ); } /** * Cache assets in batches to avoid overwhelming the browser */ async function cacheInBatches(cache, urls, batchSize = 5) { - for (let i = 0; i < urls.length; i += batchSize) { - const batch = urls.slice(i, i + batchSize); - // console.log(`[ServiceWorker] Caching batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(urls.length / batchSize)}`); + for (let i = 0; i < urls.length; i += batchSize) { + const batch = urls.slice(i, i + batchSize); - await Promise.all( - batch.map(async (url) => { - try { - await cache.add(url); - const fileName = url.split('/').pop(); - const fileSize = fileName.includes('.wasm') || fileName.includes('.whl') ? '(large file)' : ''; - // console.log(` โœ“ Cached: ${fileName} ${fileSize}`); - } catch (error) { - console.warn('[ServiceWorker] Failed to cache:', url, error.message); - } - }) - ); - } + await Promise.all( + batch.map(async (url) => { + try { + const response = await fetch(url); + if (response.ok && response.status === 200) { + const clone = response.clone(); + const buffer = await clone.arrayBuffer(); + if (buffer.byteLength > 0) { + await cache.put(url, response); + } + } + } catch (error) { + console.warn('[ServiceWorker] Failed to cache:', url, error.message); + } + }) + ); + } } self.addEventListener('message', (event) => { - if (event.data && event.data.type === 'SKIP_WAITING') { - self.skipWaiting(); - } + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } - if (event.data && event.data.type === 'CLEAR_CACHE') { - event.waitUntil( - caches.delete(CACHE_NAME).then(() => { - console.log('[ServiceWorker] Cache cleared'); - }) - ); - } + if (event.data && event.data.type === 'CLEAR_CACHE') { + event.waitUntil( + caches.delete(CACHE_NAME).then(() => { + console.log('[ServiceWorker] Cache cleared'); + }) + ); + } }); // console.log('๐ŸŽ‰ [ServiceWorker] Script loaded successfully! Ready to cache assets.'); diff --git a/public/workers/add-attachments.worker.d.ts b/public/workers/add-attachments.worker.d.ts index 8c57b42..c47d803 100644 --- a/public/workers/add-attachments.worker.d.ts +++ b/public/workers/add-attachments.worker.d.ts @@ -5,6 +5,7 @@ interface AddAttachmentsMessage { pdfBuffer: ArrayBuffer; attachmentBuffers: ArrayBuffer[]; attachmentNames: string[]; + cpdfUrl?: string; } interface AddAttachmentsSuccessResponse { @@ -17,4 +18,6 @@ interface AddAttachmentsErrorResponse { message: string; } -type AddAttachmentsResponse = AddAttachmentsSuccessResponse | AddAttachmentsErrorResponse; +type AddAttachmentsResponse = + | AddAttachmentsSuccessResponse + | AddAttachmentsErrorResponse; diff --git a/public/workers/add-attachments.worker.js b/public/workers/add-attachments.worker.js index aba62b6..b6ba15a 100644 --- a/public/workers/add-attachments.worker.js +++ b/public/workers/add-attachments.worker.js @@ -1,13 +1,32 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function parsePageRange(rangeString, totalPages) { const pages = new Set(); - const parts = rangeString.split(',').map(s => s.trim()); + const parts = rangeString.split(',').map((s) => s.trim()); for (const part of parts) { if (part.includes('-')) { - const [start, end] = part.split('-').map(s => parseInt(s.trim(), 10)); + const [start, end] = part.split('-').map((s) => parseInt(s.trim(), 10)); if (isNaN(start) || isNaN(end)) continue; for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) { pages.add(i); @@ -23,7 +42,13 @@ function parsePageRange(rangeString, totalPages) { return Array.from(pages).sort((a, b) => a - b); } -function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNames, attachmentLevel, pageRange) { +function addAttachmentsToPDFInWorker( + pdfBuffer, + attachmentBuffers, + attachmentNames, + attachmentLevel, + pageRange +) { try { const uint8Array = new Uint8Array(pdfBuffer); @@ -33,18 +58,21 @@ function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNam } catch (error) { const errorMsg = error.message || error.toString(); - if (errorMsg.includes('Failed to read PDF') || + if ( + errorMsg.includes('Failed to read PDF') || errorMsg.includes('Could not read object') || errorMsg.includes('No /Root entry') || - errorMsg.includes('PDFError')) { + errorMsg.includes('PDFError') + ) { self.postMessage({ status: 'error', - message: 'The PDF file has structural issues and cannot be processed. The file may be corrupted, incomplete, or created with non-standard tools. Please try:\n\nโ€ข Opening and re-saving the PDF in another PDF viewer\nโ€ข Using a different PDF file\nโ€ข Repairing the PDF with a PDF repair tool' + message: + 'The PDF file has structural issues and cannot be processed. The file may be corrupted, incomplete, or created with non-standard tools. Please try:\n\nโ€ข Opening and re-saving the PDF in another PDF viewer\nโ€ข Using a different PDF file\nโ€ข Repairing the PDF with a PDF repair tool', }); } else { self.postMessage({ status: 'error', - message: `Failed to load PDF: ${errorMsg}` + message: `Failed to load PDF: ${errorMsg}`, }); } return; @@ -57,7 +85,7 @@ function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNam if (!pageRange) { self.postMessage({ status: 'error', - message: 'Page range is required for page-level attachments.' + message: 'Page range is required for page-level attachments.', }); coherentpdf.deletePdf(pdf); return; @@ -66,7 +94,7 @@ function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNam if (targetPages.length === 0) { self.postMessage({ status: 'error', - message: 'Invalid page range specified.' + message: 'Invalid page range specified.', }); coherentpdf.deletePdf(pdf); return; @@ -82,21 +110,25 @@ function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNam coherentpdf.attachFileFromMemory(attachmentData, attachmentName, pdf); } else { for (const pageNum of targetPages) { - coherentpdf.attachFileToPageFromMemory(attachmentData, attachmentName, pdf, pageNum); + coherentpdf.attachFileToPageFromMemory( + attachmentData, + attachmentName, + pdf, + pageNum + ); } } } catch (error) { console.warn(`Failed to attach file ${attachmentNames[i]}:`, error); self.postMessage({ status: 'error', - message: `Failed to attach file ${attachmentNames[i]}: ${error.message || error}` + message: `Failed to attach file ${attachmentNames[i]}: ${error.message || error}`, }); coherentpdf.deletePdf(pdf); return; } } - // Save the modified PDF const modifiedBytes = coherentpdf.toMemory(pdf, false, false); coherentpdf.deletePdf(pdf); @@ -105,22 +137,46 @@ function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNam modifiedBytes.byteOffset + modifiedBytes.byteLength ); - self.postMessage({ - status: 'success', - modifiedPDF: buffer - }, [buffer]); - + self.postMessage( + { + status: 'success', + modifiedPDF: buffer, + }, + [buffer] + ); } catch (error) { self.postMessage({ status: 'error', - message: error instanceof Error - ? error.message - : 'Unknown error occurred while adding attachments.' + message: + error instanceof Error + ? error.message + : 'Unknown error occurred while adding attachments.', }); } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'add-attachments') { addAttachmentsToPDFInWorker( e.data.pdfBuffer, diff --git a/public/workers/alternate-merge.worker.d.ts b/public/workers/alternate-merge.worker.d.ts index d25e003..b6c97b6 100644 --- a/public/workers/alternate-merge.worker.d.ts +++ b/public/workers/alternate-merge.worker.d.ts @@ -1,23 +1,24 @@ declare const coherentpdf: typeof import('../../src/types/coherentpdf.global').coherentpdf; interface InterleaveFile { - name: string; - data: ArrayBuffer; + name: string; + data: ArrayBuffer; } interface InterleaveMessage { - command: 'interleave'; - files: InterleaveFile[]; + command: 'interleave'; + files: InterleaveFile[]; + cpdfUrl?: string; } interface InterleaveSuccessResponse { - status: 'success'; - pdfBytes: ArrayBuffer; + status: 'success'; + pdfBytes: ArrayBuffer; } interface InterleaveErrorResponse { - status: 'error'; - message: string; + status: 'error'; + message: string; } type InterleaveResponse = InterleaveSuccessResponse | InterleaveErrorResponse; diff --git a/public/workers/alternate-merge.worker.js b/public/workers/alternate-merge.worker.js index 5ed60e7..2e19b69 100644 --- a/public/workers/alternate-merge.worker.js +++ b/public/workers/alternate-merge.worker.js @@ -1,64 +1,109 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; -self.onmessage = function (e) { - const { command, files } = e.data; +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); - if (command === 'interleave') { - interleavePDFs(files); + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} + +self.onmessage = async function (e) { + const { command, files, cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + + if (command === 'interleave') { + interleavePDFs(files); + } }; function interleavePDFs(files) { - try { - const loadedPdfs = []; - const pageCounts = []; + try { + const loadedPdfs = []; + const pageCounts = []; - for (const file of files) { - const uint8Array = new Uint8Array(file.data); - const pdfDoc = coherentpdf.fromMemory(uint8Array, ""); - loadedPdfs.push(pdfDoc); - pageCounts.push(coherentpdf.pages(pdfDoc)); - } - - if (loadedPdfs.length < 2) { - throw new Error('At least two PDF files are required for interleaving.'); - } - - const maxPages = Math.max(...pageCounts); - - const pdfsToMerge = []; - const rangesToMerge = []; - - for (let i = 1; i <= maxPages; i++) { - for (let j = 0; j < loadedPdfs.length; j++) { - if (i <= pageCounts[j]) { - pdfsToMerge.push(loadedPdfs[j]); - rangesToMerge.push(coherentpdf.range(i, i)); - } - } - } - - if (pdfsToMerge.length === 0) { - throw new Error('No valid pages to merge.'); - } - - const mergedPdf = coherentpdf.mergeSame(pdfsToMerge, true, true, rangesToMerge); - - const mergedPdfBytes = coherentpdf.toMemory(mergedPdf, false, true); - const buffer = mergedPdfBytes.buffer; - coherentpdf.deletePdf(mergedPdf); - loadedPdfs.forEach(pdf => coherentpdf.deletePdf(pdf)); - - self.postMessage({ - status: 'success', - pdfBytes: buffer - }, [buffer]); - - } catch (error) { - self.postMessage({ - status: 'error', - message: error.message || 'Unknown error during interleave merge' - }); + for (const file of files) { + const uint8Array = new Uint8Array(file.data); + const pdfDoc = coherentpdf.fromMemory(uint8Array, ''); + loadedPdfs.push(pdfDoc); + pageCounts.push(coherentpdf.pages(pdfDoc)); } + + if (loadedPdfs.length < 2) { + throw new Error('At least two PDF files are required for interleaving.'); + } + + const maxPages = Math.max(...pageCounts); + + const pdfsToMerge = []; + const rangesToMerge = []; + + for (let i = 1; i <= maxPages; i++) { + for (let j = 0; j < loadedPdfs.length; j++) { + if (i <= pageCounts[j]) { + pdfsToMerge.push(loadedPdfs[j]); + rangesToMerge.push(coherentpdf.range(i, i)); + } + } + } + + if (pdfsToMerge.length === 0) { + throw new Error('No valid pages to merge.'); + } + + const mergedPdf = coherentpdf.mergeSame( + pdfsToMerge, + true, + true, + rangesToMerge + ); + + const mergedPdfBytes = coherentpdf.toMemory(mergedPdf, false, true); + const buffer = mergedPdfBytes.buffer; + coherentpdf.deletePdf(mergedPdf); + loadedPdfs.forEach((pdf) => coherentpdf.deletePdf(pdf)); + + self.postMessage( + { + status: 'success', + pdfBytes: buffer, + }, + [buffer] + ); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message || 'Unknown error during interleave merge', + }); + } } diff --git a/public/workers/edit-attachments.worker.d.ts b/public/workers/edit-attachments.worker.d.ts index fdca01a..0628209 100644 --- a/public/workers/edit-attachments.worker.d.ts +++ b/public/workers/edit-attachments.worker.d.ts @@ -4,6 +4,7 @@ interface GetAttachmentsMessage { command: 'get-attachments'; fileBuffer: ArrayBuffer; fileName: string; + cpdfUrl?: string; } interface EditAttachmentsMessage { @@ -11,13 +12,21 @@ interface EditAttachmentsMessage { fileBuffer: ArrayBuffer; fileName: string; attachmentsToRemove: number[]; + cpdfUrl?: string; } -type EditAttachmentsWorkerMessage = GetAttachmentsMessage | EditAttachmentsMessage; +type EditAttachmentsWorkerMessage = + | GetAttachmentsMessage + | EditAttachmentsMessage; interface GetAttachmentsSuccessResponse { status: 'success'; - attachments: Array<{ index: number; name: string; page: number; data: ArrayBuffer }>; + attachments: Array<{ + index: number; + name: string; + page: number; + data: ArrayBuffer; + }>; fileName: string; } @@ -37,6 +46,12 @@ interface EditAttachmentsErrorResponse { message: string; } -type GetAttachmentsResponse = GetAttachmentsSuccessResponse | GetAttachmentsErrorResponse; -type EditAttachmentsResponse = EditAttachmentsSuccessResponse | EditAttachmentsErrorResponse; -type EditAttachmentsWorkerResponse = GetAttachmentsResponse | EditAttachmentsResponse; \ No newline at end of file +type GetAttachmentsResponse = + | GetAttachmentsSuccessResponse + | GetAttachmentsErrorResponse; +type EditAttachmentsResponse = + | EditAttachmentsSuccessResponse + | EditAttachmentsErrorResponse; +type EditAttachmentsWorkerResponse = + | GetAttachmentsResponse + | EditAttachmentsResponse; diff --git a/public/workers/edit-attachments.worker.js b/public/workers/edit-attachments.worker.js index b935932..76be114 100644 --- a/public/workers/edit-attachments.worker.js +++ b/public/workers/edit-attachments.worker.js @@ -1,5 +1,24 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function getAttachmentsFromPDFInWorker(fileBuffer, fileName) { try { @@ -11,7 +30,7 @@ function getAttachmentsFromPDFInWorker(fileBuffer, fileName) { } catch (error) { self.postMessage({ status: 'error', - message: `Failed to load PDF: ${fileName}. Error: ${error.message || error}` + message: `Failed to load PDF: ${fileName}. Error: ${error.message || error}`, }); return; } @@ -23,7 +42,7 @@ function getAttachmentsFromPDFInWorker(fileBuffer, fileName) { self.postMessage({ status: 'success', attachments: [], - fileName: fileName + fileName: fileName, }); coherentpdf.deletePdf(pdf); return; @@ -37,13 +56,16 @@ function getAttachmentsFromPDFInWorker(fileBuffer, fileName) { const attachmentData = coherentpdf.getAttachmentData(i); const dataArray = new Uint8Array(attachmentData); - const buffer = dataArray.buffer.slice(dataArray.byteOffset, dataArray.byteOffset + dataArray.byteLength); + const buffer = dataArray.buffer.slice( + dataArray.byteOffset, + dataArray.byteOffset + dataArray.byteLength + ); attachments.push({ index: i, name: String(name), page: Number(page), - data: buffer + data: buffer, }); } catch (error) { console.warn(`Failed to get attachment ${i} from ${fileName}:`, error); @@ -56,22 +78,27 @@ function getAttachmentsFromPDFInWorker(fileBuffer, fileName) { const response = { status: 'success', attachments: attachments, - fileName: fileName + fileName: fileName, }; - const transferBuffers = attachments.map(att => att.data); + const transferBuffers = attachments.map((att) => att.data); self.postMessage(response, transferBuffers); } catch (error) { self.postMessage({ status: 'error', - message: error instanceof Error - ? error.message - : 'Unknown error occurred during attachment listing.' + message: + error instanceof Error + ? error.message + : 'Unknown error occurred during attachment listing.', }); } } -function editAttachmentsInPDFInWorker(fileBuffer, fileName, attachmentsToRemove) { +function editAttachmentsInPDFInWorker( + fileBuffer, + fileName, + attachmentsToRemove +) { try { const uint8Array = new Uint8Array(fileBuffer); @@ -81,7 +108,7 @@ function editAttachmentsInPDFInWorker(fileBuffer, fileName, attachmentsToRemove) } catch (error) { self.postMessage({ status: 'error', - message: `Failed to load PDF: ${fileName}. Error: ${error.message || error}` + message: `Failed to load PDF: ${fileName}. Error: ${error.message || error}`, }); return; } @@ -103,7 +130,7 @@ function editAttachmentsInPDFInWorker(fileBuffer, fileName, attachmentsToRemove) attachmentsToKeep.push({ name: String(name), page: Number(page), - data: dataCopy + data: dataCopy, }); } } @@ -114,9 +141,18 @@ function editAttachmentsInPDFInWorker(fileBuffer, fileName, attachmentsToRemove) for (const attachment of attachmentsToKeep) { if (attachment.page === 0) { - coherentpdf.attachFileFromMemory(attachment.data, attachment.name, pdf); + coherentpdf.attachFileFromMemory( + attachment.data, + attachment.name, + pdf + ); } else { - coherentpdf.attachFileToPageFromMemory(attachment.data, attachment.name, pdf, attachment.page); + coherentpdf.attachFileToPageFromMemory( + attachment.data, + attachment.name, + pdf, + attachment.page + ); } } } @@ -124,29 +160,58 @@ function editAttachmentsInPDFInWorker(fileBuffer, fileName, attachmentsToRemove) const modifiedBytes = coherentpdf.toMemory(pdf, false, true); coherentpdf.deletePdf(pdf); - const buffer = modifiedBytes.buffer.slice(modifiedBytes.byteOffset, modifiedBytes.byteOffset + modifiedBytes.byteLength); + const buffer = modifiedBytes.buffer.slice( + modifiedBytes.byteOffset, + modifiedBytes.byteOffset + modifiedBytes.byteLength + ); const response = { status: 'success', modifiedPDF: buffer, - fileName: fileName + fileName: fileName, }; self.postMessage(response, [response.modifiedPDF]); } catch (error) { self.postMessage({ status: 'error', - message: error instanceof Error - ? error.message - : 'Unknown error occurred during attachment editing.' + message: + error instanceof Error + ? error.message + : 'Unknown error occurred during attachment editing.', }); } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'get-attachments') { getAttachmentsFromPDFInWorker(e.data.fileBuffer, e.data.fileName); } else if (e.data.command === 'edit-attachments') { - editAttachmentsInPDFInWorker(e.data.fileBuffer, e.data.fileName, e.data.attachmentsToRemove); + editAttachmentsInPDFInWorker( + e.data.fileBuffer, + e.data.fileName, + e.data.attachmentsToRemove + ); } -}; \ No newline at end of file +}; diff --git a/public/workers/extract-attachments.worker.d.ts b/public/workers/extract-attachments.worker.d.ts index 2bf1a2d..a117630 100644 --- a/public/workers/extract-attachments.worker.d.ts +++ b/public/workers/extract-attachments.worker.d.ts @@ -4,6 +4,7 @@ interface ExtractAttachmentsMessage { command: 'extract-attachments'; fileBuffers: ArrayBuffer[]; fileNames: string[]; + cpdfUrl?: string; } interface ExtractAttachmentSuccessResponse { @@ -16,4 +17,6 @@ interface ExtractAttachmentErrorResponse { message: string; } -type ExtractAttachmentResponse = ExtractAttachmentSuccessResponse | ExtractAttachmentErrorResponse; \ No newline at end of file +type ExtractAttachmentResponse = + | ExtractAttachmentSuccessResponse + | ExtractAttachmentErrorResponse; diff --git a/public/workers/extract-attachments.worker.js b/public/workers/extract-attachments.worker.js index 1572d00..ca7e085 100644 --- a/public/workers/extract-attachments.worker.js +++ b/public/workers/extract-attachments.worker.js @@ -1,5 +1,24 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function extractAttachmentsFromPDFsInWorker(fileBuffers, fileNames) { try { @@ -37,7 +56,7 @@ function extractAttachmentsFromPDFsInWorker(fileBuffers, fileNames) { let uniqueName = attachmentName; let counter = 1; - while (allAttachments.some(att => att.name === uniqueName)) { + while (allAttachments.some((att) => att.name === uniqueName)) { const nameParts = attachmentName.split('.'); if (nameParts.length > 1) { const extension = nameParts.pop(); @@ -56,10 +75,13 @@ function extractAttachmentsFromPDFsInWorker(fileBuffers, fileNames) { allAttachments.push({ name: uniqueName, - data: attachmentData.buffer.slice(0) + data: attachmentData.buffer.slice(0), }); } catch (error) { - console.warn(`Failed to extract attachment ${j} from ${fileName}:`, error); + console.warn( + `Failed to extract attachment ${j} from ${fileName}:`, + error + ); } } @@ -70,21 +92,21 @@ function extractAttachmentsFromPDFsInWorker(fileBuffers, fileNames) { if (allAttachments.length === 0) { self.postMessage({ status: 'error', - message: 'No attachments were found in the selected PDF(s).' + message: 'No attachments were found in the selected PDF(s).', }); return; } const response = { status: 'success', - attachments: [] + attachments: [], }; const transferBuffers = []; for (const attachment of allAttachments) { response.attachments.push({ name: attachment.name, - data: attachment.data + data: attachment.data, }); transferBuffers.push(attachment.data); } @@ -93,15 +115,37 @@ function extractAttachmentsFromPDFsInWorker(fileBuffers, fileNames) { } catch (error) { self.postMessage({ status: 'error', - message: error instanceof Error - ? error.message - : 'Unknown error occurred during attachment extraction.' + message: + error instanceof Error + ? error.message + : 'Unknown error occurred during attachment extraction.', }); } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'extract-attachments') { extractAttachmentsFromPDFsInWorker(e.data.fileBuffers, e.data.fileNames); } -}; \ No newline at end of file +}; diff --git a/public/workers/json-to-pdf.worker.d.ts b/public/workers/json-to-pdf.worker.d.ts index 2da9dc4..9f824b4 100644 --- a/public/workers/json-to-pdf.worker.d.ts +++ b/public/workers/json-to-pdf.worker.d.ts @@ -4,6 +4,7 @@ interface ConvertJSONToPDFMessage { command: 'convert'; fileBuffers: ArrayBuffer[]; fileNames: string[]; + cpdfUrl?: string; } interface JSONToPDFSuccessResponse { @@ -17,4 +18,3 @@ interface JSONToPDFErrorResponse { } type JSONToPDFResponse = JSONToPDFSuccessResponse | JSONToPDFErrorResponse; - diff --git a/public/workers/json-to-pdf.worker.js b/public/workers/json-to-pdf.worker.js index 18d405c..e590c97 100644 --- a/public/workers/json-to-pdf.worker.js +++ b/public/workers/json-to-pdf.worker.js @@ -1,5 +1,24 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function convertJSONsToPDFInWorker(fileBuffers, fileNames) { try { @@ -15,13 +34,12 @@ function convertJSONsToPDFInWorker(fileBuffers, fileNames) { try { pdf = coherentpdf.fromJSONMemory(uint8Array); } catch (error) { - const errorMsg = error && error.message - ? error.message - : 'Unknown error'; + const errorMsg = + error && error.message ? error.message : 'Unknown error'; throw new Error( `Failed to convert "${fileName}" to PDF. ` + - `The JSON file must be in the format produced by cpdf's outputJSONMemory. ` + - `Error: ${errorMsg}` + `The JSON file must be in the format produced by cpdf's outputJSONMemory. ` + + `Error: ${errorMsg}` ); } @@ -56,9 +74,29 @@ function convertJSONsToPDFInWorker(fileBuffers, fileNames) { } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'convert') { convertJSONsToPDFInWorker(e.data.fileBuffers, e.data.fileNames); } }; - diff --git a/public/workers/merge.worker.d.ts b/public/workers/merge.worker.d.ts index 8e20242..168eacb 100644 --- a/public/workers/merge.worker.d.ts +++ b/public/workers/merge.worker.d.ts @@ -1,33 +1,34 @@ declare const coherentpdf: typeof import('../../src/types/coherentpdf.global').coherentpdf; interface MergeJob { - fileName: string; - rangeType: 'all' | 'specific' | 'single' | 'range'; - rangeString?: string; - pageIndex?: number; - startPage?: number; - endPage?: number; + fileName: string; + rangeType: 'all' | 'specific' | 'single' | 'range'; + rangeString?: string; + pageIndex?: number; + startPage?: number; + endPage?: number; } interface MergeFile { - name: string; - data: ArrayBuffer; + name: string; + data: ArrayBuffer; } interface MergeMessage { - command: 'merge'; - files: MergeFile[]; - jobs: MergeJob[]; + command: 'merge'; + files: MergeFile[]; + jobs: MergeJob[]; + cpdfUrl?: string; } interface MergeSuccessResponse { - status: 'success'; - pdfBytes: ArrayBuffer; + status: 'success'; + pdfBytes: ArrayBuffer; } interface MergeErrorResponse { - status: 'error'; - message: string; + status: 'error'; + message: string; } type MergeResponse = MergeSuccessResponse | MergeErrorResponse; diff --git a/public/workers/merge.worker.js b/public/workers/merge.worker.js index 23572cc..efca0fa 100644 --- a/public/workers/merge.worker.js +++ b/public/workers/merge.worker.js @@ -1,71 +1,116 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; -self.onmessage = function (e) { - const { command, files, jobs } = e.data; +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); - if (command === 'merge') { - mergePDFs(files, jobs); + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} + +self.onmessage = async function (e) { + const { command, files, jobs, cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + + if (command === 'merge') { + mergePDFs(files, jobs); + } }; function mergePDFs(files, jobs) { - try { - const loadedPdfs = {}; - const pdfsToMerge = []; - const rangesToMerge = []; + try { + const loadedPdfs = {}; + const pdfsToMerge = []; + const rangesToMerge = []; - for (const file of files) { - const uint8Array = new Uint8Array(file.data); - const pdfDoc = coherentpdf.fromMemory(uint8Array, ""); - loadedPdfs[file.name] = pdfDoc; - } - - for (const job of jobs) { - const sourcePdf = loadedPdfs[job.fileName]; - if (!sourcePdf) continue; - - let range; - if (job.rangeType === 'all') { - range = coherentpdf.all(sourcePdf); - } else if (job.rangeType === 'specific') { - if (coherentpdf.validatePagespec(job.rangeString)) { - range = coherentpdf.parsePagespec(sourcePdf, job.rangeString); - } else { - range = coherentpdf.all(sourcePdf); - } - } else if (job.rangeType === 'single') { - const pageNum = job.pageIndex + 1; - range = coherentpdf.range(pageNum, pageNum); - } else if (job.rangeType === 'range') { - range = coherentpdf.range(job.startPage, job.endPage); - } - - pdfsToMerge.push(sourcePdf); - rangesToMerge.push(range); - } - - if (pdfsToMerge.length === 0) { - throw new Error('No valid files or pages to merge.'); - } - - const mergedPdf = coherentpdf.mergeSame(pdfsToMerge, true, true, rangesToMerge); - - const mergedPdfBytes = coherentpdf.toMemory(mergedPdf, false, true); - const buffer = mergedPdfBytes.buffer; - - coherentpdf.deletePdf(mergedPdf); - Object.values(loadedPdfs).forEach(pdf => coherentpdf.deletePdf(pdf)); - - self.postMessage({ - status: 'success', - pdfBytes: buffer - }, [buffer]); - - } catch (error) { - self.postMessage({ - status: 'error', - message: error.message || 'Unknown error during merge' - }); + for (const file of files) { + const uint8Array = new Uint8Array(file.data); + const pdfDoc = coherentpdf.fromMemory(uint8Array, ''); + loadedPdfs[file.name] = pdfDoc; } + + for (const job of jobs) { + const sourcePdf = loadedPdfs[job.fileName]; + if (!sourcePdf) continue; + + let range; + if (job.rangeType === 'all') { + range = coherentpdf.all(sourcePdf); + } else if (job.rangeType === 'specific') { + if (coherentpdf.validatePagespec(job.rangeString)) { + range = coherentpdf.parsePagespec(sourcePdf, job.rangeString); + } else { + range = coherentpdf.all(sourcePdf); + } + } else if (job.rangeType === 'single') { + const pageNum = job.pageIndex + 1; + range = coherentpdf.range(pageNum, pageNum); + } else if (job.rangeType === 'range') { + range = coherentpdf.range(job.startPage, job.endPage); + } + + pdfsToMerge.push(sourcePdf); + rangesToMerge.push(range); + } + + if (pdfsToMerge.length === 0) { + throw new Error('No valid files or pages to merge.'); + } + + const mergedPdf = coherentpdf.mergeSame( + pdfsToMerge, + true, + true, + rangesToMerge + ); + + const mergedPdfBytes = coherentpdf.toMemory(mergedPdf, false, true); + const buffer = mergedPdfBytes.buffer; + + coherentpdf.deletePdf(mergedPdf); + Object.values(loadedPdfs).forEach((pdf) => coherentpdf.deletePdf(pdf)); + + self.postMessage( + { + status: 'success', + pdfBytes: buffer, + }, + [buffer] + ); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message || 'Unknown error during merge', + }); + } } diff --git a/public/workers/pdf-to-json.worker.d.ts b/public/workers/pdf-to-json.worker.d.ts index fe50026..d72dd44 100644 --- a/public/workers/pdf-to-json.worker.d.ts +++ b/public/workers/pdf-to-json.worker.d.ts @@ -4,6 +4,7 @@ interface ConvertPDFToJSONMessage { command: 'convert'; fileBuffers: ArrayBuffer[]; fileNames: string[]; + cpdfUrl?: string; } interface PDFToJSONSuccessResponse { @@ -17,4 +18,3 @@ interface PDFToJSONErrorResponse { } type PDFToJSONResponse = PDFToJSONSuccessResponse | PDFToJSONErrorResponse; - diff --git a/public/workers/pdf-to-json.worker.js b/public/workers/pdf-to-json.worker.js index 03f67f7..4eb87fd 100644 --- a/public/workers/pdf-to-json.worker.js +++ b/public/workers/pdf-to-json.worker.js @@ -1,5 +1,24 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function convertPDFsToJSONInWorker(fileBuffers, fileNames) { try { @@ -12,8 +31,6 @@ function convertPDFsToJSONInWorker(fileBuffers, fileNames) { const uint8Array = new Uint8Array(buffer); const pdf = coherentpdf.fromMemory(uint8Array, ''); - //TODO:@ALAM -> add options for users to select these settings - // parse_content: true, no_stream_data: false, decompress_streams: false const jsonData = coherentpdf.outputJSONMemory(true, false, false, pdf); const jsonBuffer = jsonData.buffer.slice(0); @@ -44,9 +61,29 @@ function convertPDFsToJSONInWorker(fileBuffers, fileNames) { } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'convert') { convertPDFsToJSONInWorker(e.data.fileBuffers, e.data.fileNames); } }; - diff --git a/public/workers/table-of-contents.worker.d.ts b/public/workers/table-of-contents.worker.d.ts index 7f53354..11c914d 100644 --- a/public/workers/table-of-contents.worker.d.ts +++ b/public/workers/table-of-contents.worker.d.ts @@ -7,6 +7,7 @@ interface GenerateTOCMessage { fontSize: number; fontFamily: number; addBookmark: boolean; + cpdfUrl?: string; } interface TOCSuccessResponse { diff --git a/public/workers/table-of-contents.worker.js b/public/workers/table-of-contents.worker.js index 088debb..43f82dc 100644 --- a/public/workers/table-of-contents.worker.js +++ b/public/workers/table-of-contents.worker.js @@ -1,5 +1,24 @@ -const baseUrl = self.location.href.substring(0, self.location.href.lastIndexOf('/workers/') + 1); -self.importScripts(baseUrl + 'coherentpdf.browser.min.js'); +let cpdfLoaded = false; + +function loadCpdf(cpdfUrl) { + if (cpdfLoaded) return Promise.resolve(); + + return new Promise((resolve, reject) => { + if (typeof coherentpdf !== 'undefined') { + cpdfLoaded = true; + resolve(); + return; + } + + try { + self.importScripts(cpdfUrl); + cpdfLoaded = true; + resolve(); + } catch (error) { + reject(new Error('Failed to load CoherentPDF: ' + error.message)); + } + }); +} function generateTableOfContentsInWorker( pdfData, @@ -49,7 +68,28 @@ function generateTableOfContentsInWorker( } } -self.onmessage = (e) => { +self.onmessage = async function (e) { + const { cpdfUrl } = e.data; + + if (!cpdfUrl) { + self.postMessage({ + status: 'error', + message: + 'CoherentPDF URL not provided. Please configure it in WASM Settings.', + }); + return; + } + + try { + await loadCpdf(cpdfUrl); + } catch (error) { + self.postMessage({ + status: 'error', + message: error.message, + }); + return; + } + if (e.data.command === 'generate-toc') { generateTableOfContentsInWorker( e.data.pdfData, diff --git a/scripts/generate-i18n-pages.mjs b/scripts/generate-i18n-pages.mjs new file mode 100644 index 0000000..52da337 --- /dev/null +++ b/scripts/generate-i18n-pages.mjs @@ -0,0 +1,271 @@ +import fs from 'fs'; +import path from 'path'; +import { JSDOM } from 'jsdom'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const DIST_DIR = path.resolve(__dirname, '../dist'); +const LOCALES_DIR = path.resolve(__dirname, '../public/locales'); +const SITE_URL = process.env.SITE_URL || 'https://bentopdf.com'; +const BASE_PATH = (process.env.BASE_URL || '/').replace(/\/$/, ''); + +const languages = fs.readdirSync(LOCALES_DIR).filter((file) => { + return fs.statSync(path.join(LOCALES_DIR, file)).isDirectory(); +}); + +const toCamelCase = (str) => { + return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); +}; + +const KEY_MAPPING = { + index: 'home', + 404: 'notFound', +}; + +function loadAllTranslations() { + const translations = {}; + for (const lang of languages) { + if (lang === 'en') continue; + const commonPath = path.join(LOCALES_DIR, `${lang}/common.json`); + const toolsPath = path.join(LOCALES_DIR, `${lang}/tools.json`); + translations[lang] = { + common: fs.existsSync(commonPath) + ? JSON.parse(fs.readFileSync(commonPath, 'utf-8')) + : {}, + tools: fs.existsSync(toolsPath) + ? JSON.parse(fs.readFileSync(toolsPath, 'utf-8')) + : {}, + }; + } + return translations; +} + +// TODO@ALAM: Let users build only a single language +function buildUrl(langPrefix, pagePath) { + const parts = [SITE_URL]; + if (BASE_PATH && BASE_PATH !== '') parts.push(BASE_PATH.replace(/^\//, '')); + if (langPrefix) parts.push(langPrefix); + if (pagePath) parts.push(pagePath.replace(/^\//, '')); + return parts.filter(Boolean).join('/').replace(/\/+$/, '') || SITE_URL; +} + +function processFileForLanguage( + originalContent, + file, + lang, + translations, + langDir +) { + const filenameNoExt = file.replace('.html', ''); + let translationKey = toCamelCase(filenameNoExt); + if (KEY_MAPPING[filenameNoExt]) { + translationKey = KEY_MAPPING[filenameNoExt]; + } + + const { tools } = translations[lang]; + const dom = new JSDOM(originalContent); + const document = dom.window.document; + + document.documentElement.lang = lang; + + let title = null; + let description = null; + + if (tools[translationKey]) { + title = + tools[translationKey].pageTitle || + (tools[translationKey].name + ? `${tools[translationKey].name} - BentoPDF` + : null); + description = tools[translationKey].subtitle; + } + + if (title) { + document.title = title; + const metaTitle = document.querySelector('meta[property="og:title"]'); + if (metaTitle) metaTitle.content = title; + const metaTwitterTitle = document.querySelector( + 'meta[name="twitter:title"]' + ); + if (metaTwitterTitle) metaTwitterTitle.content = title; + } + + if (description) { + const metaDesc = document.querySelector('meta[name="description"]'); + if (metaDesc) metaDesc.content = description; + const metaOgDesc = document.querySelector( + 'meta[property="og:description"]' + ); + if (metaOgDesc) metaOgDesc.content = description; + const metaTwitterDesc = document.querySelector( + 'meta[name="twitter:description"]' + ); + if (metaTwitterDesc) metaTwitterDesc.content = description; + } + + document + .querySelectorAll('link[rel="alternate"][hreflang]') + .forEach((el) => el.remove()); + + const pagePath = filenameNoExt === 'index' ? '' : filenameNoExt; + + languages.forEach((l) => { + const link = document.createElement('link'); + link.rel = 'alternate'; + link.hreflang = l; + link.href = buildUrl(l === 'en' ? '' : l, pagePath); + document.head.appendChild(link); + }); + + const defaultLink = document.createElement('link'); + defaultLink.rel = 'alternate'; + defaultLink.hreflang = 'x-default'; + defaultLink.href = buildUrl('', pagePath); + document.head.appendChild(defaultLink); + + let canonical = document.querySelector('link[rel="canonical"]'); + if (!canonical) { + canonical = document.createElement('link'); + canonical.rel = 'canonical'; + document.head.appendChild(canonical); + } + canonical.href = buildUrl(lang, pagePath); + + const links = document.querySelectorAll('a[href]'); + links.forEach((link) => { + const href = link.getAttribute('href'); + if (!href) return; + + if ( + href.startsWith('http') || + href.startsWith('//') || + href.startsWith('#') || + href.startsWith('mailto:') || + href.startsWith('tel:') || + href.startsWith('javascript:') + ) { + return; + } + + if (href.startsWith('/assets/') || href.includes('/assets/')) return; + + const langPrefixRegex = new RegExp( + `^(${BASE_PATH})?/(${languages.join('|')})(/|$)` + ); + if (langPrefixRegex.test(href)) return; + + let newHref; + if (href.startsWith('/')) { + const pathWithoutBase = href.startsWith(BASE_PATH) + ? href.slice(BASE_PATH.length) + : href; + newHref = `${BASE_PATH}/${lang}${pathWithoutBase}`; + } else { + newHref = `${BASE_PATH}/${lang}/${href}`; + } + + link.setAttribute('href', newHref); + }); + + const result = dom.serialize(); + + dom.window.close(); + + fs.writeFileSync(path.join(langDir, file), result); +} + +function updateEnglishFile(filePath, originalContent) { + const filenameNoExt = path.basename(filePath, '.html'); + const dom = new JSDOM(originalContent); + const document = dom.window.document; + + document + .querySelectorAll('link[rel="alternate"][hreflang]') + .forEach((el) => el.remove()); + + const pagePath = filenameNoExt === 'index' ? '' : filenameNoExt; + + languages.forEach((l) => { + const link = document.createElement('link'); + link.rel = 'alternate'; + link.hreflang = l; + link.href = buildUrl(l === 'en' ? '' : l, pagePath); + document.head.appendChild(link); + }); + + const defaultLink = document.createElement('link'); + defaultLink.rel = 'alternate'; + defaultLink.hreflang = 'x-default'; + defaultLink.href = buildUrl('', pagePath); + document.head.appendChild(defaultLink); + + const result = dom.serialize(); + + dom.window.close(); + + fs.writeFileSync(filePath, result); +} + +async function generateI18nPages() { + console.log('๐ŸŒ Generating i18n pages...'); + console.log(` SITE_URL: ${SITE_URL}`); + console.log(` BASE_PATH: ${BASE_PATH || '/'}`); + console.log(` Languages: ${languages.length} (${languages.join(', ')})`); + + if (!fs.existsSync(DIST_DIR)) { + console.error('โŒ dist directory not found. Please run build first.'); + process.exit(1); + } + + console.log(' Loading translations...'); + const translations = loadAllTranslations(); + + const htmlFiles = fs + .readdirSync(DIST_DIR) + .filter((file) => file.endsWith('.html')); + + console.log(` Processing ${htmlFiles.length} HTML files...`); + + for (const lang of languages) { + if (lang === 'en') continue; + const langDir = path.join(DIST_DIR, lang); + if (!fs.existsSync(langDir)) { + fs.mkdirSync(langDir, { recursive: true }); + } + } + + let processed = 0; + const total = htmlFiles.length * (languages.length - 1); + + for (const file of htmlFiles) { + const filePath = path.join(DIST_DIR, file); + const originalContent = fs.readFileSync(filePath, 'utf-8'); + + for (const lang of languages) { + if (lang === 'en') continue; + + const langDir = path.join(DIST_DIR, lang); + + processFileForLanguage( + originalContent, + file, + lang, + translations, + langDir + ); + + processed++; + if (processed % 10 === 0 || processed === total) { + console.log(` Progress: ${processed}/${total} pages`); + } + } + + updateEnglishFile(filePath, originalContent); + } + + console.log('โœ… i18n pages generated successfully!'); +} + +generateI18nPages().catch(console.error); diff --git a/scripts/generate-sitemap.mjs b/scripts/generate-sitemap.mjs new file mode 100644 index 0000000..7a587fd --- /dev/null +++ b/scripts/generate-sitemap.mjs @@ -0,0 +1,117 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const DIST_DIR = path.resolve(__dirname, '../dist'); +const LOCALES_DIR = path.resolve(__dirname, '../public/locales'); +const SITE_URL = process.env.SITE_URL || 'https://www.bentopdf.com'; + +const languages = fs.readdirSync(LOCALES_DIR).filter((file) => { + return fs.statSync(path.join(LOCALES_DIR, file)).isDirectory(); +}); + +const PRIORITY_MAP = { + index: 1.0, + tools: 0.9, + 'pdf-converter': 0.9, + 'pdf-editor': 0.9, + 'pdf-security': 0.9, + 'pdf-merge-split': 0.9, + 'merge-pdf': 0.9, + 'split-pdf': 0.9, + 'compress-pdf': 0.9, + 'edit-pdf': 0.9, + 'word-to-pdf': 0.9, + 'excel-to-pdf': 0.9, + 'powerpoint-to-pdf': 0.9, + 'jpg-to-pdf': 0.9, + 'pdf-to-docx': 0.9, + 'pdf-to-excel': 0.9, + 'pdf-to-jpg': 0.9, + about: 0.8, + faq: 0.8, + contact: 0.7, + privacy: 0.5, + terms: 0.5, + licensing: 0.5, + 404: 0.1, +}; + +function getPriority(pageName) { + return PRIORITY_MAP[pageName] || 0.7; +} + +function buildUrl(lang, pageName) { + const pagePath = pageName === 'index' ? '' : pageName; + if (lang === 'en') { + return pagePath ? `${SITE_URL}/${pagePath}` : SITE_URL; + } + return pagePath ? `${SITE_URL}/${lang}/${pagePath}` : `${SITE_URL}/${lang}`; +} + +function generateSitemap() { + console.log('๐Ÿ—บ๏ธ Generating multilingual sitemap...'); + console.log(` SITE_URL: ${SITE_URL}`); + console.log(` Languages: ${languages.join(', ')}`); + + // Get all HTML files from dist root (English pages) + const htmlFiles = fs + .readdirSync(DIST_DIR) + .filter((file) => file.endsWith('.html')) + .map((file) => file.replace('.html', '')); + + const today = new Date().toISOString().split('T')[0]; + + let sitemap = ` + +`; + + for (const pageName of htmlFiles) { + const priority = getPriority(pageName); + + // Generate entry for each language + for (const lang of languages) { + const url = buildUrl(lang, pageName); + + sitemap += ` + ${url} + ${today} + weekly + ${priority} +`; + + // Add hreflang alternates for all languages + for (const altLang of languages) { + const altUrl = buildUrl(altLang, pageName); + sitemap += ` +`; + } + + // Add x-default pointing to English + const defaultUrl = buildUrl('en', pageName); + sitemap += ` + +`; + } + } + + sitemap += ` +`; + + const sitemapPath = path.join(DIST_DIR, 'sitemap.xml'); + fs.writeFileSync(sitemapPath, sitemap); + + const publicSitemapPath = path.resolve(__dirname, '../public/sitemap.xml'); + fs.writeFileSync(publicSitemapPath, sitemap); + + const urlCount = htmlFiles.length * languages.length; + console.log( + `โœ… Sitemap generated with ${urlCount} URLs (${htmlFiles.length} pages ร— ${languages.length} languages)` + ); +} + +generateSitemap(); diff --git a/scripts/release.js b/scripts/release.js index 696024a..de257ae 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -80,7 +80,9 @@ function main() { execSync('npm run update-version', { stdio: 'inherit' }); // 3. Add and commit changes - execSync('git add package.json *.html src/pages/*.html', { stdio: 'inherit' }); + execSync('git add package.json *.html src/pages/*.html', { + stdio: 'inherit', + }); execSync(`git commit -m "Release v${newVersion}"`, { stdio: 'inherit' }); console.log(`๐Ÿ’พ Committed version change`); @@ -98,7 +100,7 @@ function main() { execSync(`git push origin ${tagName}`, { stdio: 'inherit' }); console.log(`๐ŸŽ‰ Release v${newVersion} complete!`); - console.log(`๐Ÿ“ฆ Docker image: bentopdf/bentopdf:${newVersion}`); + console.log(`๐Ÿ“ฆ Docker image: bentopdfteam/bentopdf:${newVersion}`); console.log(`๐Ÿ“ฆ Distribution: dist-${newVersion}.zip`); console.log( `๐Ÿท๏ธ GitHub release: https://github.com/alam00000/bentopdf/releases/tag/${tagName}` diff --git a/scripts/update-partials.js b/scripts/update-partials.js new file mode 100644 index 0000000..8d86acf --- /dev/null +++ b/scripts/update-partials.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node +/** + * Script to update all HTML files in src/pages to use Handlebars partials + * for navbar and footer + */ + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const pagesDir = path.join(__dirname, '..', 'src', 'pages'); + +// Get all HTML files in src/pages +const htmlFiles = fs.readdirSync(pagesDir).filter((f) => f.endsWith('.html')); + +console.log(`Found ${htmlFiles.length} HTML files to process...`); + +let updatedCount = 0; +let skippedCount = 0; + +for (const file of htmlFiles) { + const filePath = path.join(pagesDir, file); + let content = fs.readFileSync(filePath, 'utf-8'); + let modified = false; + + // Check if already using partials + if (content.includes('{{> navbar }}') && content.includes('{{> footer }}')) { + console.log(` [SKIP] ${file} - already using partials`); + skippedCount++; + continue; + } + + // Replace navbar - match from